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