I added to your timer script resulting in #1 506ms #2 67ms #3 1.7ms (using einsum)

import numpy as np

import timeit

#compare multiple matrix multiplication using list coms of matrices and deep arrays

#1) the matrix method

setup1 = “””

import numpy as np

A = [np.mat(np.random.randn(3,3)) for i in range(1000)]

B = [np.mat(np.random.randn(3,3)) for i in range(1000)]

“””

test1 = “””

AB = [a*b for a,b in zip(A,B)]

“””

timer1 = timeit.Timer(test1,setup1)

print timer1.timeit(100)

#2) the array method

setup2 = “””

import numpy as np

A = np.random.randn(1000,3,3)

B = np.random.randn(1000,3,3)

“””

test2 = “””

AB = np.sum(np.transpose(A,(0,2,1)).reshape(1000,3,3,1)*B.reshape(1000,3,1,3),-3)

“””

timer2 = timeit.Timer(test2,setup2)

print timer2.timeit(100)

#3) the einsum method use the same arrays as setup2

test3 = “””

AB = np.einsum(‘…ij,…ij->…ij’, A, B)

“””

timer3 = timeit.Timer(test3,setup2)

print timer3.timeit(100)

“””

to do ‘normal’ matrix multiplication the equivalent of np.dot(A[i], B[i]) for i in range(1000)

AB = np.einsum(‘…ij,…jk->…ik’, A, B)

“””

I too would love to be able to do matrix inverses on slices of an array. I have a feeling that it shouldn’t be too hard to do this because of the was data is stored in numpy. Each slice should be contiguous, or, depending on the array ordering, there should be the same ‘skip’ between every row of the slice. In theory then it’s possible to point the lapack routines at the slices independently, since they can be called with a rowskip parameter, but this isn’t available through numpy/scipy. It might be possible with a little fortran and f2py though.

Of course, even with a fortran wrapper, you’d be simply doing all the inverses in a loop. To get a _real_ parallel implementation, you’d have to start hacking around in lapack to get the inverse operatinos to happen in parallel. Thus, I made myself a little wrapper which just does the inverses in a list comprehension.

]]>The main question was actually how to do an inverse in this way; any ideas?

]]>I believe there’s a tiny error in your last example, by the way: shouldn’t the last zero in line 28 be a minus three?

]]>p(pa= Xx, Xx), not p(pa=Xx, xx). ]]>

Yep, I hadn’t discivered the joy of newaxis when I wrote this. Now my code is full of it! actually, newaxis seems to be simply a null pointer, so my code often uses A[:,:,None,:] or similar. Not sure if this will break in future numpy versions though.

]]>