Spoutnovitch
Spoutnovitch

Reputation: 119

Multplying matrix columns by matrix in numpy

I'm trying to compute this operation in a more efficient way:

y = np.array([xi*M for xi in x.T])

where x is a (m,n) matrix and M a (m,m) matrix. The output y is of shape (n,m,m), with each y[i,:,:] = np.multiply(x[:,i],M).

I was thinking of using einsum but I struggle understanding how to do it with the subscript.

Upvotes: 1

Views: 69

Answers (3)

kuzand
kuzand

Reputation: 9806

Without using einsum (just basic broadcasting):

# Example
# m, n = 5, 3
# M = np.random.rand(m,m)
# x = np.random.rand(m,n)

y = x.T[:,None] * M

Upvotes: 0

Alex Kreimer
Alex Kreimer

Reputation: 1106

Nice intro to einsum is here http://ajcr.net/Basic-guide-to-einsum.

Indexing for your case:

np.einsum('ik,jk->ijk', x.T, M)

Below a simple test:

m, n = 3, 2
x = np.arange(n*m).reshape((m, n))
M = np.arange(m*m).reshape((m,m))
x
array([[0, 1],
       [2, 3],
       [4, 5]])

M
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

y = np.array([xi*M for xi in x.T])

y
array([[[ 0,  2,  8],
        [ 0,  8, 20],
        [ 0, 14, 32]],

       [[ 0,  3, 10],
        [ 3, 12, 25],
        [ 6, 21, 40]]])
np.einsum('ik,jk->ijk', x.T, M)
array([[[ 0,  2,  8],
        [ 0,  8, 20],
        [ 0, 14, 32]],

       [[ 0,  3, 10],
        [ 3, 12, 25],
        [ 6, 21, 40]]])

Upvotes: 2

Andy L.
Andy L.

Reputation: 25239

a more direct subscript

out = np.einsum('ij,li ->jli',x,M)

Out[187]:
array([[[  0,   3,  12,  27],
        [  0,  15,  36,  63],
        [  0,  27,  60,  99],
        [  0,  39,  84, 135]],

       [[  0,   4,  14,  30],
        [  4,  20,  42,  70],
        [  8,  36,  70, 110],
        [ 12,  52,  98, 150]],

       [[  0,   5,  16,  33],
        [  8,  25,  48,  77],
        [ 16,  45,  80, 121],
        [ 24,  65, 112, 165]]])

Upvotes: 0

Related Questions