It seems a bug in SVD (Bug #1448)
Description
For floats SVD returns wron results (compared with Eigen).
cv::Mat cvA(6, 6, CV_64F, A_data);
cv::Mat cvB(6, 1, CV_64F, b_data);
cv::Mat cvA_float(6, 6, CV_32F, A_data_float);
cv::Mat cvB_float (6, 1, CV_32F, b_data_float);
cv::solve(cvA, cvB, cvr1, DECOMP_SVD);
cv::solve(cvA_float, cvB_float, cvr2, DECOMP_SVD);
cvr2 !=cvr1*
But in the same time:
Eigen::Map< Matrix<double, 6, 6> > A(A_data);
Eigen::Map< Matrix<double, 6, 1> > b(b_data);
Eigen::Map< Matrix<float, 6, 6> > A(A_data_float);
Eigen::Map< Matrix<float, 6, 1> > b(b_data_float);
Eigen::Matrix<float, 6, 1> res1 = A_float.jacobiSvd(ComputeThinU | ComputeThinV).solve(b_float);
Eigen::Matrix<double, 6, 1> res2 = A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b);
res1 == res2
Related issues
related to Bug #2027: SVD Bug Continue | Done | 2012-06-07 |
Associated revisions
fixed single-precision SVD accuracy on some very ill-conditioned matrices (ticket #1448)
Merge pull request #1448 from StevenPuttemans:bugfix_3264
History
Updated by Vadim Pisarevsky over 13 years ago
thanks for the test case! the problem seems to be fixed in r7039. BTW, since A in the test case is symmetrical, for such problems it is recommended to use DECOMP_EIG method, because SVD explicitly processes (A'*A) matrix, which is very, very ill-conditioned in your case.
- Status changed from Open to Done
- (deleted custom field) set to fixed
Updated by Andrey Kamaev almost 13 years ago
- Target version set to 2.4.0
- Category set to core
Updated by João cabral almost 13 years ago
It seems that this is not totally resolved.
See the file in the attach.
If the matrix is CV_32FC1 sometimes the SVD results are incorrect. In this example the matrix U has some values with the wrong sign, and also it has NaN and inf in some elements. The matrix Vt also has wrong sign in some elements.
If we change all the matrix to CV_64FC1 then the results are accurate.
This happens with the most recent build (booth branch 2.4.1 and trunk 2.4.9 )
Os: Ubuntu 11.10
- File testSVD.cpp added
- File svdtest.m added