import numpy as np

class VSA_bipolar(object):
    '''
    A class for the bipolar VSA (real values)
    '''
    def __init__(self,nDim):
        self.nDim=nDim # number of dimensions
        return

    def generate_vector(self,n):
        '''
        function that generates 'n' random vectors with uniform distributed values between -1 and 1
        :param n: number of vectors
        :return: the n generated vectors (row-vectors)
        '''
        v=np.random.uniform(low=-1, high=1, size=(n, self.nDim))
        return v

    def bundle(self,vector_array):
        '''
        bundle input vectors
        :param vector_array: vectors in an array (rows represent the vectors)
        :return: the bundled vector
        '''
        bundled_v=np.sum(vector_array,axis=0)
        bundled_v[np.where(bundled_v < -1)] = -1
        bundled_v[np.where(bundled_v > 1)] = 1
        return bundled_v


    def bind(self,v1,v2):
        '''
        bind two input vectors
        :param v1: input vector 1
        :param v2: input vector 2
        :return: bound vector
        '''
        bound_v=np.multiply(v1, v2)

        return bound_v

    def unbind(self,v1,v2):
        '''
        unbind the first from the second input vector
        :param v1: input vector 1
        :param v2: input vector 2
        :return: unbound vector
        '''
        unbound_v = np.multiply(v1, v2)

        return unbound_v

    def sim(self,v1,v2):
        '''
        compute the similarity (cosine) between two given vectors
        :param v1: input vector 1
        :param v2: input vector 2
        :return: scalar of the similarity
        '''
        s=np.dot(v1,np.transpose(v2))/(np.linalg.norm(v1)*np.linalg.norm(v2))
        return s



