如何在Eigen库中为接近奇异的3*3矩阵设置容差求解核(零空间)
如何在Eigen中为接近奇异的矩阵计算带容差的零空间?
你需要处理一个3×3的矩阵:它数学上是满秩3,但数值上非常接近奇异(秩趋近于2),必须通过设置容差才能找到对应的零空间。在Scilab中你已经实现了这个需求:
--> Rx_1 = -0.000004 0.0000376 -0.0000261 -0.0000017 -0.459682 0.84146 0.0000458 -0.841457 -0.459684 --> kernel(Rx_1) ans = [] <--- 无精确零空间 --> kernel(Rx_1, 0.0001) ans = <--- 0.0001为设置的容差 1. 0.0000411 <--- 通过容差找到的零空间基。 0.0000244
但在Eigen中使用FullPivLU时,你不清楚如何引入容差参数:
FullPivLU<MatrixXd> lu(Rx_1); <--- lu无法接收额外参数 MatrixXd A_null_space = lu.kernel();
解决方案
Eigen的FullPivLU类提供了setThreshold()方法来设置容差,以此判断哪些奇异值可以被视为0,从而确定矩阵的有效秩,进而计算出对应的零空间。具体代码实现如下:
#include <Eigen/Dense> using namespace Eigen; int main() { MatrixXd Rx_1(3,3); Rx_1 << -0.000004, 0.0000376, -0.0000261, -0.0000017, -0.459682, 0.84146, 0.0000458, -0.841457, -0.459684; FullPivLU<MatrixXd> lu(Rx_1); lu.setThreshold(1e-4); // 设置容差为0.0001,和Scilab中使用的参数一致 MatrixXd A_null_space = lu.kernel(); // 输出零空间基 std::cout << "零空间基:\n" << A_null_space << std::endl; return 0; }
原理说明
setThreshold()方法会修改FullPivLU内部判断奇异值是否为0的阈值,当奇异值小于等于该阈值时,会被视为0,矩阵的有效秩会相应降低。- 调用
kernel()时,会基于调整后的有效秩计算零空间,结果和Scilab中带容差的kernel函数逻辑一致,能够得到数值意义下的近似零空间基。
内容的提问来源于stack exchange,提问作者Xirdal
相关产品推荐
相关产品推荐

