我试图用最小二乘方式求解线性方程组。 使用犰狳及其求解函数我想计算抛物线拟合的三个系数。
vec coeffs = solve(CtC, Ctb)
CtC =
1.0e+009 *
+--------------------------------+
| 2.0878 0.0221 0.0002 |
| 0.0221 0.0002 0.0000 |
| 0.0002 0.0000 0.0000 |
+--------------------------------+
和Ctb =
+------------+
| -0.6163 |
| -0.0065 |
| -0.0001 |
+------------+
显然,解决()无法解决它,即使是Matlab警告:
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate.
RCOND = 1.303968e-022.
犰狳或c ++中是否有任何变通方法或更强大/更复杂的方法? 感谢
答案 0 :(得分:2)
您无法使用行列式等于零来反转矩阵。在你的情况下,行列式等于-8e-12,它实际上不等于零但是给出了反矩阵(使用R)
1.0e-009 *
[,1] [,2] [,3]
[1,] -3.815763e-16 6.806617e-14 5000
[2,] 5.111864e-14 5.000000e+03 -552500
[3,] 5.000000e+03 -5.525000e+05 8856250
请注意,此逆矩阵具有非常大和非常小的数字。这解释了你对“接近单数”和“严重缩放”的警告。根据底层浮点库,您可能会遇到非常糟糕的舍入错误。
您可以返回到您的应用程序,看看是否有任何表示列或行的变量彼此相差很多个数量级。如果是这样,你可以重新调整它们。例如。如果他们之间有一百万的因子,并且它们代表长度,则用公里表示一个,用毫米表示另一个。
答案 1 :(得分:2)
您面临的问题是矩阵的condition number非常高,由于舍入错误,这可能会使您的结果变得毫无意义。
正如rhalbersma所提出的,您可以尝试更好地扩展不同的条目以减少此问题。如果您没有这样的解决方案,那么您必须使用preconditioner。有很多(有些非常复杂),所以你应该找到一个适合你的问题。
然而,对于你手边的这个特殊系统,我只需要反转方程(1)和(3),这将产生一个较低的三角形系统,这对于Matlab来说很容易解决(不需要迭代方法)这可能对条件数非常敏感。在你的情况下,由于矩阵是对称的,Matlab可能会尝试使用cg来解决它,这是一种迭代方法)。
顺便说一句,你的问题是否已知产生接近奇异的矩阵?如果没有,我会在组装矩阵之前检查问题(或错误)(由于舍入错误,矩阵可能是非奇异的)。
编辑:在我的matlab 2009上,我在尝试解决此系统时没有收到任何警告(使用\
命令)。但是,如果我尝试使用命令pcg
,我会得到它们!