You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							399 lines
						
					
					
						
							13 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							399 lines
						
					
					
						
							13 KiB
						
					
					
				
								// 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;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								
							 |