示例#1
0
文件: tensor.py 项目: ykpku/TaGiTed
 def ttm(self, mat, dims = None, option = None):
     """ computes the tensor times the given matrix.
     arrs is a single 2-D matrix/array or a list of those matrices/arrays."""
     
     if(dims == None):
         dims = range(0,self.ndims());
     
     #Handle when arrs is a list of arrays
     if(mat.__class__ == list):
         if(len(mat) == 0):
             raise ValueError("the given list of arrays is empty!");
         
         (dims,vidx) = tools.tt_dimscheck(dims, self.ndims(), len(mat));
         
         Y = self.ttm(mat[vidx[0]],dims[0],option);
         for i in range(1, len(dims)):
             Y = Y.ttm(mat[vidx[i]],dims[i],option);
             
         return Y;                
     
     if(mat.ndim != 2):
         raise ValueError ("matrix in 2nd armuent must be a matrix!");
     
     if(dims.__class__ == list):
         if(len(dims) != 1):
             raise ValueError("Error in number of elements in dims");
         else:
             dims = dims[0];
     
     if(dims < 0 or dims > self.ndims()):
         raise ValueError ("Dimension N must be between 1 and num of dimensions");
     
     
     #Compute the product
     
     N = self.ndims();
     shp = self.shape;
     order = []
     order.extend([dims]);
     order.extend(range(0,dims));
     order.extend(range(dims+1,N));
     
     newdata = self.permute(order).data;
     newdata = newdata.reshape(shp[dims], tools.prod(shp)/shp[dims]);
     if(option == None):
         newdata = numpy.dot(mat, newdata);
         p = mat.shape[0];
     elif(option == 't'):
         newdata = numpy.dot(mat.transpose(), newdata);
         p = mat.shape[1];
     else:
         raise ValueError("Unknown option");
     
     newshp = [p];
     newshp.extend(tools.getelts(shp,range(0,dims)));
     newshp.extend(tools.getelts(shp,range(dims+1,N)));
     
     Y = tensor(newdata, newshp);
     Y = Y.ipermute(order);
     return Y;
示例#2
0
文件: tensor.py 项目: ykpku/TaGiTed
    def ttv(self, v, dims):
        """ Tensor times vector
        
        Parameters
        ----------
        v - column vector 
        d - dimensions

        Returns
        -------
        out : Khatri-Rao product as a numpy array
        """
        (dims,vidx) = tools.tt_dimscheck(dims, self.ndims(), len(v));
        remdims = numpy.setdiff1d(range(self.ndims()), dims);
        if self.ndims() > 1:
            c = self.permute(numpy.concatenate((remdims, dims))).data;
        
        n = self.ndims()-1;
        sz = numpy.array(self.shape)[numpy.concatenate((remdims, dims))]
        for i in range(len(dims)-1, -1, -1):
            c = c.reshape(numpy.prod(sz[0:n]), sz[n], order='F')
            c = numpy.dot(c, v[vidx[i]]);
            n = n-1;
        
        if n > 0:
            c = tensor.tensor(c, sz[0:n]);
        else:
            c = c[0];
        
        return c;
示例#3
0
    def ttv(self, v, dims):
        """ Tensor times vector
        
        Parameters
        ----------
        v - column vector 
        d - dimensions

        Returns
        -------
        out : Khatri-Rao product as a numpy array
        """
        (dims,vidx) = tools.tt_dimscheck(dims, self.ndims(), len(v));
        remdims = numpy.setdiff1d(range(self.ndims()), dims);
        if self.ndims() > 1:
            c = self.permute(numpy.concatenate((remdims, dims))).data;
        
        n = self.ndims()-1;
        sz = numpy.array(self.shape)[numpy.concatenate((remdims, dims))]
        for i in range(len(dims)-1, -1, -1):
            c = c.reshape(numpy.prod(sz[0:n]), sz[n], order='F')
            c = numpy.dot(c, v[vidx[i]]);
            n = n-1;
        
        if n > 0:
            c = tensor.tensor(c, sz[0:n]);
        else:
            c = c[0];
        
        return c;
示例#4
0
    def ttv(self, v, dims):
        """ 
        Computes the product of this tensor with the column vector along
        specified dimensions.
        
        Parameters
        ----------
        v - column vector 
        d - dimensions to multiply the product

        Returns
        -------
        out : a sparse tensor if 50% or fewer nonzeros
        """

        (dims, vidx) = tools.tt_dimscheck(dims, self.ndims(), len(v))
        remdims = numpy.setdiff1d(range(self.ndims()), dims)
        newvals = self.vals
        subs = self.subs

        # Multiple each value by the appropriate elements of the appropriate vector
        for n in range(len(dims)):
            idx = subs[:, dims[n]]
            # extract indices for dimension n
            w = v[vidx[n]]
            # extract nth vector
            bigw = w[idx]
            # stretch out the vector
            newvals = numpy.multiply(newvals.flatten(), bigw)

        # Case 0: all dimensions specified - return the sum
        if len(remdims) == 0:
            c = numpy.sum(newvals)
            return c

        # Otherwise figure out the subscripts and accumulate the results
        newsubs = self.subs[:, remdims]
        newsiz = numpy.array(self.shape)[remdims]

        # Case 1: return a vector
        if len(remdims) == 1:
            c = tools.accum_np(newsubs, newvals, newsiz[0])
            #if numpy.count_nonzero(c) < 0.5*newsiz[0]:
            #    c = sptensor.sptensor(numpy.arange(newsiz[0]).reshape(newsiz[0],1), c.reshape(newsiz[0],1));
            #else:
            c = tensor.tensor(c, newsiz)
            return c

        # Case 2: result is a multi-way array
        c = sptensor.sptensor(newsubs, newvals.reshape(len(newvals), 1),
                              newsiz)
        # check to see if it's dense
        if c.nnz() > 0.5 * numpy.prod(c.shape):
            return c.totensor()
        return c
示例#5
0
    def ttv(self, v, dims):
        """ 
        Computes the product of this tensor with the column vector along
        specified dimensions.
        
        Parameters
        ----------
        v - column vector 
        d - dimensions to multiply the product

        Returns
        -------
        out : a sparse tensor if 50% or fewer nonzeros
        """
        
        (dims, vidx) = tools.tt_dimscheck(dims, self.ndims(), len(v));
        remdims = numpy.setdiff1d(range(self.ndims()), dims);
        newvals = self.vals;
        subs = self.subs;
        
        # Multiple each value by the appropriate elements of the appropriate vector
        for n in range(len(dims)):
            idx = subs[:, dims[n]]; # extract indices for dimension n
            w = v[vidx[n]];         # extract nth vector
            bigw = w[idx];          # stretch out the vector
            newvals = numpy.multiply(newvals.flatten(), bigw);
            
        # Case 0: all dimensions specified - return the sum
        if len(remdims) == 0: 
            c = numpy.sum(newvals);
            return c;
        
        # Otherwise figure out the subscripts and accumulate the results
        newsubs = self.subs[:, remdims];
        newsiz = numpy.array(self.shape)[remdims];
        
        # Case 1: return a vector
        if len(remdims) == 1:
            c = tools.accum_np(newsubs, newvals, newsiz[0]);
            #if numpy.count_nonzero(c) < 0.5*newsiz[0]:
            #    c = sptensor.sptensor(numpy.arange(newsiz[0]).reshape(newsiz[0],1), c.reshape(newsiz[0],1));
            #else:
            c = tensor.tensor(c, newsiz);
            return c;
        
        # Case 2: result is a multi-way array
        c = sptensor.sptensor(newsubs, newvals.reshape(len(newvals), 1), newsiz);
        # check to see if it's dense
        if c.nnz() > 0.5*numpy.prod(c.shape):
            return c.totensor();
        return c;
示例#6
0
    def ttv(self, vec, dims=None):
        if (dims is None):
            dims = range(0, self.ndims())

        if (vec.__class__ == list):
            if (len(vec) == 0):
                raise ValueError("the given list of arrays is empty!")

                (dims, vidx) = tools.tt_dimscheck(dims, self.ndims(), len(vec))
                Y = self.ttv(vec[vidx[0]], dims[0])
                for i in range(1, len(dims)):
                    Y = Y.ttv(vec[videx[i]], dims[i])

                return Y
        if (vec.ndim != 1):
            raise ValueError("param in 2nd argment must be a vector")

        if (dims.__class__ == list):
            if (len(dims) != 1):
                raise ValueError("Error in number of elements in dims")
            else:
                dims = dims[0]

        if (dims < 0 or dims > self.ndims()):
            raise ValueError(
                "Dimension N must be between 1 and num of dimensions")

        N = self.ndims()
        shp = self.shape
        order = []
        order.extend(range(0, dims))
        order.extend(range(dims + 1, N))
        order.extend([dims])

        newdata = self.permute(order).data
        newdata = newdata.reshape(tools.prod(shp) / shp[dims], shp[dims])

        newdata = numpy.dot(newdata, vec)
        N -= 1

        sz = numpy.array(self.shape)[order]
        newshp = sz[:N]

        # newshp = []
        # newshp.extend(tools.getelts(shp, range(0, dims)))
        # newshp.extend(tools.getelts(shp, range(dims+1, N)))

        Y = tensor(newdata, newshp)
        return Y
示例#7
0
    def ttm(self, mat, dims=None, option=None, without=False):
        """ computes the sptensor times the given matrix.
        arrs is a single 2-D matrix/array or a list of those matrices/arrays."""

        if (dims == None):
            dims = range(0, self.ndims())

        #Handle when arrs is a list of arrays
        if (mat.__class__ == list):
            if (len(mat) == 0):
                raise ValueError("the given list of arrays is empty!")

            (dims, vidx) = tools.tt_dimscheck(dims,
                                              self.ndims(),
                                              len(mat),
                                              exceptdims=without)

            Y = self.ttm(mat[vidx[0]], dims[0], option)
            for i in range(1, len(dims)):
                Y = Y.ttm(mat[vidx[i]], dims[i], option)

            return Y

        if (mat.ndim != 2):
            raise ValueError("matrix in 2nd armuent must be a matrix!")

        if (option != None):
            if (option == 't'):
                mat = mat.transpose()
            else:
                raise ValueError("unknown option.")

        if (dims.__class__ == list):
            if (len(dims) != 1):
                raise ValueError("Error in number of elements in dims")
            else:
                dims = dims[0]

        if (dims < 0 or dims > self.ndims()):
            raise ValueError(
                "Dimension N must be between 1 and num of dimensions")

        #Check that sizes match
        if (self.shape[dims] != mat.shape[1]):
            raise ValueError("size mismatch on V")

        #Compute the new size
        newsiz = list(self.shape)
        newsiz[dims] = mat.shape[0]

        #Compute Xn
        Xnt = sptenmat.sptenmat(self, None, [dims], None, 't')
        rdims = Xnt.rdims
        cdims = Xnt.cdims

        I = []
        J = []
        for i in range(0, len(Xnt.subs)):
            I.extend([Xnt.subs[i][0]])
            J.extend([Xnt.subs[i][1]])

        Z = (sparse.coo_matrix(
            (Xnt.vals.flatten(), (I, J)),
            shape=(tools.getelts(Xnt.tsize, Xnt.rdims).prod(),
                   tools.getelts(Xnt.tsize, Xnt.cdims).prod())) *
             mat.transpose())

        Z = tensor.tensor(Z, newsiz).tosptensor()

        if (Z.nnz() <= 0.5 * numpy.array(newsiz).prod()):
            Ynt = sptenmat.sptenmat(Z, rdims, cdims)
            return Ynt.tosptensor()
        else:
            Ynt = tenmat.tenmat(Z.totensor(), rdims, cdims)
            return Ynt.totensor()