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;
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;
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);
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)
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)
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();
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;
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
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
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
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;
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);