Reputation: 1810
When I multiply a NxN numpy matrix by a N elements numpy array I get an error saying that the shapes are not aligned.
from numpy import matrix,ones,eye
A = matrix(eye(3))
b = ones(3)
A*b
ValueError: shapes (3,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
Also trasposing the vector does not solve the issue.
A*b.T
ValueError: shapes (3,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
This make sense as numpy does not distinguish between column and row vectors so b.T is equal to b.
How can I perform a simple matrix-vector multiplication?
Upvotes: 1
Views: 4178
Reputation: 537
The problem arises from the fact that the operator '*' is performing element-wise multiplication and NOT matrix multiplication as you intend. In python 3 this can be done using the '@' operator, as suggested by w-m. In python 2, however, you must use.
import numpy as np
result = np.dot(A,b)
The '*' operator will try to multiple every element of A with the corresponding element of b. If these are not the same shape you will get an error, which is what you see.
EDIT: I misunderstood OP's question. '*' will work for matrix multiplication if both objects are matrices. However, np.ones(3) produces a numpy array, which is not a numpy matrix object, so it doesn't work and tries to do element-wise multiplication.
if b becomes:
b = np.matrix((1,1,1)).T
then the code will work. It should also be noted that np.dot(A,b) will work even if both A and b are matrix objects, numpy arrays, or a mix of the two, making it the most general solution.
Upvotes: 0
Reputation: 114841
Because A
is a matrix, Python calls A
's __mul__
method to compute A*b
, with b
as its argument. That is, it calls A.__mul__(b)
. A numpy matrix
insists on making everything a 2-d matrix, so it converts b
to a matrix
before performing the matrix multiplication. When b
is converted to a numpy matrix, the result has shape (1, 3)
:
In [248]: b
Out[248]: array([1., 1., 1.])
In [249]: np.matrix(b).shape
Out[249]: (1, 3)
Then __mul__
complains that the shapes are not aligned, because A
has shape (3, 3)
and the converted b
has shape (1, 3)
.
One way to fix this is to ensure that b
is 2-d with shape (3, 1)
before doing the multiplication:
In [250]: b = ones((3, 1))
In [251]: A * b
Out[251]:
matrix([[1.],
[1.],
[1.]])
In the long term, though, it would be better to modify your code to not use matrix
at all, as mentioned by @w-m.
Upvotes: 0
Reputation: 11232
(Don't use np.matrix
, it's deprecated. Instead just use 2D arrays for linear algebra.)
Use the matrix multiplication operator @
:
In [177]: from numpy import ones,eye
...: A = eye(3)
...: b = ones(3)
...: A @ b
Out[177]: array([1., 1., 1.])
Upvotes: 2