设置分解阈值(容差)Eigen::JacobiSVD
Setting decomposition threshold (tolerance) Eigen::JacobiSVD
我正在尝试使用 Eigen 的 JacobiSVD 进行实验。特别是我试图从奇异值分解中重建输入矩阵。 http://eigen.tuxfamily.org/dox/classEigen_1_1JacobiSVD.html.
Eigen::MatrixXf m = Eigen::MatrixXf::Random(3,3);
Eigen::JacobiSVD<Eigen::MatrixXf, Eigen::NoQRPreconditioner> svd(m, Eigen::ComputeFullU | Eigen:: ComputeFullV);
Eigen::VectorXf SVec = svd.singularValues();
Eigen::MatrixXf S = Eigen::MatrixXf::Identity(3,3);
S(0,0) = SVec(0);
S(1,1) = SVec(1);
S(2,2) = SVec(2);
Eigen::MatrixXf recon = svd.matrixU() * S * svd.matrixV().transpose();
cout<< "diff : \n"<< m - recon << endl;
我知道SVD在内部是通过迭代方法计算的,永远无法得到完美的重构。错误按 10^-7 的顺序排列。使用上面的代码,输出是 --
diff :
9.53674e-07 1.2517e-06 -2.98023e-07
-4.47035e-08 1.3113e-06 8.9407e-07
5.96046e-07 -9.53674e-07 -7.7486e-07
对于我的应用程序,这个错误太高了,我的目标是 10^-10 - 10^-12 范围内的错误。我的问题是如何设置分解的阈值。
注意:在文档中我注意到有一种方法 setThreshold()
但它明确指出这不会为分解设置阈值,而是为奇异值与零进行比较。
注意:我尽可能不希望双打。甚至可以用 float 吗?
一个单精度浮点数(32 位 float
)有六到九个有效的 十进制 数字,所以你对 10^{-10} 的要求是不可能(假设值在 0.5f 左右)。双精度浮点数(64 位 double
)有 15-17 个有效 小数 数字,所以只要值不是 10^6 就应该工作。
我正在尝试使用 Eigen 的 JacobiSVD 进行实验。特别是我试图从奇异值分解中重建输入矩阵。 http://eigen.tuxfamily.org/dox/classEigen_1_1JacobiSVD.html.
Eigen::MatrixXf m = Eigen::MatrixXf::Random(3,3);
Eigen::JacobiSVD<Eigen::MatrixXf, Eigen::NoQRPreconditioner> svd(m, Eigen::ComputeFullU | Eigen:: ComputeFullV);
Eigen::VectorXf SVec = svd.singularValues();
Eigen::MatrixXf S = Eigen::MatrixXf::Identity(3,3);
S(0,0) = SVec(0);
S(1,1) = SVec(1);
S(2,2) = SVec(2);
Eigen::MatrixXf recon = svd.matrixU() * S * svd.matrixV().transpose();
cout<< "diff : \n"<< m - recon << endl;
我知道SVD在内部是通过迭代方法计算的,永远无法得到完美的重构。错误按 10^-7 的顺序排列。使用上面的代码,输出是 --
diff :
9.53674e-07 1.2517e-06 -2.98023e-07
-4.47035e-08 1.3113e-06 8.9407e-07
5.96046e-07 -9.53674e-07 -7.7486e-07
对于我的应用程序,这个错误太高了,我的目标是 10^-10 - 10^-12 范围内的错误。我的问题是如何设置分解的阈值。
注意:在文档中我注意到有一种方法 setThreshold()
但它明确指出这不会为分解设置阈值,而是为奇异值与零进行比较。
注意:我尽可能不希望双打。甚至可以用 float 吗?
一个单精度浮点数(32 位 float
)有六到九个有效的 十进制 数字,所以你对 10^{-10} 的要求是不可能(假设值在 0.5f 左右)。双精度浮点数(64 位 double
)有 15-17 个有效 小数 数字,所以只要值不是 10^6 就应该工作。