[Numpy-discussion] Taking a large number of dot products at once

Sturla Molden sturla at molden.no
Fri Mar 4 08:55:35 EST 2011


Den 04.03.2011 07:19, skrev Daniel Hyams:
> This is probably so easy, I'm embarrassed to ask it...but I've been 
> casting around trying things to no avail for the last hour and a half, 
> so here goes...
>
> I have a lot of dot products to take.  The length-3 vectors that I 
> want to dot are stacked in a 2D array like this:
>
> U = [u1 u2 u3....]
>
> and
> V = [v1 v2 v3....]
>
> So both of these arrays, are, say, 3x100 each.

That is the diagonal of matrix product U * V.T, that is

    np.diag(np.dot(U,V.T))

You can also write this as

    np.sum(U*V, axis=1)

The latter is faster with 100 x 3 arrays:

 >>> timeit.Timer(stmt='np.diag(np.dot(a,a.T))', setup='import numpy as 
np; a=np.zeros((100,3))').timeit(number=1000)
0.0568983632238087

 >>> timeit.Timer(stmt='np.sum(a*a,axis=1)', setup='import numpy as np; 
a=np.zeros((100,3))').timeit(number=1000)
0.03596760426239598

We can do this with Python lists of NumPy arrays as well, avoiding 
stacking the arrays in a 2D structure:

    [np.dot(u,v.T) for u,v in zip(U,V)]

with U and V lists of 1D ndarrays instead of 2D ndarrays.

 >>> timeit.Timer(stmt='[np.dot(x.T,x) for x in a]', setup='import numpy 
as np; a=100*[np.zeros(3)]').timeit(number=1000)
0.21054868368582902

While this is slower, we don't need to create the 2D stacks, and it only 
took 200 µs on average.

It could be useful is vectors are so big (or plentyful) that memory is 
an issue, or just to write more Pythonic code. We don't need to write 
FORTRAN in Python, computers are fast.

Sturla












-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20110304/fc96ab31/attachment.html>


More information about the NumPy-Discussion mailing list