为什么形状 (3,3) 矩阵乘以 (3,) 向量加上 (3,) 向量在 numpy 中形成 (1,3) 形状?
我的代码如下,进行雅可比分解来求解矩阵
def iterative_solver(M, b, Vinit, kmax, epsmax):
"""
Provides an approximation of M^{-1}b using the proposed iterative method
----------
parameters:
M : matrix in the equation MV = b to solve (numpy array of size N,N)
b : vector on the right-hand-side of the equation MV = b (numpy array of size N)
Vinit : initial vector of the iterative method (numpy array of size N)
kmax : maximum number of iterations, stops if k reaches kmax (integer)
epsmax : tolerance on the residual, stops if eps reaches epsmax (float)
returns:
V : resulting vector at the end of the iterations (numpy array of size N)
eps : vector composed of the residuals eps at every iteration (numpy array of size k)
k : number of iterations performed before the algorithm stops (integer)
"""
eps = np.inf
N = len(M)
d = list()
for i in range(N):
d.append(M[i,i])
D = np.diag(d)
R = D - M
Dinv = np.linalg.inv(D)
V = Vinit
k =0
print(f"V: {np.shape(V)} M: {np.shape(M)} b: {np.shape(b)}")
while k <= kmax and eps >= epsmax:
A = np.matmul((-M), V)+ b
print(f"np.shape(A): {np.shape(A)}")
V = V + np.matmul(Dinv,A)
print(f"np.shape(V): {np.shape(V)}")
#A = np.matmul(R,V)
#V = np.matmul(Dinv, A + b)
k += 1
eps = np.linalg.norm(M*V.T-b)
return V, eps, k
M = np.mat([[3,1,0],[-1, -5, 1], [0,2,4]])
b = np.array([4,-5,6]).T
Vinit = np.random.rand(3).T
kmax = 100
epsmax = 1e-10
print(f"solved: {iterative_solver(M, b, Vinit, kmax, epsmax)}")
,但是它给出了输出
V: (3,) M: (3, 3) b: (3,) np.shape(A): (1, 3)
这很奇怪,因为形状 (3,3) 矩阵乘以 (3,) 向量加上 (3,) 向量在 numpy 中形成 (1,3) 形状?
My code is as follows doing the jacobi decomposition to solve a matrix
def iterative_solver(M, b, Vinit, kmax, epsmax):
"""
Provides an approximation of M^{-1}b using the proposed iterative method
----------
parameters:
M : matrix in the equation MV = b to solve (numpy array of size N,N)
b : vector on the right-hand-side of the equation MV = b (numpy array of size N)
Vinit : initial vector of the iterative method (numpy array of size N)
kmax : maximum number of iterations, stops if k reaches kmax (integer)
epsmax : tolerance on the residual, stops if eps reaches epsmax (float)
returns:
V : resulting vector at the end of the iterations (numpy array of size N)
eps : vector composed of the residuals eps at every iteration (numpy array of size k)
k : number of iterations performed before the algorithm stops (integer)
"""
eps = np.inf
N = len(M)
d = list()
for i in range(N):
d.append(M[i,i])
D = np.diag(d)
R = D - M
Dinv = np.linalg.inv(D)
V = Vinit
k =0
print(f"V: {np.shape(V)} M: {np.shape(M)} b: {np.shape(b)}")
while k <= kmax and eps >= epsmax:
A = np.matmul((-M), V)+ b
print(f"np.shape(A): {np.shape(A)}")
V = V + np.matmul(Dinv,A)
print(f"np.shape(V): {np.shape(V)}")
#A = np.matmul(R,V)
#V = np.matmul(Dinv, A + b)
k += 1
eps = np.linalg.norm(M*V.T-b)
return V, eps, k
M = np.mat([[3,1,0],[-1, -5, 1], [0,2,4]])
b = np.array([4,-5,6]).T
Vinit = np.random.rand(3).T
kmax = 100
epsmax = 1e-10
print(f"solved: {iterative_solver(M, b, Vinit, kmax, epsmax)}")
However it gives me the output
V: (3,) M: (3, 3) b: (3,)
np.shape(A): (1, 3)
Which is very weird since a shape (3,3) matrix times a (3,) vector plus a (3,) vector make a (1,3) shape in numpy?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
形状业务隐藏在您的代码中,但我认为这就是您所指的:
(3,3) 与 (3,) 的
matmul
生成 (3,)。添加 (3,) 应该保留 (3,)但随后您将
V
更改为V + np.matmul(Dinv,A)
。你打印了它的形状,但我看不到。使用您的代码:
我尝试过:
我花了一点时间才注意到这是
np.matrix
!根据定义,它是 2d,因此是 (1,3) 形状。如果我传递一个 np.array 矩阵:
编辑
np.matrix 是 ndarray 的子类。它将自己的
*
和**
定义为矩阵运算,而不是按元素运算。它强制执行二维形状。如果需要,它会添加一个前导维度(numpy
默认情况下为“C”顺序)使用自己的
*
:(3,)
v
有被‘提升’到矩阵(1,3)。matmul/@
是最近添加的内容(np.matrix
已经很旧了,即将淘汰):看起来这两个函数都执行乘法,就好像它们是
>ndarray
,并将结果转换为矩阵
。如果两者都是
np.matrix
:[email protected] ]
做同样的事情。The shape business is buried in your code, but I think this is what you are referring to:
matmul
of a (3,3) with (3,) produces a (3,). Add a (3,) should stay (3,)But then you change
V
withV + np.matmul(Dinv,A)
. You print its shape, but I don't see that.With your code:
I tried:
It took me a bit to notice that this is
np.matrix
! That by definition is 2d, hence the (1,3) shape.If I pass a
np.array
matrix instead:edit
np.matrix
is a subclass ofndarray
. It defines its own*
and**
as matrix operations, as opposed to elementwise. And it enforces a 2d shape. If necessary it adds a leading dimension (numpy
is 'C' order by default)Using its own
*
:The (3,)
v
has been 'promoted' to matrix (1,3).matmul/@
is a recent addition (np.matrix
is old, and on its way out):It appears that both of these perform the multiply as though they were
ndarray
, and converts the result tomatrix
.If both are
np.matrix
:[email protected]
does the same thing.