Home | History | Annotate | Download | only in test
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2016 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #include <sstream>
     11 
     12 #ifdef EIGEN_TEST_MAX_SIZE
     13 #undef EIGEN_TEST_MAX_SIZE
     14 #endif
     15 
     16 #define EIGEN_TEST_MAX_SIZE 50
     17 
     18 #ifdef EIGEN_TEST_PART_1
     19 #include "cholesky.cpp"
     20 #endif
     21 
     22 #ifdef EIGEN_TEST_PART_2
     23 #include "lu.cpp"
     24 #endif
     25 
     26 #ifdef EIGEN_TEST_PART_3
     27 #include "qr.cpp"
     28 #endif
     29 
     30 #ifdef EIGEN_TEST_PART_4
     31 #include "qr_colpivoting.cpp"
     32 #endif
     33 
     34 #ifdef EIGEN_TEST_PART_5
     35 #include "qr_fullpivoting.cpp"
     36 #endif
     37 
     38 #ifdef EIGEN_TEST_PART_6
     39 #include "eigensolver_selfadjoint.cpp"
     40 #endif
     41 
     42 #ifdef EIGEN_TEST_PART_7
     43 #include "eigensolver_generic.cpp"
     44 #endif
     45 
     46 #ifdef EIGEN_TEST_PART_8
     47 #include "eigensolver_generalized_real.cpp"
     48 #endif
     49 
     50 #ifdef EIGEN_TEST_PART_9
     51 #include "jacobisvd.cpp"
     52 #endif
     53 
     54 #ifdef EIGEN_TEST_PART_10
     55 #include "bdcsvd.cpp"
     56 #endif
     57 
     58 #include <Eigen/Dense>
     59 
     60 #undef min
     61 #undef max
     62 #undef isnan
     63 #undef isinf
     64 #undef isfinite
     65 
     66 #include <boost/multiprecision/cpp_dec_float.hpp>
     67 #include <boost/multiprecision/number.hpp>
     68 #include <boost/math/special_functions.hpp>
     69 #include <boost/math/complex.hpp>
     70 
     71 namespace mp = boost::multiprecision;
     72 typedef mp::number<mp::cpp_dec_float<100>, mp::et_on> Real;
     73 
     74 namespace Eigen {
     75   template<> struct NumTraits<Real> : GenericNumTraits<Real> {
     76     static inline Real dummy_precision() { return 1e-50; }
     77   };
     78 
     79   template<typename T1,typename T2,typename T3,typename T4,typename T5>
     80   struct NumTraits<boost::multiprecision::detail::expression<T1,T2,T3,T4,T5> > : NumTraits<Real> {};
     81 
     82   template<>
     83   Real test_precision<Real>() { return 1e-50; }
     84 
     85   // needed in C++93 mode where number does not support explicit cast.
     86   namespace internal {
     87     template<typename NewType>
     88     struct cast_impl<Real,NewType> {
     89       static inline NewType run(const Real& x) {
     90         return x.template convert_to<NewType>();
     91       }
     92     };
     93 
     94     template<>
     95     struct cast_impl<Real,std::complex<Real> > {
     96       static inline std::complex<Real>  run(const Real& x) {
     97         return std::complex<Real>(x);
     98       }
     99     };
    100   }
    101 }
    102 
    103 namespace boost {
    104 namespace multiprecision {
    105   // to make ADL works as expected:
    106   using boost::math::isfinite;
    107   using boost::math::isnan;
    108   using boost::math::isinf;
    109   using boost::math::copysign;
    110   using boost::math::hypot;
    111 
    112   // The following is needed for std::complex<Real>:
    113   Real fabs(const Real& a) { return abs EIGEN_NOT_A_MACRO (a); }
    114   Real fmax(const Real& a, const Real& b) { using std::max; return max(a,b); }
    115 
    116   // some specialization for the unit tests:
    117   inline bool test_isMuchSmallerThan(const Real& a, const Real& b) {
    118     return internal::isMuchSmallerThan(a, b, test_precision<Real>());
    119   }
    120 
    121   inline bool test_isApprox(const Real& a, const Real& b) {
    122     return internal::isApprox(a, b, test_precision<Real>());
    123   }
    124 
    125   inline bool test_isApproxOrLessThan(const Real& a, const Real& b) {
    126     return internal::isApproxOrLessThan(a, b, test_precision<Real>());
    127   }
    128 
    129   Real get_test_precision(const Real&) {
    130     return test_precision<Real>();
    131   }
    132 
    133   Real test_relative_error(const Real &a, const Real &b) {
    134     using Eigen::numext::abs2;
    135     return sqrt(abs2<Real>(a-b)/Eigen::numext::mini<Real>(abs2(a),abs2(b)));
    136   }
    137 }
    138 }
    139 
    140 namespace Eigen {
    141 
    142 }
    143 
    144 void test_boostmultiprec()
    145 {
    146   typedef Matrix<Real,Dynamic,Dynamic> Mat;
    147   typedef Matrix<std::complex<Real>,Dynamic,Dynamic> MatC;
    148 
    149   std::cout << "NumTraits<Real>::epsilon()         = " << NumTraits<Real>::epsilon() << std::endl;
    150   std::cout << "NumTraits<Real>::dummy_precision() = " << NumTraits<Real>::dummy_precision() << std::endl;
    151   std::cout << "NumTraits<Real>::lowest()          = " << NumTraits<Real>::lowest() << std::endl;
    152   std::cout << "NumTraits<Real>::highest()         = " << NumTraits<Real>::highest() << std::endl;
    153   std::cout << "NumTraits<Real>::digits10()        = " << NumTraits<Real>::digits10() << std::endl;
    154 
    155   // chekc stream output
    156   {
    157     Mat A(10,10);
    158     A.setRandom();
    159     std::stringstream ss;
    160     ss << A;
    161   }
    162   {
    163     MatC A(10,10);
    164     A.setRandom();
    165     std::stringstream ss;
    166     ss << A;
    167   }
    168 
    169   for(int i = 0; i < g_repeat; i++) {
    170     int s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);
    171 
    172     CALL_SUBTEST_1( cholesky(Mat(s,s)) );
    173 
    174     CALL_SUBTEST_2( lu_non_invertible<Mat>() );
    175     CALL_SUBTEST_2( lu_invertible<Mat>() );
    176     CALL_SUBTEST_2( lu_non_invertible<MatC>() );
    177     CALL_SUBTEST_2( lu_invertible<MatC>() );
    178 
    179     CALL_SUBTEST_3( qr(Mat(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
    180     CALL_SUBTEST_3( qr_invertible<Mat>() );
    181 
    182     CALL_SUBTEST_4( qr<Mat>() );
    183     CALL_SUBTEST_4( cod<Mat>() );
    184     CALL_SUBTEST_4( qr_invertible<Mat>() );
    185 
    186     CALL_SUBTEST_5( qr<Mat>() );
    187     CALL_SUBTEST_5( qr_invertible<Mat>() );
    188 
    189     CALL_SUBTEST_6( selfadjointeigensolver(Mat(s,s)) );
    190 
    191     CALL_SUBTEST_7( eigensolver(Mat(s,s)) );
    192 
    193     CALL_SUBTEST_8( generalized_eigensolver_real(Mat(s,s)) );
    194 
    195     TEST_SET_BUT_UNUSED_VARIABLE(s)
    196   }
    197 
    198   CALL_SUBTEST_9(( jacobisvd(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
    199   CALL_SUBTEST_10(( bdcsvd(Mat(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));
    200 }
    201 
    202