// 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 // Copyright (C) 2008 Gael Guennebaud // // 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 . #ifndef EIGEN_TEST_MAIN_H #define EIGEN_TEST_MAIN_H #include #include #include #include #define DEFAULT_REPEAT 10 #ifndef EIGEN_NO_ASSERTION_CHECKING namespace Eigen { static const bool should_raise_an_assert = false; // Used to avoid to raise two exceptions at the time in which // case the exception is not properly catched. // This may happen when a second exceptions is raise in a destructor. static bool no_more_assert = false; struct ei_assert_exception { ei_assert_exception(void) {} ~ei_assert_exception() { Eigen::no_more_assert = false; } }; } #define EI_PP_MAKE_STRING2(S) #S #define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S) // 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 ei_assert_list; } #define ei_assert(a) \ if( (!(a)) && (!no_more_assert) ) \ { \ 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) \ { \ try { \ Eigen::ei_assert_list.clear(); \ Eigen::ei_push_assert = true; \ a; \ Eigen::ei_push_assert = false; \ std::cout << "One of the following asserts should have been raised:\n"; \ for (uint ai=0 ; ai #define VERIFY(a) QVERIFY(a) #define VERIFY_IS_APPROX(a, b) QVERIFY(test_ei_isApprox(a, b)) #define VERIFY_IS_NOT_APPROX(a, b) QVERIFY(!test_ei_isApprox(a, b)) #define VERIFY_IS_MUCH_SMALLER_THAN(a, b) QVERIFY(test_ei_isMuchSmallerThan(a, b)) #define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) QVERIFY(!test_ei_isMuchSmallerThan(a, b)) #define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) QVERIFY(test_ei_isApproxOrLessThan(a, b)) #define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) QVERIFY(!test_ei_isApproxOrLessThan(a, b)) namespace Eigen { template inline typename NumTraits::Real test_precision(); template<> inline int test_precision() { return 0; } template<> inline float test_precision() { return 1e-2f; } template<> inline double test_precision() { return 1e-5; } template<> inline float test_precision >() { return test_precision(); } template<> inline double test_precision >() { return test_precision(); } inline bool test_ei_isApprox(const int& a, const int& b) { return ei_isApprox(a, b, test_precision()); } inline bool test_ei_isMuchSmallerThan(const int& a, const int& b) { return ei_isMuchSmallerThan(a, b, test_precision()); } inline bool test_ei_isApproxOrLessThan(const int& a, const int& b) { return ei_isApproxOrLessThan(a, b, test_precision()); } inline bool test_ei_isApprox(const float& a, const float& b) { return ei_isApprox(a, b, test_precision()); } inline bool test_ei_isMuchSmallerThan(const float& a, const float& b) { return ei_isMuchSmallerThan(a, b, test_precision()); } inline bool test_ei_isApproxOrLessThan(const float& a, const float& b) { return ei_isApproxOrLessThan(a, b, test_precision()); } inline bool test_ei_isApprox(const double& a, const double& b) { return ei_isApprox(a, b, test_precision()); } inline bool test_ei_isMuchSmallerThan(const double& a, const double& b) { return ei_isMuchSmallerThan(a, b, test_precision()); } inline bool test_ei_isApproxOrLessThan(const double& a, const double& b) { return ei_isApproxOrLessThan(a, b, test_precision()); } inline bool test_ei_isApprox(const std::complex& a, const std::complex& b) { return ei_isApprox(a, b, test_precision >()); } inline bool test_ei_isMuchSmallerThan(const std::complex& a, const std::complex& b) { return ei_isMuchSmallerThan(a, b, test_precision >()); } inline bool test_ei_isApprox(const std::complex& a, const std::complex& b) { return ei_isApprox(a, b, test_precision >()); } inline bool test_ei_isMuchSmallerThan(const std::complex& a, const std::complex& b) { return ei_isMuchSmallerThan(a, b, test_precision >()); } template inline bool test_ei_isApprox(const MatrixBase& m1, const MatrixBase& m2) { return m1.isApprox(m2, test_precision::Scalar>()); } template inline bool test_ei_isMuchSmallerThan(const MatrixBase& m1, const MatrixBase& m2) { return m1.isMuchSmallerThan(m2, test_precision::Scalar>()); } template inline bool test_ei_isMuchSmallerThan(const MatrixBase& m, const typename NumTraits::Scalar>::Real& s) { return m.isMuchSmallerThan(s, test_precision::Scalar>()); } class EigenTest : public QObject { Q_OBJECT public: EigenTest(int repeat) : m_repeat(repeat) {} private slots: // void testBasicStuff(); // void testLinearStructure(); // void testProduct(); // void testAdjoint(); // void testSubmatrices(); // void testMiscMatrices(); // void testSmallVectors(); // void testMap(); // void testCwiseops(); // void testDeterminant(); // void testTriangular(); void testCholesky(); protected: int m_repeat; }; } // end namespace Eigen #endif // EIGEN_TEST_MAIN_H