几何尺寸与公差论坛

 找回密码
 注册
查看: 69|回复: 1

C++Eigen库矩阵求逆结果不正常

[复制链接]
发表于 2024-12-16 09:20:52 | 显示全部楼层 |阅读模式
C++使用Eigen库进行矩阵计算
公式:m_Xk_1 = (B.transpose()*B).inverse()*B.transpose()*L;
问题关键点: (B.transpose()*B).inverse()
计算过程及结果
首先验证了B.transpose()*B,在使用Eigen库时与使用matlab时的计算结果,虽然有细微差异,但随后将Eigen库计算的B.transpose()*B替换matlab中相应部分,matlab计算结果仍可靠,说明不是B.transpose()*B的问题。

随后验证了将Eigen库计算的 (B.transpose()*B).inverse()替换matlab中相应部分,发现matlab结果出错,因此确定了是Eigen矩阵求逆有问题。

解决方式
采用矩阵分解的方式求逆。

在此案例中,将m_Xk_1 = (B.transpose()*B).inverse()*B.transpose()*L改为:
m_Xk_1 = (B.transpose()*B).colPivHouseholderQr().solve(B.transpose()*L);
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/qq_39496491/article/details/133861708
 楼主| 发表于 2024-12-16 09:23:25 | 显示全部楼层
在Eigen库中,使用矩阵的逆(.inverse())可能会导致数值不稳定或错误,特别是在矩阵接近奇异(即行列式接近零)的情况下。这是因为直接计算矩阵的逆涉及到大量的浮点运算,这可能会放大数值误差。
你提到的问题,即使用 .inverse() 导致的错误,是Eigen库设计中已知的一个潜在问题。Eigen库推荐使用更稳定的分解方法来解决线性方程组,例如QR分解、LU分解或Cholesky分解(对于正定矩阵)。你选择的 .colPivHouseholderQr().solve() 方法是一种很好的替代方案,因为它使用列主元Householder QR分解来求解线性方程组,这种分解方法在处理一般矩阵时通常更稳定。
关于你的问题,即这个问题在最新的Eigen库代码中是否还存在:

数值稳定性问题:使用 .inverse() 可能导致的数值稳定性问题在Eigen库中依然存在,因为这是由矩阵运算本身的性质决定的,而不是库的实现错误。Eigen库的设计者们一直推荐避免直接使用 .inverse(),而是使用分解方法。


最新版本的改进:虽然基本的数值运算性质没有改变,但Eigen库在持续更新中,可能会改进分解方法的效率和稳定性。此外,Eigen库文档和社区也一直在强调避免直接使用 .inverse()。


推荐的做法:继续使用 .colPivHouseholderQr().solve() 或其他分解方法(如 .lu().solve() 或 .cholesky().solve(),如果适用)来求解线性方程组,这是更稳定且推荐的做法。


总之,你遇到的问题在Eigen库中是预期的,因为直接求逆可能导致数值问题。通过使用 .colPivHouseholderQr().solve() 或其他分解方法,你可以获得更稳定和准确的结果。如果你对Eigen库的最新进展感兴趣,可以查阅Eigen的官方文档或GitHub仓库,了解最新的更新和最佳实践。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|几何尺寸与公差论坛

GMT+8, 2024-12-31 01:58 , Processed in 0.128256 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表