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