def _mul_vector(self, other): M, N = self.shape # output array resultl = np.zeros(M, dtype=upcast_char(self.dtype.char, other.dtype.char)) resultu = np.zeros(M, dtype=upcast_char(self.dtype.char, other.dtype.char)) # csr_matvec or csc_matvec fnl = getattr(_sparsetools, self.format + '_matvec') fnl(M, N, self.indptr, self.indices, self.data, other, resultl) upper = self.transpose() # fnu = getattr(_sparsetools, upper.format + '_matvec') # fnu(M, N, upper.indptr, upper.indices, upper.data, other, resultu) csc_matvec_no_diag(N, upper.indptr, upper.indices, upper.data, other, resultu) # diagonal = self.diagonal() # result = np.zeros(M, dtype=upcast_char(self.dtype.char, other.dtype.char)) # sym_csr_matvec(M, self.indptr, self.indices, self.data, other, result) # return result return resultl + resultu # - np.multiply(other, diagonal)
def _mul_multivector(self, other): x = other if self.shift == 0: # Very simple case, handle separately return np.multiply.outer(self.get_dense_column(), other.sum(axis=0)) elif self.shift < 0: # Reverse input and roll first element back to first index x = np.concatenate(([x[0]], x[:0:-1])) shift = abs(self.shift) if shift == 1: x_folded = np.zeros((self.shape[0], x.shape[1]), dtype=other.dtype) for i in range(0, self.shape[1], self.shape[0]): x_part = x[i:i + self.shape[0]] x_folded[:len(x_part)] += x_part else: x_folded = np.column_stack([ np.bincount((np.arange(len(col)) * shift) % self.shape[0], col, self.shape[0]) for col in x.T ]) return np.fft.irfft( self.get_fourier_column()[:, None] * np.fft.rfft(x_folded, axis=0), n=self.shape[0], axis=0).astype( sputils.upcast_char(self.dtype.char, other.dtype.char))
def _mul_vector(self, other): x = np.ravel(other) if self.shift == 0: # Very simple case, handle separately return self.get_dense_column() * x.sum() elif self.shift < 0: # Reverse input and roll first element back to first index x = np.concatenate(([x[0]], x[:0:-1])) shift = abs(self.shift) if shift == 1: x_folded = np.zeros(self.shape[0], dtype=other.dtype) for i in range(0, self.shape[1], self.shape[0]): x_part = x[i:i + self.shape[0]] x_folded[:len(x_part)] += x_part else: x_folded = np.bincount((np.arange(len(x)) * shift) % self.shape[0], x, self.shape[0]) return np.fft.irfft(self.get_fourier_column() * np.fft.rfft(x_folded), n=self.shape[0]).astype( sputils.upcast_char(self.dtype.char, other.dtype.char))
def _mul_multivector(self, other): y = np.zeros( (self.shape[0], other.shape[1]), dtype=sputils.upcast_char(self.dtype.char, other.dtype.char) ) if self.shift == 0: y[:] = self.data.dot(other[self.offsets]) return y period = min(self.shape[0], abs(np.lcm(self.shift, self.shape[1])//self.shift)) y0 = np.fft.irfft( self.get_conjugate_fourier_row()[:, None]*np.fft.rfft(other, axis=0), n=self.shape[1], axis=0 ) y[:period] = y0[(self.shift*np.arange(period))%len(y0)] for i in range(period, self.shape[0], period): src = y[i - period:i] dst = y[i:i + period] size = min(len(src), len(dst)) dst[:size] = src[:size] return y
def _mul_vector(self, other): x = np.ravel(other) y = np.zeros( self.shape[0], dtype=sputils.upcast_char(self.dtype.char, other.dtype.char) ) if self.shift == 0: y0 = self.block @ x for i in range(self.n_blocks): y[i*len(y0):(i + 1)*len(y0)] = y0 return y n0 = self.block.shape[0] period = min(self.n_blocks, abs(np.lcm(self.shift, self.shape[1])//self.shift)) xr = np.empty_like(x) for i in range(period): # Equivalent to `xr = np.roll(x, -i*self.shift)``, but faster offset = -i*self.shift if offset == 0: xr[:] = x else: xr[:offset] = x[-offset:] xr[offset:] = x[:-offset] y[i*n0:(i + 1)*n0] += self.block @ xr row_period = n0*period y0 = y[:row_period] for i in range(row_period, self.shape[0], row_period): y[i:i + row_period] = y0[:len(y) - i] return y
def _add_dense(self, other): if other.shape != self.shape: raise ValueError('Incompatible shapes.') dtype = upcast_char(self.dtype.char, other.dtype.char) order = self._swap('CF')[0] result = np.array(other, dtype=dtype, order=order, copy=True) M, N = self._swap(self.shape) y = result if result.flags.c_contiguous else result.T csr_todense(M, N, self.indptr, self.indices, self.data, y) return matrix(result, copy=False)
def __init__(self, blocks, dtype=None): ns, ms = zip(*[block.shape for block in blocks]) assert min(ms) == max(ms) self._shape = sum(ns), ms[0] self.blocks = blocks self.dtype = dtype or np.dtype( sputils.upcast_char(*[block.dtype.char for block in blocks]))
def _mul_vector(self, other): M, N = self.shape # output array resultl = np.zeros(M, dtype=upcast_char(self.dtype.char, other.dtype.char)) resultu = np.zeros(M, dtype=upcast_char(self.dtype.char, other.dtype.char)) # csr_matvec or csc_matvec fnl = getattr(_sparsetools, self.format + '_matvec') fnl(M, N, self.indptr, self.indices, self.data, other, resultl) upper = self.transpose() csr_matvec_no_diag(M, upper.indptr, upper.indices, upper.data, other, resultu) return resultl + resultu
def _mul_vector(self, other): M, N = self.shape # output array result = np.zeros(M, dtype=upcast_char(self.dtype.char, other.dtype.char)) # csr_matvec or csc_matvec sparse.csr_matvec(M, N, self.indptr, self.indices, self.data, other, result) return result
def _mul_multivector(self, other): y = np.zeros((self.shape[0], other.shape[1]), dtype=sputils.upcast_char(self.dtype.char, other.dtype.char)) offset = 0 for block in self.blocks: y[offset:offset + block.shape[0]] += block @ other offset += block.shape[0] return y
def _mul_multivector(self, other): M,N = self.shape n_vecs = other.shape[1] # number of column vectors result = np.zeros((M,n_vecs), dtype=upcast_char(self.dtype.char, other.dtype.char)) # csr_matvecs or csc_matvecs fn = getattr(_sparsetools,self.format + '_matvecs') fn(M, N, n_vecs, self.indptr, self.indices, self.data, other.ravel(), result.ravel()) return result
def _mul_vector(self, other): M,N = self.shape # output array result = np.zeros(M, dtype=upcast_char(self.dtype.char, other.dtype.char)) # csr_matvec or csc_matvec fn = getattr(_sparsetools,self.format + '_matvec') fn(M, N, self.indptr, self.indices, self.data, other, result) return result
def _mul_vector(self, other): x = np.ravel(other) y = np.zeros(self.shape[0], dtype=sputils.upcast_char(self.dtype.char, other.dtype.char)) offset = 0 for block in self.blocks: y[offset:offset + block.shape[0]] += block @ x offset += block.shape[0] return y
def _mul_vector(self, other): xs = other.reshape(self.n_blocks, self.block.shape[1]) y = np.zeros( self.shape[0], dtype=sputils.upcast_char(self.dtype.char, other.dtype.char) ) for i in range(self.n_blocks): y0 = self.block @ xs[i] offset = (i*self.shift)%self.shape[0] if offset == 0: y += y0 else: y[:offset] += y0[-offset:] y[offset:] += y0[:-offset] return y
def _mul_vector(self, other): #output array result = np.zeros(self.shape[0], dtype=upcast_char(self.dtype.char, other.dtype.char)) coo_matvec(self.nnz, self.row, self.col, self.data, other, result) return result