diff options
Diffstat (limited to 'eigen/test/eigen2/main.h')
-rw-r--r-- | eigen/test/eigen2/main.h | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/eigen/test/eigen2/main.h b/eigen/test/eigen2/main.h new file mode 100644 index 0000000..ad2ba19 --- /dev/null +++ b/eigen/test/eigen2/main.h @@ -0,0 +1,399 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <cstdlib> +#include <ctime> +#include <iostream> +#include <string> +#include <vector> + +#ifndef EIGEN_TEST_FUNC +#error EIGEN_TEST_FUNC must be defined +#endif + +#define DEFAULT_REPEAT 10 + +namespace Eigen +{ + static std::vector<std::string> g_test_stack; + static int g_repeat; +} + +#define EI_PP_MAKE_STRING2(S) #S +#define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S) + +#define EI_PP_CAT2(a,b) a ## b +#define EI_PP_CAT(a,b) EI_PP_CAT2(a,b) + +#ifndef EIGEN_NO_ASSERTION_CHECKING + + namespace Eigen + { + static const bool should_raise_an_assert = false; + + // Used to avoid to raise two exceptions at a time in which + // case the exception is not properly caught. + // This may happen when a second exceptions is raise in a destructor. + static bool no_more_assert = false; + + struct eigen_assert_exception + { + eigen_assert_exception(void) {} + ~eigen_assert_exception() { Eigen::no_more_assert = false; } + }; + } + + // If EIGEN_DEBUG_ASSERTS is defined and if no assertion is raised while + // one should have been, then the list of excecuted assertions is printed out. + // + // EIGEN_DEBUG_ASSERTS is not enabled by default as it + // significantly increases the compilation time + // and might even introduce side effects that would hide + // some memory errors. + #ifdef EIGEN_DEBUG_ASSERTS + + namespace Eigen + { + static bool ei_push_assert = false; + static std::vector<std::string> eigen_assert_list; + } + + #define eigen_assert(a) \ + if( (!(a)) && (!no_more_assert) ) \ + { \ + Eigen::no_more_assert = true; \ + throw Eigen::eigen_assert_exception(); \ + } \ + else if (Eigen::ei_push_assert) \ + { \ + eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__)" ("EI_PP_MAKE_STRING(__LINE__)") : "#a) ); \ + } + + #define VERIFY_RAISES_ASSERT(a) \ + { \ + Eigen::no_more_assert = false; \ + try { \ + Eigen::eigen_assert_list.clear(); \ + Eigen::ei_push_assert = true; \ + a; \ + Eigen::ei_push_assert = false; \ + std::cerr << "One of the following asserts should have been raised:\n"; \ + for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai) \ + std::cerr << " " << eigen_assert_list[ai] << "\n"; \ + VERIFY(Eigen::should_raise_an_assert && # a); \ + } catch (Eigen::eigen_assert_exception e) { \ + Eigen::ei_push_assert = false; VERIFY(true); \ + } \ + } + + #else // EIGEN_DEBUG_ASSERTS + + #undef eigen_assert + + // see bug 89. The copy_bool here is working around a bug in gcc <= 4.3 + #define eigen_assert(a) \ + if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) ) \ + { \ + Eigen::no_more_assert = true; \ + throw Eigen::eigen_assert_exception(); \ + } + + #define VERIFY_RAISES_ASSERT(a) { \ + Eigen::no_more_assert = false; \ + try { a; VERIFY(Eigen::should_raise_an_assert && # a); } \ + catch (Eigen::eigen_assert_exception e) { VERIFY(true); } \ + } + + #endif // EIGEN_DEBUG_ASSERTS + + #define EIGEN_USE_CUSTOM_ASSERT + +#else // EIGEN_NO_ASSERTION_CHECKING + + #define VERIFY_RAISES_ASSERT(a) {} + +#endif // EIGEN_NO_ASSERTION_CHECKING + + +#define EIGEN_INTERNAL_DEBUGGING +#define EIGEN_NICE_RANDOM +#include <Eigen/Array> + + +#define VERIFY(a) do { if (!(a)) { \ + std::cerr << "Test " << g_test_stack.back() << " failed in "EI_PP_MAKE_STRING(__FILE__) << " (" << EI_PP_MAKE_STRING(__LINE__) << ")" \ + << std::endl << " " << EI_PP_MAKE_STRING(a) << std::endl << std::endl; \ + abort(); \ + } } while (0) + +#define VERIFY_IS_APPROX(a, b) VERIFY(test_ei_isApprox(a, b)) +#define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_ei_isApprox(a, b)) +#define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_ei_isMuchSmallerThan(a, b)) +#define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_ei_isMuchSmallerThan(a, b)) +#define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_ei_isApproxOrLessThan(a, b)) +#define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_ei_isApproxOrLessThan(a, b)) + +#define CALL_SUBTEST(FUNC) do { \ + g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \ + FUNC; \ + g_test_stack.pop_back(); \ + } while (0) + +namespace Eigen { + +template<typename T> inline typename NumTraits<T>::Real test_precision(); +template<> inline int test_precision<int>() { return 0; } +template<> inline float test_precision<float>() { return 1e-3f; } +template<> inline double test_precision<double>() { return 1e-6; } +template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); } +template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); } +template<> inline long double test_precision<long double>() { return 1e-6; } + +inline bool test_ei_isApprox(const int& a, const int& b) +{ return ei_isApprox(a, b, test_precision<int>()); } +inline bool test_ei_isMuchSmallerThan(const int& a, const int& b) +{ return ei_isMuchSmallerThan(a, b, test_precision<int>()); } +inline bool test_ei_isApproxOrLessThan(const int& a, const int& b) +{ return ei_isApproxOrLessThan(a, b, test_precision<int>()); } + +inline bool test_ei_isApprox(const float& a, const float& b) +{ return ei_isApprox(a, b, test_precision<float>()); } +inline bool test_ei_isMuchSmallerThan(const float& a, const float& b) +{ return ei_isMuchSmallerThan(a, b, test_precision<float>()); } +inline bool test_ei_isApproxOrLessThan(const float& a, const float& b) +{ return ei_isApproxOrLessThan(a, b, test_precision<float>()); } + +inline bool test_ei_isApprox(const double& a, const double& b) +{ return ei_isApprox(a, b, test_precision<double>()); } +inline bool test_ei_isMuchSmallerThan(const double& a, const double& b) +{ return ei_isMuchSmallerThan(a, b, test_precision<double>()); } +inline bool test_ei_isApproxOrLessThan(const double& a, const double& b) +{ return ei_isApproxOrLessThan(a, b, test_precision<double>()); } + +inline bool test_ei_isApprox(const std::complex<float>& a, const std::complex<float>& b) +{ return ei_isApprox(a, b, test_precision<std::complex<float> >()); } +inline bool test_ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b) +{ return ei_isMuchSmallerThan(a, b, test_precision<std::complex<float> >()); } + +inline bool test_ei_isApprox(const std::complex<double>& a, const std::complex<double>& b) +{ return ei_isApprox(a, b, test_precision<std::complex<double> >()); } +inline bool test_ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b) +{ return ei_isMuchSmallerThan(a, b, test_precision<std::complex<double> >()); } + +inline bool test_ei_isApprox(const long double& a, const long double& b) +{ return ei_isApprox(a, b, test_precision<long double>()); } +inline bool test_ei_isMuchSmallerThan(const long double& a, const long double& b) +{ return ei_isMuchSmallerThan(a, b, test_precision<long double>()); } +inline bool test_ei_isApproxOrLessThan(const long double& a, const long double& b) +{ return ei_isApproxOrLessThan(a, b, test_precision<long double>()); } + +template<typename Type1, typename Type2> +inline bool test_ei_isApprox(const Type1& a, const Type2& b) +{ + return a.isApprox(b, test_precision<typename Type1::Scalar>()); +} + +template<typename Derived1, typename Derived2> +inline bool test_ei_isMuchSmallerThan(const MatrixBase<Derived1>& m1, + const MatrixBase<Derived2>& m2) +{ + return m1.isMuchSmallerThan(m2, test_precision<typename ei_traits<Derived1>::Scalar>()); +} + +template<typename Derived> +inline bool test_ei_isMuchSmallerThan(const MatrixBase<Derived>& m, + const typename NumTraits<typename ei_traits<Derived>::Scalar>::Real& s) +{ + return m.isMuchSmallerThan(s, test_precision<typename ei_traits<Derived>::Scalar>()); +} + +} // end namespace Eigen + +template<typename T> struct GetDifferentType; + +template<> struct GetDifferentType<float> { typedef double type; }; +template<> struct GetDifferentType<double> { typedef float type; }; +template<typename T> struct GetDifferentType<std::complex<T> > +{ typedef std::complex<typename GetDifferentType<T>::type> type; }; + +// forward declaration of the main test function +void EI_PP_CAT(test_,EIGEN_TEST_FUNC)(); + +using namespace Eigen; + +#ifdef EIGEN_TEST_PART_1 +#define CALL_SUBTEST_1(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_1(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_2 +#define CALL_SUBTEST_2(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_2(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_3 +#define CALL_SUBTEST_3(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_3(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_4 +#define CALL_SUBTEST_4(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_4(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_5 +#define CALL_SUBTEST_5(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_5(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_6 +#define CALL_SUBTEST_6(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_6(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_7 +#define CALL_SUBTEST_7(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_7(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_8 +#define CALL_SUBTEST_8(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_8(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_9 +#define CALL_SUBTEST_9(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_9(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_10 +#define CALL_SUBTEST_10(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_10(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_11 +#define CALL_SUBTEST_11(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_11(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_12 +#define CALL_SUBTEST_12(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_12(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_13 +#define CALL_SUBTEST_13(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_13(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_14 +#define CALL_SUBTEST_14(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_14(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_15 +#define CALL_SUBTEST_15(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_15(FUNC) +#endif + +#ifdef EIGEN_TEST_PART_16 +#define CALL_SUBTEST_16(FUNC) CALL_SUBTEST(FUNC) +#else +#define CALL_SUBTEST_16(FUNC) +#endif + + + +int main(int argc, char *argv[]) +{ + bool has_set_repeat = false; + bool has_set_seed = false; + bool need_help = false; + unsigned int seed = 0; + int repeat = DEFAULT_REPEAT; + + for(int i = 1; i < argc; i++) + { + if(argv[i][0] == 'r') + { + if(has_set_repeat) + { + std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl; + return 1; + } + repeat = std::atoi(argv[i]+1); + has_set_repeat = true; + if(repeat <= 0) + { + std::cout << "Invalid \'repeat\' value " << argv[i]+1 << std::endl; + return 1; + } + } + else if(argv[i][0] == 's') + { + if(has_set_seed) + { + std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl; + return 1; + } + seed = int(std::strtoul(argv[i]+1, 0, 10)); + has_set_seed = true; + bool ok = seed!=0; + if(!ok) + { + std::cout << "Invalid \'seed\' value " << argv[i]+1 << std::endl; + return 1; + } + } + else + { + need_help = true; + } + } + + if(need_help) + { + std::cout << "This test application takes the following optional arguments:" << std::endl; + std::cout << " rN Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl; + std::cout << " sN Use N as seed for random numbers (default: based on current time)" << std::endl; + return 1; + } + + if(!has_set_seed) seed = (unsigned int) std::time(NULL); + if(!has_set_repeat) repeat = DEFAULT_REPEAT; + + std::cout << "Initializing random number generator with seed " << seed << std::endl; + std::srand(seed); + std::cout << "Repeating each test " << repeat << " times" << std::endl; + + Eigen::g_repeat = repeat; + Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC)); + + EI_PP_CAT(test_,EIGEN_TEST_FUNC)(); + return 0; +} + + + |