You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
7.9 KiB

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
  5. // Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
  6. // Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
  7. // Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
  8. //
  9. // This Source Code Form is subject to the terms of the Mozilla
  10. // Public License v. 2.0. If a copy of the MPL was not distributed
  11. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/
  12. #include "svd_common.h"
  13. #include <iostream>
  14. #include <Eigen/LU>
  15. // check if "svd" is the good image of "m"
  16. template<typename MatrixType>
  17. void bdcsvd_check_full(const MatrixType& m, const BDCSVD<MatrixType>& svd)
  18. {
  19. svd_check_full< MatrixType, BDCSVD< MatrixType > >(m, svd);
  20. }
  21. // Compare to a reference value
  22. template<typename MatrixType>
  23. void bdcsvd_compare_to_full(const MatrixType& m,
  24. unsigned int computationOptions,
  25. const BDCSVD<MatrixType>& referenceSvd)
  26. {
  27. svd_compare_to_full< MatrixType, BDCSVD< MatrixType > >(m, computationOptions, referenceSvd);
  28. } // end bdcsvd_compare_to_full
  29. template<typename MatrixType>
  30. void bdcsvd_solve(const MatrixType& m, unsigned int computationOptions)
  31. {
  32. svd_solve< MatrixType, BDCSVD< MatrixType > >(m, computationOptions);
  33. } // end template bdcsvd_solve
  34. // test the computations options
  35. template<typename MatrixType>
  36. void bdcsvd_test_all_computation_options(const MatrixType& m)
  37. {
  38. BDCSVD<MatrixType> fullSvd(m, ComputeFullU|ComputeFullV);
  39. svd_test_computation_options_1< MatrixType, BDCSVD< MatrixType > >(m, fullSvd);
  40. svd_test_computation_options_2< MatrixType, BDCSVD< MatrixType > >(m, fullSvd);
  41. } // end bdcsvd_test_all_computation_options
  42. // Call a test with all the computations options
  43. template<typename MatrixType>
  44. void bdcsvd(const MatrixType& a = MatrixType(), bool pickrandom = true)
  45. {
  46. MatrixType m = pickrandom ? MatrixType::Random(a.rows(), a.cols()) : a;
  47. bdcsvd_test_all_computation_options<MatrixType>(m);
  48. } // end template bdcsvd
  49. // verify assert
  50. template<typename MatrixType>
  51. void bdcsvd_verify_assert(const MatrixType& m)
  52. {
  53. svd_verify_assert< MatrixType, BDCSVD< MatrixType > >(m);
  54. }// end template bdcsvd_verify_assert
  55. // test weird values
  56. template<typename MatrixType>
  57. void bdcsvd_inf_nan()
  58. {
  59. svd_inf_nan< MatrixType, BDCSVD< MatrixType > >();
  60. }// end template bdcsvd_inf_nan
  61. void bdcsvd_preallocate()
  62. {
  63. svd_preallocate< BDCSVD< MatrixXf > >();
  64. } // end bdcsvd_preallocate
  65. // compare the Singular values returned with Jacobi and Bdc
  66. template<typename MatrixType>
  67. void compare_bdc_jacobi(const MatrixType& a = MatrixType(), unsigned int computationOptions = 0)
  68. {
  69. std::cout << "debut compare" << std::endl;
  70. MatrixType m = MatrixType::Random(a.rows(), a.cols());
  71. BDCSVD<MatrixType> bdc_svd(m);
  72. JacobiSVD<MatrixType> jacobi_svd(m);
  73. VERIFY_IS_APPROX(bdc_svd.singularValues(), jacobi_svd.singularValues());
  74. if(computationOptions & ComputeFullU)
  75. VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
  76. if(computationOptions & ComputeThinU)
  77. VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());
  78. if(computationOptions & ComputeFullV)
  79. VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
  80. if(computationOptions & ComputeThinV)
  81. VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());
  82. std::cout << "fin compare" << std::endl;
  83. } // end template compare_bdc_jacobi
  84. // call the tests
  85. void test_bdcsvd()
  86. {
  87. // test of Dynamic defined Matrix (42, 42) of float
  88. CALL_SUBTEST_11(( bdcsvd_verify_assert<Matrix<float,Dynamic,Dynamic> >
  89. (Matrix<float,Dynamic,Dynamic>(42,42)) ));
  90. CALL_SUBTEST_11(( compare_bdc_jacobi<Matrix<float,Dynamic,Dynamic> >
  91. (Matrix<float,Dynamic,Dynamic>(42,42), 0) ));
  92. CALL_SUBTEST_11(( bdcsvd<Matrix<float,Dynamic,Dynamic> >
  93. (Matrix<float,Dynamic,Dynamic>(42,42)) ));
  94. // test of Dynamic defined Matrix (50, 50) of double
  95. CALL_SUBTEST_13(( bdcsvd_verify_assert<Matrix<double,Dynamic,Dynamic> >
  96. (Matrix<double,Dynamic,Dynamic>(50,50)) ));
  97. CALL_SUBTEST_13(( compare_bdc_jacobi<Matrix<double,Dynamic,Dynamic> >
  98. (Matrix<double,Dynamic,Dynamic>(50,50), 0) ));
  99. CALL_SUBTEST_13(( bdcsvd<Matrix<double,Dynamic,Dynamic> >
  100. (Matrix<double,Dynamic,Dynamic>(50, 50)) ));
  101. // test of Dynamic defined Matrix (22, 22) of complex double
  102. CALL_SUBTEST_14(( bdcsvd_verify_assert<Matrix<std::complex<double>,Dynamic,Dynamic> >
  103. (Matrix<std::complex<double>,Dynamic,Dynamic>(22,22)) ));
  104. CALL_SUBTEST_14(( compare_bdc_jacobi<Matrix<std::complex<double>,Dynamic,Dynamic> >
  105. (Matrix<std::complex<double>, Dynamic, Dynamic> (22,22), 0) ));
  106. CALL_SUBTEST_14(( bdcsvd<Matrix<std::complex<double>,Dynamic,Dynamic> >
  107. (Matrix<std::complex<double>,Dynamic,Dynamic>(22, 22)) ));
  108. // test of Dynamic defined Matrix (10, 10) of int
  109. //CALL_SUBTEST_15(( bdcsvd_verify_assert<Matrix<int,Dynamic,Dynamic> >
  110. // (Matrix<int,Dynamic,Dynamic>(10,10)) ));
  111. //CALL_SUBTEST_15(( compare_bdc_jacobi<Matrix<int,Dynamic,Dynamic> >
  112. // (Matrix<int,Dynamic,Dynamic>(10,10), 0) ));
  113. //CALL_SUBTEST_15(( bdcsvd<Matrix<int,Dynamic,Dynamic> >
  114. // (Matrix<int,Dynamic,Dynamic>(10, 10)) ));
  115. // test of Dynamic defined Matrix (8, 6) of double
  116. CALL_SUBTEST_16(( bdcsvd_verify_assert<Matrix<double,Dynamic,Dynamic> >
  117. (Matrix<double,Dynamic,Dynamic>(8,6)) ));
  118. CALL_SUBTEST_16(( compare_bdc_jacobi<Matrix<double,Dynamic,Dynamic> >
  119. (Matrix<double,Dynamic,Dynamic>(8, 6), 0) ));
  120. CALL_SUBTEST_16(( bdcsvd<Matrix<double,Dynamic,Dynamic> >
  121. (Matrix<double,Dynamic,Dynamic>(8, 6)) ));
  122. // test of Dynamic defined Matrix (36, 12) of float
  123. CALL_SUBTEST_17(( compare_bdc_jacobi<Matrix<float,Dynamic,Dynamic> >
  124. (Matrix<float,Dynamic,Dynamic>(36, 12), 0) ));
  125. CALL_SUBTEST_17(( bdcsvd<Matrix<float,Dynamic,Dynamic> >
  126. (Matrix<float,Dynamic,Dynamic>(36, 12)) ));
  127. // test of Dynamic defined Matrix (5, 8) of double
  128. CALL_SUBTEST_18(( compare_bdc_jacobi<Matrix<double,Dynamic,Dynamic> >
  129. (Matrix<double,Dynamic,Dynamic>(5, 8), 0) ));
  130. CALL_SUBTEST_18(( bdcsvd<Matrix<double,Dynamic,Dynamic> >
  131. (Matrix<double,Dynamic,Dynamic>(5, 8)) ));
  132. // non regression tests
  133. CALL_SUBTEST_3(( bdcsvd_verify_assert(Matrix3f()) ));
  134. CALL_SUBTEST_4(( bdcsvd_verify_assert(Matrix4d()) ));
  135. CALL_SUBTEST_7(( bdcsvd_verify_assert(MatrixXf(10,12)) ));
  136. CALL_SUBTEST_8(( bdcsvd_verify_assert(MatrixXcd(7,5)) ));
  137. // SUBTESTS 1 and 2 on specifics matrix
  138. for(int i = 0; i < g_repeat; i++) {
  139. Matrix2cd m;
  140. m << 0, 1,
  141. 0, 1;
  142. CALL_SUBTEST_1(( bdcsvd(m, false) ));
  143. m << 1, 0,
  144. 1, 0;
  145. CALL_SUBTEST_1(( bdcsvd(m, false) ));
  146. Matrix2d n;
  147. n << 0, 0,
  148. 0, 0;
  149. CALL_SUBTEST_2(( bdcsvd(n, false) ));
  150. n << 0, 0,
  151. 0, 1;
  152. CALL_SUBTEST_2(( bdcsvd(n, false) ));
  153. // Statics matrix don't work with BDSVD yet
  154. // bdc algo on a random 3x3 float matrix
  155. // CALL_SUBTEST_3(( bdcsvd<Matrix3f>() ));
  156. // bdc algo on a random 4x4 double matrix
  157. // CALL_SUBTEST_4(( bdcsvd<Matrix4d>() ));
  158. // bdc algo on a random 3x5 float matrix
  159. // CALL_SUBTEST_5(( bdcsvd<Matrix<float,3,5> >() ));
  160. int r = internal::random<int>(1, 30),
  161. c = internal::random<int>(1, 30);
  162. CALL_SUBTEST_7(( bdcsvd<MatrixXf>(MatrixXf(r,c)) ));
  163. CALL_SUBTEST_8(( bdcsvd<MatrixXcd>(MatrixXcd(r,c)) ));
  164. (void) r;
  165. (void) c;
  166. // Test on inf/nan matrix
  167. CALL_SUBTEST_7( bdcsvd_inf_nan<MatrixXf>() );
  168. }
  169. CALL_SUBTEST_7(( bdcsvd<MatrixXf>(MatrixXf(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
  170. CALL_SUBTEST_8(( bdcsvd<MatrixXcd>(MatrixXcd(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3))) ));
  171. // Test problem size constructors
  172. CALL_SUBTEST_7( BDCSVD<MatrixXf>(10,10) );
  173. } // end test_bdcsvd