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 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 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