Example #1
0
 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_dimscehck(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;
Example #2
0
 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;
Example #3
0
    def totensor(self):
        sz = self.tsize;
        order = numpy.concatenate((self.rindices, self.cindices));
        order = order.tolist();
        data = self.data.reshape(tools.getelts(sz,order));

        data = tensor.tensor(data).ipermute(order).data;

        return tensor.tensor(data, sz);
Example #4
0
    def totensor(self):
        sz = self.tsize
        order = numpy.concatenate((self.rindices, self.cindices))
        order = order.tolist()
        data = self.data.reshape(tools.getelts(sz, order))

        data = tensor.tensor(data).ipermute(order).data

        return tensor.tensor(data, sz)
Example #5
0
    def __init__(self, T, rdim=None, cdim=None, tsiz=None, option=None):
        """Create a sptenmat object from a given ndarray or sptensor T"""

        if (rdim != None and rdim.__class__ == list):
            rdim = numpy.array(rdim)
        if (cdim != None and cdim.__class__ == list):
            cdim = numpy.array(cdim)
        if (tsiz != None and tsiz.__class__ == list):
            tsiz = numpy.array(tsiz)

        #subs, vals, rdims, cdims, tsize are all given

        #When I is a (2-D) ndarray or sptensor, and rdim, cdim, tsiz are given
        if (rdim != None and cdim != None and tsiz != None):

            B = T.flatten().reshape(len(T), T.size / len(T))
            subs = []
            vals = []
            maxrowind = 0
            maxcolind = 0
            for i in range(0, len(B)):
                for j in range(0, len(B[0])):
                    if (B[i][j] != 0):
                        subs.extend([[i, j]])
                        vals.extend([B[i][j]])
                        if (i > maxrowind): maxrowind = i
                        if (j > maxcolind): maxcolind = j

            self.subs = numpy.array(subs)
            self.vals = numpy.array(vals)
            self.rdims = rdim.copy()
            self.cdims = cdim.copy()
            self.tsize = tsiz

            n = len(self.tsize)

            temp = numpy.concatenate((self.rdims, self.cdims))
            temp.sort()
            if not ((numpy.arange(n) == temp).all()):
                raise ValueError("Incorrect specification of dimensions")
            if (tools.getelts(self.tsize, self.rdims).prod() < maxrowind):
                raise ValueError("error, invalid row index")
            if (tools.getelts(self.tsize, self.cdims).prod() < maxcolind):
                raise ValueError("error, invalid column index")
            return

        # T is a sptensor
        T = T.copy()
        self.tsize = T.shape
        self.subs = T.subs
        self.vals = T.vals
        n = T.ndims()

        if (rdim != None):
            if (cdim != None):
                self.rdims = rdim
                self.cdims = cdim

            elif (option != None):
                if (option == 'fc'):
                    self.rdims = rdim
                    if (self.rdims.size != 1):
                        raise ValueError(
                            "only one row dimension for 'fc' option")

                    self.cdims = []
                    for i in range(self.rdim[0] + 1, n):
                        self.cdims.append(i)
                    for i in range(0, self.rdim[0]):
                        self.cdims.append(i)
                    self.cdims = numpy.array(self.cdims)

                elif (option == 'bc'):
                    self.rdims = rdim
                    if (self.rdims.size != 1):
                        raise ValueError(
                            "only one row dimension for 'bc' option")

                    self.cdims = []
                    for i in range(0, self.rdim[0])[::-1]:
                        self.cdims.append(i)
                    for i in range(self.rdim[0] + 1, n)[::-1]:
                        self.cdims.append(i)
                    self.cdims = numpy.array(self.cdims)

                else:
                    raise ValueError("unknown option: {0}".format(option))

            else:
                self.rdims = rdim
                self.cdims = tools.notin(n, self.rdims)

        elif (cdim != None):
            self.cdims = cdim
            if (option == 't'):
                self.rdims = tools.notin(n, self.cdims)
            else:
                raise ValueError("unknown option: {0}".format(option))
        else:
            raise ValueError("Both rdims and cdims are None")

        #error check
        temp = numpy.concatenate((self.rdims, self.cdims))
        temp.sort()
        if not ((numpy.arange(n) == temp).all()):
            raise ValueError("Incorrect specification of dimensions")

        rsize = tools.getelts(self.tsize, self.rdims)
        csize = tools.getelts(self.tsize, self.cdims)

        if (len(rsize) == 0):
            ridx = numpy.ndarray([T.nnz()])
            ridx.fill(0)
        else:
            temp1 = []
            for i in range(0, len(self.subs)):
                temp2 = []
                for j in range(0, len(self.rdims)):
                    temp2.extend([self.subs[i][self.rdims[j]]])
                temp1.extend([temp2])
            temp1 = numpy.array(temp1)
            ridx = tools.sub2ind(rsize, temp1)

        if (len(csize) == 0):
            cidx = numpy.ndarray([T.nnz()])
            cidx.fill(0)

        else:
            temp1 = []
            for i in range(0, len(self.subs)):
                temp2 = []
                for j in range(0, len(self.cdims)):
                    temp2.extend([self.subs[i][self.cdims[j]]])
                temp1.extend([temp2])

            temp1 = numpy.array(temp1)
            cidx = tools.sub2ind(csize, temp1)

        self.subs = []
        for i in range(0, len(ridx)):
            self.subs.extend([[ridx[i][0], cidx[i][0]]])
        self.subs = numpy.array(self.subs)
Example #6
0
    def ttm(self, mat, dims = None, option = None):
        """ 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_dimscehck(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(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();
Example #7
0
    def __init__(self, T, rdim = None, cdim = None, tsiz = None, option = None):

        if(rdim is not None and rdim.__class__ == list):
            rdim = numpy.array(rdim);
        if(cdim is not None and cdim.__class__ == list):
            cdim = numpy.array(cdim);
        if(tsiz is not None and tsiz.__class__ == list):
            tsiz = numpy.array(tsiz);


    #constructor for the call tenmat(A, RDIMS, CDIMS, TSIZE)
        if(rdim is not None and cdim is not None and tsiz is not None):
            if(T.__class__ == numpy.ndarray):
                # self.data = T.copy();
                self.data = T
            if(T.__class__ == tensor.tensor):
                # self.data = T.data.copy();
                self.data = T.data
            self.rindices = rdim;
            self.cindices = cdim;
            # self.tsize = tuple(tsiz);
            self.tsize = tsiz

            n = len(self.tsize);

            temp = numpy.concatenate((self.rindices,self.cindices));
            temp.sort();
            if not ((numpy.arange(n) == temp).all()):
                raise ValueError("Incorrect specification of dimensions");
            elif (tools.getelts(self.tsize, self.rindices).prod()
                  != len(self.data)):
                raise ValueError("size(T,0) does not match size specified");
            elif (tools.getelts(self.tsize, self.cindices).prod()
                  != len(self.data[0])):
                raise ValueError("size(T,1) does not match size specified");

            return;



    #convert tensor to a tenmat
        if(rdim is None and cdim is None):
            self.data = None;
            self.rindices = None;
            self.cindices = None;
            self.tsize = None;
            return
        #     raise ValueError("Both of rdim and cdim are not given");

        # T = T.copy(); #copy the tensor


        self.tsize = numpy.array(T.shape);
        n = T.ndims();

        if (rdim is not None):
            if(cdim is not None):
                rdims = rdim;
                cdims = cdim;
            elif(option is not None):
                if(option == 'fc'):
                    rdims = rdim;
                    if(rdims.size != 1):
                        raise ValueError("only one row dimension for 'fc' option");

                    cdims = [];
                    for i in range(rdim[0]+1,n):
                        cdims.append(i);
                    for i in range(0, rdim[0]):
                        cdims.append(i);
                    cdims = numpy.array(cdims);


                elif(option == 'bc'):
                    rdims = rdim;
                    if(rdims.size != 1):
                        raise ValueError("only one row dimension for 'bc' option");
                    cdims = [];
                    for i in range(0, rdim[0])[::-1]:
                        cdims.append(i);
                    for i in range(rdim[0]+1,n)[::-1]:
                        cdims.append(i);
                    cdims = numpy.array(cdims);

                elif(option == 't'):
                    cdims = rdim
                    rdims = tools.notin(n, cdims)


                else:
                    raise ValueError("unknown option {0}".format(option));

            #一般只指定rdims的执行这里
            else:
                rdims = rdim;
                cdims = tools.notin(n, rdims);

        else:
            if(option == 't'):
                cdims = cdim;
                rdims = tools.notin(n, cdims);
            else:
                raise ValueError("unknown option {0}".format(option));


        #error check
        temp = numpy.concatenate((rdims,cdims));
        temp.sort();
        if not ((numpy.arange(n) == temp).all()):
            raise ValueError("error, Incorrect specification of dimensions");


        #permute T so that the dimensions specified by RDIMS come first

        #!!!! order of data in ndarray is different from that in Matlab!
        #this is (kind of odd process) needed to conform the result with Matlab!
        #lis = list(T.shape);
        #temp = lis[T.ndims()-1];
        #lis[T.ndims()-1] = lis[T.ndims()-2];
        #lis[T.ndims()-2] = temp;
        #T.data = T.data.reshape(lis).swapaxes(T.ndims()-1, T.ndims()-2);
        #print T;


        #T = T.permute([T.ndims()-1, T.ndims()-2]+(range(0,T.ndims()-2)));
        #print T;

        # ------原始是permute------------
        # T = T.permute(numpy.concatenate((rdims,cdims)));


        #convert T to a matrix;

        # -------这里我改成了without_copy

        T = T.permute_without_copy(numpy.concatenate((rdims,cdims)));


        row = tools.getelts(self.tsize, rdims).prod()
        col = tools.getelts(self.tsize, cdims).prod()

        self.data = T.data.reshape([row, col]);
        self.rindices = rdims;
        self.cindices = cdims;
Example #8
0
    def __init__(self, T, rdim=None, cdim=None, tsiz=None, option=None):
        """ 
        A matricized tensor object.
        Converting a tensor to a matrix requires an ordered mapping of the tensor indices for the rows and columns
        """
        if (rdim != None and rdim.__class__ == list):
            rdim = numpy.array(rdim)
        if (cdim != None and cdim.__class__ == list):
            cdim = numpy.array(cdim)
        if (tsiz != None and tsiz.__class__ == list):
            tsiz = numpy.array(tsiz)

        #constructor for the call tenmat(A, RDIMS, CDIMS, TSIZE)
        if (rdim != None and cdim != None and tsiz != None):
            if (T.__class__ == numpy.ndarray):
                self.data = T.copy()
            if (T.__class__ == tensor.tensor):
                self.data = T.data.copy()
            self.rindices = rdim
            self.cindices = cdim
            self.tsize = tuple(tsiz)

            n = len(self.tsize)

            temp = numpy.concatenate((self.rindices, self.cindices))
            temp.sort()
            if not ((numpy.arange(n) == temp).all()):
                raise ValueError("Incorrect specification of dimensions")
            elif (tools.getelts(self.tsize, self.rindices).prod() != len(
                    self.data)):
                raise ValueError("size(T,0) does not match size specified")
            elif (tools.getelts(self.tsize, self.cindices).prod() != len(
                    self.data[0])):
                raise ValueError("size(T,1) does not match size specified")

            return

        #convert tensor to a tenmat
        if (rdim == None and cdim == None):
            raise ValueError("Both of rdim and cdim are not given")

        T = T.copy()
        #copy the tensor
        self.tsize = T.shape
        n = T.ndims()

        if (rdim != None):
            if (cdim != None):
                rdims = rdim
                cdims = cdim
            elif (option != None):
                if (option == 'fc'):
                    rdims = rdim
                    if (rdims.size != 1):
                        raise ValueError(
                            "only one row dimension for 'fc' option")

                    cdims = []
                    for i in range(rdim[0] + 1, n):
                        cdims.append(i)
                    for i in range(0, rdim[0]):
                        cdims.append(i)
                    cdims = numpy.array(cdims)

                elif (option == 'bc'):
                    rdims = rdim
                    if (rdims.size != 1):
                        raise ValueError(
                            "only one row dimension for 'bc' option")
                    cdims = []
                    for i in range(0, rdim[0])[::-1]:
                        cdims.append(i)
                    for i in range(rdim[0] + 1, n)[::-1]:
                        cdims.append(i)
                    cdims = numpy.array(cdims)

                else:
                    raise ValueError("unknown option {0}".format(option))

            else:
                rdims = rdim
                cdims = tools.notin(n, rdims)

        else:
            if (option == 't'):
                cdims = cdim
                rdims = tools.notin(n, cdims)
            else:
                raise ValueError("unknown option {0}".format(option))

        #error check
        temp = numpy.concatenate((rdims, cdims))
        temp.sort()
        if not ((numpy.arange(n) == temp).all()):
            raise ValueError("error, Incorrect specification of dimensions")

        #permute T so that the dimensions specified by RDIMS come first

        #!!!! order of data in ndarray is different from that in Matlab!
        #this is (kind of odd process) needed to conform the result with Matlab!
        #lis = list(T.shape);
        #temp = lis[T.ndims()-1];
        #lis[T.ndims()-1] = lis[T.ndims()-2];
        #lis[T.ndims()-2] = temp;
        #T.data = T.data.reshape(lis).swapaxes(T.ndims()-1, T.ndims()-2);
        #print T;

        #T = T.permute([T.ndims()-1, T.ndims()-2]+(range(0,T.ndims()-2)));
        #print T;
        T = T.permute(numpy.concatenate((rdims, cdims)))
        #convert T to a matrix;

        row = tools.getelts(self.tsize, rdims).prod()
        col = tools.getelts(self.tsize, cdims).prod()

        self.data = T.data.reshape([row, col], order='F')
        self.rindices = rdims
        self.cindices = cdims
Example #9
0
    def ttm(self, mat, dims = None, option = None):
        """ 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_dimscehck(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(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();
Example #10
0
    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_dimscehck(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))

        # 第一步把对应模I Permute到第一个,然后reshape成(I,I~)
        # 第二步matrix * 上面得到的矩阵

        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)
        # 这里的ipermute很关键,按照相反permute,理解的不是很直观,有时间可以多想想
        Y = Y.ipermute(order)
        return Y
Example #11
0
    def __init__(self, T, rdim=None, cdim=None, tsiz=None, option=None):
        """ 
        A matricized tensor object.
        Converting a tensor to a matrix requires an ordered mapping of the tensor indices for the rows and columns
        """
        if rdim != None and rdim.__class__ == list:
            rdim = numpy.array(rdim)
        if cdim != None and cdim.__class__ == list:
            cdim = numpy.array(cdim)
        if tsiz != None and tsiz.__class__ == list:
            tsiz = numpy.array(tsiz)

        # constructor for the call tenmat(A, RDIMS, CDIMS, TSIZE)
        if rdim != None and cdim != None and tsiz != None:
            if T.__class__ == numpy.ndarray:
                self.data = T.copy()
            if T.__class__ == tensor.tensor:
                self.data = T.data.copy()
            self.rindices = rdim
            self.cindices = cdim
            self.tsize = tuple(tsiz)

            n = len(self.tsize)

            temp = numpy.concatenate((self.rindices, self.cindices))
            temp.sort()
            if not ((numpy.arange(n) == temp).all()):
                raise ValueError("Incorrect specification of dimensions")
            elif tools.getelts(self.tsize, self.rindices).prod() != len(self.data):
                raise ValueError("size(T,0) does not match size specified")
            elif tools.getelts(self.tsize, self.cindices).prod() != len(self.data[0]):
                raise ValueError("size(T,1) does not match size specified")

            return

        # convert tensor to a tenmat
        if rdim == None and cdim == None:
            raise ValueError("Both of rdim and cdim are not given")

        T = T.copy()
        # copy the tensor
        self.tsize = T.shape
        n = T.ndims()

        if rdim != None:
            if cdim != None:
                rdims = rdim
                cdims = cdim
            elif option != None:
                if option == "fc":
                    rdims = rdim
                    if rdims.size != 1:
                        raise ValueError("only one row dimension for 'fc' option")

                    cdims = []
                    for i in range(rdim[0] + 1, n):
                        cdims.append(i)
                    for i in range(0, rdim[0]):
                        cdims.append(i)
                    cdims = numpy.array(cdims)

                elif option == "bc":
                    rdims = rdim
                    if rdims.size != 1:
                        raise ValueError("only one row dimension for 'bc' option")
                    cdims = []
                    for i in range(0, rdim[0])[::-1]:
                        cdims.append(i)
                    for i in range(rdim[0] + 1, n)[::-1]:
                        cdims.append(i)
                    cdims = numpy.array(cdims)

                else:
                    raise ValueError("unknown option {0}".format(option))

            else:
                rdims = rdim
                cdims = tools.notin(n, rdims)

        else:
            if option == "t":
                cdims = cdim
                rdims = tools.notin(n, cdims)
            else:
                raise ValueError("unknown option {0}".format(option))

        # error check
        temp = numpy.concatenate((rdims, cdims))
        temp.sort()
        if not ((numpy.arange(n) == temp).all()):
            raise ValueError("error, Incorrect specification of dimensions")

        # permute T so that the dimensions specified by RDIMS come first

        #!!!! order of data in ndarray is different from that in Matlab!
        # this is (kind of odd process) needed to conform the result with Matlab!
        # lis = list(T.shape);
        # temp = lis[T.ndims()-1];
        # lis[T.ndims()-1] = lis[T.ndims()-2];
        # lis[T.ndims()-2] = temp;
        # T.data = T.data.reshape(lis).swapaxes(T.ndims()-1, T.ndims()-2);
        # print T;

        # T = T.permute([T.ndims()-1, T.ndims()-2]+(range(0,T.ndims()-2)));
        # print T;
        T = T.permute(numpy.concatenate((rdims, cdims)))
        # convert T to a matrix;

        row = tools.getelts(self.tsize, rdims).prod()
        col = tools.getelts(self.tsize, cdims).prod()

        self.data = T.data.reshape([row, col], order="F")
        self.rindices = rdims
        self.cindices = cdims
Example #12
0
    def __init__(self, T, rdim = None, cdim = None, tsiz = None, option = None):
        
        if(rdim != None and rdim.__class__ == list):
            rdim = numpy.array(rdim);
        if(cdim != None and cdim.__class__ == list):
            cdim = numpy.array(cdim);
        if(tsiz != None and tsiz.__class__ == list):
            tsiz = numpy.array(tsiz);        
    

    #constructor for the call tenmat(A, RDIMS, CDIMS, TSIZE)
        if(rdim != None and cdim != None and tsiz != None):
            if(T.__class__ == numpy.ndarray):
                self.data = T.copy();
            if(T.__class__ == tensor.tensor):
                self.data = T.data.copy();
            self.rindices = rdim;
            self.cindices = cdim;
            self.tsize = tuple(tsiz);
    
            n = len(self.tsize);
            
            temp = numpy.concatenate((self.rindices,self.cindices));
            temp.sort();
            if not ((numpy.arange(n) == temp).all()):
                raise ValueError("Incorrect specification of dimensions");
            elif (tools.getelts(self.tsize, self.rindices).prod()
                  != len(self.data)):
                raise ValueError("size(T,0) does not match size specified");
            elif (tools.getelts(self.tsize, self.cindices).prod()
                  != len(self.data[0])):
                raise ValueError("size(T,1) does not match size specified");
              
            return;
        
    
    
    #convert tensor to a tenmat
        if(rdim == None and cdim == None):
            raise ValueError("Both of rdim and cdim are not given");
        
        T = T.copy(); #copy the tensor
        self.tsize = T.shape;
        n = T.ndims();
        
        if (rdim != None):
            if(cdim != None):
                rdims = rdim;
                cdims = cdim;
            elif(option != None):
                if(option == 'fc'):
                    rdims = rdim;
                    if(rdims.size != 1):
                        raise ValueError("only one row dimension for 'fc' option");
                        
                    cdims = [];
                    for i in range(rdim[0]+1,n):
                        cdims.append(i);
                    for i in range(0, rdim[0]):
                        cdims.append(i);
                    cdims = numpy.array(cdims);
                    
                    
                elif(option == 'bc'):
                    rdims = rdim;
                    if(rdims.size != 1):
                        raise ValueError("only one row dimension for 'bc' option");                    
                    cdims = [];
                    for i in range(0, rdim[0])[::-1]:
                        cdims.append(i);
                    for i in range(rdim[0]+1,n)[::-1]:
                        cdims.append(i);
                    cdims = numpy.array(cdims);
                    
                else:
                    raise ValueError("unknown option {0}".format(option));
                    
            else:
                rdims = rdim;
                cdims = tools.notin(n, rdims);
        
        else:
            if(option == 't'):
                cdims = cdim;
                rdims = tools.notin(n, cdims);
            else:
                raise ValueError("unknown option {0}".format(option));
        
        
        #error check
        temp = numpy.concatenate((rdims,cdims));
        temp.sort();
        if not ((numpy.arange(n) == temp).all()):
            raise ValueError("error, Incorrect specification of dimensions");
        
            
        #permute T so that the dimensions specified by RDIMS come first
        
        #!!!! order of data in ndarray is different from that in Matlab!
        #this is (kind of odd process) needed to conform the result with Matlab!
        #lis = list(T.shape);
        #temp = lis[T.ndims()-1];
        #lis[T.ndims()-1] = lis[T.ndims()-2];
        #lis[T.ndims()-2] = temp;
        #T.data = T.data.reshape(lis).swapaxes(T.ndims()-1, T.ndims()-2);
        #print T;
        
        
        #T = T.permute([T.ndims()-1, T.ndims()-2]+(range(0,T.ndims()-2)));
        #print T;  
        T = T.permute(numpy.concatenate((rdims,cdims)));
        #convert T to a matrix;
        
        row = tools.getelts(self.tsize, rdims).prod()
        col = tools.getelts(self.tsize, cdims).prod()
        
        self.data = T.data.reshape([row, col]);
        self.rindices = rdims;
        self.cindices = cdims;
Example #13
0
 def __init__(self, T, rdim = None, cdim = None, tsiz = None, option = None):
     """Create a sptenmat object from a given ndarray or sptensor T"""
            
     if(rdim != None and rdim.__class__ == list):
         rdim = numpy.array(rdim);
     if(cdim != None and cdim.__class__ == list):
         cdim = numpy.array(cdim);
     if(tsiz != None and tsiz.__class__ == list):
         tsiz = numpy.array(tsiz);
     
     #subs, vals, rdims, cdims, tsize are all given
     
     #When I is a (2-D) ndarray or sptensor, and rdim, cdim, tsiz are given
     if(rdim != None and cdim != None and tsiz != None):
         
         B = T.flatten().reshape(len(T), T.size / len(T));
         subs = [];
         vals = [];
         maxrowind = 0;
         maxcolind = 0;
         for i in range(0,len(B)):
             for j in range(0, len(B[0])):
                 if(B[i][j] != 0):
                     subs.extend([[i,j]]);
                     vals.extend([B[i][j]]);
                     if(i > maxrowind): maxrowind = i;
                     if(j > maxcolind): maxcolind = j;
         
         self.subs = numpy.array(subs);
         self.vals = numpy.array(vals);
         self.rdims = rdim.copy();
         self.cdims = cdim.copy();
         self.tsize = tsiz;
         
         n = len(self.tsize);
         
         temp = numpy.concatenate((self.rdims,self.cdims));
         temp.sort();
         if not ((numpy.arange(n) == temp).all()):
             raise ValueError ("Incorrect specification of dimensions");
         if (tools.getelts(self.tsize, self.rdims).prod() < maxrowind):
             raise ValueError ("error, invalid row index");
         if (tools.getelts(self.tsize, self.cdims).prod() < maxcolind):
             raise ValueError ("error, invalid column index");
         return;
 
 
     # T is a sptensor
     T = T.copy();
     self.tsize = T.shape;
     self.subs = T.subs;
     self.vals = T.vals;
     n = T.ndims();
     
     if (rdim != None):
         if(cdim != None):
             self.rdims = rdim;
             self.cdims = cdim;
             
         elif(option != None):
             if(option == 'fc'):
                 self.rdims = rdim;
                 if(self.rdims.size != 1):
                     raise ValueError ("only one row dimension for 'fc' option");
                 
                 self.cdims = [];
                 for i in range(self.rdim[0]+1,n):
                     self.cdims.append(i);
                 for i in range(0, self.rdim[0]):
                     self.cdims.append(i);
                 self.cdims = numpy.array(self.cdims);
                 
                 
             elif(option == 'bc'):
                 self.rdims = rdim;
                 if(self.rdims.size != 1):
                     raise ValueError ("only one row dimension for 'bc' option");
                 
                 
                 self.cdims = [];
                 for i in range(0, self.rdim[0])[::-1]:
                     self.cdims.append(i);
                 for i in range(self.rdim[0]+1,n)[::-1]:
                     self.cdims.append(i);
                 self.cdims = numpy.array(self.cdims);
                                     
             else:
                 raise ValueError ("unknown option: {0}".format(option));
         
         else:
             self.rdims = rdim;
             self.cdims = tools.notin(n, self.rdims);
             
     elif(cdim != None):
         self.cdims = cdim;
         if(option == 't'):
             self.rdims = tools.notin(n, self.cdims);
         else:
             raise ValueError ("unknown option: {0}".format(option));
     else:
         raise ValueError("Both rdims and cdims are None");
 
 
     #error check
     temp = numpy.concatenate((self.rdims,self.cdims));
     temp.sort();
     if not ((numpy.arange(n) == temp).all()):
         raise ValueError ("Incorrect specification of dimensions");
         
     rsize = tools.getelts(self.tsize, self.rdims);
     csize = tools.getelts(self.tsize, self.cdims);
     
     
     if (len(rsize) == 0):
         ridx = numpy.ndarray([T.nnz()]);
         ridx.fill(0);
     else:
         temp1 = [];
         for i in range (0, len(self.subs)):
             temp2 = [];
             for j in range(0, len(self.rdims)):
                 temp2.extend([self.subs[i][self.rdims[j]]]);
             temp1.extend([temp2]);
         temp1 = numpy.array(temp1);
         ridx = tools.sub2ind(rsize, temp1);
         
 
     if (len(csize) == 0):
         cidx = numpy.ndarray([T.nnz()]);
         cidx.fill(0);
         
     else:
         temp1 = [];
         for i in range (0, len(self.subs)):
             temp2 = [];
             for j in range(0, len(self.cdims)):
                 temp2.extend([self.subs[i][self.cdims[j]]]);
             temp1.extend([temp2]);
             
         temp1 = numpy.array(temp1);
         cidx = tools.sub2ind(csize, temp1);
         
     
     self.subs = [];
     for i in range(0,len(ridx)):
         self.subs.extend([[ridx[i][0], cidx[i][0]]]);
     self.subs = numpy.array(self.subs);