Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way of taking Logarithm function in a sparse matrix

I have a big sparse matrix. I want to take log4 for all element in that sparse matrix.

I try to use numpy.log() but it doesn't work with matrices.

I can also take logarithm row by row. Then I crush old row with a new one.

# Assume A is a sparse matrix (Linked List Format) with float values as data
# It is only for one row

import numpy as np
c = np.log(A.getrow(0)) / numpy.log(4)
A[0, :] = c

This was not as quick as I'd expected. Is there a faster way to do this?

like image 405
Baskaya Avatar asked Mar 22 '12 21:03

Baskaya


1 Answers

You can modify the data attribute directly:

>>> a = np.array([[5,0,0,0,0,0,0],[0,0,0,0,2,0,0]])
>>> coo = coo_matrix(a)
>>> coo.data
array([5, 2])
>>> coo.data = np.log(coo.data)
>>> coo.data
array([ 1.60943791,  0.69314718])
>>> coo.todense()
matrix([[ 1.60943791,  0.        ,  0.        ,  0.        ,  0.        ,
          0.        ,  0.        ],
        [ 0.        ,  0.        ,  0.        ,  0.        ,  0.69314718,
          0.        ,  0.        ]])

Note that this doesn't work properly if the sparse format has repeated elements (which is valid in the COO format); it'll take the logs individually, and log(a) + log(b) != log(a + b). You probably want to convert to CSR or CSC first (which is fast) to avoid this problem.

You'll also have to add checks if the sparse matrix is in a different format, of course. And if you don't want to modify the matrix in-place, just construct a new sparse matrix as you did in your answer, but without adding 3 because that's completely unnecessary here.

like image 95
Danica Avatar answered Sep 21 '22 17:09

Danica