Matlab 不准确求解线性方程组的倍频程?
我发现倍频程不准确地解方程组Matlab 不准确求解线性方程组的倍频程?,matlab,numpy,octave,Matlab,Numpy,Octave,我发现倍频程不准确地解方程组 k= [1.0000e+015, -2.6667e-001, 3.3333e-002;-2.6667e-001, 5.3333e-001, -2.6667e-001;3.3333e-002, -2.6667e-001, 2.3333e-001]; f = [0;6.66667;41.66667]; x = (k\f) x1 = inv(k)*f x=(k\f) -3.8893e-031 -1.9136e+001 1.1192e+001 x1=in
k= [1.0000e+015, -2.6667e-001, 3.3333e-002;-2.6667e-001, 5.3333e-001, -2.6667e-001;3.3333e-002, -2.6667e-001, 2.3333e-001];
f = [0;6.66667;41.66667];
x = (k\f)
x1 = inv(k)*f
x=(k\f)
-3.8893e-031
-1.9136e+001
1.1192e+001
x1=inv(k)*f
4.8339e-014
2.3752e+002
4.5003e+002
这两个答案有区别。为了检查其他软件是否可以解决这个问题,我尝试了python numpy
import numpy as np
k = np.array ([[1.0000e+015, -2.6667e-001, 3.3333e-002],[-2.6667e-001, 5.3333e-001, -2.6667e-001],[ 3.3333e-002, -2.6667e-001, 2.3333e-001]])
f = np.array([[0],[6.66667],[41.66667]])
x = np.linalg.solve(k, f)
print(x)
[[ 4.83388655e-14]
[ 2.37521517e+02]
[ 4.50034428e+02]]
它正确地解决了这个问题。
我想在倍频程中使用操作符\
来解方程(我想这是MATLAB中推荐的方法)。有什么建议吗
在Windows上使用Octave 4.2.x
编辑:
为什么答案被否决?以下是GNU Octave所说的:
与许多Matlab脚本兼容的插件
试着在MATLAB中运行相同的脚本,然后自己思考
评论家们把责任归咎于病态矩阵。一个好的求解器应该能够以足够的精度进行求解(就像numpy和MATLAB所做的那样)。摘要:倍频程开发人员选择返回(标记的)奇异方程组的“最小范数解” ===============
k
的第一个元素远大于所有其他元素,而f
的对应项为0。在x1
解决方案中
4.8339e-014
2.3752e+002
4.5003e+002
第一个术语实际上是0
对剩余的2x2矩阵执行解算,会产生相同的值:
>> inv(k(2:end,2:end))*f(2:end)
ans =
237.52
450.03
>> k(2:end,2:end)\f(2:end)
ans =
237.52
450.03
在numpy
中:
In [518]: np.linalg.solve(k[1:,1:],f[1:])
Out[518]:
array([[ 237.52151737],
[ 450.0344278 ]])
=================
由于某些原因,\
解算器对矩阵奇异性更为敏感
>> k\f
warning: matrix singular to machine precision, rcond = 6.66612e-17
warning: matrix singular to machine precision, rcond = 6.66612e-17
是的,对这个解决方案的测试表明它已经过时了
>> k*(k\f)
ans =
5.4761
-13.1904
7.7144
>> rcond(k)
ans = 6.6661e-17
>> rcond(k(2:end,2:end))
ans = 0.083327
我不确定这一点的意义,但是numpy
lstsqr
解算器返回与k\f
相同的坏值:
In [525]: np.linalg.lstsq(k,f)
Out[525]:
(array([[ -3.88925778e-31],
[ -1.91360857e+01],
[ 1.11917602e+01]]),
array([], dtype=float64),
2,
array([ 1.00000000e+15, 6.89292234e-01, 7.73677656e-02]))
>> pinv(k)*f # Moore-Penrose pseudoinverse
ans =
-3.8893e-31
-1.9136e+01
1.1192e+01
-声称这是记录在案的。对于奇异、欠定或超定方程,倍频程返回“最小范数解”,而不是“基本解”(由MATLAB选择)
我不这么认为。它特定于倍频程运算符\可能是该运算符的算法。其他方法可行,但不推荐。如果浮点有问题,这两种方法都不应该起作用。您在尝试这些方法时是否注意到警告?“警告:矩阵对机器精度的奇异性,rcond=6.66612e-17”是,尽管如此,
numpy
给出了更准确的答案。实际上,倍频程inv
也起作用。当两种方法都给出警告时,请查看倍频程\和inv
中的错误大小。这是一个条件非常差的矩阵。毫不奇怪,你会得到很大的错误。我认为k\f
与inv(k)*f
不同,它是数值上更稳定的伪逆,即inv(k'k)*(k'f)
:这就是结果不同的原因。