1

I am trying to compute the Hadamard product of two matrices stored in COO-sparse format (in SciPy). There's a lecture that reads

fast and easy item-wise operations, manipulate data array directly (fast NumPy machinery)

I understand the sum and difference part since we can just concatenate the matrix.row, matrix.column and matrix.data. However, I guess it's actually quite non-trivial to compute the Hadamard/entry-wise product by leveraging the COO structure (possibly have to match the coordinates and apply "&").

Is there any way to compute Hadamard product more efficiently using COO-sparse format or is it just a misunderstanding?

  • All that comment means is that you can do `M.data = np.sin(M.data)` to compute the `sin` (or some other function) of all nonzero elements of the matrix. It's not referring to binary operations (product, sum, subtract, etc). – hpaulj Jun 25 '19 at 15:56
  • @hpaulj Got it! Thank you so much! I really did read into it too much haha – Jonathan Chang Jun 26 '19 at 00:22

1 Answers1

0

The multiply method does element-wise multiplication.

Here's an example, in which a and b are sparse matrices with COO format. (The .A attribute returns a regular numpy array. I use it to display the values in the sparse matrices.)

In [41]: a                                                                                                                            
Out[41]: 
<5x8 sparse matrix of type '<class 'numpy.int64'>'
    with 20 stored elements in COOrdinate format>

In [42]: a.A                                                                                                                          
Out[42]: 
array([[0, 9, 2, 9, 0, 6, 6, 2],
       [2, 0, 0, 0, 1, 0, 8, 0],
       [0, 3, 0, 0, 2, 9, 0, 4],
       [0, 0, 0, 0, 0, 0, 0, 5],
       [0, 0, 7, 1, 0, 0, 7, 7]])

In [43]: b                                                                                                                            
Out[43]: 
<5x8 sparse matrix of type '<class 'numpy.int64'>'
    with 20 stored elements in COOrdinate format>

In [44]: b.A                                                                                                                          
Out[44]: 
array([[0, 0, 0, 7, 9, 0, 5, 0],
       [0, 7, 0, 0, 6, 6, 0, 0],
       [3, 0, 2, 0, 3, 0, 0, 0],
       [5, 0, 0, 3, 0, 0, 7, 0],
       [8, 0, 6, 8, 0, 0, 4, 0]])

Compute the element-wise product of a and b. Note that c uses the CSR format.

In [45]: c = a.multiply(b)                                                                                                            

In [46]: c                                                                                                                            
Out[46]: 
<5x8 sparse matrix of type '<class 'numpy.int64'>'
    with 7 stored elements in Compressed Sparse Row format>

In [47]: c.A                                                                                                                          
Out[47]: 
array([[ 0,  0,  0, 63,  0,  0, 30,  0],
       [ 0,  0,  0,  0,  6,  0,  0,  0],
       [ 0,  0,  0,  0,  6,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0, 42,  8,  0,  0, 28,  0]], dtype=int64)

Verify the result by computing the element-wise product of the corresponding numpy arrays.

In [48]: a.A * b.A                                                                                                                    
Out[48]: 
array([[ 0,  0,  0, 63,  0,  0, 30,  0],
       [ 0,  0,  0,  0,  6,  0,  0,  0],
       [ 0,  0,  0,  0,  6,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0, 42,  8,  0,  0, 28,  0]])
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • Oops I realized that this method is sitting in the documentation described as point-wise product. Thank you for sharing! Also it's good to know that the method essentially converts it to CSR and do the computation. – Jonathan Chang Jun 26 '19 at 00:24