def estimate_blocksize(A,efficiency=0.7): """Attempt to determine the blocksize of a sparse matrix Returns a blocksize=(r,c) such that - A.nnz / A.tobsr( (r,c) ).nnz > efficiency """ if not (isspmatrix_csr(A) or isspmatrix_csc(A)): A = csr_matrix(A) if A.nnz == 0: return (1,1) if not 0 < efficiency < 1.0: raise ValueError,'efficiency must satisfy 0.0 < efficiency < 1.0' high_efficiency = (1.0 + efficiency) / 2.0 nnz = float(A.nnz) M,N = A.shape if M % 2 == 0 and N % 2 == 0: e22 = nnz / ( 4 * count_blocks(A,(2,2)) ) else: e22 = 0.0 if M % 3 == 0 and N % 3 == 0: e33 = nnz / ( 9 * count_blocks(A,(3,3)) ) else: e33 = 0.0 if e22 > high_efficiency and e33 > high_efficiency: e66 = nnz / ( 36 * count_blocks(A,(6,6)) ) if e66 > efficiency: return (6,6) else: return (3,3) else: if M % 4 == 0 and N % 4 == 0: e44 = nnz / ( 16 * count_blocks(A,(4,4)) ) else: e44 = 0.0 if e44 > efficiency: return (4,4) elif e33 > efficiency: return (3,3) elif e22 > efficiency: return (2,2) else: return (1,1)
def estimate_blocksize(A, efficiency=0.7): """Attempt to determine the blocksize of a sparse matrix Returns a blocksize=(r,c) such that - A.nnz / A.tobsr( (r,c) ).nnz > efficiency """ if not (isspmatrix_csr(A) or isspmatrix_csc(A)): A = csr_matrix(A) if A.nnz == 0: return (1, 1) if not 0 < efficiency < 1.0: raise ValueError('efficiency must satisfy 0.0 < efficiency < 1.0') high_efficiency = (1.0 + efficiency) / 2.0 nnz = float(A.nnz) M, N = A.shape if M % 2 == 0 and N % 2 == 0: e22 = nnz / (4 * count_blocks(A, (2, 2))) else: e22 = 0.0 if M % 3 == 0 and N % 3 == 0: e33 = nnz / (9 * count_blocks(A, (3, 3))) else: e33 = 0.0 if e22 > high_efficiency and e33 > high_efficiency: e66 = nnz / (36 * count_blocks(A, (6, 6))) if e66 > efficiency: return (6, 6) else: return (3, 3) else: if M % 4 == 0 and N % 4 == 0: e44 = nnz / (16 * count_blocks(A, (4, 4))) else: e44 = 0.0 if e44 > efficiency: return (4, 4) elif e33 > efficiency: return (3, 3) elif e22 > efficiency: return (2, 2) else: return (1, 1)
def _mul_sparse_matrix(self, other): M, K1 = self.shape K2, N = other.shape indptr = np.empty_like(self.indptr) R, n = self.blocksize # convert to this format if isspmatrix_bsr(other): C = other.blocksize[1] else: C = 1 from csr import isspmatrix_csr if isspmatrix_csr(other) and n == 1: other = other.tobsr(blocksize=(n, C), copy=False) # lightweight conversion else: other = other.tobsr(blocksize=(n, C)) csr_matmat_pass1(M // R, N // C, self.indptr, self.indices, other.indptr, other.indices, indptr) bnnz = indptr[-1] indices = np.empty(bnnz, dtype=np.intc) data = np.empty(R * C * bnnz, dtype=upcast(self.dtype, other.dtype)) bsr_matmat_pass2( M // R, N // C, R, C, n, self.indptr, self.indices, np.ravel(self.data), other.indptr, other.indices, np.ravel(other.data), indptr, indices, data, ) data = data.reshape(-1, R, C) # TODO eliminate zeros return bsr_matrix((data, indices, indptr), shape=(M, N), blocksize=(R, C))
def count_blocks(A,blocksize): """For a given blocksize=(r,c) count the number of occupied blocks in a sparse matrix A """ r,c = blocksize if r < 1 or c < 1: raise ValueError,'r and c must be positive' if isspmatrix_csr(A): M,N = A.shape return csr_count_blocks(M,N,r,c,A.indptr,A.indices) elif isspmatrix_csc(A): return count_blocks(A.T,(c,r)) else: return count_blocks(csr_matrix(A),blocksize)
def count_blocks(A, blocksize): """For a given blocksize=(r,c) count the number of occupied blocks in a sparse matrix A """ r, c = blocksize if r < 1 or c < 1: raise ValueError('r and c must be positive') if isspmatrix_csr(A): M, N = A.shape return csr_count_blocks(M, N, r, c, A.indptr, A.indices) elif isspmatrix_csc(A): return count_blocks(A.T, (c, r)) else: return count_blocks(csr_matrix(A), blocksize)
def _mul_sparse_matrix(self, other): M, K1 = self.shape K2, N = other.shape indptr = np.empty_like(self.indptr) R, n = self.blocksize #convert to this format if isspmatrix_bsr(other): C = other.blocksize[1] else: C = 1 from csr import isspmatrix_csr if isspmatrix_csr(other) and n == 1: other = other.tobsr(blocksize=(n, C), copy=False) #lightweight conversion else: other = other.tobsr(blocksize=(n, C)) csr_matmat_pass1( M/R, N/C, \ self.indptr, self.indices, \ other.indptr, other.indices, \ indptr) bnnz = indptr[-1] indices = np.empty(bnnz, dtype=np.intc) data = np.empty(R * C * bnnz, dtype=upcast(self.dtype, other.dtype)) bsr_matmat_pass2( M/R, N/C, R, C, n, \ self.indptr, self.indices, np.ravel(self.data), \ other.indptr, other.indices, np.ravel(other.data), \ indptr, indices, data) data = data.reshape(-1, R, C) #TODO eliminate zeros return bsr_matrix((data, indices, indptr), shape=(M, N), blocksize=(R, C))