I am trying to create a code that generates the matrix-vector product (sparse-matrix multiplied by vector).But I'm getting the following error. -
<ipython-input-13-b43c92e5efc9>:50: RuntimeWarning: LinearOperator subclass should implement at least one of _matvec and _matmat. final_add__csr = CSRMatrix(final_add)---------------------------------------------------------------------------AttributeError Traceback (most recent call last)<ipython-input-13-b43c92e5efc9> in <cell line: 89>() 87 #final_add_data, final_add_indices, final_add_indptr, final_add_shape = p1.add(A_coo,B_coo) 88 ---> 89 final_add_data, final_add_indices, final_add_indptr, final_add_shape = CSRMatrix.add(A_coo,B_coo) 90 91 matvec1 = p1.matvec(final_add_data, final_add_indices, final_add_indptr, final_add_shape,x)1 frames<ipython-input-13-b43c92e5efc9> in add(other1, other2) 48 final_add = other1 + other2 49 #self_csr = CSRMatrix(final_add)---> 50 final_add__csr = CSRMatrix(final_add) 51 print("The final addition matrix in the CSR fomrat is:-") 52 print(self_csr)<ipython-input-13-b43c92e5efc9> in __init__(self, coo_matrix) 10 self.shape = coo_matrix.shape 11 self.dtype = coo_matrix.dtype---> 12 self.row = coo_matrix.row 13 self.col = coo_matrix.col 14 self.data = coo_matrix.dataAttributeError: 'csr_matrix' object has no attribute 'row'
I am confused why I am getting this error and how to resolve this.
I have been given the following template -
from scipy.sparse.linalg import LinearOperatorclass CSRMatrix(LinearOperator): def __init__(self, coo_matrix): self.shape = coo_matrix.shape self.dtype = coo_matrix.dtype # You'll need to put more code here def __add__(self, other):"""Add the CSR matrix other to this matrix.""" pass def _matvec(self, vector):"""Compute a matrix-vector product.""" pass
with the condition that-
(1) The method init takes a COO matrix as input and will initialise the CSR matrix: it currently includes one line that will store the shape of the input matrix. You should add code here that extracts important data from a Scipy COO to and computes and stores the appropriate data for a CSR matrix. You may use any functionality of Python and various libraries in your code, but you should not use an library’s implementation of a CSR matrix.
(2) The method add will overload + and so allow you to add two of your CSR matrices together. The add method should avoid converting any matrices to dense matrices. You could implement this in one of two ways:(i) you could convert both matrices to COO matrices, compute the sum, then pass this into CSRMatrix();or(ii) you could compute the data, indices and indptr for the sum, and use these to create a SciPy CSR matrix.
(3) The method matvec will define a matrix-vector product: Scipy will use this when you tell it to use a sparse solver on your operator.
-I am choosing the route where the code is supposed to take 2 COO matrices, add them, then convert the answer matrix to CSR and use it for further vector multiplication. I am wrting the following code-
import scipyfrom scipy.sparse.linalg import LinearOperatorimport numbaimport numpy as npfrom scipy.sparse import coo_matrixfrom scipy.sparse import coo_arrayclass CSRMatrix(LinearOperator): def __init__(self, coo_matrix): self.shape = coo_matrix.shape self.dtype = coo_matrix.dtype self.row = coo_matrix.row self.col = coo_matrix.col self.data = coo_matrix.data self.indices = coo_matrix.col self_csr = coo_matrix.tocsr() def add(other1, other2): if np.shape(other1) == np.shape(other2) : final_add = other1 + other2 final_add__csr = CSRMatrix(final_add) print("The final addition matrix in the CSR fomrat is:-") print(self_csr) self = self_csr return self.data, self.indices, self.indptr, self.shape else : print("Error : Shape of matrix A is not equal to shape of matrix B. Thus, cannot proceed towards addition to generate a final addition matrix and cannot produce matrix vector multiplication result using the final addition matrix.") @numba.jit(nopython=True, parallel=True) #def matvec(self.data, self.indices, self.indptr, self.shape, x): def csr_matvec(data, indices, indptr, shape, x): m, n = shape y = np.zeros(m, dtype=np.float64) for row_index in numba.prange(m): col_start = indptr[row_index] col_end = indptr[row_index + 1] for col_index in range(col_start, col_end): y[row_index] += data[col_index] * x[indices[col_index]] return yA = np.array([[1, 0],[3, 4],[6, 0]]) #3rows,2columnsB = np.array([[1, 2],[5, 6],[7, 8]]) #3rows,2columnsA_coo = coo_matrix(A)B_coo = coo_matrix(B)# Generate a random vectorrand = np.random.RandomState(0)N = 5x = rand.randn(2 * N) #2rows,Ncolumnsfinal_add_data, final_add_indices, final_add_indptr, final_add_shape = CSRMatrix.add(A_coo,B_coo)matvec1 = p1.matvec(final_add_data, final_add_indices, final_add_indptr, final_add_shape,x)print(matvec1)