core: add iterations limit check in eigenNonSymmetric()
authorAlexander Alekhin <alexander.alekhin@intel.com>
Mon, 18 Mar 2019 14:47:07 +0000 (17:47 +0300)
committerAlexander Alekhin <alexander.alekhin@intel.com>
Mon, 18 Mar 2019 14:49:17 +0000 (17:49 +0300)
modules/core/src/lda.cpp
modules/core/test/test_eigen.cpp

index abbb43e..80c97c0 100644 (file)
@@ -322,6 +322,8 @@ private:
         //  Fortran subroutine in EISPACK.
 
         // Initialize
+        const int max_iters_count = 1000 * this->n;
+
         int nn = this->n;
         int n1 = nn - 1;
         int low = 0;
@@ -487,7 +489,9 @@ private:
                     }
                 }
 
-                iter = iter + 1; // (Could check iteration count here.)
+                iter = iter + 1;
+                if (iter > max_iters_count)
+                    CV_Error(Error::StsNoConv, "Algorithm doesn't converge (complex eigen values?)");
 
                 // Look for two consecutive small sub-diagonal elements
                 int m = n1 - 2;
index b2f09ea..a5b9c3a 100644 (file)
@@ -519,4 +519,15 @@ TEST_P(Core_EigenZero, double)
 }
 INSTANTIATE_TEST_CASE_P(/**/, Core_EigenZero, testing::Values(2, 3, 5));
 
+TEST(Core_EigenNonSymmetric, convergence)
+{
+    Matx33d m(
+        0, -1, 0,
+        1, 0, 1,
+        0, -1, 0);
+    Mat eigenvalues, eigenvectors;
+    // eigen values are complex, algorithm doesn't converge
+    EXPECT_THROW(cv::eigenNonSymmetric(m, eigenvalues, eigenvectors), cv::Exception);  // exception instead of hang
+}
+
 }} // namespace