1 // This file is part of Eigen, a lightweight C++ template library
4 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
21 // The following includes of STL headers have to be done _before_ the
22 // definition of macros min() and max(). The reason is that many STL
23 // implementations will not work properly as the min and max symbols collide
24 // with the STL functions std:min() and std::max(). The STL headers may check
25 // for the macro definition of min/max and issue a warning or undefine the
28 // Still, Windows defines min() and max() in windef.h as part of the regular
29 // Windows system interfaces and many other Windows APIs depend on these
30 // macros being available. To prevent the macro expansion of min/max and to
31 // make Eigen compatible with the Windows environment all function calls of
32 // std::min() and std::max() have to be written with parenthesis around the
35 // All STL headers used by Eigen should be included here. Because main.h is
36 // included before any Eigen header and because the STL headers are guarded
37 // against multiple inclusions, no STL header will see our own min/max macro
46 // To test that all calls from Eigen code to std::min() and std::max() are
47 // protected by parenthesis against macro expansion, the min()/max() macros
48 // are defined here and any not-parenthesized min/max call will cause a
50 #define min(A,B) please_protect_your_min_with_parentheses
51 #define max(A,B) please_protect_your_max_with_parentheses
53 #define FORBIDDEN_IDENTIFIER (this_identifier_is_forbidden_to_avoid_clashes) this_identifier_is_forbidden_to_avoid_clashes
54 // B0 is defined in POSIX header termios.h
55 #define B0 FORBIDDEN_IDENTIFIER
58 // shuts down ICC's remark #593: variable "XXX" was set but never used
59 #define TEST_SET_BUT_UNUSED_VARIABLE(X) X = X + 0;
61 // the following file is automatically generated by cmake
62 #include "split_test_helper.h"
68 // On windows CE, NDEBUG is automatically defined <assert.h> if NDEBUG is not defined.
73 // bounds integer values for AltiVec
75 #define EIGEN_MAKING_DOCS
78 #ifndef EIGEN_TEST_FUNC
79 #error EIGEN_TEST_FUNC must be defined
82 #define DEFAULT_REPEAT 10
86 static std::vector
<std::string
> g_test_stack
;
88 static unsigned int g_seed
;
89 static bool g_has_set_repeat
, g_has_set_seed
;
92 #define EI_PP_MAKE_STRING2(S) #S
93 #define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)
95 #define EIGEN_DEFAULT_IO_FORMAT IOFormat(4, 0, " ", "\n", "", "", "", "")
97 #ifndef EIGEN_NO_ASSERTION_CHECKING
101 static const bool should_raise_an_assert
= false;
103 // Used to avoid to raise two exceptions at a time in which
104 // case the exception is not properly caught.
105 // This may happen when a second exceptions is triggered in a destructor.
106 static bool no_more_assert
= false;
107 static bool report_on_cerr_on_assert_failure
= true;
109 struct eigen_assert_exception
111 eigen_assert_exception(void) {}
112 ~eigen_assert_exception() { Eigen::no_more_assert
= false; }
115 // If EIGEN_DEBUG_ASSERTS is defined and if no assertion is triggered while
116 // one should have been, then the list of excecuted assertions is printed out.
118 // EIGEN_DEBUG_ASSERTS is not enabled by default as it
119 // significantly increases the compilation time
120 // and might even introduce side effects that would hide
121 // some memory errors.
122 #ifdef EIGEN_DEBUG_ASSERTS
128 static bool push_assert
= false;
130 static std::vector
<std::string
> eigen_assert_list
;
132 #define eigen_assert(a) \
133 if( (!(a)) && (!no_more_assert) ) \
135 if(report_on_cerr_on_assert_failure) \
136 std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \
137 Eigen::no_more_assert = true; \
138 throw Eigen::eigen_assert_exception(); \
140 else if (Eigen::internal::push_assert) \
142 eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__) " (" EI_PP_MAKE_STRING(__LINE__) ") : " #a) ); \
145 #define VERIFY_RAISES_ASSERT(a) \
147 Eigen::no_more_assert = false; \
148 Eigen::eigen_assert_list.clear(); \
149 Eigen::internal::push_assert = true; \
150 Eigen::report_on_cerr_on_assert_failure = false; \
153 std::cerr << "One of the following asserts should have been triggered:\n"; \
154 for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai) \
155 std::cerr << " " << eigen_assert_list[ai] << "\n"; \
156 VERIFY(Eigen::should_raise_an_assert && # a); \
157 } catch (Eigen::eigen_assert_exception) { \
158 Eigen::internal::push_assert = false; VERIFY(true); \
160 Eigen::report_on_cerr_on_assert_failure = true; \
161 Eigen::internal::push_assert = false; \
164 #else // EIGEN_DEBUG_ASSERTS
165 // see bug 89. The copy_bool here is working around a bug in gcc <= 4.3
166 #define eigen_assert(a) \
167 if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\
169 Eigen::no_more_assert = true; \
170 if(report_on_cerr_on_assert_failure) \
171 eigen_plain_assert(a); \
173 throw Eigen::eigen_assert_exception(); \
175 #define VERIFY_RAISES_ASSERT(a) { \
176 Eigen::no_more_assert = false; \
177 Eigen::report_on_cerr_on_assert_failure = false; \
180 VERIFY(Eigen::should_raise_an_assert && # a); \
182 catch (Eigen::eigen_assert_exception&) { VERIFY(true); } \
183 Eigen::report_on_cerr_on_assert_failure = true; \
186 #endif // EIGEN_DEBUG_ASSERTS
188 #define EIGEN_USE_CUSTOM_ASSERT
190 #else // EIGEN_NO_ASSERTION_CHECKING
192 #define VERIFY_RAISES_ASSERT(a) {}
194 #endif // EIGEN_NO_ASSERTION_CHECKING
197 #define EIGEN_INTERNAL_DEBUGGING
198 #include <Eigen/QR> // required for createRandomPIMatrixOfRank
200 inline void verify_impl(bool condition
, const char *testname
, const char *file
, int line
, const char *condition_as_string
)
204 std::cerr
<< "Test " << testname
<< " failed in " << file
<< " (" << line
<< ")"
205 << std::endl
<< " " << condition_as_string
<< std::endl
;
206 std::cerr
<< "Stack:\n";
207 const int test_stack_size
= static_cast<int>(Eigen::g_test_stack
.size());
208 for(int i
=test_stack_size
-1; i
>=0; --i
)
209 std::cerr
<< " - " << Eigen::g_test_stack
[i
] << "\n";
215 #define VERIFY(a) ::verify_impl(a, g_test_stack.back().c_str(), __FILE__, __LINE__, EI_PP_MAKE_STRING(a))
217 #define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b))
218 #define VERIFY_IS_APPROX(a, b) VERIFY(test_isApprox(a, b))
219 #define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_isApprox(a, b))
220 #define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_isMuchSmallerThan(a, b))
221 #define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_isMuchSmallerThan(a, b))
222 #define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_isApproxOrLessThan(a, b))
223 #define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_isApproxOrLessThan(a, b))
225 #define VERIFY_IS_UNITARY(a) VERIFY(test_isUnitary(a))
227 #define CALL_SUBTEST(FUNC) do { \
228 g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \
230 g_test_stack.pop_back(); \
236 template<typename T
> inline typename NumTraits
<T
>::Real
test_precision() { return NumTraits
<T
>::dummy_precision(); }
237 template<> inline float test_precision
<float>() { return 1e-3f
; }
238 template<> inline double test_precision
<double>() { return 1e-6; }
239 template<> inline float test_precision
<std::complex<float> >() { return test_precision
<float>(); }
240 template<> inline double test_precision
<std::complex<double> >() { return test_precision
<double>(); }
241 template<> inline long double test_precision
<long double>() { return 1e-6; }
243 inline bool test_isApprox(const int& a
, const int& b
)
244 { return internal::isApprox(a
, b
, test_precision
<int>()); }
245 inline bool test_isMuchSmallerThan(const int& a
, const int& b
)
246 { return internal::isMuchSmallerThan(a
, b
, test_precision
<int>()); }
247 inline bool test_isApproxOrLessThan(const int& a
, const int& b
)
248 { return internal::isApproxOrLessThan(a
, b
, test_precision
<int>()); }
250 inline bool test_isApprox(const float& a
, const float& b
)
251 { return internal::isApprox(a
, b
, test_precision
<float>()); }
252 inline bool test_isMuchSmallerThan(const float& a
, const float& b
)
253 { return internal::isMuchSmallerThan(a
, b
, test_precision
<float>()); }
254 inline bool test_isApproxOrLessThan(const float& a
, const float& b
)
255 { return internal::isApproxOrLessThan(a
, b
, test_precision
<float>()); }
256 inline bool test_isApprox(const double& a
, const double& b
)
257 { return internal::isApprox(a
, b
, test_precision
<double>()); }
259 inline bool test_isMuchSmallerThan(const double& a
, const double& b
)
260 { return internal::isMuchSmallerThan(a
, b
, test_precision
<double>()); }
261 inline bool test_isApproxOrLessThan(const double& a
, const double& b
)
262 { return internal::isApproxOrLessThan(a
, b
, test_precision
<double>()); }
264 inline bool test_isApprox(const std::complex<float>& a
, const std::complex<float>& b
)
265 { return internal::isApprox(a
, b
, test_precision
<std::complex<float> >()); }
266 inline bool test_isMuchSmallerThan(const std::complex<float>& a
, const std::complex<float>& b
)
267 { return internal::isMuchSmallerThan(a
, b
, test_precision
<std::complex<float> >()); }
269 inline bool test_isApprox(const std::complex<double>& a
, const std::complex<double>& b
)
270 { return internal::isApprox(a
, b
, test_precision
<std::complex<double> >()); }
271 inline bool test_isMuchSmallerThan(const std::complex<double>& a
, const std::complex<double>& b
)
272 { return internal::isMuchSmallerThan(a
, b
, test_precision
<std::complex<double> >()); }
274 inline bool test_isApprox(const long double& a
, const long double& b
)
276 bool ret
= internal::isApprox(a
, b
, test_precision
<long double>());
278 << std::endl
<< " actual = " << a
279 << std::endl
<< " expected = " << b
<< std::endl
<< std::endl
;
283 inline bool test_isMuchSmallerThan(const long double& a
, const long double& b
)
284 { return internal::isMuchSmallerThan(a
, b
, test_precision
<long double>()); }
285 inline bool test_isApproxOrLessThan(const long double& a
, const long double& b
)
286 { return internal::isApproxOrLessThan(a
, b
, test_precision
<long double>()); }
288 template<typename Type1
, typename Type2
>
289 inline bool test_isApprox(const Type1
& a
, const Type2
& b
)
291 return a
.isApprox(b
, test_precision
<typename
Type1::Scalar
>());
294 // The idea behind this function is to compare the two scalars a and b where
295 // the scalar ref is a hint about the expected order of magnitude of a and b.
296 // WARNING: the scalar a and b must be positive
297 // Therefore, if for some reason a and b are very small compared to ref,
298 // we won't issue a false negative.
299 // This test could be: abs(a-b) <= eps * ref
300 // However, it seems that simply comparing a+ref and b+ref is more sensitive to true error.
301 template<typename Scalar
,typename ScalarRef
>
302 inline bool test_isApproxWithRef(const Scalar
& a
, const Scalar
& b
, const ScalarRef
& ref
)
304 return test_isApprox(a
+ref
, b
+ref
);
307 template<typename Derived1
, typename Derived2
>
308 inline bool test_isMuchSmallerThan(const MatrixBase
<Derived1
>& m1
,
309 const MatrixBase
<Derived2
>& m2
)
311 return m1
.isMuchSmallerThan(m2
, test_precision
<typename
internal::traits
<Derived1
>::Scalar
>());
314 template<typename Derived
>
315 inline bool test_isMuchSmallerThan(const MatrixBase
<Derived
>& m
,
316 const typename NumTraits
<typename
internal::traits
<Derived
>::Scalar
>::Real
& s
)
318 return m
.isMuchSmallerThan(s
, test_precision
<typename
internal::traits
<Derived
>::Scalar
>());
321 template<typename Derived
>
322 inline bool test_isUnitary(const MatrixBase
<Derived
>& m
)
324 return m
.isUnitary(test_precision
<typename
internal::traits
<Derived
>::Scalar
>());
327 // Forward declaration to avoid ICC warning
328 template<typename T
, typename U
>
329 bool test_is_equal(const T
& actual
, const U
& expected
);
331 template<typename T
, typename U
>
332 bool test_is_equal(const T
& actual
, const U
& expected
)
334 if (actual
==expected
)
338 << std::endl
<< " actual = " << actual
339 << std::endl
<< " expected = " << expected
<< std::endl
<< std::endl
;
343 /** Creates a random Partial Isometry matrix of given rank.
345 * A partial isometry is a matrix all of whose singular values are either 0 or 1.
346 * This is very useful to test rank-revealing algorithms.
348 // Forward declaration to avoid ICC warning
349 template<typename MatrixType
>
350 void createRandomPIMatrixOfRank(typename
MatrixType::Index desired_rank
, typename
MatrixType::Index rows
, typename
MatrixType::Index cols
, MatrixType
& m
);
351 template<typename MatrixType
>
352 void createRandomPIMatrixOfRank(typename
MatrixType::Index desired_rank
, typename
MatrixType::Index rows
, typename
MatrixType::Index cols
, MatrixType
& m
)
354 typedef typename
internal::traits
<MatrixType
>::Index Index
;
355 typedef typename
internal::traits
<MatrixType
>::Scalar Scalar
;
356 enum { Rows
= MatrixType::RowsAtCompileTime
, Cols
= MatrixType::ColsAtCompileTime
};
358 typedef Matrix
<Scalar
, Dynamic
, 1> VectorType
;
359 typedef Matrix
<Scalar
, Rows
, Rows
> MatrixAType
;
360 typedef Matrix
<Scalar
, Cols
, Cols
> MatrixBType
;
362 if(desired_rank
== 0)
364 m
.setZero(rows
,cols
);
368 if(desired_rank
== 1)
370 // here we normalize the vectors to get a partial isometry
371 m
= VectorType::Random(rows
).normalized() * VectorType::Random(cols
).normalized().transpose();
375 MatrixAType a
= MatrixAType::Random(rows
,rows
);
376 MatrixType d
= MatrixType::Identity(rows
,cols
);
377 MatrixBType b
= MatrixBType::Random(cols
,cols
);
379 // set the diagonal such that only desired_rank non-zero entries reamain
380 const Index diag_size
= (std::min
)(d
.rows(),d
.cols());
381 if(diag_size
!= desired_rank
)
382 d
.diagonal().segment(desired_rank
, diag_size
-desired_rank
) = VectorType::Zero(diag_size
-desired_rank
);
384 HouseholderQR
<MatrixAType
> qra(a
);
385 HouseholderQR
<MatrixBType
> qrb(b
);
386 m
= qra
.householderQ() * d
* qrb
.householderQ();
389 // Forward declaration to avoid ICC warning
390 template<typename PermutationVectorType
>
391 void randomPermutationVector(PermutationVectorType
& v
, typename
PermutationVectorType::Index size
);
392 template<typename PermutationVectorType
>
393 void randomPermutationVector(PermutationVectorType
& v
, typename
PermutationVectorType::Index size
)
395 typedef typename
PermutationVectorType::Index Index
;
396 typedef typename
PermutationVectorType::Scalar Scalar
;
398 for(Index i
= 0; i
< size
; ++i
) v(i
) = Scalar(i
);
399 if(size
== 1) return;
400 for(Index n
= 0; n
< 3 * size
; ++n
)
402 Index i
= internal::random
<Index
>(0, size
-1);
404 do j
= internal::random
<Index
>(0, size
-1); while(j
==i
);
405 std::swap(v(i
), v(j
));
409 template<typename T
> bool isNotNaN(const T
& x
)
414 template<typename T
> bool isNaN(const T
& x
)
419 template<typename T
> bool isInf(const T
& x
)
421 return x
> NumTraits
<T
>::highest();
424 template<typename T
> bool isMinusInf(const T
& x
)
426 return x
< NumTraits
<T
>::lowest();
429 } // end namespace Eigen
431 template<typename T
> struct GetDifferentType
;
433 template<> struct GetDifferentType
<float> { typedef double type
; };
434 template<> struct GetDifferentType
<double> { typedef float type
; };
435 template<typename T
> struct GetDifferentType
<std::complex<T
> >
436 { typedef std::complex<typename GetDifferentType
<T
>::type
> type
; };
438 // Forward declaration to avoid ICC warning
439 template<typename T
> std::string
type_name();
440 template<typename T
> std::string
type_name() { return "other"; }
441 template<> std::string type_name
<float>() { return "float"; }
442 template<> std::string type_name
<double>() { return "double"; }
443 template<> std::string type_name
<int>() { return "int"; }
444 template<> std::string type_name
<std::complex<float> >() { return "complex<float>"; }
445 template<> std::string type_name
<std::complex<double> >() { return "complex<double>"; }
446 template<> std::string type_name
<std::complex<int> >() { return "complex<int>"; }
448 // forward declaration of the main test function
449 void EIGEN_CAT(test_
,EIGEN_TEST_FUNC
)();
451 using namespace Eigen
;
453 inline void set_repeat_from_string(const char *str
)
456 g_repeat
= int(strtoul(str
, 0, 10));
457 if(errno
|| g_repeat
<= 0)
459 std::cout
<< "Invalid repeat value " << str
<< std::endl
;
462 g_has_set_repeat
= true;
465 inline void set_seed_from_string(const char *str
)
468 g_seed
= int(strtoul(str
, 0, 10));
469 if(errno
|| g_seed
== 0)
471 std::cout
<< "Invalid seed value " << str
<< std::endl
;
474 g_has_set_seed
= true;
477 int main(int argc
, char *argv
[])
479 g_has_set_repeat
= false;
480 g_has_set_seed
= false;
481 bool need_help
= false;
483 for(int i
= 1; i
< argc
; i
++)
485 if(argv
[i
][0] == 'r')
489 std::cout
<< "Argument " << argv
[i
] << " conflicting with a former argument" << std::endl
;
492 set_repeat_from_string(argv
[i
]+1);
494 else if(argv
[i
][0] == 's')
498 std::cout
<< "Argument " << argv
[i
] << " conflicting with a former argument" << std::endl
;
501 set_seed_from_string(argv
[i
]+1);
511 std::cout
<< "This test application takes the following optional arguments:" << std::endl
;
512 std::cout
<< " rN Repeat each test N times (default: " << DEFAULT_REPEAT
<< ")" << std::endl
;
513 std::cout
<< " sN Use N as seed for random numbers (default: based on current time)" << std::endl
;
514 std::cout
<< std::endl
;
515 std::cout
<< "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl
;
516 std::cout
<< "will be used as default values for these parameters." << std::endl
;
520 char *env_EIGEN_REPEAT
= getenv("EIGEN_REPEAT");
521 if(!g_has_set_repeat
&& env_EIGEN_REPEAT
)
522 set_repeat_from_string(env_EIGEN_REPEAT
);
523 char *env_EIGEN_SEED
= getenv("EIGEN_SEED");
524 if(!g_has_set_seed
&& env_EIGEN_SEED
)
525 set_seed_from_string(env_EIGEN_SEED
);
527 if(!g_has_set_seed
) g_seed
= (unsigned int) time(NULL
);
528 if(!g_has_set_repeat
) g_repeat
= DEFAULT_REPEAT
;
530 std::cout
<< "Initializing random number generator with seed " << g_seed
<< std::endl
;
531 std::stringstream ss
;
532 ss
<< "Seed: " << g_seed
;
533 g_test_stack
.push_back(ss
.str());
535 std::cout
<< "Repeating each test " << g_repeat
<< " times" << std::endl
;
537 Eigen::g_test_stack
.push_back(std::string(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC
)));
539 EIGEN_CAT(test_
,EIGEN_TEST_FUNC
)();
543 // These warning are disabled here such that they are still ON when parsing Eigen's header files.
544 #if defined __INTEL_COMPILER
545 // remark #383: value copied to temporary, reference to temporary used
546 // -> this warning is raised even for legal usage as: g_test_stack.push_back("foo"); where g_test_stack is a std::vector<std::string>
547 // remark #1418: external function definition with no prior declaration
548 // -> this warning is raised for all our test functions. Declaring them static would fix the issue.
549 // warning #279: controlling expression is constant
550 // remark #1572: floating-point equality and inequality comparisons are unreliable
551 #pragma warning disable 279 383 1418 1572