matrix multipy ...

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

matrix multipy ...

matteo (Bugzilla)
Perhaps it's simple, but...

Suppose I have 2 "vectors" (1xN matrix really)

n [27]: a = mat("1,2,3,4,5")
In [29]: b = mat("1,2,3")

If I whant the product, no problem.

But suppose I have a list of vectors (a proper matrix)

In [37]: aa = mat("1,2,3,4,5;6,7,8,9,0")
In [38]: bb = mat("1,2,3;4,5,6")

Can I avoid a loop and have the resulting "cube"?

In [40]: aa[0].T*bb[0]
Out[40]:
matrix([[ 1,  2,  3],
        [ 2,  4,  6],
        [ 3,  6,  9],
        [ 4,  8, 12],
        [ 5, 10, 15]])

I admit, I can't really understand array slicing power/limits!

Thank you,
Matteo Bertini

_______________________________________________
SciPy-user mailing list
[hidden email]
http://projects.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: matrix multipy ...

Johann Cohen-Tanugi-2
hi Matteo,

In [1]: import numpy as np

In [2]: aa = np.mat("1,2,3,4,5;6,7,8,9,0")

In [3]: bb = np.mat("1,2,3;4,5,6")

In [4]: np.outer(aa.T,bb)
Out[4]:
array([[ 1,  2,  3,  4,  5,  6],
       [ 6, 12, 18, 24, 30, 36],
       [ 2,  4,  6,  8, 10, 12],
       [ 7, 14, 21, 28, 35, 42],
       [ 3,  6,  9, 12, 15, 18],
       [ 8, 16, 24, 32, 40, 48],
       [ 4,  8, 12, 16, 20, 24],
       [ 9, 18, 27, 36, 45, 54],
       [ 5, 10, 15, 20, 25, 30],
       [ 0,  0,  0,  0,  0,  0]])

In [5]: np.outer(aa,bb)
Out[5]:
array([[ 1,  2,  3,  4,  5,  6],
       [ 2,  4,  6,  8, 10, 12],
       [ 3,  6,  9, 12, 15, 18],
       [ 4,  8, 12, 16, 20, 24],
       [ 5, 10, 15, 20, 25, 30],
       [ 6, 12, 18, 24, 30, 36],
       [ 7, 14, 21, 28, 35, 42],
       [ 8, 16, 24, 32, 40, 48],
       [ 9, 18, 27, 36, 45, 54],
       [ 0,  0,  0,  0,  0,  0]])

Is that what you were looking for?
cheers,
Johann

Matteo Bertini wrote:

> Perhaps it's simple, but...
>
> Suppose I have 2 "vectors" (1xN matrix really)
>
> n [27]: a = mat("1,2,3,4,5")
> In [29]: b = mat("1,2,3")
>
> If I whant the product, no problem.
>
> But suppose I have a list of vectors (a proper matrix)
>
> In [37]: aa = mat("1,2,3,4,5;6,7,8,9,0")
> In [38]: bb = mat("1,2,3;4,5,6")
>
> Can I avoid a loop and have the resulting "cube"?
>
> In [40]: aa[0].T*bb[0]
> Out[40]:
> matrix([[ 1,  2,  3],
>         [ 2,  4,  6],
>         [ 3,  6,  9],
>         [ 4,  8, 12],
>         [ 5, 10, 15]])
>
> I admit, I can't really understand array slicing power/limits!
>
> Thank you,
> Matteo Bertini
>
> _______________________________________________
> SciPy-user mailing list
> [hidden email]
> http://projects.scipy.org/mailman/listinfo/scipy-user
>  
_______________________________________________
SciPy-user mailing list
[hidden email]
http://projects.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: matrix multipy ...

matteo (Bugzilla)
Johann Cohen-Tanugi ha scritto:

> hi Matteo,
>
> In [1]: import numpy as np
>
> In [2]: aa = np.mat("1,2,3,4,5;6,7,8,9,0")
>
> In [3]: bb = np.mat("1,2,3;4,5,6")
>
> In [5]: np.outer(aa,bb)
> Out[5]:
> array([[ 1,  2,  3,  4,  5,  6],
>        [ 2,  4,  6,  8, 10, 12],
>        [ 3,  6,  9, 12, 15, 18],
>        [ 4,  8, 12, 16, 20, 24],
>        [ 5, 10, 15, 20, 25, 30],
>        [ 6, 12, 18, 24, 30, 36],
>        [ 7, 14, 21, 28, 35, 42],
>        [ 8, 16, 24, 32, 40, 48],
>        [ 9, 18, 27, 36, 45, 54],
>        [ 0,  0,  0,  0,  0,  0]])
>
> Is that what you were looking for?
> cheers,
> Johann

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]

In [66]: cc
Out[66]:
array([[[  1.,   2.,   3.],
        [  2.,   4.,   6.],
        [  3.,   6.,   9.],
        [  4.,   8.,  12.],
        [  5.,  10.,  15.]],

       [[ 24.,  30.,  36.],
        [ 28.,  35.,  42.],
        [ 32.,  40.,  48.],
        [ 36.,  45.,  54.],
        [  0.,   0.,   0.]]])

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.

Thank you,
Matteo

_______________________________________________
SciPy-user mailing list
[hidden email]
http://projects.scipy.org/mailman/listinfo/scipy-user
Reply | Threaded
Open this post in threaded view
|

Re: matrix multipy ...

Anne Archibald
2008/5/19 Matteo Bertini <[hidden email]>:

> 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
_______________________________________________
SciPy-user mailing list
[hidden email]
http://projects.scipy.org/mailman/listinfo/scipy-user