Wan*_*ick 0 python matlab numpy matrix linear-algebra
我尝试使用 numpy 来求解矩阵逆,但无法使其工作。Python代码如下所示:
import copy
import numpy as np
from numpy.linalg import *
K=[[0.13535533905932737, -0.03535533905932737, 0.0, 0.0, -0.1],
[-0.03535533905932737, 0.13535533905932737, 0.0, -0.1, 0.0],
[0.0, 0.0, 0.13535533905932737, 0.03535533905932737, -0.03535533905932737],
[0.0, -0.1, 0.03535533905932737, 0.13535533905932737, -0.03535533905932737],
[-0.1, 0.0, -0.03535533905932737, -0.03535533905932737, 0.13535533905932737]]
newK = np.array(K)
newK = inv(newK)
Run Code Online (Sandbox Code Playgroud)
结果如下:
[[ -2.74615429e+16 -2.74615429e+16 1.89368970e+00 -2.74615429e+16
-2.74615429e+16]
[ -2.74615429e+16 -2.74615429e+16 -1.37357926e+00 -2.74615429e+16
-2.74615429e+16]
[ 9.23495156e-01 -1.84699031e+00 8.84484598e+00 -3.69398063e+00
1.84699031e+00]
[ -2.74615429e+16 -2.74615429e+16 -2.52873329e+00 -2.74615429e+16
-2.74615429e+16]
[ -2.74615429e+16 -2.74615429e+16 3.04884372e+00 -2.74615429e+16
-2.74615429e+16]]
Run Code Online (Sandbox Code Playgroud)
我也尝试使用 MATLAB 检查这个值,但结果是:
a =
0.1340 -0.0350 0 0 -0.1000
-0.0350 0.1350 0 -0.1000 0
0 0 0.1350 0.0350 -0.0350
0 -0.1000 0.0350 0.1350 -0.0350
-0.1000 0 -0.0350 -0.0350 0.1350
>> inv(a)
ans =
1.0e+03 *
-1.0000 -1.0000 0.0000 -1.0000 -1.0000
-1.0000 -0.9808 -0.0033 -0.9841 -0.9967
0.0000 -0.0033 0.0089 -0.0044 0.0011
-1.0000 -0.9841 -0.0044 -0.9785 -0.9956
-1.0000 -0.9967 0.0011 -0.9956 -0.9911
Run Code Online (Sandbox Code Playgroud)
有人可以帮我解决这个问题吗?
首先,两个程序的两个矩阵不相同:
麻木:
In [295]: np.linalg.det(newK)
Out[295]: -4.5051744884111939e-21
Run Code Online (Sandbox Code Playgroud)
MATLAB:
>> det(a)
ans =
-1.067499999999957e-07
Run Code Online (Sandbox Code Playgroud)
在 numpy 中使用相同的矩阵:
In [296]: K2=np.array([[0.1340, -0.0350, 0, 0, -0.1000],[-0.0350, 0.1350, 0, -0.1000, 0],[0, 0, 0.1350, 0.0350, -0.0350],[0, -0.1000, 0.0350, 0.1350, -0.0350],[-0.1000, 0, -0.0350, -0.0350, 0.135]])
In [297]: np.linalg.det(K2)
Out[297]: -1.0674999999999714e-07
Run Code Online (Sandbox Code Playgroud)
反之亦然:
In [298]: np.linalg.inv(K2)
Out[298]:
array([[ -1.00000000e+03, -1.00000000e+03, -2.93090593e-14,
-1.00000000e+03, -1.00000000e+03],
[ -1.00000000e+03, -9.80796253e+02, -3.27868852e+00,
-9.84074941e+02, -9.96721311e+02],
[ -5.26327952e-14, -3.27868852e+00, 8.85245902e+00,
-4.42622951e+00, 1.14754098e+00],
[ -1.00000000e+03, -9.84074941e+02, -4.42622951e+00,
-9.78501171e+02, -9.95573770e+02],
[ -1.00000000e+03, -9.96721311e+02, 1.14754098e+00,
-9.95573770e+02, -9.91147541e+02]])
Run Code Online (Sandbox Code Playgroud)
其次,您的 numpy 情况下的矩阵实际上是奇异的,其行列式是1e-21。1e16这意味着它的逆矩阵不存在,并且在结果中充其量是非常不明确的(解释了大小为 的矩阵元素)。
请注意,矩阵之间的差异不能轻易消失,说“两个矩阵内部是相同的,只是 matlab 没有写那么多小数位”,因为 numpy 的矩阵元素与 matlab 中0.13535533905932737一样打印0.1340,这显然是错误的,与印刷精度无关。
另请注意,您的 matlab 矩阵不是那么奇异的唯一原因是它的大多数元素都是0.135,但它的第一个元素是0.134。如果你让这个元素变得等于其他元素(就像在 numpy 的情况下一样!),你会得到
>> b=a
>> b(1,1)=0.135
>> det(b)
ans =
1.481453848484194e-21
Run Code Online (Sandbox Code Playgroud)
你有它。如果你的实际矩阵是 numpy 中的矩阵,那么解决方案很简单:不要反转它,因为它没有逆矩阵。
为了说服您,请考虑一个与您的矩阵具有相同元素模式的随机矩阵newK:
k1=np.random.rand()*2-1 #element [0,0]
k2=np.random.rand()*2-1 #element [0,1]
k3=k1+k2 #element [0,-1]
Krand=np.array([[k1,k2,0,0,k3],[k2,k1,0,k3,0],[0,0,k1,-k2,k2],[0,k3,-k2,k1,k2],[k3,0,k2,k2,k1]])
Run Code Online (Sandbox Code Playgroud)
然后你得到
In [322]: np.linalg.det(Krand)
Out[322]: 3.3121334687895703e-17
Run Code Online (Sandbox Code Playgroud)
这意味着任何具有这种结构的矩阵都是奇异的。
使用 sympy 最终证明:
import sympy as sym
k1,k2=sym.symbols('k1,k2')
Ksym=sym.Matrix([[k1,k2,0,0,k1+k2],[k2,k1,0,k1+k2,0],[0,0,k1,-k2,k2],[0,k1+k2,-k2,k1,k2],[k1+k2,0,k2,k2,k1]])
Run Code Online (Sandbox Code Playgroud)
那么符号行列式是
In [347]: sym.det(Ksym)
Out[347]: 0
Run Code Online (Sandbox Code Playgroud)