| // This file is part of Eigen, a lightweight C++ template library | 
 | // for linear algebra. | 
 | // | 
 | // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> | 
 | // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> | 
 | // | 
 | // Eigen is free software; you can redistribute it and/or | 
 | // modify it under the terms of the GNU Lesser General Public | 
 | // License as published by the Free Software Foundation; either | 
 | // version 3 of the License, or (at your option) any later version. | 
 | // | 
 | // Alternatively, you can redistribute it and/or | 
 | // modify it under the terms of the GNU General Public License as | 
 | // published by the Free Software Foundation; either version 2 of | 
 | // the License, or (at your option) any later version. | 
 | // | 
 | // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY | 
 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 
 | // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the | 
 | // GNU General Public License for more details. | 
 | // | 
 | // You should have received a copy of the GNU Lesser General Public | 
 | // License and a copy of the GNU General Public License along with | 
 | // Eigen. If not, see <http://www.gnu.org/licenses/>. | 
 |  | 
 | #include <cstdlib> | 
 | #include <cerrno> | 
 | #include <ctime> | 
 | #include <iostream> | 
 | #include <string> | 
 | #include <vector> | 
 | #include <typeinfo> | 
 |  | 
 | #ifdef NDEBUG | 
 | #undef NDEBUG | 
 | #endif | 
 |  | 
 | #ifndef EIGEN_TEST_FUNC | 
 | #error EIGEN_TEST_FUNC must be defined | 
 | #endif | 
 |  | 
 | #define DEFAULT_REPEAT 10 | 
 |  | 
 | #ifdef __ICC | 
 | // disable warning #279: controlling expression is constant | 
 | #pragma warning disable 279 | 
 | #endif | 
 |  | 
 | namespace Eigen | 
 | { | 
 |   static std::vector<std::string> g_test_stack; | 
 |   static int g_repeat; | 
 |   static unsigned int g_seed; | 
 |   static bool g_has_set_repeat, g_has_set_seed; | 
 | } | 
 |  | 
 | #define EI_PP_MAKE_STRING2(S) #S | 
 | #define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S) | 
 |  | 
 | #define EIGEN_DEFAULT_IO_FORMAT IOFormat(4, 0, "  ", "\n", "", "", "", "") | 
 |  | 
 | #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; | 
 |     static bool report_on_cerr_on_assert_failure = true; | 
 |  | 
 |     struct ei_assert_exception | 
 |     { | 
 |       ei_assert_exception(void) {} | 
 |       ~ei_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> ei_assert_list; | 
 |     } | 
 |  | 
 |     #define ei_assert(a)                       \ | 
 |       if( (!(a)) && (!no_more_assert) )     \ | 
 |       { \ | 
 |         if(report_on_cerr_on_assert_failure) \ | 
 |           std::cerr <<  #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \ | 
 |         Eigen::no_more_assert = true;       \ | 
 |         throw Eigen::ei_assert_exception(); \ | 
 |       }                                     \ | 
 |       else if (Eigen::ei_push_assert)       \ | 
 |       {                                     \ | 
 |         ei_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::ei_assert_list.clear();                                          \ | 
 |           Eigen::ei_push_assert = true;                                           \ | 
 |           Eigen::report_on_cerr_on_assert_failure = false;                        \ | 
 |           a;                                                                      \ | 
 |           Eigen::report_on_cerr_on_assert_failure = true;                         \ | 
 |           Eigen::ei_push_assert = false;                                          \ | 
 |           std::cerr << "One of the following asserts should have been raised:\n"; \ | 
 |           for (uint ai=0 ; ai<ei_assert_list.size() ; ++ai)                       \ | 
 |             std::cerr << "  " << ei_assert_list[ai] << "\n";                      \ | 
 |           VERIFY(Eigen::should_raise_an_assert && # a);                           \ | 
 |         } catch (Eigen::ei_assert_exception e) {                                  \ | 
 |           Eigen::ei_push_assert = false; VERIFY(true);                            \ | 
 |         }                                                                         \ | 
 |       } | 
 |  | 
 |   #else // EIGEN_DEBUG_ASSERTS | 
 |  | 
 |     #define ei_assert(a) \ | 
 |       if( (!(a)) && (!no_more_assert) )     \ | 
 |       {                                     \ | 
 |         Eigen::no_more_assert = true;       \ | 
 |         if(report_on_cerr_on_assert_failure) \ | 
 |           std::cerr <<  #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \ | 
 |         throw Eigen::ei_assert_exception(); \ | 
 |       } | 
 |  | 
 |     #define VERIFY_RAISES_ASSERT(a) {                             \ | 
 |         Eigen::no_more_assert = false;                            \ | 
 |         try { \ | 
 |           Eigen::report_on_cerr_on_assert_failure = false;                        \ | 
 |           a; \ | 
 |           Eigen::report_on_cerr_on_assert_failure = true;                        \ | 
 |           VERIFY(Eigen::should_raise_an_assert && # a); \ | 
 |         }  \ | 
 |         catch (Eigen::ei_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 | 
 | #include <Eigen/QR> // required for createRandomPIMatrixOfRank | 
 |  | 
 |  | 
 | #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; \ | 
 |     exit(2); \ | 
 |   } } while (0) | 
 |  | 
 | #define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b)) | 
 | #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 VERIFY_IS_UNITARY(a) VERIFY(test_isUnitary(a)) | 
 |  | 
 | #define CALL_SUBTEST(FUNC) do { \ | 
 |     g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \ | 
 |     FUNC; \ | 
 |     g_test_stack.pop_back(); \ | 
 |   } while (0) | 
 |  | 
 | #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 | 
 |  | 
 | namespace Eigen { | 
 |  | 
 | template<typename T> inline typename NumTraits<T>::Real test_precision() { return T(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) | 
 | { | 
 |     bool ret = ei_isApprox(a, b, test_precision<double>()); | 
 |     if (!ret) std::cerr | 
 |         << std::endl << "    actual   = " << a | 
 |         << std::endl << "    expected = " << b << std::endl << std::endl; | 
 |     return ret; | 
 | } | 
 |  | 
 | 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) | 
 | { | 
 |     bool ret = ei_isApprox(a, b, test_precision<long double>()); | 
 |     if (!ret) std::cerr | 
 |         << std::endl << "    actual   = " << a | 
 |         << std::endl << "    expected = " << b << std::endl << std::endl; | 
 |     return ret; | 
 | } | 
 |  | 
 | 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>()); | 
 | } | 
 |  | 
 | template<typename Derived> | 
 | inline bool test_isUnitary(const MatrixBase<Derived>& m) | 
 | { | 
 |   return m.isUnitary(test_precision<typename ei_traits<Derived>::Scalar>()); | 
 | } | 
 |  | 
 | template<typename T, typename U> | 
 | bool test_is_equal(const T& actual, const U& expected) | 
 | { | 
 |     if (actual==expected) | 
 |         return true; | 
 |     // false: | 
 |     std::cerr | 
 |         << std::endl << "    actual   = " << actual | 
 |         << std::endl << "    expected = " << expected << std::endl << std::endl; | 
 |     return false; | 
 | } | 
 |  | 
 | /** Creates a random Partial Isometry matrix of given rank. | 
 |   * | 
 |   * A partial isometry is a matrix all of whose singular values are either 0 or 1. | 
 |   * This is very useful to test rank-revealing algorithms. | 
 |   */ | 
 | template<typename MatrixType> | 
 | void createRandomPIMatrixOfRank(typename MatrixType::Index desired_rank, typename MatrixType::Index rows, typename MatrixType::Index cols, MatrixType& m) | 
 | { | 
 |   typedef typename ei_traits<MatrixType>::Index Index; | 
 |   typedef typename ei_traits<MatrixType>::Scalar Scalar; | 
 |   enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime }; | 
 |  | 
 |   typedef Matrix<Scalar, Dynamic, 1> VectorType; | 
 |   typedef Matrix<Scalar, Rows, Rows> MatrixAType; | 
 |   typedef Matrix<Scalar, Cols, Cols> MatrixBType; | 
 |  | 
 |   if(desired_rank == 0) | 
 |   { | 
 |     m.setZero(rows,cols); | 
 |     return; | 
 |   } | 
 |  | 
 |   if(desired_rank == 1) | 
 |   { | 
 |     // here we normalize the vectors to get a partial isometry | 
 |     m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose(); | 
 |     return; | 
 |   } | 
 |  | 
 |   MatrixAType a = MatrixAType::Random(rows,rows); | 
 |   MatrixType d = MatrixType::Identity(rows,cols); | 
 |   MatrixBType  b = MatrixBType::Random(cols,cols); | 
 |  | 
 |   // set the diagonal such that only desired_rank non-zero entries reamain | 
 |   const Index diag_size = std::min(d.rows(),d.cols()); | 
 |   if(diag_size != desired_rank) | 
 |     d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank); | 
 |  | 
 |   HouseholderQR<MatrixAType> qra(a); | 
 |   HouseholderQR<MatrixBType> qrb(b); | 
 |   m = qra.householderQ() * d * qrb.householderQ(); | 
 | } | 
 |  | 
 | } // 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; }; | 
 |  | 
 | template<typename T> std::string type_name() { return "other"; } | 
 | template<> std::string type_name<float>() { return "float"; } | 
 | template<> std::string type_name<double>() { return "double"; } | 
 | template<> std::string type_name<int>() { return "int"; } | 
 | template<> std::string type_name<std::complex<float> >() { return "complex<float>"; } | 
 | template<> std::string type_name<std::complex<double> >() { return "complex<double>"; } | 
 | template<> std::string type_name<std::complex<int> >() { return "complex<int>"; } | 
 |  | 
 | // forward declaration of the main test function | 
 | void EIGEN_CAT(test_,EIGEN_TEST_FUNC)(); | 
 |  | 
 | using namespace Eigen; | 
 |  | 
 | void set_repeat_from_string(const char *str) | 
 | { | 
 |   errno = 0; | 
 |   g_repeat = int(strtoul(str, 0, 10)); | 
 |   if(errno || g_repeat <= 0) | 
 |   { | 
 |     std::cout << "Invalid repeat value " << str << std::endl; | 
 |     exit(EXIT_FAILURE); | 
 |   } | 
 |   g_has_set_repeat = true; | 
 | } | 
 |  | 
 | void set_seed_from_string(const char *str) | 
 | { | 
 |   errno = 0; | 
 |   g_seed = strtoul(str, 0, 10); | 
 |   if(errno || g_seed == 0) | 
 |   { | 
 |     std::cout << "Invalid seed value " << str << std::endl; | 
 |     exit(EXIT_FAILURE); | 
 |   } | 
 |   g_has_set_seed = true; | 
 | } | 
 |  | 
 | int main(int argc, char *argv[]) | 
 | { | 
 |     g_has_set_repeat = false; | 
 |     g_has_set_seed = false; | 
 |     bool need_help = false; | 
 |  | 
 |     for(int i = 1; i < argc; i++) | 
 |     { | 
 |       if(argv[i][0] == 'r') | 
 |       { | 
 |         if(g_has_set_repeat) | 
 |         { | 
 |           std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl; | 
 |           return 1; | 
 |         } | 
 |         set_repeat_from_string(argv[i]+1); | 
 |       } | 
 |       else if(argv[i][0] == 's') | 
 |       { | 
 |         if(g_has_set_seed) | 
 |         { | 
 |           std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl; | 
 |           return 1; | 
 |         } | 
 |          set_seed_from_string(argv[i]+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; | 
 |       std::cout << std::endl; | 
 |       std::cout << "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl; | 
 |       std::cout << "will be used as default values for these parameters." << std::endl; | 
 |       return 1; | 
 |     } | 
 |  | 
 |     char *env_EIGEN_REPEAT = getenv("EIGEN_REPEAT"); | 
 |     if(!g_has_set_repeat && env_EIGEN_REPEAT) | 
 |       set_repeat_from_string(env_EIGEN_REPEAT); | 
 |     char *env_EIGEN_SEED = getenv("EIGEN_SEED"); | 
 |     if(!g_has_set_seed && env_EIGEN_SEED) | 
 |       set_seed_from_string(env_EIGEN_SEED); | 
 |  | 
 |     if(!g_has_set_seed) g_seed = (unsigned int) time(NULL); | 
 |     if(!g_has_set_repeat) g_repeat = DEFAULT_REPEAT; | 
 |  | 
 |     std::cout << "Initializing random number generator with seed " << g_seed << std::endl; | 
 |     srand(g_seed); | 
 |     std::cout << "Repeating each test " << g_repeat << " times" << std::endl; | 
 |  | 
 |     Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC)); | 
 |  | 
 |     EIGEN_CAT(test_,EIGEN_TEST_FUNC)(); | 
 |     return 0; | 
 | } | 
 |  |