我正在尝试使用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()
,但它明确指出这不会设置分解的阈值,而是设置奇数值与零的比较。
注意:我尽可能不想加倍。它有可能浮动吗?
答案 0 :(得分:3)
单个精度浮点(32位float
)具有6到9个重要的十进制数字,因此您的10 ^ { - 10}的要求是不可能的(假设值约为0.5f)。双精度浮点(64位double
)具有15-17个重要的十进制数字,因此只要值不是10 ^ 6就可以工作。