In [1]:
import numpy as np
from scipy import sparse
from numba import jit

In [2]:
n, m = 5, 5
A = sparse.rand(n, m, density=0.4, format='csr')

In [3]:
print A.toarray()
print A.data
print A.indices
print A.indptr


[[ 0.64747691  0.          0.75692587  0.          0.34508964]
 [ 0.          0.          0.          0.57437148  0.        ]
 [ 0.          0.22944897  0.          0.          0.        ]
 [ 0.21498657  0.2321051   0.          0.          0.90333395]
 [ 0.          0.          0.38547218  0.          0.9662785 ]]
[ 0.64747691  0.75692587  0.34508964  0.57437148  0.22944897  0.21498657
  0.2321051   0.90333395  0.38547218  0.9662785 ]
[0 2 4 3 1 0 1 4 2 4]
[ 0  3  4  5  8 10]

In [4]:
@jit(nopython=True)
def _csr_vecmat(num_rows, x, data, indices, indptr, out):
    for i in range(num_rows):
        for k in range(indptr[i], indptr[i+1]):
            out[indices[k]] += x[i] * data[k]

In [5]:
def csr_vecmat(x, A):
    n, m = A.shape
    if len(x) != n:
        raise ValueError('dimensions do not match')
    y = np.zeros(m)
    _csr_vecmat(n, x, A.data, A.indices, A.indptr, y)
    return y

In [6]:
x = np.arange(n)

In [7]:
csr_vecmat(x, A)


Out[7]:
array([ 0.64495971,  1.15521324,  1.54188873,  0.57437148,  6.57511582])

In [8]:
x.dot(A.toarray())


Out[8]:
array([ 0.64495971,  1.15521324,  1.54188873,  0.57437148,  6.57511582])

In [9]:
A.T.dot(x)


Out[9]:
array([ 0.64495971,  1.15521324,  1.54188873,  0.57437148,  6.57511582])

In [10]:
%timeit csr_vecmat(x, A)
%timeit A.T.dot(x)
%timeit x.dot(A.toarray())


100000 loops, best of 3: 2.81 µs per loop
10000 loops, best of 3: 63.7 µs per loop
10000 loops, best of 3: 81.5 µs per loop

In [11]:
n, m = 5, 3
A = sparse.rand(n, m, density=0.4, format='csr')
x = np.ones(n)

In [12]:
csr_vecmat(x, A)


Out[12]:
array([ 0.77932713,  0.32551008,  2.01678306])

In [13]:
A.T.dot(x)


Out[13]:
array([ 0.77932713,  0.32551008,  2.01678306])

In [14]:
n = 10**2
m = n
A = sparse.rand(n, m, density=0.4, format='csr')
x = np.ones(n)
%timeit csr_vecmat(x, A)
%timeit A.T.dot(x)
%timeit x.dot(A.toarray())


100000 loops, best of 3: 11.6 µs per loop
10000 loops, best of 3: 66.8 µs per loop
10000 loops, best of 3: 118 µs per loop

In [15]:
n = 10**2 * 3
m = n
A = sparse.rand(n, m, density=0.4, format='csr')
x = np.ones(n)
%timeit csr_vecmat(x, A)
%timeit A.T.dot(x)
%timeit x.dot(A.toarray())


10000 loops, best of 3: 78.9 µs per loop
10000 loops, best of 3: 99.3 µs per loop
1000 loops, best of 3: 434 µs per loop

In [16]:
n = 10**3
m = n
A = sparse.rand(n, m, density=0.4, format='csr')
x = np.ones(n)

In [17]:
%timeit csr_vecmat(x, A)
%timeit A.T.dot(x)
%timeit x.dot(A.toarray())


1000 loops, best of 3: 807 µs per loop
1000 loops, best of 3: 432 µs per loop
100 loops, best of 3: 6.2 ms per loop

In [18]:
n = 10**4
m = n
A = sparse.rand(n, m, density=0.4, format='csr')
x = np.ones(n)

In [19]:
%timeit csr_vecmat(x, A)
%timeit A.T.dot(x)
%timeit x.dot(A.toarray())


10 loops, best of 3: 83.9 ms per loop
10 loops, best of 3: 42.8 ms per loop
1 loops, best of 3: 951 ms per loop

In [20]:
import platform
print platform.platform()


Darwin-13.4.0-x86_64-i386-64bit

In [21]:
import sys
print sys.version


2.7.8 (default, Jul  2 2014, 10:14:46) 
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)]

In [22]:
print np.__version__


1.9.2

In [23]:
import scipy
print scipy.__version__


0.15.1

In [24]:
import numba
print numba.__version__


0.18.2

In [24]: