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)
:这就是结果不同的原因。