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.

509 lines
20 KiB

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
  5. // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
  6. //
  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/.
  10. #include <cstdlib>
  11. #include <cerrno>
  12. #include <ctime>
  13. #include <iostream>
  14. #include <fstream>
  15. #include <string>
  16. #include <sstream>
  17. #include <vector>
  18. #include <typeinfo>
  19. #include <limits>
  20. #include <algorithm>
  21. #include <sstream>
  22. #include <complex>
  23. #include <deque>
  24. #include <queue>
  25. #define min(A,B) please_protect_your_min_with_parentheses
  26. #define max(A,B) please_protect_your_max_with_parentheses
  27. #define FORBIDDEN_IDENTIFIER (this_identifier_is_forbidden_to_avoid_clashes) this_identifier_is_forbidden_to_avoid_clashes
  28. // B0 is defined in POSIX header termios.h
  29. #define B0 FORBIDDEN_IDENTIFIER
  30. // shuts down ICC's remark #593: variable "XXX" was set but never used
  31. #define TEST_SET_BUT_UNUSED_VARIABLE(X) X = X + 0;
  32. // the following file is automatically generated by cmake
  33. #include "split_test_helper.h"
  34. #ifdef NDEBUG
  35. #undef NDEBUG
  36. #endif
  37. // On windows CE, NDEBUG is automatically defined <assert.h> if NDEBUG is not defined.
  38. #ifndef DEBUG
  39. #define DEBUG
  40. #endif
  41. // bounds integer values for AltiVec
  42. #ifdef __ALTIVEC__
  43. #define EIGEN_MAKING_DOCS
  44. #endif
  45. #ifndef EIGEN_TEST_FUNC
  46. #error EIGEN_TEST_FUNC must be defined
  47. #endif
  48. #define DEFAULT_REPEAT 10
  49. namespace Eigen
  50. {
  51. static std::vector<std::string> g_test_stack;
  52. static int g_repeat;
  53. static unsigned int g_seed;
  54. static bool g_has_set_repeat, g_has_set_seed;
  55. }
  56. #define EI_PP_MAKE_STRING2(S) #S
  57. #define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)
  58. #define EIGEN_DEFAULT_IO_FORMAT IOFormat(4, 0, " ", "\n", "", "", "", "")
  59. #ifndef EIGEN_NO_ASSERTION_CHECKING
  60. namespace Eigen
  61. {
  62. static const bool should_raise_an_assert = false;
  63. // Used to avoid to raise two exceptions at a time in which
  64. // case the exception is not properly caught.
  65. // This may happen when a second exceptions is triggered in a destructor.
  66. static bool no_more_assert = false;
  67. static bool report_on_cerr_on_assert_failure = true;
  68. struct eigen_assert_exception
  69. {
  70. eigen_assert_exception(void) {}
  71. ~eigen_assert_exception() { Eigen::no_more_assert = false; }
  72. };
  73. }
  74. // If EIGEN_DEBUG_ASSERTS is defined and if no assertion is triggered while
  75. // one should have been, then the list of excecuted assertions is printed out.
  76. //
  77. // EIGEN_DEBUG_ASSERTS is not enabled by default as it
  78. // significantly increases the compilation time
  79. // and might even introduce side effects that would hide
  80. // some memory errors.
  81. #ifdef EIGEN_DEBUG_ASSERTS
  82. namespace Eigen
  83. {
  84. namespace internal
  85. {
  86. static bool push_assert = false;
  87. }
  88. static std::vector<std::string> eigen_assert_list;
  89. }
  90. #define eigen_assert(a) \
  91. if( (!(a)) && (!no_more_assert) ) \
  92. { \
  93. if(report_on_cerr_on_assert_failure) \
  94. std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \
  95. Eigen::no_more_assert = true; \
  96. throw Eigen::eigen_assert_exception(); \
  97. } \
  98. else if (Eigen::internal::push_assert) \
  99. { \
  100. eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__) " (" EI_PP_MAKE_STRING(__LINE__) ") : " #a) ); \
  101. }
  102. #define VERIFY_RAISES_ASSERT(a) \
  103. { \
  104. Eigen::no_more_assert = false; \
  105. Eigen::eigen_assert_list.clear(); \
  106. Eigen::internal::push_assert = true; \
  107. Eigen::report_on_cerr_on_assert_failure = false; \
  108. try { \
  109. a; \
  110. std::cerr << "One of the following asserts should have been triggered:\n"; \
  111. for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai) \
  112. std::cerr << " " << eigen_assert_list[ai] << "\n"; \
  113. VERIFY(Eigen::should_raise_an_assert && # a); \
  114. } catch (Eigen::eigen_assert_exception) { \
  115. Eigen::internal::push_assert = false; VERIFY(true); \
  116. } \
  117. Eigen::report_on_cerr_on_assert_failure = true; \
  118. Eigen::internal::push_assert = false; \
  119. }
  120. #else // EIGEN_DEBUG_ASSERTS
  121. // see bug 89. The copy_bool here is working around a bug in gcc <= 4.3
  122. #define eigen_assert(a) \
  123. if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\
  124. { \
  125. Eigen::no_more_assert = true; \
  126. if(report_on_cerr_on_assert_failure) \
  127. eigen_plain_assert(a); \
  128. else \
  129. throw Eigen::eigen_assert_exception(); \
  130. }
  131. #define VERIFY_RAISES_ASSERT(a) { \
  132. Eigen::no_more_assert = false; \
  133. Eigen::report_on_cerr_on_assert_failure = false; \
  134. try { \
  135. a; \
  136. VERIFY(Eigen::should_raise_an_assert && # a); \
  137. } \
  138. catch (Eigen::eigen_assert_exception&) { VERIFY(true); } \
  139. Eigen::report_on_cerr_on_assert_failure = true; \
  140. }
  141. #endif // EIGEN_DEBUG_ASSERTS
  142. #define EIGEN_USE_CUSTOM_ASSERT
  143. #else // EIGEN_NO_ASSERTION_CHECKING
  144. #define VERIFY_RAISES_ASSERT(a) {}
  145. #endif // EIGEN_NO_ASSERTION_CHECKING
  146. #define EIGEN_INTERNAL_DEBUGGING
  147. #include <Eigen/QR> // required for createRandomPIMatrixOfRank
  148. inline void verify_impl(bool condition, const char *testname, const char *file, int line, const char *condition_as_string)
  149. {
  150. if (!condition)
  151. {
  152. std::cerr << "Test " << testname << " failed in " << file << " (" << line << ")"
  153. << std::endl << " " << condition_as_string << std::endl;
  154. std::cerr << "Stack:\n";
  155. const int test_stack_size = static_cast<int>(Eigen::g_test_stack.size());
  156. for(int i=test_stack_size-1; i>=0; --i)
  157. std::cerr << " - " << Eigen::g_test_stack[i] << "\n";
  158. std::cerr << "\n";
  159. abort();
  160. }
  161. }
  162. #define VERIFY(a) ::verify_impl(a, g_test_stack.back().c_str(), __FILE__, __LINE__, EI_PP_MAKE_STRING(a))
  163. #define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b))
  164. #define VERIFY_IS_APPROX(a, b) VERIFY(test_isApprox(a, b))
  165. #define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_isApprox(a, b))
  166. #define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_isMuchSmallerThan(a, b))
  167. #define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_isMuchSmallerThan(a, b))
  168. #define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_isApproxOrLessThan(a, b))
  169. #define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_isApproxOrLessThan(a, b))
  170. #define VERIFY_IS_UNITARY(a) VERIFY(test_isUnitary(a))
  171. #define CALL_SUBTEST(FUNC) do { \
  172. g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \
  173. FUNC; \
  174. g_test_stack.pop_back(); \
  175. } while (0)
  176. namespace Eigen {
  177. template<typename T> inline typename NumTraits<T>::Real test_precision() { return NumTraits<T>::dummy_precision(); }
  178. template<> inline float test_precision<float>() { return 1e-3f; }
  179. template<> inline double test_precision<double>() { return 1e-6; }
  180. template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }
  181. template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }
  182. template<> inline long double test_precision<long double>() { return 1e-6; }
  183. inline bool test_isApprox(const int& a, const int& b)
  184. { return internal::isApprox(a, b, test_precision<int>()); }
  185. inline bool test_isMuchSmallerThan(const int& a, const int& b)
  186. { return internal::isMuchSmallerThan(a, b, test_precision<int>()); }
  187. inline bool test_isApproxOrLessThan(const int& a, const int& b)
  188. { return internal::isApproxOrLessThan(a, b, test_precision<int>()); }
  189. inline bool test_isApprox(const float& a, const float& b)
  190. { return internal::isApprox(a, b, test_precision<float>()); }
  191. inline bool test_isMuchSmallerThan(const float& a, const float& b)
  192. { return internal::isMuchSmallerThan(a, b, test_precision<float>()); }
  193. inline bool test_isApproxOrLessThan(const float& a, const float& b)
  194. { return internal::isApproxOrLessThan(a, b, test_precision<float>()); }
  195. inline bool test_isApprox(const double& a, const double& b)
  196. { return internal::isApprox(a, b, test_precision<double>()); }
  197. inline bool test_isMuchSmallerThan(const double& a, const double& b)
  198. { return internal::isMuchSmallerThan(a, b, test_precision<double>()); }
  199. inline bool test_isApproxOrLessThan(const double& a, const double& b)
  200. { return internal::isApproxOrLessThan(a, b, test_precision<double>()); }
  201. inline bool test_isApprox(const std::complex<float>& a, const std::complex<float>& b)
  202. { return internal::isApprox(a, b, test_precision<std::complex<float> >()); }
  203. inline bool test_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b)
  204. { return internal::isMuchSmallerThan(a, b, test_precision<std::complex<float> >()); }
  205. inline bool test_isApprox(const std::complex<double>& a, const std::complex<double>& b)
  206. { return internal::isApprox(a, b, test_precision<std::complex<double> >()); }
  207. inline bool test_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b)
  208. { return internal::isMuchSmallerThan(a, b, test_precision<std::complex<double> >()); }
  209. inline bool test_isApprox(const long double& a, const long double& b)
  210. {
  211. bool ret = internal::isApprox(a, b, test_precision<long double>());
  212. if (!ret) std::cerr
  213. << std::endl << " actual = " << a
  214. << std::endl << " expected = " << b << std::endl << std::endl;
  215. return ret;
  216. }
  217. inline bool test_isMuchSmallerThan(const long double& a, const long double& b)
  218. { return internal::isMuchSmallerThan(a, b, test_precision<long double>()); }
  219. inline bool test_isApproxOrLessThan(const long double& a, const long double& b)
  220. { return internal::isApproxOrLessThan(a, b, test_precision<long double>()); }
  221. template<typename Type1, typename Type2>
  222. inline bool test_isApprox(const Type1& a, const Type2& b)
  223. {
  224. return a.isApprox(b, test_precision<typename Type1::Scalar>());
  225. }
  226. // The idea behind this function is to compare the two scalars a and b where
  227. // the scalar ref is a hint about the expected order of magnitude of a and b.
  228. // WARNING: the scalar a and b must be positive
  229. // Therefore, if for some reason a and b are very small compared to ref,
  230. // we won't issue a false negative.
  231. // This test could be: abs(a-b) <= eps * ref
  232. // However, it seems that simply comparing a+ref and b+ref is more sensitive to true error.
  233. template<typename Scalar,typename ScalarRef>
  234. inline bool test_isApproxWithRef(const Scalar& a, const Scalar& b, const ScalarRef& ref)
  235. {
  236. return test_isApprox(a+ref, b+ref);
  237. }
  238. template<typename Derived1, typename Derived2>
  239. inline bool test_isMuchSmallerThan(const MatrixBase<Derived1>& m1,
  240. const MatrixBase<Derived2>& m2)
  241. {
  242. return m1.isMuchSmallerThan(m2, test_precision<typename internal::traits<Derived1>::Scalar>());
  243. }
  244. template<typename Derived>
  245. inline bool test_isMuchSmallerThan(const MatrixBase<Derived>& m,
  246. const typename NumTraits<typename internal::traits<Derived>::Scalar>::Real& s)
  247. {
  248. return m.isMuchSmallerThan(s, test_precision<typename internal::traits<Derived>::Scalar>());
  249. }
  250. template<typename Derived>
  251. inline bool test_isUnitary(const MatrixBase<Derived>& m)
  252. {
  253. return m.isUnitary(test_precision<typename internal::traits<Derived>::Scalar>());
  254. }
  255. // Forward declaration to avoid ICC warning
  256. template<typename T, typename U>
  257. bool test_is_equal(const T& actual, const U& expected);
  258. template<typename T, typename U>
  259. bool test_is_equal(const T& actual, const U& expected)
  260. {
  261. if (actual==expected)
  262. return true;
  263. // false:
  264. std::cerr
  265. << std::endl << " actual = " << actual
  266. << std::endl << " expected = " << expected << std::endl << std::endl;
  267. return false;
  268. }
  269. /** Creates a random Partial Isometry matrix of given rank.
  270. *
  271. * A partial isometry is a matrix all of whose singular values are either 0 or 1.
  272. * This is very useful to test rank-revealing algorithms.
  273. */
  274. // Forward declaration to avoid ICC warning
  275. template<typename MatrixType>
  276. void createRandomPIMatrixOfRank(typename MatrixType::Index desired_rank, typename MatrixType::Index rows, typename MatrixType::Index cols, MatrixType& m);
  277. template<typename MatrixType>
  278. void createRandomPIMatrixOfRank(typename MatrixType::Index desired_rank, typename MatrixType::Index rows, typename MatrixType::Index cols, MatrixType& m)
  279. {
  280. typedef typename internal::traits<MatrixType>::Index Index;
  281. typedef typename internal::traits<MatrixType>::Scalar Scalar;
  282. enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
  283. typedef Matrix<Scalar, Dynamic, 1> VectorType;
  284. typedef Matrix<Scalar, Rows, Rows> MatrixAType;
  285. typedef Matrix<Scalar, Cols, Cols> MatrixBType;
  286. if(desired_rank == 0)
  287. {
  288. m.setZero(rows,cols);
  289. return;
  290. }
  291. if(desired_rank == 1)
  292. {
  293. // here we normalize the vectors to get a partial isometry
  294. m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
  295. return;
  296. }
  297. MatrixAType a = MatrixAType::Random(rows,rows);
  298. MatrixType d = MatrixType::Identity(rows,cols);
  299. MatrixBType b = MatrixBType::Random(cols,cols);
  300. // set the diagonal such that only desired_rank non-zero entries reamain
  301. const Index diag_size = (std::min)(d.rows(),d.cols());
  302. if(diag_size != desired_rank)
  303. d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);
  304. HouseholderQR<MatrixAType> qra(a);
  305. HouseholderQR<MatrixBType> qrb(b);
  306. m = qra.householderQ() * d * qrb.householderQ();
  307. }
  308. // Forward declaration to avoid ICC warning
  309. template<typename PermutationVectorType>
  310. void randomPermutationVector(PermutationVectorType& v, typename PermutationVectorType::Index size);
  311. template<typename PermutationVectorType>
  312. void randomPermutationVector(PermutationVectorType& v, typename PermutationVectorType::Index size)
  313. {
  314. typedef typename PermutationVectorType::Index Index;
  315. typedef typename PermutationVectorType::Scalar Scalar;
  316. v.resize(size);
  317. for(Index i = 0; i < size; ++i) v(i) = Scalar(i);
  318. if(size == 1) return;
  319. for(Index n = 0; n < 3 * size; ++n)
  320. {
  321. Index i = internal::random<Index>(0, size-1);
  322. Index j;
  323. do j = internal::random<Index>(0, size-1); while(j==i);
  324. std::swap(v(i), v(j));
  325. }
  326. }
  327. } // end namespace Eigen
  328. template<typename T> struct GetDifferentType;
  329. template<> struct GetDifferentType<float> { typedef double type; };
  330. template<> struct GetDifferentType<double> { typedef float type; };
  331. template<typename T> struct GetDifferentType<std::complex<T> >
  332. { typedef std::complex<typename GetDifferentType<T>::type> type; };
  333. // Forward declaration to avoid ICC warning
  334. template<typename T> std::string type_name();
  335. template<typename T> std::string type_name() { return "other"; }
  336. template<> std::string type_name<float>() { return "float"; }
  337. template<> std::string type_name<double>() { return "double"; }
  338. template<> std::string type_name<int>() { return "int"; }
  339. template<> std::string type_name<std::complex<float> >() { return "complex<float>"; }
  340. template<> std::string type_name<std::complex<double> >() { return "complex<double>"; }
  341. template<> std::string type_name<std::complex<int> >() { return "complex<int>"; }
  342. // forward declaration of the main test function
  343. void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
  344. using namespace Eigen;
  345. inline void set_repeat_from_string(const char *str)
  346. {
  347. errno = 0;
  348. g_repeat = int(strtoul(str, 0, 10));
  349. if(errno || g_repeat <= 0)
  350. {
  351. std::cout << "Invalid repeat value " << str << std::endl;
  352. exit(EXIT_FAILURE);
  353. }
  354. g_has_set_repeat = true;
  355. }
  356. inline void set_seed_from_string(const char *str)
  357. {
  358. errno = 0;
  359. g_seed = int(strtoul(str, 0, 10));
  360. if(errno || g_seed == 0)
  361. {
  362. std::cout << "Invalid seed value " << str << std::endl;
  363. exit(EXIT_FAILURE);
  364. }
  365. g_has_set_seed = true;
  366. }
  367. int main(int argc, char *argv[])
  368. {
  369. g_has_set_repeat = false;
  370. g_has_set_seed = false;
  371. bool need_help = false;
  372. for(int i = 1; i < argc; i++)
  373. {
  374. if(argv[i][0] == 'r')
  375. {
  376. if(g_has_set_repeat)
  377. {
  378. std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
  379. return 1;
  380. }
  381. set_repeat_from_string(argv[i]+1);
  382. }
  383. else if(argv[i][0] == 's')
  384. {
  385. if(g_has_set_seed)
  386. {
  387. std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
  388. return 1;
  389. }
  390. set_seed_from_string(argv[i]+1);
  391. }
  392. else
  393. {
  394. need_help = true;
  395. }
  396. }
  397. if(need_help)
  398. {
  399. std::cout << "This test application takes the following optional arguments:" << std::endl;
  400. std::cout << " rN Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;
  401. std::cout << " sN Use N as seed for random numbers (default: based on current time)" << std::endl;
  402. std::cout << std::endl;
  403. std::cout << "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl;
  404. std::cout << "will be used as default values for these parameters." << std::endl;
  405. return 1;
  406. }
  407. char *env_EIGEN_REPEAT = getenv("EIGEN_REPEAT");
  408. if(!g_has_set_repeat && env_EIGEN_REPEAT)
  409. set_repeat_from_string(env_EIGEN_REPEAT);
  410. char *env_EIGEN_SEED = getenv("EIGEN_SEED");
  411. if(!g_has_set_seed && env_EIGEN_SEED)
  412. set_seed_from_string(env_EIGEN_SEED);
  413. if(!g_has_set_seed) g_seed = (unsigned int) time(NULL);
  414. if(!g_has_set_repeat) g_repeat = DEFAULT_REPEAT;
  415. std::cout << "Initializing random number generator with seed " << g_seed << std::endl;
  416. std::stringstream ss;
  417. ss << "Seed: " << g_seed;
  418. g_test_stack.push_back(ss.str());
  419. srand(g_seed);
  420. std::cout << "Repeating each test " << g_repeat << " times" << std::endl;
  421. Eigen::g_test_stack.push_back(std::string(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC)));
  422. EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
  423. return 0;
  424. }
  425. // These warning are disabled here such that they are still ON when parsing Eigen's header files.
  426. #if defined __INTEL_COMPILER
  427. // remark #383: value copied to temporary, reference to temporary used
  428. // -> 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>
  429. // remark #1418: external function definition with no prior declaration
  430. // -> this warning is raised for all our test functions. Declaring them static would fix the issue.
  431. // warning #279: controlling expression is constant
  432. // remark #1572: floating-point equality and inequality comparisons are unreliable
  433. #pragma warning disable 279 383 1418 1572
  434. #endif