How To Vectorize Multiple Matrix Multiplications In Numpy?
For a conceptual idea of what I mean, I have 2 data points: x_0 = np.array([0.6, 1.4])[:, None] x_1 = np.array([2.6, 3.4])[:, None] And a 2x2 matrix: y = np.array([[2, 2], [2, 2]]
Solution 1:
With x
as the column stacked version of x_0
, x_1
and so on, we can use np.einsum
-
np.einsum('ji,jk,ki->i',x,y,x)
With a mix of np.einsum
and matrix-multiplcation
-
np.einsum('ij,ji->i',x.T.dot(y),x)
As stated earlier, x
was assumed to be column-stacked, like so :
x = np.column_stack((x_0, x_1))
Runtime test -
In [236]: x = np.random.randint(0,255,(3,100000))
In [237]: y = np.random.randint(0,255,(3,3))
# Proposed in @titipata's post/comments under this post
In [238]: %timeit (x.T.dot(y)*x.T).sum(1)
100 loops, best of 3: 3.45 ms per loop
# Proposed earlier in this post
In [239]: %timeit np.einsum('ji,jk,ki->i',x,y,x)
1000 loops, best of 3: 832 µs per loop
# Proposed earlier in this post
In [240]: %timeit np.einsum('ij,ji->i',x.T.dot(y),x)
100 loops, best of 3: 2.6 ms per loop
Solution 2:
Basically, you want to do the operation (x.T).dot(A).dot(x)
for all x
that you have.
x_0 = np.array([0.6, 1.4])[:, None]
x_1 = np.array([2.6, 3.4])[:, None]
x = np.hstack((x_0, x_1)) # [[ 0.6 2.6], [ 1.4 3.4]]
The easy way to think about it is to do multiplication for all x_i
that you have with y
as
[x_i.dot(y).dot(x_i) for x_i in x.T]
>> [8.0, 72.0]
But of course this is not too efficient. However, you can do the trick where you can do dot product of x
with y
first and multiply back with itself and sum over column i.e. you manually do dot product. This will make the calculation much faster:
x = x.T
(x.dot(y) * x).sum(axis=1)
>> array([ 8., 72.])
Note that I transpose the matrix first because we want to multiply column of y
to each row of x
Post a Comment for "How To Vectorize Multiple Matrix Multiplications In Numpy?"