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 <ctime>
00028 #include <iostream>
00029 #include <string>
00030 #include <vector>
00031
00032 #ifndef EIGEN_TEST_FUNC
00033 #error EIGEN_TEST_FUNC must be defined
00034 #endif
00035
00036 #define DEFAULT_REPEAT 10
00037
00038 namespace Eigen
00039 {
00040 static std::vector<std::string> g_test_stack;
00041 static int g_repeat;
00042 }
00043
00044 #define EI_PP_MAKE_STRING2(S) #S
00045 #define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)
00046
00047 #define EI_PP_CAT2(a,b) a ## b
00048 #define EI_PP_CAT(a,b) EI_PP_CAT2(a,b)
00049
00050 #ifndef EIGEN_NO_ASSERTION_CHECKING
00051
00052 namespace Eigen
00053 {
00054 static const bool should_raise_an_assert = false;
00055
00056
00057
00058
00059 static bool no_more_assert = false;
00060
00061 struct eigen_assert_exception
00062 {
00063 eigen_assert_exception(void) {}
00064 ~eigen_assert_exception() { Eigen::no_more_assert = false; }
00065 };
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075 #ifdef EIGEN_DEBUG_ASSERTS
00076
00077 namespace Eigen
00078 {
00079 static bool ei_push_assert = false;
00080 static std::vector<std::string> eigen_assert_list;
00081 }
00082
00083 #define eigen_assert(a) \
00084 if( (!(a)) && (!no_more_assert) ) \
00085 { \
00086 Eigen::no_more_assert = true; \
00087 throw Eigen::eigen_assert_exception(); \
00088 } \
00089 else if (Eigen::ei_push_assert) \
00090 { \
00091 eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__)" ("EI_PP_MAKE_STRING(__LINE__)") : "#a) ); \
00092 }
00093
00094 #define VERIFY_RAISES_ASSERT(a) \
00095 { \
00096 Eigen::no_more_assert = false; \
00097 try { \
00098 Eigen::eigen_assert_list.clear(); \
00099 Eigen::ei_push_assert = true; \
00100 a; \
00101 Eigen::ei_push_assert = false; \
00102 std::cerr << "One of the following asserts should have been raised:\n"; \
00103 for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai) \
00104 std::cerr << " " << eigen_assert_list[ai] << "\n"; \
00105 VERIFY(Eigen::should_raise_an_assert && # a); \
00106 } catch (Eigen::eigen_assert_exception e) { \
00107 Eigen::ei_push_assert = false; VERIFY(true); \
00108 } \
00109 }
00110
00111 #else // EIGEN_DEBUG_ASSERTS
00112
00113 #undef eigen_assert
00114
00115
00116 #define eigen_assert(a) \
00117 if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) ) \
00118 { \
00119 Eigen::no_more_assert = true; \
00120 throw Eigen::eigen_assert_exception(); \
00121 }
00122
00123 #define VERIFY_RAISES_ASSERT(a) { \
00124 Eigen::no_more_assert = false; \
00125 try { a; VERIFY(Eigen::should_raise_an_assert && # a); } \
00126 catch (Eigen::eigen_assert_exception e) { VERIFY(true); } \
00127 }
00128
00129 #endif // EIGEN_DEBUG_ASSERTS
00130
00131 #define EIGEN_USE_CUSTOM_ASSERT
00132
00133 #else // EIGEN_NO_ASSERTION_CHECKING
00134
00135 #define VERIFY_RAISES_ASSERT(a) {}
00136
00137 #endif // EIGEN_NO_ASSERTION_CHECKING
00138
00139
00140 #define EIGEN_INTERNAL_DEBUGGING
00141 #define EIGEN_NICE_RANDOM
00142 #include <Eigen/Array>
00143
00144
00145 #define VERIFY(a) do { if (!(a)) { \
00146 std::cerr << "Test " << g_test_stack.back() << " failed in "EI_PP_MAKE_STRING(__FILE__) << " (" << EI_PP_MAKE_STRING(__LINE__) << ")" \
00147 << std::endl << " " << EI_PP_MAKE_STRING(a) << std::endl << std::endl; \
00148 abort(); \
00149 } } while (0)
00150
00151 #define VERIFY_IS_APPROX(a, b) VERIFY(test_ei_isApprox(a, b))
00152 #define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_ei_isApprox(a, b))
00153 #define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_ei_isMuchSmallerThan(a, b))
00154 #define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_ei_isMuchSmallerThan(a, b))
00155 #define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_ei_isApproxOrLessThan(a, b))
00156 #define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_ei_isApproxOrLessThan(a, b))
00157
00158 #define CALL_SUBTEST(FUNC) do { \
00159 g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \
00160 FUNC; \
00161 g_test_stack.pop_back(); \
00162 } while (0)
00163
00164 namespace Eigen {
00165
00166 template<typename T> inline typename NumTraits<T>::Real test_precision();
00167 template<> inline int test_precision<int>() { return 0; }
00168 template<> inline float test_precision<float>() { return 1e-3f; }
00169 template<> inline double test_precision<double>() { return 1e-6; }
00170 template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }
00171 template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }
00172 template<> inline long double test_precision<long double>() { return 1e-6; }
00173
00174 inline bool test_ei_isApprox(const int& a, const int& b)
00175 { return ei_isApprox(a, b, test_precision<int>()); }
00176 inline bool test_ei_isMuchSmallerThan(const int& a, const int& b)
00177 { return ei_isMuchSmallerThan(a, b, test_precision<int>()); }
00178 inline bool test_ei_isApproxOrLessThan(const int& a, const int& b)
00179 { return ei_isApproxOrLessThan(a, b, test_precision<int>()); }
00180
00181 inline bool test_ei_isApprox(const float& a, const float& b)
00182 { return ei_isApprox(a, b, test_precision<float>()); }
00183 inline bool test_ei_isMuchSmallerThan(const float& a, const float& b)
00184 { return ei_isMuchSmallerThan(a, b, test_precision<float>()); }
00185 inline bool test_ei_isApproxOrLessThan(const float& a, const float& b)
00186 { return ei_isApproxOrLessThan(a, b, test_precision<float>()); }
00187
00188 inline bool test_ei_isApprox(const double& a, const double& b)
00189 { return ei_isApprox(a, b, test_precision<double>()); }
00190 inline bool test_ei_isMuchSmallerThan(const double& a, const double& b)
00191 { return ei_isMuchSmallerThan(a, b, test_precision<double>()); }
00192 inline bool test_ei_isApproxOrLessThan(const double& a, const double& b)
00193 { return ei_isApproxOrLessThan(a, b, test_precision<double>()); }
00194
00195 inline bool test_ei_isApprox(const std::complex<float>& a, const std::complex<float>& b)
00196 { return ei_isApprox(a, b, test_precision<std::complex<float> >()); }
00197 inline bool test_ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b)
00198 { return ei_isMuchSmallerThan(a, b, test_precision<std::complex<float> >()); }
00199
00200 inline bool test_ei_isApprox(const std::complex<double>& a, const std::complex<double>& b)
00201 { return ei_isApprox(a, b, test_precision<std::complex<double> >()); }
00202 inline bool test_ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b)
00203 { return ei_isMuchSmallerThan(a, b, test_precision<std::complex<double> >()); }
00204
00205 inline bool test_ei_isApprox(const long double& a, const long double& b)
00206 { return ei_isApprox(a, b, test_precision<long double>()); }
00207 inline bool test_ei_isMuchSmallerThan(const long double& a, const long double& b)
00208 { return ei_isMuchSmallerThan(a, b, test_precision<long double>()); }
00209 inline bool test_ei_isApproxOrLessThan(const long double& a, const long double& b)
00210 { return ei_isApproxOrLessThan(a, b, test_precision<long double>()); }
00211
00212 template<typename Type1, typename Type2>
00213 inline bool test_ei_isApprox(const Type1& a, const Type2& b)
00214 {
00215 return a.isApprox(b, test_precision<typename Type1::Scalar>());
00216 }
00217
00218 template<typename Derived1, typename Derived2>
00219 inline bool test_ei_isMuchSmallerThan(const MatrixBase<Derived1>& m1,
00220 const MatrixBase<Derived2>& m2)
00221 {
00222 return m1.isMuchSmallerThan(m2, test_precision<typename ei_traits<Derived1>::Scalar>());
00223 }
00224
00225 template<typename Derived>
00226 inline bool test_ei_isMuchSmallerThan(const MatrixBase<Derived>& m,
00227 const typename NumTraits<typename ei_traits<Derived>::Scalar>::Real& s)
00228 {
00229 return m.isMuchSmallerThan(s, test_precision<typename ei_traits<Derived>::Scalar>());
00230 }
00231
00232 }
00233
00234 template<typename T> struct GetDifferentType;
00235
00236 template<> struct GetDifferentType<float> { typedef double type; };
00237 template<> struct GetDifferentType<double> { typedef float type; };
00238 template<typename T> struct GetDifferentType<std::complex<T> >
00239 { typedef std::complex<typename GetDifferentType<T>::type> type; };
00240
00241
00242 void EI_PP_CAT(test_,EIGEN_TEST_FUNC)();
00243
00244 using namespace Eigen;
00245
00246 #ifdef EIGEN_TEST_PART_1
00247 #define CALL_SUBTEST_1(FUNC) CALL_SUBTEST(FUNC)
00248 #else
00249 #define CALL_SUBTEST_1(FUNC)
00250 #endif
00251
00252 #ifdef EIGEN_TEST_PART_2
00253 #define CALL_SUBTEST_2(FUNC) CALL_SUBTEST(FUNC)
00254 #else
00255 #define CALL_SUBTEST_2(FUNC)
00256 #endif
00257
00258 #ifdef EIGEN_TEST_PART_3
00259 #define CALL_SUBTEST_3(FUNC) CALL_SUBTEST(FUNC)
00260 #else
00261 #define CALL_SUBTEST_3(FUNC)
00262 #endif
00263
00264 #ifdef EIGEN_TEST_PART_4
00265 #define CALL_SUBTEST_4(FUNC) CALL_SUBTEST(FUNC)
00266 #else
00267 #define CALL_SUBTEST_4(FUNC)
00268 #endif
00269
00270 #ifdef EIGEN_TEST_PART_5
00271 #define CALL_SUBTEST_5(FUNC) CALL_SUBTEST(FUNC)
00272 #else
00273 #define CALL_SUBTEST_5(FUNC)
00274 #endif
00275
00276 #ifdef EIGEN_TEST_PART_6
00277 #define CALL_SUBTEST_6(FUNC) CALL_SUBTEST(FUNC)
00278 #else
00279 #define CALL_SUBTEST_6(FUNC)
00280 #endif
00281
00282 #ifdef EIGEN_TEST_PART_7
00283 #define CALL_SUBTEST_7(FUNC) CALL_SUBTEST(FUNC)
00284 #else
00285 #define CALL_SUBTEST_7(FUNC)
00286 #endif
00287
00288 #ifdef EIGEN_TEST_PART_8
00289 #define CALL_SUBTEST_8(FUNC) CALL_SUBTEST(FUNC)
00290 #else
00291 #define CALL_SUBTEST_8(FUNC)
00292 #endif
00293
00294 #ifdef EIGEN_TEST_PART_9
00295 #define CALL_SUBTEST_9(FUNC) CALL_SUBTEST(FUNC)
00296 #else
00297 #define CALL_SUBTEST_9(FUNC)
00298 #endif
00299
00300 #ifdef EIGEN_TEST_PART_10
00301 #define CALL_SUBTEST_10(FUNC) CALL_SUBTEST(FUNC)
00302 #else
00303 #define CALL_SUBTEST_10(FUNC)
00304 #endif
00305
00306 #ifdef EIGEN_TEST_PART_11
00307 #define CALL_SUBTEST_11(FUNC) CALL_SUBTEST(FUNC)
00308 #else
00309 #define CALL_SUBTEST_11(FUNC)
00310 #endif
00311
00312 #ifdef EIGEN_TEST_PART_12
00313 #define CALL_SUBTEST_12(FUNC) CALL_SUBTEST(FUNC)
00314 #else
00315 #define CALL_SUBTEST_12(FUNC)
00316 #endif
00317
00318 #ifdef EIGEN_TEST_PART_13
00319 #define CALL_SUBTEST_13(FUNC) CALL_SUBTEST(FUNC)
00320 #else
00321 #define CALL_SUBTEST_13(FUNC)
00322 #endif
00323
00324 #ifdef EIGEN_TEST_PART_14
00325 #define CALL_SUBTEST_14(FUNC) CALL_SUBTEST(FUNC)
00326 #else
00327 #define CALL_SUBTEST_14(FUNC)
00328 #endif
00329
00330 #ifdef EIGEN_TEST_PART_15
00331 #define CALL_SUBTEST_15(FUNC) CALL_SUBTEST(FUNC)
00332 #else
00333 #define CALL_SUBTEST_15(FUNC)
00334 #endif
00335
00336 #ifdef EIGEN_TEST_PART_16
00337 #define CALL_SUBTEST_16(FUNC) CALL_SUBTEST(FUNC)
00338 #else
00339 #define CALL_SUBTEST_16(FUNC)
00340 #endif
00341
00342
00343
00344 int main(int argc, char *argv[])
00345 {
00346 bool has_set_repeat = false;
00347 bool has_set_seed = false;
00348 bool need_help = false;
00349 unsigned int seed = 0;
00350 int repeat = DEFAULT_REPEAT;
00351
00352 for(int i = 1; i < argc; i++)
00353 {
00354 if(argv[i][0] == 'r')
00355 {
00356 if(has_set_repeat)
00357 {
00358 std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
00359 return 1;
00360 }
00361 repeat = std::atoi(argv[i]+1);
00362 has_set_repeat = true;
00363 if(repeat <= 0)
00364 {
00365 std::cout << "Invalid \'repeat\' value " << argv[i]+1 << std::endl;
00366 return 1;
00367 }
00368 }
00369 else if(argv[i][0] == 's')
00370 {
00371 if(has_set_seed)
00372 {
00373 std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
00374 return 1;
00375 }
00376 seed = int(std::strtoul(argv[i]+1, 0, 10));
00377 has_set_seed = true;
00378 bool ok = seed!=0;
00379 if(!ok)
00380 {
00381 std::cout << "Invalid \'seed\' value " << argv[i]+1 << std::endl;
00382 return 1;
00383 }
00384 }
00385 else
00386 {
00387 need_help = true;
00388 }
00389 }
00390
00391 if(need_help)
00392 {
00393 std::cout << "This test application takes the following optional arguments:" << std::endl;
00394 std::cout << " rN Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;
00395 std::cout << " sN Use N as seed for random numbers (default: based on current time)" << std::endl;
00396 return 1;
00397 }
00398
00399 if(!has_set_seed) seed = (unsigned int) std::time(NULL);
00400 if(!has_set_repeat) repeat = DEFAULT_REPEAT;
00401
00402 std::cout << "Initializing random number generator with seed " << seed << std::endl;
00403 std::srand(seed);
00404 std::cout << "Repeating each test " << repeat << " times" << std::endl;
00405
00406 Eigen::g_repeat = repeat;
00407 Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC));
00408
00409 EI_PP_CAT(test_,EIGEN_TEST_FUNC)();
00410 return 0;
00411 }
00412
00413
00414