设置分解阈值(容差)Eigen :: JacobiSVD

时间:2015-08-25 03:34:31

标签: eigen eigen3

我正在尝试使用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(),但它明确指出这不会设置分解的阈值,而是设置奇数值与零的比较。

注意:我尽可能不想加倍。它有可能浮动吗?

1 个答案:

答案 0 :(得分:3)

单个精度浮点(32位float)具有6到9个重要的十进制数字,因此您的10 ^ { - 10}的要求是不可能的(假设值约为0.5f)。双精度浮点(64位double)具有15-17个重要的十进制数字,因此只要值不是10 ^ 6就可以工作。