Установка порога разложения (допуска) Eigen::JacobiSVD

Я пытаюсь поэкспериментировать с JacobiSVD от Eigen. В частности, я пытаюсь восстановить входную матрицу из ее разложения по сингулярным значениям. 1JacobiSVD.html" rel="nofollow">http://eigen.tuxfamily.org/dox/classEigen

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;
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(), но в нем четко указано, что он устанавливает порог не для разложения, а для сравнения сингулярных значений с нулем.

ПРИМЕЧАНИЕ: насколько это возможно, я не хочу делать двойное. Возможно ли это даже с поплавком?


person mkuse    schedule 25.08.2015    source источник


Ответы (1)


Число с плавающей запятой одинарной точности (32-битное float) имеет от шести до девяти значащих десятичных цифр, поэтому ваше требование 10^{-10} невозможно (при условии, что значения составляют около 0,5f). Двойная точность с плавающей запятой (64-битное double) имеет 15–17 значащих десятичных цифр, поэтому должно работать, пока значения не равны 10^6.

person Avi Ginsburg    schedule 25.08.2015