diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2978a1fd8..c96578331 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,43 +2,78 @@ IF(BUILD_TESTS) OPTION(EIGEN_NO_ASSERTION_CHECKING "Disable checking of assertions" OFF) +# similar to SET_TARGET_PROPERTIES but append the property instead of overwritting it +MACRO(EI_ADD_TARGET_PROPERTY target prop value) + + GET_TARGET_PROPERTY(previous ${target} ${prop}) + SET_TARGET_PROPERTIES(${target} PROPERTIES ${prop} "${previous} ${value}") + +ENDMACRO(EI_ADD_TARGET_PROPERTY) + +# Macro to add a test +# +# the unique parameter testname must correspond to a file +# .cpp which follows this pattern: +# +# #include "main.h" +# void test_() { ... } +# +# this macro add an executable test_ as well as a ctest test +# named +# +# On platforms with bash simply run: +# "ctest -V" or "ctest -V -R " +# On other platform use ctest as usual +# +MACRO(EI_ADD_TEST testname) + + SET(targetname test_${testname}) + + ADD_EXECUTABLE(${targetname} ${testname}.cpp) + + IF(NOT EIGEN_NO_ASSERTION_CHECKING) + + SET_TARGET_PROPERTIES(${targetname} PROPERTIES COMPILE_FLAGS "-fexceptions") + OPTION(EIGEN_DEBUG_ASSERTS "Enable debuging of assertions" OFF) + IF(EIGEN_DEBUG_ASSERTS) + SET_TARGET_PROPERTIES(${targetname} PROPERTIES COMPILE_DEFINITIONS "-DEIGEN_DEBUG_ASSERTS=1") + ENDIF(EIGEN_DEBUG_ASSERTS) + + ELSE(NOT EIGEN_NO_ASSERTION_CHECKING) + + SET_TARGET_PROPERTIES(${targetname} PROPERTIES COMPILE_DEFINITIONS "-DEIGEN_NO_ASSERTION_CHECKING=1") + + ENDIF(NOT EIGEN_NO_ASSERTION_CHECKING) + + EI_ADD_TARGET_PROPERTY(${targetname} COMPILE_FLAGS "-DEIGEN_TEST_FUNC=${testname}") + + IF(WIN32) + ADD_TEST(${testname} "${targetname}") + ELSE(WIN32) + ADD_TEST(${testname} "${CMAKE_CURRENT_SOURCE_DIR}/runtest.sh" "${testname}") + ENDIF(WIN32) + + TARGET_LINK_LIBRARIES(${targetname} ${QT_QTCORE_LIBRARY} ${QT_QTTEST_LIBRARY} ) + +ENDMACRO(EI_ADD_TEST) + + ENABLE_TESTING() + FIND_PACKAGE(Qt4 REQUIRED) INCLUDE_DIRECTORIES( ${QT_INCLUDE_DIR} ) -SET(test_SRCS - cholesky.cpp - main.cpp - basicstuff.cpp - linearstructure.cpp - product.cpp - adjoint.cpp - submatrices.cpp - miscmatrices.cpp - smallvectors.cpp - map.cpp - cwiseop.cpp -# determinant.cpp - triangular.cpp -) -QT4_AUTOMOC(${test_SRCS}) - -ADD_EXECUTABLE(test ${test_SRCS}) -TARGET_LINK_LIBRARIES(test ${QT_QTCORE_LIBRARY} ${QT_QTTEST_LIBRARY}) -IF(NOT EIGEN_NO_ASSERTION_CHECKING) - - SET_TARGET_PROPERTIES(test PROPERTIES COMPILE_FLAGS "-fexceptions") - OPTION(EIGEN_DEBUG_ASSERTS "Enable debuging of assertions" OFF) - IF(EIGEN_DEBUG_ASSERTS) - ADD_DEFINITIONS(-DEIGEN_DEBUG_ASSERTS=1) - ENDIF(EIGEN_DEBUG_ASSERTS) - -ELSE(NOT EIGEN_NO_ASSERTION_CHECKING) - - ADD_DEFINITIONS(-DEIGEN_NO_ASSERTION_CHECKING=1) - -ENDIF(NOT EIGEN_NO_ASSERTION_CHECKING) - -ADD_TEST(Eigen test) +EI_ADD_TEST(basicstuff) +EI_ADD_TEST(miscmatrices) +EI_ADD_TEST(adjoint) +EI_ADD_TEST(submatrices) +EI_ADD_TEST(smallvectors) +EI_ADD_TEST(cwiseop) +EI_ADD_TEST(map) +EI_ADD_TEST(linearstructure) +EI_ADD_TEST(product) +EI_ADD_TEST(triangular) +EI_ADD_TEST(cholesky) +# EI_ADD_TEST(determinant) ENDIF(BUILD_TESTS) diff --git a/test/adjoint.cpp b/test/adjoint.cpp index a400e948e..ae1b002e5 100644 --- a/test/adjoint.cpp +++ b/test/adjoint.cpp @@ -24,8 +24,6 @@ #include "main.h" -namespace Eigen { - template void adjoint(const MatrixType& m) { /* this test covers the following files: @@ -95,17 +93,16 @@ template void adjoint(const MatrixType& m) } -void EigenTest::testAdjoint() +void test_adjoint() { - for(int i = 0; i < m_repeat; i++) { - adjoint(Matrix()); - adjoint(Matrix4d()); - adjoint(MatrixXcf(3, 3)); - adjoint(MatrixXi(8, 12)); - adjoint(MatrixXcd(20, 20)); + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( adjoint(Matrix()) ); + CALL_SUBTEST( adjoint(Matrix4d()) ); + CALL_SUBTEST( adjoint(MatrixXcf(3, 3)) ); + CALL_SUBTEST( adjoint(MatrixXi(8, 12)) ); + CALL_SUBTEST( adjoint(MatrixXcd(20, 20)) ); } // test a large matrix only once - adjoint(Matrix()); + CALL_SUBTEST( adjoint(Matrix()) ); } -} // namespace Eigen diff --git a/test/basicstuff.cpp b/test/basicstuff.cpp index 052880321..a2ad3dedf 100644 --- a/test/basicstuff.cpp +++ b/test/basicstuff.cpp @@ -24,8 +24,6 @@ #include "main.h" -namespace Eigen { - template void basicStuff(const MatrixType& m) { typedef typename MatrixType::Scalar Scalar; @@ -86,49 +84,14 @@ template void basicStuff(const MatrixType& m) } } -void EigenTest::testBasicStuff() +void test_basicstuff() { - for(int i = 0; i < m_repeat; i++) { - basicStuff(Matrix()); - basicStuff(Matrix4d()); - basicStuff(MatrixXcf(3, 3)); - basicStuff(MatrixXi(8, 12)); - basicStuff(MatrixXcd(20, 20)); - basicStuff(Matrix()); - } - - // some additional basic tests - { - Matrix3d m3; - Matrix4d m4; - VERIFY_RAISES_ASSERT(m4 = m3); - - VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8) ); - VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) ); - - double data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - - m3 = Matrix3d::random(); - m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9; - VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); - - Vector3d vec[3]; - vec[0] << 1, 4, 7; - vec[1] << 2, 5, 8; - vec[2] << 3, 6, 9; - m3 = Matrix3d::random(); - m3 << vec[0], vec[1], vec[2]; - VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); - - vec[0] << 1, 2, 3; - vec[1] << 4, 5, 6; - vec[2] << 7, 8, 9; - m3 = Matrix3d::random(); - m3 << vec[0].transpose(), - 4, 5, 6, - vec[2].transpose(); - VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( basicStuff(Matrix()) ); + CALL_SUBTEST( basicStuff(Matrix4d()) ); + CALL_SUBTEST( basicStuff(MatrixXcf(3, 3)) ); + CALL_SUBTEST( basicStuff(MatrixXi(8, 12)) ); + CALL_SUBTEST( basicStuff(MatrixXcd(20, 20)) ); + CALL_SUBTEST( basicStuff(Matrix()) ); } } - -} // namespace Eigen diff --git a/test/cholesky.cpp b/test/cholesky.cpp index 21e632b29..2f18771c2 100644 --- a/test/cholesky.cpp +++ b/test/cholesky.cpp @@ -23,11 +23,8 @@ // Eigen. If not, see . #include "main.h" - #include -namespace Eigen { - template void cholesky(const MatrixType& m) { /* this test covers the following files: @@ -53,13 +50,11 @@ template void cholesky(const MatrixType& m) VERIFY_IS_APPROX(covMat * chol.solve(b), b); } -void EigenTest::testCholesky() +void test_cholesky() { for(int i = 0; i < 1; i++) { - cholesky(Matrix3f()); - cholesky(Matrix4d()); - cholesky(MatrixXcd(7,7)); + CALL_SUBTEST( cholesky(Matrix3f()) ); + CALL_SUBTEST( cholesky(Matrix4d()) ); + CALL_SUBTEST( cholesky(MatrixXcd(7,7)) ); } } - -} // namespace Eigen diff --git a/test/commainitializer.cpp b/test/commainitializer.cpp new file mode 100644 index 000000000..acd1fb630 --- /dev/null +++ b/test/commainitializer.cpp @@ -0,0 +1,58 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// 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 . + +#include "main.h" + +void test_commainitializer() +{ + Matrix3d m3; + Matrix4d m4; + VERIFY_RAISES_ASSERT(m4 = m3); + + VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8) ); + VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) ); + + double data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + + m3 = Matrix3d::random(); + m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9; + VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); + + Vector3d vec[3]; + vec[0] << 1, 4, 7; + vec[1] << 2, 5, 8; + vec[2] << 3, 6, 9; + m3 = Matrix3d::random(); + m3 << vec[0], vec[1], vec[2]; + VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); + + vec[0] << 1, 2, 3; + vec[1] << 4, 5, 6; + vec[2] << 7, 8, 9; + m3 = Matrix3d::random(); + m3 << vec[0].transpose(), + 4, 5, 6, + vec[2].transpose(); + VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); +} diff --git a/test/cwiseop.cpp b/test/cwiseop.cpp index 156ddb38c..b8b7c44eb 100644 --- a/test/cwiseop.cpp +++ b/test/cwiseop.cpp @@ -24,15 +24,10 @@ // Eigen. If not, see . #include "main.h" -#include -#include -#include #include using namespace std; -namespace Eigen { - template struct AddIfNull { const Scalar operator() (const Scalar a, const Scalar b) const {return a<=1e-3 ? b : a;} enum { Cost = NumTraits::AddCost }; @@ -76,15 +71,13 @@ template void cwiseops(const MatrixType& m) // VERIFY_IS_APPROX( cwiseMin(m1,m1-mones), m1-mones ); } -void EigenTest::testCwiseops() +void test_cwiseop() { - for(int i = 0; i < m_repeat ; i++) { - cwiseops(Matrix()); - cwiseops(Matrix4d()); - cwiseops(MatrixXf(3, 3)); - cwiseops(MatrixXi(8, 12)); - cwiseops(MatrixXd(20, 20)); + for(int i = 0; i < g_repeat ; i++) { + CALL_SUBTEST( cwiseops(Matrix()) ); + CALL_SUBTEST( cwiseops(Matrix4d()) ); + CALL_SUBTEST( cwiseops(MatrixXf(3, 3)) ); + CALL_SUBTEST( cwiseops(MatrixXi(8, 12)) ); + CALL_SUBTEST( cwiseops(MatrixXd(20, 20)) ); } } - -} // namespace Eigen diff --git a/test/determinant.cpp b/test/determinant.cpp index ecb058a80..af0a0cc3f 100644 --- a/test/determinant.cpp +++ b/test/determinant.cpp @@ -23,11 +23,8 @@ // Eigen. If not, see . #include "main.h" - #include -namespace Eigen { - template void nullDeterminant(const MatrixType& m) { /* this test covers the following files: @@ -69,15 +66,13 @@ template void nullDeterminant(const MatrixType& m) VERIFY(!notInvertibleCovarianceMatrix.inverse().exists()); } -void EigenTest::testDeterminant() +void test_determinant() { - for(int i = 0; i < m_repeat; i++) { - nullDeterminant(Matrix()); - nullDeterminant(Matrix()); - nullDeterminant(Matrix()); - nullDeterminant(Matrix()); -// nullDeterminant(MatrixXd(20,4)); + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( nullDeterminant(Matrix()) ); + CALL_SUBTEST( nullDeterminant(Matrix()) ); + CALL_SUBTEST( nullDeterminant(Matrix()) ); + CALL_SUBTEST( nullDeterminant(Matrix()) ); +// CALL_SUBTEST( nullDeterminant(MatrixXd(20,4)); } } - -} // namespace Eigen diff --git a/test/linearstructure.cpp b/test/linearstructure.cpp index 25d0bdc2c..a7b058d69 100644 --- a/test/linearstructure.cpp +++ b/test/linearstructure.cpp @@ -24,8 +24,6 @@ #include "main.h" -namespace Eigen { - template void linearStructure(const MatrixType& m) { /* this test covers the following files: @@ -97,16 +95,14 @@ template void linearStructure(const MatrixType& m) VERIFY_IS_APPROX(m1.block(0,0,rows,cols) * s1, m1 * s1); } -void EigenTest::testLinearStructure() +void test_linearstructure() { - for(int i = 0; i < m_repeat; i++) { - linearStructure(Matrix()); - linearStructure(Matrix4d()); - linearStructure(MatrixXcf(3, 3)); - linearStructure(MatrixXf(8, 12)); - linearStructure(MatrixXi(8, 12)); - linearStructure(MatrixXcd(20, 20)); + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( linearStructure(Matrix()) ); + CALL_SUBTEST( linearStructure(Matrix4d()) ); + CALL_SUBTEST( linearStructure(MatrixXcf(3, 3)) ); + CALL_SUBTEST( linearStructure(MatrixXf(8, 12)) ); + CALL_SUBTEST( linearStructure(MatrixXi(8, 12)) ); + CALL_SUBTEST( linearStructure(MatrixXcd(20, 20)) ); } } - -} // namespace Eigen diff --git a/test/main.cpp b/test/main.cpp deleted file mode 100644 index f4361f3a5..000000000 --- a/test/main.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// 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 -// -// 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 . - -#include "main.h" - -int main(int argc, char *argv[]) -{ - QCoreApplication app(argc, argv); - - bool has_set_repeat = false; - bool has_set_seed = false; - bool need_help = false; - unsigned int seed; - int repeat; - - QStringList args = QCoreApplication::instance()->arguments(); - args.takeFirst(); // throw away the first argument (path to executable) - foreach(QString arg, args) - { - if(arg.startsWith("r")) - { - if(has_set_repeat) - { - qDebug() << "Argument" << arg << "conflicting with a former argument"; - return 1; - } - repeat = arg.remove(0, 1).toInt(); - has_set_repeat = true; - if(repeat <= 0) - { - qDebug() << "Invalid \'repeat\' value" << arg; - return 1; - } - } - else if(arg.startsWith("s")) - { - if(has_set_seed) - { - qDebug() << "Argument" << arg << "conflicting with a former argument"; - return 1; - } - bool ok; - seed = arg.remove(0, 1).toUInt(&ok); - has_set_seed = true; - if(!ok) - { - qDebug() << "Invalid \'seed\' value" << arg; - return 1; - } - } - else - { - need_help = true; - } - } - - if(need_help) - { - qDebug() << "This test application takes the following optional arguments:"; - qDebug() << " rN Repeat each test N times (default:" << DEFAULT_REPEAT << ")"; - qDebug() << " sN Use N as seed for random numbers (default: based on current time)"; - return 1; - } - - if(!has_set_seed) seed = (unsigned int) time(NULL); - if(!has_set_repeat) repeat = DEFAULT_REPEAT; - - qDebug() << "Initializing random number generator with seed" << seed; - srand(seed); - qDebug() << "Repeating each test" << repeat << "times"; - - Eigen::EigenTest test(repeat); - return QTest::qExec(&test, 1, argv); -} - -#include "main.moc" diff --git a/test/main.h b/test/main.h index b2cde4b1d..afce02b45 100644 --- a/test/main.h +++ b/test/main.h @@ -23,17 +23,31 @@ // 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 +#include +#include +#include + +#ifndef EIGEN_TEST_FUNC +#error EIGEN_TEST_FUNC must be defined +#endif #define DEFAULT_REPEAT 10 +namespace Eigen +{ + static std::vector 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 @@ -52,9 +66,6 @@ }; } - #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. // @@ -88,12 +99,12 @@ Eigen::ei_push_assert = true; \ a; \ Eigen::ei_push_assert = false; \ - std::cout << "One of the following asserts should have been raised:\n"; \ + std::cerr << "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)) +#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_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 { @@ -196,30 +218,86 @@ inline bool test_ei_isMuchSmallerThan(const MatrixBase& m, 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(); //determinant for size > 4x4 unimplemented for now - void testTriangular(); - void testCholesky(); - protected: - int m_repeat; -}; - } // end namespace Eigen -#endif // EIGEN_TEST_MAIN_H + +// forward declaration of the main test function +void EI_PP_CAT(test_,EIGEN_TEST_FUNC)(); + +using namespace Eigen; + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + bool has_set_repeat = false; + bool has_set_seed = false; + bool need_help = false; + unsigned int seed = 0; + int repeat = DEFAULT_REPEAT; + + QStringList args = QCoreApplication::instance()->arguments(); + args.takeFirst(); // throw away the first argument (path to executable) + foreach(QString arg, args) + { + if(arg.startsWith("r")) + { + if(has_set_repeat) + { + qDebug() << "Argument" << arg << "conflicting with a former argument"; + return 1; + } + repeat = arg.remove(0, 1).toInt(); + has_set_repeat = true; + if(repeat <= 0) + { + qDebug() << "Invalid \'repeat\' value" << arg; + return 1; + } + } + else if(arg.startsWith("s")) + { + if(has_set_seed) + { + qDebug() << "Argument" << arg << "conflicting with a former argument"; + return 1; + } + bool ok; + seed = arg.remove(0, 1).toUInt(&ok); + has_set_seed = true; + if(!ok) + { + qDebug() << "Invalid \'seed\' value" << arg; + return 1; + } + } + else + { + need_help = true; + } + } + + if(need_help) + { + qDebug() << "This test application takes the following optional arguments:"; + qDebug() << " rN Repeat each test N times (default:" << DEFAULT_REPEAT << ")"; + qDebug() << " sN Use N as seed for random numbers (default: based on current time)"; + return 1; + } + + if(!has_set_seed) seed = (unsigned int) time(NULL); + if(!has_set_repeat) repeat = DEFAULT_REPEAT; + + qDebug() << "Initializing random number generator with seed" << seed; + srand(seed); + qDebug() << "Repeating each test" << repeat << "times"; + + 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; +} + + + diff --git a/test/map.cpp b/test/map.cpp index a057d5973..2ae78a4c7 100644 --- a/test/map.cpp +++ b/test/map.cpp @@ -5,12 +5,12 @@ // // 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 +// 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 +// 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 @@ -18,20 +18,18 @@ // 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 +// 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 . #include "main.h" -namespace Eigen { - template void tmap(const VectorType& m) { typedef typename VectorType::Scalar Scalar; - + int size = m.size(); - + // test Map.h Scalar* array1 = new Scalar[size]; Scalar* array2 = new Scalar[size]; @@ -45,15 +43,13 @@ template void tmap(const VectorType& m) delete[] array2; } -void EigenTest::testMap() +void test_map() { - for(int i = 0; i < m_repeat; i++) { - tmap(Matrix()); - tmap(Vector4d()); - tmap(RowVector4f()); - tmap(VectorXcf(8)); - tmap(VectorXi(12)); + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( tmap(Matrix()) ); + CALL_SUBTEST( tmap(Vector4d()) ); + CALL_SUBTEST( tmap(RowVector4f()) ); + CALL_SUBTEST( tmap(VectorXcf(8)) ); + CALL_SUBTEST( tmap(VectorXi(12)) ); } } - -} // namespace Eigen diff --git a/test/miscmatrices.cpp b/test/miscmatrices.cpp index 54a5934c1..aed7f36f1 100644 --- a/test/miscmatrices.cpp +++ b/test/miscmatrices.cpp @@ -5,12 +5,12 @@ // // 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 +// 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 +// 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 @@ -18,14 +18,12 @@ // 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 +// 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 . #include "main.h" -namespace Eigen { - template void miscMatrices(const MatrixType& m) { /* this test covers the following files: @@ -37,7 +35,7 @@ template void miscMatrices(const MatrixType& m) typedef Matrix RowVectorType; int rows = m.rows(); int cols = m.cols(); - + int r = ei_random(0, rows-1), r2 = ei_random(0, rows-1), c = ei_random(0, cols-1); VERIFY_IS_APPROX(MatrixType::ones(rows,cols)(r,c), static_cast(1)); MatrixType m1 = MatrixType::ones(rows,cols); @@ -53,15 +51,13 @@ template void miscMatrices(const MatrixType& m) VERIFY_IS_APPROX(square, MatrixType::identity(rows, rows)); } -void EigenTest::testMiscMatrices() +void test_miscmatrices() { - for(int i = 0; i < m_repeat; i++) { - miscMatrices(Matrix()); - miscMatrices(Matrix4d()); - miscMatrices(MatrixXcf(3, 3)); - miscMatrices(MatrixXi(8, 12)); - miscMatrices(MatrixXcd(20, 20)); + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( miscMatrices(Matrix()) ); + CALL_SUBTEST( miscMatrices(Matrix4d()) ); + CALL_SUBTEST( miscMatrices(MatrixXcf(3, 3)) ); + CALL_SUBTEST( miscMatrices(MatrixXi(8, 12)) ); + CALL_SUBTEST( miscMatrices(MatrixXcd(20, 20)) ); } } - -} // namespace Eigen diff --git a/test/product.cpp b/test/product.cpp index 6fdca2cda..bac2a897e 100644 --- a/test/product.cpp +++ b/test/product.cpp @@ -24,8 +24,6 @@ #include "main.h" -namespace Eigen { - template void product(const MatrixType& m) { /* this test covers the following files: @@ -91,23 +89,23 @@ template void product(const MatrixType& m) VERIFY_RAISES_ASSERT(m3 = m1*m1); } -void EigenTest::testProduct() +void test_product() { - for(int i = 0; i < m_repeat; i++) { - product(Matrix()); - product(Matrix()); - product(Matrix()); - product(Matrix4d()); - } - for(int i = 0; i < m_repeat; i++) { +// for(int i = 0; i < g_repeat; i++) { +// CALL_SUBTEST( product(Matrix()) ); +// CALL_SUBTEST( product(Matrix()) ); +// CALL_SUBTEST( product(Matrix()) ); +// CALL_SUBTEST( product(Matrix4d()) ); +// } + for(int i = 0; i < g_repeat; i++) { int rows = ei_random(1,320); int cols = ei_random(1,320); - product(MatrixXf(rows, cols)); - product(MatrixXd(rows, cols)); - product(MatrixXi(rows, cols)); - product(MatrixXcf(rows, cols)); - product(MatrixXcd(rows, cols)); + std::cout << "test MatrixXf " << rows << "x" << cols << "\n"; + CALL_SUBTEST( product(MatrixXf(rows, cols)) ); + std::cout << "test MatrixXd " << rows << "x" << cols << "\n"; + CALL_SUBTEST( product(MatrixXd(rows, cols)) ); +// CALL_SUBTEST( product(MatrixXi(rows, cols)) ); +// CALL_SUBTEST( product(MatrixXcf(rows, cols)) ); +// CALL_SUBTEST( product(MatrixXcd(rows, cols)) ); } } - -} // namespace Eigen diff --git a/test/runtest.sh b/test/runtest.sh new file mode 100755 index 000000000..649513b50 --- /dev/null +++ b/test/runtest.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +black='\E[30m' +red='\E[31m' +green='\E[32m' +yellow='\E[33m' +blue='\E[34m' +magenta='\E[35m' +cyan='\E[36m' +white='\E[37m' + +if make test_$1 > /dev/null 2> .runtest.log ; then + if ! ./test_$1 > /dev/null 2> .runtest.log ; then + echo -e $red Test $1 failed: $black + echo -e $blue + cat .runtest.log + echo -e $black + exit 1 + else + echo -e $green Test $1 passed$black + fi +else + echo -e $red Build of target $1 failed: $black + echo -e $blue + cat .runtest.log + echo -e $black + exit 1 +fi diff --git a/test/smallvectors.cpp b/test/smallvectors.cpp index b8c7d47f6..6a41ff447 100644 --- a/test/smallvectors.cpp +++ b/test/smallvectors.cpp @@ -5,12 +5,12 @@ // // 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 +// 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 +// 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 @@ -18,14 +18,12 @@ // 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 +// 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 . #include "main.h" -namespace Eigen { - template void smallVectors() { typedef Matrix V2; @@ -49,13 +47,11 @@ template void smallVectors() VERIFY_IS_APPROX(x4, v4.w()); } -void EigenTest::testSmallVectors() +void test_smallvectors() { - for(int i = 0; i < m_repeat; i++) { - smallVectors(); - smallVectors(); - smallVectors(); + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( smallVectors() ); + CALL_SUBTEST( smallVectors() ); + CALL_SUBTEST( smallVectors() ); } } - -} // namespace Eigen diff --git a/test/submatrices.cpp b/test/submatrices.cpp index 34e3676f2..d486943e3 100644 --- a/test/submatrices.cpp +++ b/test/submatrices.cpp @@ -24,8 +24,6 @@ #include "main.h" -namespace Eigen { - // check minor separately in order to avoid the possible creation of a zero-sized // array. Comes from a compilation error with gcc-3.4 or gcc-4 with -ansi -pedantic. // Another solution would be to declare the array like this: T m_data[Size==0?1:Size]; in ei_matrix_storage @@ -63,7 +61,7 @@ template void submatrices(const MatrixType& m) typedef Matrix RowVectorType; int rows = m.rows(); int cols = m.cols(); - + MatrixType m1 = MatrixType::random(rows, cols), m2 = MatrixType::random(rows, cols), m3(rows, cols), @@ -101,39 +99,37 @@ template void submatrices(const MatrixType& m) //check operator(), both constant and non-constant, on block() m1.block(r1,c1,r2-r1+1,c2-c1+1) = s1 * m2.block(0, 0, r2-r1+1,c2-c1+1); m1.block(r1,c1,r2-r1+1,c2-c1+1)(r2-r1,c2-c1) = m2.block(0, 0, r2-r1+1,c2-c1+1)(0,0); - + //check minor() CheckMinor checkminor(m1,r1,c1); - + //check diagonal() VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal()); m2.diagonal() = 2 * m1.diagonal(); m2.diagonal()[0] *= 3; VERIFY_IS_APPROX(m2.diagonal()[0], static_cast(6) * m1.diagonal()[0]); -} -void EigenTest::testSubmatrices() -{ - for(int i = 0; i < m_repeat; i++) { - submatrices(Matrix()); - submatrices(Matrix4d()); - submatrices(MatrixXcf(3, 3)); - submatrices(MatrixXi(8, 12)); - submatrices(MatrixXcd(20, 20)); - - // test fixed block() separately as it is a template method so doesn't support - // being called as a member of a class that is itself a template parameter - // (at least as of g++ 4.2) - Matrix m = Matrix::random(); - float s = ei_random(); + const int BlockRows = EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime,2); + const int BlockCols = EIGEN_ENUM_MIN(MatrixType::ColsAtCompileTime,5); + if (rows>=5 && cols>=8) + { // test fixed block() as lvalue - m.block<2,5>(1,1) *= s; + m1.template block(1,1) *= s1; // test operator() on fixed block() both as constant and non-constant - m.block<2,5>(1,1)(0, 3) = m.block<2,5>(1,1)(1,2); + m1.template block(1,1)(0, 3) = m1.template block<2,5>(1,1)(1,2); // check that fixed block() and block() agree - MatrixXf b = m.block<3,2>(3,3); - VERIFY_IS_APPROX(b, m.block(3,3,3,2)); + Matrix b = m1.template block(3,3); + VERIFY_IS_APPROX(b, m1.block(3,3,BlockRows,BlockCols)); } } -} // namespace Eigen +void test_submatrices() +{ + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST( submatrices(Matrix()) ); + CALL_SUBTEST( submatrices(Matrix4d()) ); + CALL_SUBTEST( submatrices(MatrixXcf(3, 3)) ); + CALL_SUBTEST( submatrices(MatrixXi(8, 12)) ); + CALL_SUBTEST( submatrices(MatrixXcd(20, 20)) ); + } +} diff --git a/test/triangular.cpp b/test/triangular.cpp index 985c6aacd..f384c4d50 100644 --- a/test/triangular.cpp +++ b/test/triangular.cpp @@ -24,8 +24,6 @@ #include "main.h" -namespace Eigen { - template void triangular(const MatrixType& m) { typedef typename MatrixType::Scalar Scalar; @@ -87,14 +85,12 @@ template void triangular(const MatrixType& m) } -void EigenTest::testTriangular() +void test_triangular() { - for(int i = 0; i < m_repeat ; i++) { + for(int i = 0; i < g_repeat ; i++) { // triangular(Matrix()); - triangular(Matrix3d()); - triangular(MatrixXcf(4, 4)); -// triangular(Matrix,8, 8>()); + CALL_SUBTEST( triangular(Matrix3d()) ); + CALL_SUBTEST( triangular(MatrixXcf(4, 4)) ); +// CALL_SUBTEST( triangular(Matrix,8, 8>()) ); } } - -} // namespace Eigen