jacobisvd.cpp
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
00006 //
00007 // This Source Code Form is subject to the terms of the Mozilla
00008 // Public License v. 2.0. If a copy of the MPL was not distributed
00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
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 // Regression test for bug 286: JacobiSVD loops indefinitely with some
00114 // matrices containing denormal numbers.
00115 void jacobisvd_bug286()
00116 {
00117 #if defined __INTEL_COMPILER
00118 // shut up warning #239: floating point underflow
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); // just check we don't loop indefinitely
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     // Test on inf/nan matrix
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   // test matrixbase method
00186   CALL_SUBTEST_1(( jacobisvd_method<Matrix2cd>() ));
00187   CALL_SUBTEST_3(( jacobisvd_method<Matrix3f>() ));
00188 
00189 
00190   // Test problem size constructors
00191   CALL_SUBTEST_7( JacobiSVD<MatrixXf>(10,10) );
00192 
00193   // Check that preallocation avoids subsequent mallocs
00194   CALL_SUBTEST_9( jacobisvd_preallocate() );
00195 
00196   // Regression check for bug 286
00197   CALL_SUBTEST_2( jacobisvd_bug286() );
00198 }


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:32:12