numpy matrix vector multiplication
--
Track title: CC O Beethoven - Piano Sonata No 3 in C
--
Chapters
00:00 Question
00:52 Accepted answer (Score 448)
04:48 Thank you
--
Full question
https://stackoverflow.com/questions/2156...
Accepted answer links:
[here]: http://docs.scipy.org/doc/numpy/referenc...
[numpy.matrix]: http://docs.scipy.org/doc/numpy/referenc...
[the note in its documentation]: https://numpy.org/doc/stable/reference/g...
[numpy.einsum]: https://docs.scipy.org/doc/numpy/referen...
[this answer]: https://stackoverflow.com/a/33641428/163...
[numpy.matmul]: https://docs.scipy.org/doc/numpy/referen...
[numpy.inner]: https://docs.scipy.org/doc/numpy/referen...
[the inner product and dot product]: https://en.wikipedia.org/wiki/Inner_prod...
[see this SO answer]: https://stackoverflow.com/questions/1103...
[np.linalg.multi_dot]: https://numpy.org/doc/stable/reference/g...
[numpy.tensordot]: https://docs.scipy.org/doc/numpy/referen...
[numpy.vdot]: https://docs.scipy.org/doc/numpy/referen...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #arrays #numpy #vector #matrix
#avk47
ACCEPTED ANSWER
Score 468
Simplest solution
Use numpy.dot or a.dot(b). See the documentation here.
>>> a = np.array([[ 5, 1 ,3],
[ 1, 1 ,1],
[ 1, 2 ,1]])
>>> b = np.array([1, 2, 3])
>>> print a.dot(b)
array([16, 6, 8])
This occurs because numpy arrays are not matrices, and the standard operations *, +, -, / work element-wise on arrays.
Note that while you can use numpy.matrix (as of early 2021) where * will be treated like standard matrix multiplication, numpy.matrix is deprecated and may be removed in future releases.. See the note in its documentation (reproduced below):
It is no longer recommended to use this class, even for linear algebra. Instead use regular arrays. The class may be removed in the future.
Thanks @HopeKing.
Other Solutions
Also know there are other options:
As noted below, if using python3.5+ and numpy v1.10+, the
@operator works as you'd expect:>>> print(a @ b) array([16, 6, 8])If you want overkill, you can use
numpy.einsum. The documentation will give you a flavor for how it works, but honestly, I didn't fully understand how to use it until reading this answer and just playing around with it on my own.>>> np.einsum('ji,i->j', a, b) array([16, 6, 8])As of mid 2016 (numpy 1.10.1), you can try the experimental
numpy.matmul, which works likenumpy.dotwith two major exceptions: no scalar multiplication but it works with stacks of matrices.>>> np.matmul(a, b) array([16, 6, 8])numpy.innerfunctions the same way asnumpy.dotfor matrix-vector multiplication but behaves differently for matrix-matrix and tensor multiplication (see Wikipedia regarding the differences between the inner product and dot product in general or see this SO answer regarding numpy's implementations).>>> np.inner(a, b) array([16, 6, 8]) # Beware using for matrix-matrix multiplication though! >>> b = a.T >>> np.dot(a, b) array([[35, 9, 10], [ 9, 3, 4], [10, 4, 6]]) >>> np.inner(a, b) array([[29, 12, 19], [ 7, 4, 5], [ 8, 5, 6]])If you have multiple 2D arrays to
dottogether, you may consider thenp.linalg.multi_dotfunction, which simplifies the syntax of many nestednp.dots. Note that this only works with 2D arrays (i.e. not for matrix-vector multiplication).>>> np.dot(np.dot(a, a.T), a).dot(a.T) array([[1406, 382, 446], [ 382, 106, 126], [ 446, 126, 152]]) >>> np.linalg.multi_dot((a, a.T, a, a.T)) array([[1406, 382, 446], [ 382, 106, 126], [ 446, 126, 152]])
Rarer options for edge cases
If you have tensors (arrays of dimension greater than or equal to one), you can use
numpy.tensordotwith the optional argumentaxes=1:>>> np.tensordot(a, b, axes=1) array([16, 6, 8])Don't use
numpy.vdotif you have a matrix of complex numbers, as the matrix will be flattened to a 1D array, then it will try to find the complex conjugate dot product between your flattened matrix and vector (which will fail due to a size mismatchn*mvsn).