00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #define min(A,B) please_protect_your_min_with_parentheses
00027 #define max(A,B) please_protect_your_max_with_parentheses
00028
00029 #include <cstdlib>
00030 #include <cerrno>
00031 #include <ctime>
00032 #include <iostream>
00033 #include <string>
00034 #include <vector>
00035 #include <typeinfo>
00036
00037 #ifdef NDEBUG
00038 #undef NDEBUG
00039 #endif
00040
00041
00042 #ifdef __ALTIVEC__
00043 #define EIGEN_MAKING_DOCS
00044 #endif
00045
00046 #ifndef EIGEN_TEST_FUNC
00047 #error EIGEN_TEST_FUNC must be defined
00048 #endif
00049
00050 #define DEFAULT_REPEAT 10
00051
00052 #ifdef __ICC
00053
00054 #pragma warning disable 279
00055 #endif
00056
00057 namespace Eigen
00058 {
00059 static std::vector<std::string> g_test_stack;
00060 static int g_repeat;
00061 static unsigned int g_seed;
00062 static bool g_has_set_repeat, g_has_set_seed;
00063 }
00064
00065 #define EI_PP_MAKE_STRING2(S) #S
00066 #define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)
00067
00068 #define EIGEN_DEFAULT_IO_FORMAT IOFormat(4, 0, " ", "\n", "", "", "", "")
00069
00070 #ifndef EIGEN_NO_ASSERTION_CHECKING
00071
00072 namespace Eigen
00073 {
00074 static const bool should_raise_an_assert = false;
00075
00076
00077
00078
00079 static bool no_more_assert = false;
00080 static bool report_on_cerr_on_assert_failure = true;
00081
00082 struct eigen_assert_exception
00083 {
00084 eigen_assert_exception(void) {}
00085 ~eigen_assert_exception() { Eigen::no_more_assert = false; }
00086 };
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 #ifdef EIGEN_DEBUG_ASSERTS
00096
00097 namespace Eigen
00098 {
00099 namespace internal
00100 {
00101 static bool push_assert = false;
00102 }
00103 static std::vector<std::string> eigen_assert_list;
00104 }
00105 #define eigen_assert(a) \
00106 if( (!(a)) && (!no_more_assert) ) \
00107 { \
00108 if(report_on_cerr_on_assert_failure) \
00109 std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \
00110 Eigen::no_more_assert = true; \
00111 throw Eigen::eigen_assert_exception(); \
00112 } \
00113 else if (Eigen::internal::push_assert) \
00114 { \
00115 eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__)" ("EI_PP_MAKE_STRING(__LINE__)") : "#a) ); \
00116 }
00117
00118 #define VERIFY_RAISES_ASSERT(a) \
00119 { \
00120 Eigen::no_more_assert = false; \
00121 Eigen::eigen_assert_list.clear(); \
00122 Eigen::internal::push_assert = true; \
00123 Eigen::report_on_cerr_on_assert_failure = false; \
00124 try { \
00125 a; \
00126 std::cerr << "One of the following asserts should have been triggered:\n"; \
00127 for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai) \
00128 std::cerr << " " << eigen_assert_list[ai] << "\n"; \
00129 VERIFY(Eigen::should_raise_an_assert && # a); \
00130 } catch (Eigen::eigen_assert_exception) { \
00131 Eigen::internal::push_assert = false; VERIFY(true); \
00132 } \
00133 Eigen::report_on_cerr_on_assert_failure = true; \
00134 Eigen::internal::push_assert = false; \
00135 }
00136
00137 #else // EIGEN_DEBUG_ASSERTS
00138
00139 #define eigen_assert(a) \
00140 if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\
00141 { \
00142 Eigen::no_more_assert = true; \
00143 if(report_on_cerr_on_assert_failure) \
00144 eigen_plain_assert(a); \
00145 else \
00146 throw Eigen::eigen_assert_exception(); \
00147 }
00148 #define VERIFY_RAISES_ASSERT(a) { \
00149 Eigen::no_more_assert = false; \
00150 Eigen::report_on_cerr_on_assert_failure = false; \
00151 try { \
00152 a; \
00153 VERIFY(Eigen::should_raise_an_assert && # a); \
00154 } \
00155 catch (Eigen::eigen_assert_exception&) { VERIFY(true); } \
00156 Eigen::report_on_cerr_on_assert_failure = true; \
00157 }
00158
00159 #endif // EIGEN_DEBUG_ASSERTS
00160
00161 #define EIGEN_USE_CUSTOM_ASSERT
00162
00163 #else // EIGEN_NO_ASSERTION_CHECKING
00164
00165 #define VERIFY_RAISES_ASSERT(a) {}
00166
00167 #endif // EIGEN_NO_ASSERTION_CHECKING
00168
00169
00170 #define EIGEN_INTERNAL_DEBUGGING
00171 #include <Eigen/QR>
00172
00173 static void verify_impl(bool condition, const char *testname, const char *file, int line, const char *condition_as_string)
00174 {
00175 if (!condition)
00176 {
00177 std::cerr << "Test " << testname << " failed in " << file << " (" << line << ")" \
00178 << std::endl << " " << condition_as_string << std::endl << std::endl; \
00179 abort();
00180 }
00181 }
00182
00183 #define VERIFY(a) verify_impl(a, g_test_stack.back().c_str(), __FILE__, __LINE__, EI_PP_MAKE_STRING(a))
00184
00185 #define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b))
00186 #define VERIFY_IS_APPROX(a, b) VERIFY(test_isApprox(a, b))
00187 #define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_isApprox(a, b))
00188 #define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_isMuchSmallerThan(a, b))
00189 #define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_isMuchSmallerThan(a, b))
00190 #define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_isApproxOrLessThan(a, b))
00191 #define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_isApproxOrLessThan(a, b))
00192
00193 #define VERIFY_IS_UNITARY(a) VERIFY(test_isUnitary(a))
00194
00195 #define CALL_SUBTEST(FUNC) do { \
00196 g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \
00197 FUNC; \
00198 g_test_stack.pop_back(); \
00199 } while (0)
00200
00201 #ifdef EIGEN_TEST_PART_1
00202 #define CALL_SUBTEST_1(FUNC) CALL_SUBTEST(FUNC)
00203 #else
00204 #define CALL_SUBTEST_1(FUNC)
00205 #endif
00206
00207 #ifdef EIGEN_TEST_PART_2
00208 #define CALL_SUBTEST_2(FUNC) CALL_SUBTEST(FUNC)
00209 #else
00210 #define CALL_SUBTEST_2(FUNC)
00211 #endif
00212
00213 #ifdef EIGEN_TEST_PART_3
00214 #define CALL_SUBTEST_3(FUNC) CALL_SUBTEST(FUNC)
00215 #else
00216 #define CALL_SUBTEST_3(FUNC)
00217 #endif
00218
00219 #ifdef EIGEN_TEST_PART_4
00220 #define CALL_SUBTEST_4(FUNC) CALL_SUBTEST(FUNC)
00221 #else
00222 #define CALL_SUBTEST_4(FUNC)
00223 #endif
00224
00225 #ifdef EIGEN_TEST_PART_5
00226 #define CALL_SUBTEST_5(FUNC) CALL_SUBTEST(FUNC)
00227 #else
00228 #define CALL_SUBTEST_5(FUNC)
00229 #endif
00230
00231 #ifdef EIGEN_TEST_PART_6
00232 #define CALL_SUBTEST_6(FUNC) CALL_SUBTEST(FUNC)
00233 #else
00234 #define CALL_SUBTEST_6(FUNC)
00235 #endif
00236
00237 #ifdef EIGEN_TEST_PART_7
00238 #define CALL_SUBTEST_7(FUNC) CALL_SUBTEST(FUNC)
00239 #else
00240 #define CALL_SUBTEST_7(FUNC)
00241 #endif
00242
00243 #ifdef EIGEN_TEST_PART_8
00244 #define CALL_SUBTEST_8(FUNC) CALL_SUBTEST(FUNC)
00245 #else
00246 #define CALL_SUBTEST_8(FUNC)
00247 #endif
00248
00249 #ifdef EIGEN_TEST_PART_9
00250 #define CALL_SUBTEST_9(FUNC) CALL_SUBTEST(FUNC)
00251 #else
00252 #define CALL_SUBTEST_9(FUNC)
00253 #endif
00254
00255 #ifdef EIGEN_TEST_PART_10
00256 #define CALL_SUBTEST_10(FUNC) CALL_SUBTEST(FUNC)
00257 #else
00258 #define CALL_SUBTEST_10(FUNC)
00259 #endif
00260
00261 #ifdef EIGEN_TEST_PART_11
00262 #define CALL_SUBTEST_11(FUNC) CALL_SUBTEST(FUNC)
00263 #else
00264 #define CALL_SUBTEST_11(FUNC)
00265 #endif
00266
00267 #ifdef EIGEN_TEST_PART_12
00268 #define CALL_SUBTEST_12(FUNC) CALL_SUBTEST(FUNC)
00269 #else
00270 #define CALL_SUBTEST_12(FUNC)
00271 #endif
00272
00273 #ifdef EIGEN_TEST_PART_13
00274 #define CALL_SUBTEST_13(FUNC) CALL_SUBTEST(FUNC)
00275 #else
00276 #define CALL_SUBTEST_13(FUNC)
00277 #endif
00278
00279 #ifdef EIGEN_TEST_PART_14
00280 #define CALL_SUBTEST_14(FUNC) CALL_SUBTEST(FUNC)
00281 #else
00282 #define CALL_SUBTEST_14(FUNC)
00283 #endif
00284
00285 #ifdef EIGEN_TEST_PART_15
00286 #define CALL_SUBTEST_15(FUNC) CALL_SUBTEST(FUNC)
00287 #else
00288 #define CALL_SUBTEST_15(FUNC)
00289 #endif
00290
00291 #ifdef EIGEN_TEST_PART_16
00292 #define CALL_SUBTEST_16(FUNC) CALL_SUBTEST(FUNC)
00293 #else
00294 #define CALL_SUBTEST_16(FUNC)
00295 #endif
00296
00297 namespace Eigen {
00298
00299 template<typename T> inline typename NumTraits<T>::Real test_precision() { return NumTraits<T>::dummy_precision(); }
00300 template<> inline float test_precision<float>() { return 1e-3f; }
00301 template<> inline double test_precision<double>() { return 1e-6; }
00302 template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }
00303 template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }
00304 template<> inline long double test_precision<long double>() { return 1e-6; }
00305
00306 inline bool test_isApprox(const int& a, const int& b)
00307 { return internal::isApprox(a, b, test_precision<int>()); }
00308 inline bool test_isMuchSmallerThan(const int& a, const int& b)
00309 { return internal::isMuchSmallerThan(a, b, test_precision<int>()); }
00310 inline bool test_isApproxOrLessThan(const int& a, const int& b)
00311 { return internal::isApproxOrLessThan(a, b, test_precision<int>()); }
00312
00313 inline bool test_isApprox(const float& a, const float& b)
00314 { return internal::isApprox(a, b, test_precision<float>()); }
00315 inline bool test_isMuchSmallerThan(const float& a, const float& b)
00316 { return internal::isMuchSmallerThan(a, b, test_precision<float>()); }
00317 inline bool test_isApproxOrLessThan(const float& a, const float& b)
00318 { return internal::isApproxOrLessThan(a, b, test_precision<float>()); }
00319 inline bool test_isApprox(const double& a, const double& b)
00320 { return internal::isApprox(a, b, test_precision<double>()); }
00321
00322 inline bool test_isMuchSmallerThan(const double& a, const double& b)
00323 { return internal::isMuchSmallerThan(a, b, test_precision<double>()); }
00324 inline bool test_isApproxOrLessThan(const double& a, const double& b)
00325 { return internal::isApproxOrLessThan(a, b, test_precision<double>()); }
00326
00327 inline bool test_isApprox(const std::complex<float>& a, const std::complex<float>& b)
00328 { return internal::isApprox(a, b, test_precision<std::complex<float> >()); }
00329 inline bool test_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b)
00330 { return internal::isMuchSmallerThan(a, b, test_precision<std::complex<float> >()); }
00331
00332 inline bool test_isApprox(const std::complex<double>& a, const std::complex<double>& b)
00333 { return internal::isApprox(a, b, test_precision<std::complex<double> >()); }
00334 inline bool test_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b)
00335 { return internal::isMuchSmallerThan(a, b, test_precision<std::complex<double> >()); }
00336
00337 inline bool test_isApprox(const long double& a, const long double& b)
00338 {
00339 bool ret = internal::isApprox(a, b, test_precision<long double>());
00340 if (!ret) std::cerr
00341 << std::endl << " actual = " << a
00342 << std::endl << " expected = " << b << std::endl << std::endl;
00343 return ret;
00344 }
00345
00346 inline bool test_isMuchSmallerThan(const long double& a, const long double& b)
00347 { return internal::isMuchSmallerThan(a, b, test_precision<long double>()); }
00348 inline bool test_isApproxOrLessThan(const long double& a, const long double& b)
00349 { return internal::isApproxOrLessThan(a, b, test_precision<long double>()); }
00350
00351 template<typename Type1, typename Type2>
00352 inline bool test_isApprox(const Type1& a, const Type2& b)
00353 {
00354 return a.isApprox(b, test_precision<typename Type1::Scalar>());
00355 }
00356
00357
00358
00359
00360
00361
00362
00363 template<typename Scalar,typename ScalarRef>
00364 inline bool test_isApproxWithRef(const Scalar& a, const Scalar& b, const ScalarRef& ref)
00365 {
00366 return test_isApprox(a+ref, b+ref);
00367 }
00368
00369 template<typename Derived1, typename Derived2>
00370 inline bool test_isMuchSmallerThan(const MatrixBase<Derived1>& m1,
00371 const MatrixBase<Derived2>& m2)
00372 {
00373 return m1.isMuchSmallerThan(m2, test_precision<typename internal::traits<Derived1>::Scalar>());
00374 }
00375
00376 template<typename Derived>
00377 inline bool test_isMuchSmallerThan(const MatrixBase<Derived>& m,
00378 const typename NumTraits<typename internal::traits<Derived>::Scalar>::Real& s)
00379 {
00380 return m.isMuchSmallerThan(s, test_precision<typename internal::traits<Derived>::Scalar>());
00381 }
00382
00383 template<typename Derived>
00384 inline bool test_isUnitary(const MatrixBase<Derived>& m)
00385 {
00386 return m.isUnitary(test_precision<typename internal::traits<Derived>::Scalar>());
00387 }
00388
00389 template<typename T, typename U>
00390 bool test_is_equal(const T& actual, const U& expected)
00391 {
00392 if (actual==expected)
00393 return true;
00394
00395 std::cerr
00396 << std::endl << " actual = " << actual
00397 << std::endl << " expected = " << expected << std::endl << std::endl;
00398 return false;
00399 }
00400
00406 template<typename MatrixType>
00407 void createRandomPIMatrixOfRank(typename MatrixType::Index desired_rank, typename MatrixType::Index rows, typename MatrixType::Index cols, MatrixType& m)
00408 {
00409 typedef typename internal::traits<MatrixType>::Index Index;
00410 typedef typename internal::traits<MatrixType>::Scalar Scalar;
00411 enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
00412
00413 typedef Matrix<Scalar, Dynamic, 1> VectorType;
00414 typedef Matrix<Scalar, Rows, Rows> MatrixAType;
00415 typedef Matrix<Scalar, Cols, Cols> MatrixBType;
00416
00417 if(desired_rank == 0)
00418 {
00419 m.setZero(rows,cols);
00420 return;
00421 }
00422
00423 if(desired_rank == 1)
00424 {
00425
00426 m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
00427 return;
00428 }
00429
00430 MatrixAType a = MatrixAType::Random(rows,rows);
00431 MatrixType d = MatrixType::Identity(rows,cols);
00432 MatrixBType b = MatrixBType::Random(cols,cols);
00433
00434
00435 const Index diag_size = (std::min)(d.rows(),d.cols());
00436 if(diag_size != desired_rank)
00437 d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);
00438
00439 HouseholderQR<MatrixAType> qra(a);
00440 HouseholderQR<MatrixBType> qrb(b);
00441 m = qra.householderQ() * d * qrb.householderQ();
00442 }
00443
00444 }
00445
00446 template<typename T> struct GetDifferentType;
00447
00448 template<> struct GetDifferentType<float> { typedef double type; };
00449 template<> struct GetDifferentType<double> { typedef float type; };
00450 template<typename T> struct GetDifferentType<std::complex<T> >
00451 { typedef std::complex<typename GetDifferentType<T>::type> type; };
00452
00453 template<typename T> std::string type_name() { return "other"; }
00454 template<> std::string type_name<float>() { return "float"; }
00455 template<> std::string type_name<double>() { return "double"; }
00456 template<> std::string type_name<int>() { return "int"; }
00457 template<> std::string type_name<std::complex<float> >() { return "complex<float>"; }
00458 template<> std::string type_name<std::complex<double> >() { return "complex<double>"; }
00459 template<> std::string type_name<std::complex<int> >() { return "complex<int>"; }
00460
00461
00462 void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
00463
00464 using namespace Eigen;
00465
00466 void set_repeat_from_string(const char *str)
00467 {
00468 errno = 0;
00469 g_repeat = int(strtoul(str, 0, 10));
00470 if(errno || g_repeat <= 0)
00471 {
00472 std::cout << "Invalid repeat value " << str << std::endl;
00473 exit(EXIT_FAILURE);
00474 }
00475 g_has_set_repeat = true;
00476 }
00477
00478 void set_seed_from_string(const char *str)
00479 {
00480 errno = 0;
00481 g_seed = strtoul(str, 0, 10);
00482 if(errno || g_seed == 0)
00483 {
00484 std::cout << "Invalid seed value " << str << std::endl;
00485 exit(EXIT_FAILURE);
00486 }
00487 g_has_set_seed = true;
00488 }
00489
00490 int main(int argc, char *argv[])
00491 {
00492 g_has_set_repeat = false;
00493 g_has_set_seed = false;
00494 bool need_help = false;
00495
00496 for(int i = 1; i < argc; i++)
00497 {
00498 if(argv[i][0] == 'r')
00499 {
00500 if(g_has_set_repeat)
00501 {
00502 std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
00503 return 1;
00504 }
00505 set_repeat_from_string(argv[i]+1);
00506 }
00507 else if(argv[i][0] == 's')
00508 {
00509 if(g_has_set_seed)
00510 {
00511 std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
00512 return 1;
00513 }
00514 set_seed_from_string(argv[i]+1);
00515 }
00516 else
00517 {
00518 need_help = true;
00519 }
00520 }
00521
00522 if(need_help)
00523 {
00524 std::cout << "This test application takes the following optional arguments:" << std::endl;
00525 std::cout << " rN Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;
00526 std::cout << " sN Use N as seed for random numbers (default: based on current time)" << std::endl;
00527 std::cout << std::endl;
00528 std::cout << "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl;
00529 std::cout << "will be used as default values for these parameters." << std::endl;
00530 return 1;
00531 }
00532
00533 char *env_EIGEN_REPEAT = getenv("EIGEN_REPEAT");
00534 if(!g_has_set_repeat && env_EIGEN_REPEAT)
00535 set_repeat_from_string(env_EIGEN_REPEAT);
00536 char *env_EIGEN_SEED = getenv("EIGEN_SEED");
00537 if(!g_has_set_seed && env_EIGEN_SEED)
00538 set_seed_from_string(env_EIGEN_SEED);
00539
00540 if(!g_has_set_seed) g_seed = (unsigned int) time(NULL);
00541 if(!g_has_set_repeat) g_repeat = DEFAULT_REPEAT;
00542
00543 std::cout << "Initializing random number generator with seed " << g_seed << std::endl;
00544 srand(g_seed);
00545 std::cout << "Repeating each test " << g_repeat << " times" << std::endl;
00546
00547 Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC));
00548
00549 EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
00550 return 0;
00551 }