Reputation: 119
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
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
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
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