main.h (33109B)
1 2 // This file is part of Eigen, a lightweight C++ template library 3 // for linear algebra. 4 // 5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> 6 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 7 // 8 // This Source Code Form is subject to the terms of the Mozilla 9 // Public License v. 2.0. If a copy of the MPL was not distributed 10 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 12 #include <cstdlib> 13 #include <cerrno> 14 #include <ctime> 15 #include <iostream> 16 #include <fstream> 17 #include <string> 18 #include <sstream> 19 #include <vector> 20 #include <typeinfo> 21 #include <functional> 22 23 // The following includes of STL headers have to be done _before_ the 24 // definition of macros min() and max(). The reason is that many STL 25 // implementations will not work properly as the min and max symbols collide 26 // with the STL functions std:min() and std::max(). The STL headers may check 27 // for the macro definition of min/max and issue a warning or undefine the 28 // macros. 29 // 30 // Still, Windows defines min() and max() in windef.h as part of the regular 31 // Windows system interfaces and many other Windows APIs depend on these 32 // macros being available. To prevent the macro expansion of min/max and to 33 // make Eigen compatible with the Windows environment all function calls of 34 // std::min() and std::max() have to be written with parenthesis around the 35 // function name. 36 // 37 // All STL headers used by Eigen should be included here. Because main.h is 38 // included before any Eigen header and because the STL headers are guarded 39 // against multiple inclusions, no STL header will see our own min/max macro 40 // definitions. 41 #include <limits> 42 #include <algorithm> 43 // Disable ICC's std::complex operator specializations so we can use our own. 44 #define _OVERRIDE_COMPLEX_SPECIALIZATION_ 1 45 #include <complex> 46 #include <deque> 47 #include <queue> 48 #include <cassert> 49 #include <list> 50 #if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) 51 #include <random> 52 #include <chrono> 53 #ifdef EIGEN_USE_THREADS 54 #include <future> 55 #endif 56 #endif 57 58 // Same for cuda_fp16.h 59 #if defined(__CUDACC__) && !defined(EIGEN_NO_CUDA) 60 // Means the compiler is either nvcc or clang with CUDA enabled 61 #define EIGEN_CUDACC __CUDACC__ 62 #endif 63 #if defined(EIGEN_CUDACC) 64 #include <cuda.h> 65 #define EIGEN_CUDA_SDK_VER (CUDA_VERSION * 10) 66 #else 67 #define EIGEN_CUDA_SDK_VER 0 68 #endif 69 #if EIGEN_CUDA_SDK_VER >= 70500 70 #include <cuda_fp16.h> 71 #endif 72 73 // To test that all calls from Eigen code to std::min() and std::max() are 74 // protected by parenthesis against macro expansion, the min()/max() macros 75 // are defined here and any not-parenthesized min/max call will cause a 76 // compiler error. 77 #if !defined(__HIPCC__) && !defined(EIGEN_USE_SYCL) 78 // 79 // HIP header files include the following files 80 // <thread> 81 // <regex> 82 // <unordered_map> 83 // which seem to contain not-parenthesized calls to "max"/"min", triggering the following check and causing the compile to fail 84 // 85 // Including those header files before the following macro definition for "min" / "max", only partially resolves the issue 86 // This is because other HIP header files also define "isnan" / "isinf" / "isfinite" functions, which are needed in other 87 // headers. 88 // 89 // So instead choosing to simply disable this check for HIP 90 // 91 #define min(A,B) please_protect_your_min_with_parentheses 92 #define max(A,B) please_protect_your_max_with_parentheses 93 #define isnan(X) please_protect_your_isnan_with_parentheses 94 #define isinf(X) please_protect_your_isinf_with_parentheses 95 #define isfinite(X) please_protect_your_isfinite_with_parentheses 96 #endif 97 98 99 // test possible conflicts 100 struct real {}; 101 struct imag {}; 102 103 #ifdef M_PI 104 #undef M_PI 105 #endif 106 #define M_PI please_use_EIGEN_PI_instead_of_M_PI 107 108 #define FORBIDDEN_IDENTIFIER (this_identifier_is_forbidden_to_avoid_clashes) this_identifier_is_forbidden_to_avoid_clashes 109 // B0 is defined in POSIX header termios.h 110 #define B0 FORBIDDEN_IDENTIFIER 111 // `I` may be defined by complex.h: 112 #define I FORBIDDEN_IDENTIFIER 113 114 // Unit tests calling Eigen's blas library must preserve the default blocking size 115 // to avoid troubles. 116 #ifndef EIGEN_NO_DEBUG_SMALL_PRODUCT_BLOCKS 117 #define EIGEN_DEBUG_SMALL_PRODUCT_BLOCKS 118 #endif 119 120 // shuts down ICC's remark #593: variable "XXX" was set but never used 121 #define TEST_SET_BUT_UNUSED_VARIABLE(X) EIGEN_UNUSED_VARIABLE(X) 122 123 #ifdef TEST_ENABLE_TEMPORARY_TRACKING 124 125 static long int nb_temporaries; 126 static long int nb_temporaries_on_assert = -1; 127 128 inline void on_temporary_creation(long int size) { 129 // here's a great place to set a breakpoint when debugging failures in this test! 130 if(size!=0) nb_temporaries++; 131 if(nb_temporaries_on_assert>0) assert(nb_temporaries<nb_temporaries_on_assert); 132 } 133 134 #define EIGEN_DENSE_STORAGE_CTOR_PLUGIN { on_temporary_creation(size); } 135 136 #define VERIFY_EVALUATION_COUNT(XPR,N) {\ 137 nb_temporaries = 0; \ 138 XPR; \ 139 if(nb_temporaries!=(N)) { std::cerr << "nb_temporaries == " << nb_temporaries << "\n"; }\ 140 VERIFY( (#XPR) && nb_temporaries==(N) ); \ 141 } 142 143 #endif 144 145 #include "split_test_helper.h" 146 147 #ifdef NDEBUG 148 #undef NDEBUG 149 #endif 150 151 // On windows CE, NDEBUG is automatically defined <assert.h> if NDEBUG is not defined. 152 #ifndef DEBUG 153 #define DEBUG 154 #endif 155 156 // bounds integer values for AltiVec 157 #if defined(__ALTIVEC__) || defined(__VSX__) 158 #define EIGEN_MAKING_DOCS 159 #endif 160 161 #define DEFAULT_REPEAT 10 162 163 namespace Eigen 164 { 165 static std::vector<std::string> g_test_stack; 166 // level == 0 <=> abort if test fail 167 // level >= 1 <=> warning message to std::cerr if test fail 168 static int g_test_level = 0; 169 static int g_repeat = 1; 170 static unsigned int g_seed = 0; 171 static bool g_has_set_repeat = false, g_has_set_seed = false; 172 173 class EigenTest 174 { 175 public: 176 EigenTest() : m_func(0) {} 177 EigenTest(const char* a_name, void (*func)(void)) 178 : m_name(a_name), m_func(func) 179 { 180 get_registered_tests().push_back(this); 181 } 182 const std::string& name() const { return m_name; } 183 void operator()() const { m_func(); } 184 185 static const std::vector<EigenTest*>& all() { return get_registered_tests(); } 186 protected: 187 static std::vector<EigenTest*>& get_registered_tests() 188 { 189 static std::vector<EigenTest*>* ms_registered_tests = new std::vector<EigenTest*>(); 190 return *ms_registered_tests; 191 } 192 std::string m_name; 193 void (*m_func)(void); 194 }; 195 196 // Declare and register a test, e.g.: 197 // EIGEN_DECLARE_TEST(mytest) { ... } 198 // will create a function: 199 // void test_mytest() { ... } 200 // that will be automatically called. 201 #define EIGEN_DECLARE_TEST(X) \ 202 void EIGEN_CAT(test_,X) (); \ 203 static EigenTest EIGEN_CAT(test_handler_,X) (EIGEN_MAKESTRING(X), & EIGEN_CAT(test_,X)); \ 204 void EIGEN_CAT(test_,X) () 205 } 206 207 #define TRACK std::cerr << __FILE__ << " " << __LINE__ << std::endl 208 // #define TRACK while() 209 210 #define EIGEN_DEFAULT_IO_FORMAT IOFormat(4, 0, " ", "\n", "", "", "", "") 211 212 #if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(__CUDA_ARCH__) && !defined(__HIP_DEVICE_COMPILE__) && !defined(__SYCL_DEVICE_ONLY__) 213 #define EIGEN_EXCEPTIONS 214 #endif 215 216 #ifndef EIGEN_NO_ASSERTION_CHECKING 217 218 namespace Eigen 219 { 220 static const bool should_raise_an_assert = false; 221 222 // Used to avoid to raise two exceptions at a time in which 223 // case the exception is not properly caught. 224 // This may happen when a second exceptions is triggered in a destructor. 225 static bool no_more_assert = false; 226 static bool report_on_cerr_on_assert_failure = true; 227 228 struct eigen_assert_exception 229 { 230 eigen_assert_exception(void) {} 231 ~eigen_assert_exception() { Eigen::no_more_assert = false; } 232 }; 233 234 struct eigen_static_assert_exception 235 { 236 eigen_static_assert_exception(void) {} 237 ~eigen_static_assert_exception() { Eigen::no_more_assert = false; } 238 }; 239 } 240 // If EIGEN_DEBUG_ASSERTS is defined and if no assertion is triggered while 241 // one should have been, then the list of executed assertions is printed out. 242 // 243 // EIGEN_DEBUG_ASSERTS is not enabled by default as it 244 // significantly increases the compilation time 245 // and might even introduce side effects that would hide 246 // some memory errors. 247 #ifdef EIGEN_DEBUG_ASSERTS 248 249 namespace Eigen 250 { 251 namespace internal 252 { 253 static bool push_assert = false; 254 } 255 static std::vector<std::string> eigen_assert_list; 256 } 257 #define eigen_assert(a) \ 258 if( (!(a)) && (!no_more_assert) ) \ 259 { \ 260 if(report_on_cerr_on_assert_failure) \ 261 std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \ 262 Eigen::no_more_assert = true; \ 263 EIGEN_THROW_X(Eigen::eigen_assert_exception()); \ 264 } \ 265 else if (Eigen::internal::push_assert) \ 266 { \ 267 eigen_assert_list.push_back(std::string(EIGEN_MAKESTRING(__FILE__) " (" EIGEN_MAKESTRING(__LINE__) ") : " #a) ); \ 268 } 269 270 #ifdef EIGEN_EXCEPTIONS 271 #define VERIFY_RAISES_ASSERT(a) \ 272 { \ 273 Eigen::no_more_assert = false; \ 274 Eigen::eigen_assert_list.clear(); \ 275 Eigen::internal::push_assert = true; \ 276 Eigen::report_on_cerr_on_assert_failure = false; \ 277 try { \ 278 a; \ 279 std::cerr << "One of the following asserts should have been triggered:\n"; \ 280 for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai) \ 281 std::cerr << " " << eigen_assert_list[ai] << "\n"; \ 282 VERIFY(Eigen::should_raise_an_assert && # a); \ 283 } catch (Eigen::eigen_assert_exception) { \ 284 Eigen::internal::push_assert = false; VERIFY(true); \ 285 } \ 286 Eigen::report_on_cerr_on_assert_failure = true; \ 287 Eigen::internal::push_assert = false; \ 288 } 289 #endif //EIGEN_EXCEPTIONS 290 291 #elif !defined(__CUDACC__) && !defined(__HIPCC__) && !defined(SYCL_DEVICE_ONLY) // EIGEN_DEBUG_ASSERTS 292 // see bug 89. The copy_bool here is working around a bug in gcc <= 4.3 293 #define eigen_assert(a) \ 294 if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\ 295 { \ 296 Eigen::no_more_assert = true; \ 297 if(report_on_cerr_on_assert_failure) \ 298 eigen_plain_assert(a); \ 299 else \ 300 EIGEN_THROW_X(Eigen::eigen_assert_exception()); \ 301 } 302 303 #ifdef EIGEN_EXCEPTIONS 304 #define VERIFY_RAISES_ASSERT(a) { \ 305 Eigen::no_more_assert = false; \ 306 Eigen::report_on_cerr_on_assert_failure = false; \ 307 try { \ 308 a; \ 309 VERIFY(Eigen::should_raise_an_assert && # a); \ 310 } \ 311 catch (Eigen::eigen_assert_exception&) { VERIFY(true); } \ 312 Eigen::report_on_cerr_on_assert_failure = true; \ 313 } 314 #endif // EIGEN_EXCEPTIONS 315 #endif // EIGEN_DEBUG_ASSERTS 316 317 #if defined(TEST_CHECK_STATIC_ASSERTIONS) && defined(EIGEN_EXCEPTIONS) 318 #define EIGEN_STATIC_ASSERT(a,MSG) \ 319 if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\ 320 { \ 321 Eigen::no_more_assert = true; \ 322 if(report_on_cerr_on_assert_failure) \ 323 eigen_plain_assert((a) && #MSG); \ 324 else \ 325 EIGEN_THROW_X(Eigen::eigen_static_assert_exception()); \ 326 } 327 #define VERIFY_RAISES_STATIC_ASSERT(a) { \ 328 Eigen::no_more_assert = false; \ 329 Eigen::report_on_cerr_on_assert_failure = false; \ 330 try { \ 331 a; \ 332 VERIFY(Eigen::should_raise_an_assert && # a); \ 333 } \ 334 catch (Eigen::eigen_static_assert_exception&) { VERIFY(true); } \ 335 Eigen::report_on_cerr_on_assert_failure = true; \ 336 } 337 #endif // TEST_CHECK_STATIC_ASSERTIONS 338 339 #ifndef VERIFY_RAISES_ASSERT 340 #define VERIFY_RAISES_ASSERT(a) \ 341 std::cout << "Can't VERIFY_RAISES_ASSERT( " #a " ) with exceptions disabled\n"; 342 #endif 343 #ifndef VERIFY_RAISES_STATIC_ASSERT 344 #define VERIFY_RAISES_STATIC_ASSERT(a) \ 345 std::cout << "Can't VERIFY_RAISES_STATIC_ASSERT( " #a " ) with exceptions disabled\n"; 346 #endif 347 348 #if !defined(__CUDACC__) && !defined(__HIPCC__) && !defined(SYCL_DEVICE_ONLY) 349 #define EIGEN_USE_CUSTOM_ASSERT 350 #endif 351 352 #else // EIGEN_NO_ASSERTION_CHECKING 353 354 #define VERIFY_RAISES_ASSERT(a) {} 355 #define VERIFY_RAISES_STATIC_ASSERT(a) {} 356 357 #endif // EIGEN_NO_ASSERTION_CHECKING 358 359 #define EIGEN_INTERNAL_DEBUGGING 360 #include <Eigen/QR> // required for createRandomPIMatrixOfRank 361 362 inline void verify_impl(bool condition, const char *testname, const char *file, int line, const char *condition_as_string) 363 { 364 if (!condition) 365 { 366 if(Eigen::g_test_level>0) 367 std::cerr << "WARNING: "; 368 std::cerr << "Test " << testname << " failed in " << file << " (" << line << ")" 369 << std::endl << " " << condition_as_string << std::endl; 370 std::cerr << "Stack:\n"; 371 const int test_stack_size = static_cast<int>(Eigen::g_test_stack.size()); 372 for(int i=test_stack_size-1; i>=0; --i) 373 std::cerr << " - " << Eigen::g_test_stack[i] << "\n"; 374 std::cerr << "\n"; 375 if(Eigen::g_test_level==0) 376 abort(); 377 } 378 } 379 380 #define VERIFY(a) ::verify_impl(a, g_test_stack.back().c_str(), __FILE__, __LINE__, EIGEN_MAKESTRING(a)) 381 382 #define VERIFY_GE(a, b) ::verify_impl(a >= b, g_test_stack.back().c_str(), __FILE__, __LINE__, EIGEN_MAKESTRING(a >= b)) 383 #define VERIFY_LE(a, b) ::verify_impl(a <= b, g_test_stack.back().c_str(), __FILE__, __LINE__, EIGEN_MAKESTRING(a <= b)) 384 385 386 #define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b, true)) 387 #define VERIFY_IS_NOT_EQUAL(a, b) VERIFY(test_is_equal(a, b, false)) 388 #define VERIFY_IS_APPROX(a, b) VERIFY(verifyIsApprox(a, b)) 389 #define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_isApprox(a, b)) 390 #define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_isMuchSmallerThan(a, b)) 391 #define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_isMuchSmallerThan(a, b)) 392 #define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_isApproxOrLessThan(a, b)) 393 #define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_isApproxOrLessThan(a, b)) 394 395 #define VERIFY_IS_UNITARY(a) VERIFY(test_isUnitary(a)) 396 397 #define STATIC_CHECK(COND) EIGEN_STATIC_ASSERT( (COND) , EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT ) 398 399 #define CALL_SUBTEST(FUNC) do { \ 400 g_test_stack.push_back(EIGEN_MAKESTRING(FUNC)); \ 401 FUNC; \ 402 g_test_stack.pop_back(); \ 403 } while (0) 404 405 406 namespace Eigen { 407 408 template<typename T1,typename T2> 409 typename internal::enable_if<internal::is_same<T1,T2>::value,bool>::type 410 is_same_type(const T1&, const T2&) 411 { 412 return true; 413 } 414 415 template<typename T> inline typename NumTraits<T>::Real test_precision() { return NumTraits<T>::dummy_precision(); } 416 template<> inline float test_precision<float>() { return 1e-3f; } 417 template<> inline double test_precision<double>() { return 1e-6; } 418 template<> inline long double test_precision<long double>() { return 1e-6l; } 419 template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); } 420 template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); } 421 template<> inline long double test_precision<std::complex<long double> >() { return test_precision<long double>(); } 422 423 #define EIGEN_TEST_SCALAR_TEST_OVERLOAD(TYPE) \ 424 inline bool test_isApprox(TYPE a, TYPE b) \ 425 { return internal::isApprox(a, b, test_precision<TYPE>()); } \ 426 inline bool test_isMuchSmallerThan(TYPE a, TYPE b) \ 427 { return internal::isMuchSmallerThan(a, b, test_precision<TYPE>()); } \ 428 inline bool test_isApproxOrLessThan(TYPE a, TYPE b) \ 429 { return internal::isApproxOrLessThan(a, b, test_precision<TYPE>()); } 430 431 EIGEN_TEST_SCALAR_TEST_OVERLOAD(short) 432 EIGEN_TEST_SCALAR_TEST_OVERLOAD(unsigned short) 433 EIGEN_TEST_SCALAR_TEST_OVERLOAD(int) 434 EIGEN_TEST_SCALAR_TEST_OVERLOAD(unsigned int) 435 EIGEN_TEST_SCALAR_TEST_OVERLOAD(long) 436 EIGEN_TEST_SCALAR_TEST_OVERLOAD(unsigned long) 437 #if EIGEN_HAS_CXX11 438 EIGEN_TEST_SCALAR_TEST_OVERLOAD(long long) 439 EIGEN_TEST_SCALAR_TEST_OVERLOAD(unsigned long long) 440 #endif 441 EIGEN_TEST_SCALAR_TEST_OVERLOAD(float) 442 EIGEN_TEST_SCALAR_TEST_OVERLOAD(double) 443 EIGEN_TEST_SCALAR_TEST_OVERLOAD(half) 444 EIGEN_TEST_SCALAR_TEST_OVERLOAD(bfloat16) 445 446 #undef EIGEN_TEST_SCALAR_TEST_OVERLOAD 447 448 #ifndef EIGEN_TEST_NO_COMPLEX 449 inline bool test_isApprox(const std::complex<float>& a, const std::complex<float>& b) 450 { return internal::isApprox(a, b, test_precision<std::complex<float> >()); } 451 inline bool test_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b) 452 { return internal::isMuchSmallerThan(a, b, test_precision<std::complex<float> >()); } 453 454 inline bool test_isApprox(const std::complex<double>& a, const std::complex<double>& b) 455 { return internal::isApprox(a, b, test_precision<std::complex<double> >()); } 456 inline bool test_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b) 457 { return internal::isMuchSmallerThan(a, b, test_precision<std::complex<double> >()); } 458 459 #ifndef EIGEN_TEST_NO_LONGDOUBLE 460 inline bool test_isApprox(const std::complex<long double>& a, const std::complex<long double>& b) 461 { return internal::isApprox(a, b, test_precision<std::complex<long double> >()); } 462 inline bool test_isMuchSmallerThan(const std::complex<long double>& a, const std::complex<long double>& b) 463 { return internal::isMuchSmallerThan(a, b, test_precision<std::complex<long double> >()); } 464 #endif 465 #endif 466 467 #ifndef EIGEN_TEST_NO_LONGDOUBLE 468 inline bool test_isApprox(const long double& a, const long double& b) 469 { 470 bool ret = internal::isApprox(a, b, test_precision<long double>()); 471 if (!ret) std::cerr 472 << std::endl << " actual = " << a 473 << std::endl << " expected = " << b << std::endl << std::endl; 474 return ret; 475 } 476 477 inline bool test_isMuchSmallerThan(const long double& a, const long double& b) 478 { return internal::isMuchSmallerThan(a, b, test_precision<long double>()); } 479 inline bool test_isApproxOrLessThan(const long double& a, const long double& b) 480 { return internal::isApproxOrLessThan(a, b, test_precision<long double>()); } 481 #endif // EIGEN_TEST_NO_LONGDOUBLE 482 483 // test_relative_error returns the relative difference between a and b as a real scalar as used in isApprox. 484 template<typename T1,typename T2> 485 typename NumTraits<typename T1::RealScalar>::NonInteger test_relative_error(const EigenBase<T1> &a, const EigenBase<T2> &b) 486 { 487 using std::sqrt; 488 typedef typename NumTraits<typename T1::RealScalar>::NonInteger RealScalar; 489 typename internal::nested_eval<T1,2>::type ea(a.derived()); 490 typename internal::nested_eval<T2,2>::type eb(b.derived()); 491 return sqrt(RealScalar((ea-eb).cwiseAbs2().sum()) / RealScalar((std::min)(eb.cwiseAbs2().sum(),ea.cwiseAbs2().sum()))); 492 } 493 494 template<typename T1,typename T2> 495 typename T1::RealScalar test_relative_error(const T1 &a, const T2 &b, const typename T1::Coefficients* = 0) 496 { 497 return test_relative_error(a.coeffs(), b.coeffs()); 498 } 499 500 template<typename T1,typename T2> 501 typename T1::Scalar test_relative_error(const T1 &a, const T2 &b, const typename T1::MatrixType* = 0) 502 { 503 return test_relative_error(a.matrix(), b.matrix()); 504 } 505 506 template<typename S, int D> 507 S test_relative_error(const Translation<S,D> &a, const Translation<S,D> &b) 508 { 509 return test_relative_error(a.vector(), b.vector()); 510 } 511 512 template <typename S, int D, int O> 513 S test_relative_error(const ParametrizedLine<S,D,O> &a, const ParametrizedLine<S,D,O> &b) 514 { 515 return (std::max)(test_relative_error(a.origin(), b.origin()), test_relative_error(a.origin(), b.origin())); 516 } 517 518 template <typename S, int D> 519 S test_relative_error(const AlignedBox<S,D> &a, const AlignedBox<S,D> &b) 520 { 521 return (std::max)(test_relative_error((a.min)(), (b.min)()), test_relative_error((a.max)(), (b.max)())); 522 } 523 524 template<typename Derived> class SparseMatrixBase; 525 template<typename T1,typename T2> 526 typename T1::RealScalar test_relative_error(const MatrixBase<T1> &a, const SparseMatrixBase<T2> &b) 527 { 528 return test_relative_error(a,b.toDense()); 529 } 530 531 template<typename Derived> class SparseMatrixBase; 532 template<typename T1,typename T2> 533 typename T1::RealScalar test_relative_error(const SparseMatrixBase<T1> &a, const MatrixBase<T2> &b) 534 { 535 return test_relative_error(a.toDense(),b); 536 } 537 538 template<typename Derived> class SparseMatrixBase; 539 template<typename T1,typename T2> 540 typename T1::RealScalar test_relative_error(const SparseMatrixBase<T1> &a, const SparseMatrixBase<T2> &b) 541 { 542 return test_relative_error(a.toDense(),b.toDense()); 543 } 544 545 template<typename T1,typename T2> 546 typename NumTraits<typename NumTraits<T1>::Real>::NonInteger test_relative_error(const T1 &a, const T2 &b, typename internal::enable_if<internal::is_arithmetic<typename NumTraits<T1>::Real>::value, T1>::type* = 0) 547 { 548 typedef typename NumTraits<typename NumTraits<T1>::Real>::NonInteger RealScalar; 549 return numext::sqrt(RealScalar(numext::abs2(a-b))/(numext::mini)(RealScalar(numext::abs2(a)),RealScalar(numext::abs2(b)))); 550 } 551 552 template<typename T> 553 T test_relative_error(const Rotation2D<T> &a, const Rotation2D<T> &b) 554 { 555 return test_relative_error(a.angle(), b.angle()); 556 } 557 558 template<typename T> 559 T test_relative_error(const AngleAxis<T> &a, const AngleAxis<T> &b) 560 { 561 return (std::max)(test_relative_error(a.angle(), b.angle()), test_relative_error(a.axis(), b.axis())); 562 } 563 564 template<typename Type1, typename Type2> 565 inline bool test_isApprox(const Type1& a, const Type2& b, typename Type1::Scalar* = 0) // Enabled for Eigen's type only 566 { 567 return a.isApprox(b, test_precision<typename Type1::Scalar>()); 568 } 569 570 // get_test_precision is a small wrapper to test_precision allowing to return the scalar precision for either scalars or expressions 571 template<typename T> 572 typename NumTraits<typename T::Scalar>::Real get_test_precision(const T&, const typename T::Scalar* = 0) 573 { 574 return test_precision<typename NumTraits<typename T::Scalar>::Real>(); 575 } 576 577 template<typename T> 578 typename NumTraits<T>::Real get_test_precision(const T&,typename internal::enable_if<internal::is_arithmetic<typename NumTraits<T>::Real>::value, T>::type* = 0) 579 { 580 return test_precision<typename NumTraits<T>::Real>(); 581 } 582 583 // verifyIsApprox is a wrapper to test_isApprox that outputs the relative difference magnitude if the test fails. 584 template<typename Type1, typename Type2> 585 inline bool verifyIsApprox(const Type1& a, const Type2& b) 586 { 587 bool ret = test_isApprox(a,b); 588 if(!ret) 589 { 590 std::cerr << "Difference too large wrt tolerance " << get_test_precision(a) << ", relative error is: " << test_relative_error(a,b) << std::endl; 591 } 592 return ret; 593 } 594 595 // The idea behind this function is to compare the two scalars a and b where 596 // the scalar ref is a hint about the expected order of magnitude of a and b. 597 // WARNING: the scalar a and b must be positive 598 // Therefore, if for some reason a and b are very small compared to ref, 599 // we won't issue a false negative. 600 // This test could be: abs(a-b) <= eps * ref 601 // However, it seems that simply comparing a+ref and b+ref is more sensitive to true error. 602 template<typename Scalar,typename ScalarRef> 603 inline bool test_isApproxWithRef(const Scalar& a, const Scalar& b, const ScalarRef& ref) 604 { 605 return test_isApprox(a+ref, b+ref); 606 } 607 608 template<typename Derived1, typename Derived2> 609 inline bool test_isMuchSmallerThan(const MatrixBase<Derived1>& m1, 610 const MatrixBase<Derived2>& m2) 611 { 612 return m1.isMuchSmallerThan(m2, test_precision<typename internal::traits<Derived1>::Scalar>()); 613 } 614 615 template<typename Derived> 616 inline bool test_isMuchSmallerThan(const MatrixBase<Derived>& m, 617 const typename NumTraits<typename internal::traits<Derived>::Scalar>::Real& s) 618 { 619 return m.isMuchSmallerThan(s, test_precision<typename internal::traits<Derived>::Scalar>()); 620 } 621 622 template<typename Derived> 623 inline bool test_isUnitary(const MatrixBase<Derived>& m) 624 { 625 return m.isUnitary(test_precision<typename internal::traits<Derived>::Scalar>()); 626 } 627 628 // Forward declaration to avoid ICC warning 629 template<typename T, typename U> 630 bool test_is_equal(const T& actual, const U& expected, bool expect_equal=true); 631 632 template<typename T, typename U> 633 bool test_is_equal(const T& actual, const U& expected, bool expect_equal) 634 { 635 if ((actual==expected) == expect_equal) 636 return true; 637 // false: 638 std::cerr 639 << "\n actual = " << actual 640 << "\n expected " << (expect_equal ? "= " : "!=") << expected << "\n\n"; 641 return false; 642 } 643 644 /** Creates a random Partial Isometry matrix of given rank. 645 * 646 * A partial isometry is a matrix all of whose singular values are either 0 or 1. 647 * This is very useful to test rank-revealing algorithms. 648 */ 649 // Forward declaration to avoid ICC warning 650 template<typename MatrixType> 651 void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m); 652 template<typename MatrixType> 653 void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m) 654 { 655 typedef typename internal::traits<MatrixType>::Scalar Scalar; 656 enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime }; 657 658 typedef Matrix<Scalar, Dynamic, 1> VectorType; 659 typedef Matrix<Scalar, Rows, Rows> MatrixAType; 660 typedef Matrix<Scalar, Cols, Cols> MatrixBType; 661 662 if(desired_rank == 0) 663 { 664 m.setZero(rows,cols); 665 return; 666 } 667 668 if(desired_rank == 1) 669 { 670 // here we normalize the vectors to get a partial isometry 671 m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose(); 672 return; 673 } 674 675 MatrixAType a = MatrixAType::Random(rows,rows); 676 MatrixType d = MatrixType::Identity(rows,cols); 677 MatrixBType b = MatrixBType::Random(cols,cols); 678 679 // set the diagonal such that only desired_rank non-zero entries reamain 680 const Index diag_size = (std::min)(d.rows(),d.cols()); 681 if(diag_size != desired_rank) 682 d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank); 683 684 HouseholderQR<MatrixAType> qra(a); 685 HouseholderQR<MatrixBType> qrb(b); 686 m = qra.householderQ() * d * qrb.householderQ(); 687 } 688 689 // Forward declaration to avoid ICC warning 690 template<typename PermutationVectorType> 691 void randomPermutationVector(PermutationVectorType& v, Index size); 692 template<typename PermutationVectorType> 693 void randomPermutationVector(PermutationVectorType& v, Index size) 694 { 695 typedef typename PermutationVectorType::Scalar Scalar; 696 v.resize(size); 697 for(Index i = 0; i < size; ++i) v(i) = Scalar(i); 698 if(size == 1) return; 699 for(Index n = 0; n < 3 * size; ++n) 700 { 701 Index i = internal::random<Index>(0, size-1); 702 Index j; 703 do j = internal::random<Index>(0, size-1); while(j==i); 704 std::swap(v(i), v(j)); 705 } 706 } 707 708 template<typename T> bool isNotNaN(const T& x) 709 { 710 return x==x; 711 } 712 713 template<typename T> bool isPlusInf(const T& x) 714 { 715 return x > NumTraits<T>::highest(); 716 } 717 718 template<typename T> bool isMinusInf(const T& x) 719 { 720 return x < NumTraits<T>::lowest(); 721 } 722 723 } // end namespace Eigen 724 725 template<typename T> struct GetDifferentType; 726 727 template<> struct GetDifferentType<float> { typedef double type; }; 728 template<> struct GetDifferentType<double> { typedef float type; }; 729 template<typename T> struct GetDifferentType<std::complex<T> > 730 { typedef std::complex<typename GetDifferentType<T>::type> type; }; 731 732 // Forward declaration to avoid ICC warning 733 template<typename T> std::string type_name(); 734 template<typename T> std::string type_name() { return "other"; } 735 template<> std::string type_name<float>() { return "float"; } 736 template<> std::string type_name<double>() { return "double"; } 737 template<> std::string type_name<long double>() { return "long double"; } 738 template<> std::string type_name<int>() { return "int"; } 739 template<> std::string type_name<std::complex<float> >() { return "complex<float>"; } 740 template<> std::string type_name<std::complex<double> >() { return "complex<double>"; } 741 template<> std::string type_name<std::complex<long double> >() { return "complex<long double>"; } 742 template<> std::string type_name<std::complex<int> >() { return "complex<int>"; } 743 744 using namespace Eigen; 745 746 inline void set_repeat_from_string(const char *str) 747 { 748 errno = 0; 749 g_repeat = int(strtoul(str, 0, 10)); 750 if(errno || g_repeat <= 0) 751 { 752 std::cout << "Invalid repeat value " << str << std::endl; 753 exit(EXIT_FAILURE); 754 } 755 g_has_set_repeat = true; 756 } 757 758 inline void set_seed_from_string(const char *str) 759 { 760 errno = 0; 761 g_seed = int(strtoul(str, 0, 10)); 762 if(errno || g_seed == 0) 763 { 764 std::cout << "Invalid seed value " << str << std::endl; 765 exit(EXIT_FAILURE); 766 } 767 g_has_set_seed = true; 768 } 769 770 int main(int argc, char *argv[]) 771 { 772 g_has_set_repeat = false; 773 g_has_set_seed = false; 774 bool need_help = false; 775 776 for(int i = 1; i < argc; i++) 777 { 778 if(argv[i][0] == 'r') 779 { 780 if(g_has_set_repeat) 781 { 782 std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl; 783 return 1; 784 } 785 set_repeat_from_string(argv[i]+1); 786 } 787 else if(argv[i][0] == 's') 788 { 789 if(g_has_set_seed) 790 { 791 std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl; 792 return 1; 793 } 794 set_seed_from_string(argv[i]+1); 795 } 796 else 797 { 798 need_help = true; 799 } 800 } 801 802 if(need_help) 803 { 804 std::cout << "This test application takes the following optional arguments:" << std::endl; 805 std::cout << " rN Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl; 806 std::cout << " sN Use N as seed for random numbers (default: based on current time)" << std::endl; 807 std::cout << std::endl; 808 std::cout << "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl; 809 std::cout << "will be used as default values for these parameters." << std::endl; 810 return 1; 811 } 812 813 char *env_EIGEN_REPEAT = getenv("EIGEN_REPEAT"); 814 if(!g_has_set_repeat && env_EIGEN_REPEAT) 815 set_repeat_from_string(env_EIGEN_REPEAT); 816 char *env_EIGEN_SEED = getenv("EIGEN_SEED"); 817 if(!g_has_set_seed && env_EIGEN_SEED) 818 set_seed_from_string(env_EIGEN_SEED); 819 820 if(!g_has_set_seed) g_seed = (unsigned int) time(NULL); 821 if(!g_has_set_repeat) g_repeat = DEFAULT_REPEAT; 822 823 std::cout << "Initializing random number generator with seed " << g_seed << std::endl; 824 std::stringstream ss; 825 ss << "Seed: " << g_seed; 826 g_test_stack.push_back(ss.str()); 827 srand(g_seed); 828 std::cout << "Repeating each test " << g_repeat << " times" << std::endl; 829 830 VERIFY(EigenTest::all().size()>0); 831 832 for(std::size_t i=0; i<EigenTest::all().size(); ++i) 833 { 834 const EigenTest& current_test = *EigenTest::all()[i]; 835 Eigen::g_test_stack.push_back(current_test.name()); 836 current_test(); 837 Eigen::g_test_stack.pop_back(); 838 } 839 840 return 0; 841 } 842 843 // These warning are disabled here such that they are still ON when parsing Eigen's header files. 844 #if defined __INTEL_COMPILER 845 // remark #383: value copied to temporary, reference to temporary used 846 // -> this warning is raised even for legal usage as: g_test_stack.push_back("foo"); where g_test_stack is a std::vector<std::string> 847 // remark #1418: external function definition with no prior declaration 848 // -> this warning is raised for all our test functions. Declaring them static would fix the issue. 849 // warning #279: controlling expression is constant 850 // remark #1572: floating-point equality and inequality comparisons are unreliable 851 #pragma warning disable 279 383 1418 1572 852 #endif 853 854 #ifdef _MSC_VER 855 // 4503 - decorated name length exceeded, name was truncated 856 #pragma warning( disable : 4503) 857 #endif