test_eigen.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  5. // By downloading, copying, installing or using the software you agree to this license.
  6. // If you do not agree to this license, do not download, install,
  7. // copy or use the software.
  8. //
  9. //
  10. // License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
  14. // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
  15. // Third party copyrights are property of their respective owners.
  16. //
  17. // Redistribution and use in source and binary forms, with or without modification,
  18. // are permitted provided that the following conditions are met:
  19. //
  20. // * Redistribution's of source code must retain the above copyright notice,
  21. // this list of conditions and the following disclaimer.
  22. //
  23. // * Redistribution's in binary form must reproduce the above copyright notice,
  24. // this list of conditions and the following disclaimer in the documentation
  25. // and/or other materials provided with the distribution.
  26. //
  27. // * The name of the copyright holders may not be used to endorse or promote products
  28. // derived from this software without specific prior written permission.
  29. //
  30. // This software is provided by the copyright holders and contributors "as is" and
  31. // any express or implied warranties, including, but not limited to, the implied
  32. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  33. // In no event shall the Intel Corporation or contributors be liable for any direct,
  34. // indirect, incidental, special, exemplary, or consequential damages
  35. // (including, but not limited to, procurement of substitute goods or services;
  36. // loss of use, data, or profits; or business interruption) however caused
  37. // and on any theory of liability, whether in contract, strict liability,
  38. // or tort (including negligence or otherwise) arising in any way out of
  39. // the use of this software, even if advised of the possibility of such damage.
  40. //
  41. //M*/
  42. #include "test_precomp.hpp"
  43. namespace opencv_test { namespace {
  44. #define sign(a) a > 0 ? 1 : a == 0 ? 0 : -1
  45. #define CORE_EIGEN_ERROR_COUNT 1
  46. #define CORE_EIGEN_ERROR_SIZE 2
  47. #define CORE_EIGEN_ERROR_DIFF 3
  48. #define CORE_EIGEN_ERROR_ORTHO 4
  49. #define CORE_EIGEN_ERROR_ORDER 5
  50. #define MESSAGE_ERROR_COUNT "Matrix of eigen values must have the same rows as source matrix and 1 column."
  51. #define MESSAGE_ERROR_SIZE "Source matrix and matrix of eigen vectors must have the same sizes."
  52. #define MESSAGE_ERROR_DIFF_1 "Accuracy of eigen values computing less than required."
  53. #define MESSAGE_ERROR_DIFF_2 "Accuracy of eigen vectors computing less than required."
  54. #define MESSAGE_ERROR_ORTHO "Matrix of eigen vectors is not orthogonal."
  55. #define MESSAGE_ERROR_ORDER "Eigen values are not sorted in descending order."
  56. const int COUNT_NORM_TYPES = 3;
  57. const int NORM_TYPE[COUNT_NORM_TYPES] = {cv::NORM_L1, cv::NORM_L2, cv::NORM_INF};
  58. enum TASK_TYPE_EIGEN {VALUES, VECTORS};
  59. class Core_EigenTest: public cvtest::BaseTest
  60. {
  61. public:
  62. Core_EigenTest();
  63. ~Core_EigenTest();
  64. protected:
  65. bool test_values(const cv::Mat& src); // complex test for eigen without vectors
  66. bool check_full(int type); // complex test for symmetric matrix
  67. virtual void run (int) = 0; // main testing method
  68. protected:
  69. float eps_val_32, eps_vec_32;
  70. float eps_val_64, eps_vec_64;
  71. int ntests;
  72. bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index = -1, int high_index = -1);
  73. bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index = -1, int high_index = -1);
  74. bool check_pairs_order(const cv::Mat& eigen_values); // checking order of eigen values & vectors (it should be none up)
  75. bool check_orthogonality(const cv::Mat& U); // checking is matrix of eigen vectors orthogonal
  76. bool test_pairs(const cv::Mat& src); // complex test for eigen with vectors
  77. void print_information(const size_t norm_idx, const cv::Mat& src, double diff, double max_diff);
  78. };
  79. class Core_EigenTest_Scalar : public Core_EigenTest
  80. {
  81. public:
  82. Core_EigenTest_Scalar() : Core_EigenTest() {}
  83. ~Core_EigenTest_Scalar();
  84. virtual void run(int) = 0;
  85. };
  86. class Core_EigenTest_Scalar_32 : public Core_EigenTest_Scalar
  87. {
  88. public:
  89. Core_EigenTest_Scalar_32() : Core_EigenTest_Scalar() {}
  90. ~Core_EigenTest_Scalar_32();
  91. void run(int);
  92. };
  93. class Core_EigenTest_Scalar_64 : public Core_EigenTest_Scalar
  94. {
  95. public:
  96. Core_EigenTest_Scalar_64() : Core_EigenTest_Scalar() {}
  97. ~Core_EigenTest_Scalar_64();
  98. void run(int);
  99. };
  100. class Core_EigenTest_32 : public Core_EigenTest
  101. {
  102. public:
  103. Core_EigenTest_32(): Core_EigenTest() {}
  104. ~Core_EigenTest_32() {}
  105. void run(int);
  106. };
  107. class Core_EigenTest_64 : public Core_EigenTest
  108. {
  109. public:
  110. Core_EigenTest_64(): Core_EigenTest() {}
  111. ~Core_EigenTest_64() {}
  112. void run(int);
  113. };
  114. Core_EigenTest_Scalar::~Core_EigenTest_Scalar() {}
  115. Core_EigenTest_Scalar_32::~Core_EigenTest_Scalar_32() {}
  116. Core_EigenTest_Scalar_64::~Core_EigenTest_Scalar_64() {}
  117. void Core_EigenTest_Scalar_32::run(int)
  118. {
  119. for (int i = 0; i < ntests; ++i)
  120. {
  121. float value = cv::randu<float>();
  122. cv::Mat src(1, 1, CV_32FC1, Scalar::all((float)value));
  123. test_values(src);
  124. }
  125. }
  126. void Core_EigenTest_Scalar_64::run(int)
  127. {
  128. for (int i = 0; i < ntests; ++i)
  129. {
  130. float value = cv::randu<float>();
  131. cv::Mat src(1, 1, CV_64FC1, Scalar::all((double)value));
  132. test_values(src);
  133. }
  134. }
  135. void Core_EigenTest_32::run(int) { check_full(CV_32FC1); }
  136. void Core_EigenTest_64::run(int) { check_full(CV_64FC1); }
  137. Core_EigenTest::Core_EigenTest()
  138. : eps_val_32(1e-3f), eps_vec_32(1e-3f),
  139. eps_val_64(1e-4f), eps_vec_64(1e-4f), ntests(100) {}
  140. Core_EigenTest::~Core_EigenTest() {}
  141. bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index, int high_index)
  142. {
  143. int n = src.rows, s = sign(high_index);
  144. if (!( (evalues.rows == n - max<int>(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1)))) && (evalues.cols == 1)))
  145. {
  146. std::cout << endl; std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl;
  147. std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl;
  148. std::cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl;
  149. CV_Error(CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT);
  150. }
  151. return true;
  152. }
  153. bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index, int high_index)
  154. {
  155. int n = src.rows, s = sign(high_index);
  156. int right_eigen_pair_count = n - max<int>(0, low_index) - ((int)((n/2.0)*(s*s-s)) + (1+s-s*s)*(n - (high_index+1)));
  157. if (!(evectors.rows == right_eigen_pair_count && evectors.cols == right_eigen_pair_count))
  158. {
  159. std::cout << endl; std::cout << "Checking sizes of eigen vectors matrix " << evectors << "..." << endl;
  160. std::cout << "Number of rows: " << evectors.rows << " Number of cols: " << evectors.cols << endl;
  161. std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl;
  162. CV_Error (CORE_EIGEN_ERROR_SIZE, MESSAGE_ERROR_SIZE);
  163. }
  164. if (!(evalues.rows == right_eigen_pair_count && evalues.cols == 1))
  165. {
  166. std::cout << endl; std::cout << "Checking sizes of eigen values matrix " << evalues << "..." << endl;
  167. std::cout << "Number of rows: " << evalues.rows << " Number of cols: " << evalues.cols << endl;
  168. std:: cout << "Size of src symmetric matrix: " << src.rows << " * " << src.cols << endl; std::cout << endl;
  169. CV_Error (CORE_EIGEN_ERROR_COUNT, MESSAGE_ERROR_COUNT);
  170. }
  171. return true;
  172. }
  173. void Core_EigenTest::print_information(const size_t norm_idx, const cv::Mat& src, double diff, double max_diff)
  174. {
  175. switch (NORM_TYPE[norm_idx])
  176. {
  177. case cv::NORM_L1: std::cout << "L1"; break;
  178. case cv::NORM_L2: std::cout << "L2"; break;
  179. case cv::NORM_INF: std::cout << "INF"; break;
  180. default: break;
  181. }
  182. cout << "-criteria... " << endl;
  183. cout << "Source size: " << src.rows << " * " << src.cols << endl;
  184. cout << "Difference between original eigen vectors matrix and result: " << diff << endl;
  185. cout << "Maximum allowed difference: " << max_diff << endl; cout << endl;
  186. }
  187. bool Core_EigenTest::check_orthogonality(const cv::Mat& U)
  188. {
  189. int type = U.type();
  190. double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64;
  191. cv::Mat UUt; cv::mulTransposed(U, UUt, false);
  192. cv::Mat E = Mat::eye(U.rows, U.cols, type);
  193. for (int i = 0; i < COUNT_NORM_TYPES; ++i)
  194. {
  195. double diff = cvtest::norm(UUt, E, NORM_TYPE[i] | cv::NORM_RELATIVE);
  196. if (diff > eps_vec)
  197. {
  198. std::cout << endl; std::cout << "Checking orthogonality of matrix " << U << ": ";
  199. print_information(i, U, diff, eps_vec);
  200. CV_Error(CORE_EIGEN_ERROR_ORTHO, MESSAGE_ERROR_ORTHO);
  201. }
  202. }
  203. return true;
  204. }
  205. bool Core_EigenTest::check_pairs_order(const cv::Mat& eigen_values)
  206. {
  207. switch (eigen_values.type())
  208. {
  209. case CV_32FC1:
  210. {
  211. for (int i = 0; i < (int)(eigen_values.total() - 1); ++i)
  212. if (!(eigen_values.at<float>(i, 0) > eigen_values.at<float>(i+1, 0)))
  213. {
  214. std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl;
  215. std::cout << "Pair of indexes with non descending of eigen values: (" << i << ", " << i+1 << ")." << endl;
  216. std::cout << endl;
  217. CV_Error(CORE_EIGEN_ERROR_ORDER, MESSAGE_ERROR_ORDER);
  218. }
  219. break;
  220. }
  221. case CV_64FC1:
  222. {
  223. for (int i = 0; i < (int)(eigen_values.total() - 1); ++i)
  224. if (!(eigen_values.at<double>(i, 0) > eigen_values.at<double>(i+1, 0)))
  225. {
  226. std::cout << endl; std::cout << "Checking order of eigen values vector " << eigen_values << "..." << endl;
  227. std::cout << "Pair of indexes with non descending of eigen values: (" << i << ", " << i+1 << ")." << endl;
  228. std::cout << endl;
  229. CV_Error(CORE_EIGEN_ERROR_ORDER, "Eigen values are not sorted in descending order.");
  230. }
  231. break;
  232. }
  233. default:;
  234. }
  235. return true;
  236. }
  237. bool Core_EigenTest::test_pairs(const cv::Mat& src)
  238. {
  239. int type = src.type();
  240. double eps_vec = type == CV_32FC1 ? eps_vec_32 : eps_vec_64;
  241. cv::Mat eigen_values, eigen_vectors;
  242. cv::eigen(src, eigen_values, eigen_vectors);
  243. if (!check_pair_count(src, eigen_values, eigen_vectors))
  244. return false;
  245. if (!check_orthogonality (eigen_vectors))
  246. return false;
  247. if (!check_pairs_order(eigen_values))
  248. return false;
  249. cv::Mat eigen_vectors_t; cv::transpose(eigen_vectors, eigen_vectors_t);
  250. // Check:
  251. // src * eigenvector = eigenval * eigenvector
  252. cv::Mat lhs(src.rows, src.cols, type);
  253. cv::Mat rhs(src.rows, src.cols, type);
  254. lhs = src*eigen_vectors_t;
  255. for (int i = 0; i < src.cols; ++i)
  256. {
  257. double eigenval = 0;
  258. switch (type)
  259. {
  260. case CV_32FC1: eigenval = eigen_values.at<float>(i, 0); break;
  261. case CV_64FC1: eigenval = eigen_values.at<double>(i, 0); break;
  262. }
  263. cv::Mat rhs_v = eigenval * eigen_vectors_t.col(i);
  264. rhs_v.copyTo(rhs.col(i));
  265. }
  266. for (int i = 0; i < COUNT_NORM_TYPES; ++i)
  267. {
  268. double diff = cvtest::norm(lhs, rhs, NORM_TYPE[i] | cv::NORM_RELATIVE);
  269. if (diff > eps_vec)
  270. {
  271. std::cout << endl; std::cout << "Checking accuracy of eigen vectors computing for matrix " << src << ": ";
  272. print_information(i, src, diff, eps_vec);
  273. CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_2);
  274. }
  275. }
  276. return true;
  277. }
  278. bool Core_EigenTest::test_values(const cv::Mat& src)
  279. {
  280. int type = src.type();
  281. double eps_val = type == CV_32FC1 ? eps_val_32 : eps_val_64;
  282. cv::Mat eigen_values_1, eigen_values_2, eigen_vectors;
  283. if (!test_pairs(src)) return false;
  284. cv::eigen(src, eigen_values_1, eigen_vectors);
  285. cv::eigen(src, eigen_values_2);
  286. if (!check_pair_count(src, eigen_values_2)) return false;
  287. for (int i = 0; i < COUNT_NORM_TYPES; ++i)
  288. {
  289. double diff = cvtest::norm(eigen_values_1, eigen_values_2, NORM_TYPE[i] | cv::NORM_RELATIVE);
  290. if (diff > eps_val)
  291. {
  292. std::cout << endl; std::cout << "Checking accuracy of eigen values computing for matrix " << src << ": ";
  293. print_information(i, src, diff, eps_val);
  294. CV_Error(CORE_EIGEN_ERROR_DIFF, MESSAGE_ERROR_DIFF_1);
  295. }
  296. }
  297. return true;
  298. }
  299. bool Core_EigenTest::check_full(int type)
  300. {
  301. const int MAX_DEGREE = 7;
  302. RNG rng = cv::theRNG(); // fix the seed
  303. for (int i = 0; i < ntests; ++i)
  304. {
  305. int src_size = (int)(std::pow(2.0, (rng.uniform(0, MAX_DEGREE) + 1.)));
  306. cv::Mat src(src_size, src_size, type);
  307. for (int j = 0; j < src.rows; ++j)
  308. for (int k = j; k < src.cols; ++k)
  309. if (type == CV_32FC1) src.at<float>(k, j) = src.at<float>(j, k) = cv::randu<float>();
  310. else src.at<double>(k, j) = src.at<double>(j, k) = cv::randu<double>();
  311. if (!test_values(src)) return false;
  312. }
  313. return true;
  314. }
  315. TEST(Core_Eigen, scalar_32) {Core_EigenTest_Scalar_32 test; test.safe_run(); }
  316. TEST(Core_Eigen, scalar_64) {Core_EigenTest_Scalar_64 test; test.safe_run(); }
  317. TEST(Core_Eigen, vector_32) { Core_EigenTest_32 test; test.safe_run(); }
  318. TEST(Core_Eigen, vector_64) { Core_EigenTest_64 test; test.safe_run(); }
  319. template<typename T>
  320. static void testEigen(const Mat_<T>& src, const Mat_<T>& expected_eigenvalues, bool runSymmetric = false)
  321. {
  322. SCOPED_TRACE(runSymmetric ? "cv::eigen" : "cv::eigenNonSymmetric");
  323. int type = traits::Type<T>::value;
  324. const T eps = src.type() == CV_32F ? 1e-4f : 1e-6f;
  325. Mat eigenvalues, eigenvectors, eigenvalues0;
  326. if (runSymmetric)
  327. {
  328. cv::eigen(src, eigenvalues0, noArray());
  329. cv::eigen(src, eigenvalues, eigenvectors);
  330. }
  331. else
  332. {
  333. cv::eigenNonSymmetric(src, eigenvalues0, noArray());
  334. cv::eigenNonSymmetric(src, eigenvalues, eigenvectors);
  335. }
  336. #if 0
  337. std::cout << "src = " << src << std::endl;
  338. std::cout << "eigenvalues.t() = " << eigenvalues.t() << std::endl;
  339. std::cout << "eigenvectors = " << eigenvectors << std::endl;
  340. #endif
  341. ASSERT_EQ(type, eigenvalues0.type());
  342. ASSERT_EQ(type, eigenvalues.type());
  343. ASSERT_EQ(type, eigenvectors.type());
  344. ASSERT_EQ(src.rows, eigenvalues.rows);
  345. ASSERT_EQ(eigenvalues.rows, eigenvectors.rows);
  346. ASSERT_EQ(src.rows, eigenvectors.cols);
  347. EXPECT_LT(cvtest::norm(eigenvalues, eigenvalues0, NORM_INF), eps);
  348. // check definition: src*eigenvectors.row(i).t() = eigenvalues.at<srcType>(i)*eigenvectors.row(i).t()
  349. for (int i = 0; i < src.rows; i++)
  350. {
  351. EXPECT_NEAR(eigenvalues.at<T>(i), expected_eigenvalues(i), eps) << "i=" << i;
  352. Mat lhs = src*eigenvectors.row(i).t();
  353. Mat rhs = eigenvalues.at<T>(i)*eigenvectors.row(i).t();
  354. EXPECT_LT(cvtest::norm(lhs, rhs, NORM_INF), eps)
  355. << "i=" << i << " eigenvalue=" << eigenvalues.at<T>(i) << std::endl
  356. << "lhs=" << lhs.t() << std::endl
  357. << "rhs=" << rhs.t();
  358. }
  359. }
  360. template<typename T>
  361. static void testEigenSymmetric3x3()
  362. {
  363. /*const*/ T values_[] = {
  364. 2, -1, 0,
  365. -1, 2, -1,
  366. 0, -1, 2
  367. };
  368. Mat_<T> src(3, 3, values_);
  369. /*const*/ T expected_eigenvalues_[] = { 3.414213562373095f, 2, 0.585786437626905f };
  370. Mat_<T> expected_eigenvalues(3, 1, expected_eigenvalues_);
  371. testEigen(src, expected_eigenvalues);
  372. testEigen(src, expected_eigenvalues, true);
  373. }
  374. TEST(Core_EigenSymmetric, float3x3) { testEigenSymmetric3x3<float>(); }
  375. TEST(Core_EigenSymmetric, double3x3) { testEigenSymmetric3x3<double>(); }
  376. template<typename T>
  377. static void testEigenSymmetric5x5()
  378. {
  379. /*const*/ T values_[5*5] = {
  380. 5, -1, 0, 2, 1,
  381. -1, 4, -1, 0, 0,
  382. 0, -1, 3, 1, -1,
  383. 2, 0, 1, 4, 0,
  384. 1, 0, -1, 0, 1
  385. };
  386. Mat_<T> src(5, 5, values_);
  387. /*const*/ T expected_eigenvalues_[] = { 7.028919644935684f, 4.406130784616501f, 3.73626552682258f, 1.438067799899037f, 0.390616243726198f };
  388. Mat_<T> expected_eigenvalues(5, 1, expected_eigenvalues_);
  389. testEigen(src, expected_eigenvalues);
  390. testEigen(src, expected_eigenvalues, true);
  391. }
  392. TEST(Core_EigenSymmetric, float5x5) { testEigenSymmetric5x5<float>(); }
  393. TEST(Core_EigenSymmetric, double5x5) { testEigenSymmetric5x5<double>(); }
  394. template<typename T>
  395. static void testEigen2x2()
  396. {
  397. /*const*/ T values_[] = { 4, 1, 6, 3 };
  398. Mat_<T> src(2, 2, values_);
  399. /*const*/ T expected_eigenvalues_[] = { 6, 1 };
  400. Mat_<T> expected_eigenvalues(2, 1, expected_eigenvalues_);
  401. testEigen(src, expected_eigenvalues);
  402. }
  403. TEST(Core_EigenNonSymmetric, float2x2) { testEigen2x2<float>(); }
  404. TEST(Core_EigenNonSymmetric, double2x2) { testEigen2x2<double>(); }
  405. template<typename T>
  406. static void testEigen3x3()
  407. {
  408. /*const*/ T values_[3*3] = {
  409. 3,1,0,
  410. 0,3,1,
  411. 0,0,3
  412. };
  413. Mat_<T> src(3, 3, values_);
  414. /*const*/ T expected_eigenvalues_[] = { 3, 3, 3 };
  415. Mat_<T> expected_eigenvalues(3, 1, expected_eigenvalues_);
  416. testEigen(src, expected_eigenvalues);
  417. }
  418. TEST(Core_EigenNonSymmetric, float3x3) { testEigen3x3<float>(); }
  419. TEST(Core_EigenNonSymmetric, double3x3) { testEigen3x3<double>(); }
  420. typedef testing::TestWithParam<int> Core_EigenZero;
  421. TEST_P(Core_EigenZero, double)
  422. {
  423. int N = GetParam();
  424. Mat_<double> srcZero = Mat_<double>::zeros(N, N);
  425. Mat_<double> expected_eigenvalueZero = Mat_<double>::zeros(N, 1); // 1D Mat
  426. testEigen(srcZero, expected_eigenvalueZero);
  427. testEigen(srcZero, expected_eigenvalueZero, true);
  428. }
  429. INSTANTIATE_TEST_CASE_P(/**/, Core_EigenZero, testing::Values(2, 3, 5));
  430. TEST(Core_EigenNonSymmetric, convergence)
  431. {
  432. Matx33d m(
  433. 0, -1, 0,
  434. 1, 0, 1,
  435. 0, -1, 0);
  436. Mat eigenvalues, eigenvectors;
  437. // eigen values are complex, algorithm doesn't converge
  438. try
  439. {
  440. cv::eigenNonSymmetric(m, eigenvalues, eigenvectors);
  441. std::cout << Mat(eigenvalues.t()) << std::endl;
  442. }
  443. catch (const cv::Exception& e)
  444. {
  445. EXPECT_EQ(Error::StsNoConv, e.code) << e.what();
  446. }
  447. catch (...)
  448. {
  449. FAIL() << "Unknown exception has been raised";
  450. }
  451. }
  452. }} // namespace