fixed U non-orthogonality in SVD (http://code.opencv.org/issues/3801)
authorVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Wed, 29 Apr 2015 13:09:58 +0000 (16:09 +0300)
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Wed, 29 Apr 2015 13:09:58 +0000 (16:09 +0300)
modules/core/src/lapack.cpp
modules/core/test/test_mat.cpp

index dea25dd..3fbe85b 100644 (file)
@@ -527,7 +527,7 @@ JacobiSVDImpl_(_Tp* At, size_t astep, _Tp* _W, _Tp* Vt, size_t vstep,
                         At[i*astep + k] = t;
                         asum += std::abs(t);
                     }
-                    asum = asum ? 1/asum : 0;
+                    asum = asum > eps*100 ? 1/asum : 0;
                     for( k = 0; k < m; k++ )
                         At[i*astep + k] *= asum;
                 }
index 8cd92dd..60b2444 100644 (file)
@@ -1209,3 +1209,17 @@ TEST(Core_Mat, copyNx1ToVector)
 
     ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), ref_dst16, cv::Mat_<ushort>(dst16));
 }
+
+TEST(Core_SVD, orthogonality)
+{
+    for( int i = 0; i < 2; i++ )
+    {
+        int type = i == 0 ? CV_32F : CV_64F;
+        Mat mat_D(2, 2, type);
+        mat_D.setTo(88.);
+        Mat mat_U, mat_W;
+        SVD::compute(mat_D, mat_W, mat_U, noArray(), SVD::FULL_UV);
+        mat_U *= mat_U.t();
+        ASSERT_LT(norm(mat_U, Mat::eye(2, 2, type), NORM_INF), 1e-5);
+    }
+}