00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "svd_common.h"
00012
00013 template<typename MatrixType, int QRPreconditioner>
00014 void jacobisvd_check_full(const MatrixType& m, const JacobiSVD<MatrixType, QRPreconditioner>& svd)
00015 {
00016 svd_check_full<MatrixType, JacobiSVD<MatrixType, QRPreconditioner > >(m, svd);
00017 }
00018
00019 template<typename MatrixType, int QRPreconditioner>
00020 void jacobisvd_compare_to_full(const MatrixType& m,
00021 unsigned int computationOptions,
00022 const JacobiSVD<MatrixType, QRPreconditioner>& referenceSvd)
00023 {
00024 svd_compare_to_full<MatrixType, JacobiSVD<MatrixType, QRPreconditioner> >(m, computationOptions, referenceSvd);
00025 }
00026
00027
00028 template<typename MatrixType, int QRPreconditioner>
00029 void jacobisvd_solve(const MatrixType& m, unsigned int computationOptions)
00030 {
00031 svd_solve< MatrixType, JacobiSVD< MatrixType, QRPreconditioner > >(m, computationOptions);
00032 }
00033
00034
00035
00036 template<typename MatrixType, int QRPreconditioner>
00037 void jacobisvd_test_all_computation_options(const MatrixType& m)
00038 {
00039
00040 if (QRPreconditioner == NoQRPreconditioner && m.rows() != m.cols())
00041 return;
00042
00043 JacobiSVD< MatrixType, QRPreconditioner > fullSvd(m, ComputeFullU|ComputeFullV);
00044 svd_test_computation_options_1< MatrixType, JacobiSVD< MatrixType, QRPreconditioner > >(m, fullSvd);
00045
00046 if(QRPreconditioner == FullPivHouseholderQRPreconditioner)
00047 return;
00048 svd_test_computation_options_2< MatrixType, JacobiSVD< MatrixType, QRPreconditioner > >(m, fullSvd);
00049
00050 }
00051
00052 template<typename MatrixType>
00053 void jacobisvd(const MatrixType& a = MatrixType(), bool pickrandom = true)
00054 {
00055 MatrixType m = pickrandom ? MatrixType::Random(a.rows(), a.cols()) : a;
00056
00057 jacobisvd_test_all_computation_options<MatrixType, FullPivHouseholderQRPreconditioner>(m);
00058 jacobisvd_test_all_computation_options<MatrixType, ColPivHouseholderQRPreconditioner>(m);
00059 jacobisvd_test_all_computation_options<MatrixType, HouseholderQRPreconditioner>(m);
00060 jacobisvd_test_all_computation_options<MatrixType, NoQRPreconditioner>(m);
00061 }
00062
00063
00064 template<typename MatrixType>
00065 void jacobisvd_verify_assert(const MatrixType& m)
00066 {
00067
00068 svd_verify_assert<MatrixType, JacobiSVD< MatrixType > >(m);
00069
00070 typedef typename MatrixType::Index Index;
00071 Index rows = m.rows();
00072 Index cols = m.cols();
00073
00074 enum {
00075 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
00076 ColsAtCompileTime = MatrixType::ColsAtCompileTime
00077 };
00078
00079 MatrixType a = MatrixType::Zero(rows, cols);
00080 a.setZero();
00081
00082 if (ColsAtCompileTime == Dynamic)
00083 {
00084 JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner> svd_fullqr;
00085 VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeFullU|ComputeThinV))
00086 VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeThinV))
00087 VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeFullV))
00088 }
00089 }
00090
00091 template<typename MatrixType>
00092 void jacobisvd_method()
00093 {
00094 enum { Size = MatrixType::RowsAtCompileTime };
00095 typedef typename MatrixType::RealScalar RealScalar;
00096 typedef Matrix<RealScalar, Size, 1> RealVecType;
00097 MatrixType m = MatrixType::Identity();
00098 VERIFY_IS_APPROX(m.jacobiSvd().singularValues(), RealVecType::Ones());
00099 VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixU());
00100 VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixV());
00101 VERIFY_IS_APPROX(m.jacobiSvd(ComputeFullU|ComputeFullV).solve(m), m);
00102 }
00103
00104
00105
00106 template<typename MatrixType>
00107 void jacobisvd_inf_nan()
00108 {
00109 svd_inf_nan<MatrixType, JacobiSVD< MatrixType > >();
00110 }
00111
00112
00113
00114
00115 void jacobisvd_bug286()
00116 {
00117 #if defined __INTEL_COMPILER
00118
00119 #pragma warning push
00120 #pragma warning disable 239
00121 #endif
00122 Matrix2d M;
00123 M << -7.90884e-313, -4.94e-324,
00124 0, 5.60844e-313;
00125 #if defined __INTEL_COMPILER
00126 #pragma warning pop
00127 #endif
00128 JacobiSVD<Matrix2d> svd;
00129 svd.compute(M);
00130 }
00131
00132
00133 void jacobisvd_preallocate()
00134 {
00135 svd_preallocate< JacobiSVD <MatrixXf> >();
00136 }
00137
00138 void test_jacobisvd()
00139 {
00140 CALL_SUBTEST_11(( jacobisvd<Matrix<double,Dynamic,Dynamic> >
00141 (Matrix<double,Dynamic,Dynamic>(16, 6)) ));
00142
00143 CALL_SUBTEST_3(( jacobisvd_verify_assert(Matrix3f()) ));
00144 CALL_SUBTEST_4(( jacobisvd_verify_assert(Matrix4d()) ));
00145 CALL_SUBTEST_7(( jacobisvd_verify_assert(MatrixXf(10,12)) ));
00146 CALL_SUBTEST_8(( jacobisvd_verify_assert(MatrixXcd(7,5)) ));
00147
00148 for(int i = 0; i < g_repeat; i++) {
00149 Matrix2cd m;
00150 m << 0, 1,
00151 0, 1;
00152 CALL_SUBTEST_1(( jacobisvd(m, false) ));
00153 m << 1, 0,
00154 1, 0;
00155 CALL_SUBTEST_1(( jacobisvd(m, false) ));
00156
00157 Matrix2d n;
00158 n << 0, 0,
00159 0, 0;
00160 CALL_SUBTEST_2(( jacobisvd(n, false) ));
00161 n << 0, 0,
00162 0, 1;
00163 CALL_SUBTEST_2(( jacobisvd(n, false) ));
00164
00165 CALL_SUBTEST_3(( jacobisvd<Matrix3f>() ));
00166 CALL_SUBTEST_4(( jacobisvd<Matrix4d>() ));
00167 CALL_SUBTEST_5(( jacobisvd<Matrix<float,3,5> >() ));
00168 CALL_SUBTEST_6(( jacobisvd<Matrix<double,Dynamic,2> >(Matrix<double,Dynamic,2>(10,2)) ));
00169
00170 int r = internal::random<int>(1, 30),
00171 c = internal::random<int>(1, 30);
00172 CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(r,c)) ));
00173 CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(r,c)) ));
00174 (void) r;
00175 (void) c;
00176
00177
00178 CALL_SUBTEST_7( jacobisvd_inf_nan<MatrixXf>() );
00179 }
00180
00181 CALL_SUBTEST_7(( jacobisvd<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))) ));
00182 CALL_SUBTEST_8(( jacobisvd<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))) ));
00183
00184
00185
00186 CALL_SUBTEST_1(( jacobisvd_method<Matrix2cd>() ));
00187 CALL_SUBTEST_3(( jacobisvd_method<Matrix3f>() ));
00188
00189
00190
00191 CALL_SUBTEST_7( JacobiSVD<MatrixXf>(10,10) );
00192
00193
00194 CALL_SUBTEST_9( jacobisvd_preallocate() );
00195
00196
00197 CALL_SUBTEST_2( jacobisvd_bug286() );
00198 }