Reputation: 2104
I need to perform the dot product of two matrices in numpy. However, one of them actually has the same value in each row. Something like:
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2]])
For optimization purposes, I only store one column as a 1d array.
Is there a way to calculate the dot product between this and a usual 2d matrix without having to explicitly create the above matrix?
Upvotes: 4
Views: 2333
Reputation: 4209
if you have an array:
a = np.array([0, 1, 2])
which represents a matrix like:
>>> np.repeat(a[:,np.newaxis], 5, 1)
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2]])
and you want a dot product with matrix m:
m = np.arange(5*4).reshape(5,4)
you may use:
a[:,np.newaxis] * np.sum(m, axis=0)
Upvotes: 3
Reputation: 67417
When you do the dot product of two arrays, you are computing the dot product of every row of the first array with every column of the second. If your matrix-that-fits-in-a-vector (MTFIAV) is the first operand of the dot product, it is easy to see that you can factor the repeating value from the dot product, and do a single multiplication with the result of summing up every column of the second array:
>>> a = np.arange(3)
>>> a
array([0, 1, 2])
>>> aa = np.repeat(a, 5).reshape(len(a), -1)
>>> aa
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2]])
>>> np.dot(aa, b)
array([[ 0, 0, 0, 0],
[ 40, 45, 50, 55],
[ 80, 90, 100, 110]])
>>> np.outer(a, b.sum(axis=0))
array([[ 0, 0, 0, 0],
[ 40, 45, 50, 55],
[ 80, 90, 100, 110]])
If your MTFIAV is the second operand, it isn't hard to see that the result will also be a MTFIAV, and that its vector representation can be obtained computing the dot product of the first operand with the vector:
>>> c = np.arange(12).reshape(4, 3)
>>> np.dot(c, aa)
array([[ 5, 5, 5, 5, 5],
[14, 14, 14, 14, 14],
[23, 23, 23, 23, 23],
[32, 32, 32, 32, 32]])
>>> np.dot(c, a)
array([ 5, 14, 23, 32])
Upvotes: 4