[SciPy-user] matrix multipy ...

Anne Archibald peridot.faceted@gmail....
Mon May 19 23:59:47 CDT 2008


2008/5/19 Matteo Bertini <matteo@naufraghi.net>:

> Not really, the loop I'd like to avoid is this:
>
> In [63]: cc = N.zeros((bb.shape[0], aa.shape[1], bb.shape[1]))
>
> In [64]: for i in range(cc.shape[0]):
>   ....:     cc[i] = aa[i].T*bb[i]

> The outer product produces the same results in Q1 and Q3, but does
> useles (in this case :P) computation in Q2 and Q4.
>
> Dunno if the computation can be faster, but I'd like to find out if
> there is a slice trick to do this kind of things.

In general, I don't think there is an efficient way to do
"element-wise matrix multiplication". It's frustrating, because that's
something one often wants to do. The inefficient way to do it looks
like:

In [2]: A = np.random.randn(3,4)

In [3]: B = np.random.randn(4,5)

In [4]: np.dot(A,B)
Out[4]:
array([[-2.16160901,  1.37419626,  1.69220464, -1.92437171, -2.81084305],
       [-1.11186059, -3.22519623, -0.13694365,  0.58809612,  1.14769438],
       [ 3.50699881,  3.14051249, -1.36108516,  0.41971033, -1.38753093]])

In [5]: np.sum(A[:,:,np.newaxis]*B[np.newaxis,:,:],axis=1)
Out[5]:
array([[-2.16160901,  1.37419626,  1.69220464, -1.92437171, -2.81084305],
       [-1.11186059, -3.22519623, -0.13694365,  0.58809612,  1.14769438],
       [ 3.50699881,  3.14051249, -1.36108516,  0.41971033, -1.38753093]])

This is only one matrix, but you can add in any number of additional
axes at the beginning. The big problem with this is that because the
sum is done separately, there is a temporary of size N*M*R, which is
very much larger than either of the original two matrices.

In your case, things are a bit simpler because you're doing vector products:

In [7]: A = np.random.randn(3,4,5)

In [8]: B = np.random.randn(3,4,5)

In [12]: np.sum(A*B,axis=-1).shape
Out[12]: (3, 4)

Here the temporary is no larger than the two input arrays, so it's not
as big a problem.

Anne


More information about the SciPy-user mailing list