main.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra. Eigen itself is part of the KDE project.
00003 //
00004 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
00006 //
00007 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00025 
00026 #include <cstdlib>
00027 #include <ctime>
00028 #include <iostream>
00029 #include <string>
00030 #include <vector>
00031 
00032 #ifndef EIGEN_TEST_FUNC
00033 #error EIGEN_TEST_FUNC must be defined
00034 #endif
00035 
00036 #define DEFAULT_REPEAT 10
00037 
00038 namespace Eigen
00039 {
00040   static std::vector<std::string> g_test_stack;
00041   static int g_repeat;
00042 }
00043 
00044 #define EI_PP_MAKE_STRING2(S) #S
00045 #define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)
00046 
00047 #define EI_PP_CAT2(a,b) a ## b
00048 #define EI_PP_CAT(a,b) EI_PP_CAT2(a,b)
00049 
00050 #ifndef EIGEN_NO_ASSERTION_CHECKING
00051 
00052   namespace Eigen
00053   {
00054     static const bool should_raise_an_assert = false;
00055 
00056     // Used to avoid to raise two exceptions at a time in which
00057     // case the exception is not properly caught.
00058     // This may happen when a second exceptions is raise in a destructor.
00059     static bool no_more_assert = false;
00060 
00061     struct eigen_assert_exception
00062     {
00063       eigen_assert_exception(void) {}
00064       ~eigen_assert_exception() { Eigen::no_more_assert = false; }
00065     };
00066   }
00067 
00068   // If EIGEN_DEBUG_ASSERTS is defined and if no assertion is raised while
00069   // one should have been, then the list of excecuted assertions is printed out.
00070   //
00071   // EIGEN_DEBUG_ASSERTS is not enabled by default as it
00072   // significantly increases the compilation time
00073   // and might even introduce side effects that would hide
00074   // some memory errors.
00075   #ifdef EIGEN_DEBUG_ASSERTS
00076 
00077     namespace Eigen
00078     {
00079       static bool ei_push_assert = false;
00080       static std::vector<std::string> eigen_assert_list;
00081     }
00082 
00083     #define eigen_assert(a)                       \
00084       if( (!(a)) && (!no_more_assert) )     \
00085       {                                     \
00086         Eigen::no_more_assert = true;       \
00087         throw Eigen::eigen_assert_exception(); \
00088       }                                     \
00089       else if (Eigen::ei_push_assert)       \
00090       {                                     \
00091         eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__)" ("EI_PP_MAKE_STRING(__LINE__)") : "#a) ); \
00092       }
00093 
00094     #define VERIFY_RAISES_ASSERT(a)                                               \
00095       {                                                                           \
00096         Eigen::no_more_assert = false;                                            \
00097         try {                                                                     \
00098           Eigen::eigen_assert_list.clear();                                          \
00099           Eigen::ei_push_assert = true;                                           \
00100           a;                                                                      \
00101           Eigen::ei_push_assert = false;                                          \
00102           std::cerr << "One of the following asserts should have been raised:\n"; \
00103           for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai)                       \
00104             std::cerr << "  " << eigen_assert_list[ai] << "\n";                      \
00105           VERIFY(Eigen::should_raise_an_assert && # a);                           \
00106         } catch (Eigen::eigen_assert_exception e) {                                  \
00107           Eigen::ei_push_assert = false; VERIFY(true);                            \
00108         }                                                                         \
00109       }
00110 
00111   #else // EIGEN_DEBUG_ASSERTS
00112 
00113     #undef eigen_assert
00114 
00115     // see bug 89. The copy_bool here is working around a bug in gcc <= 4.3
00116     #define eigen_assert(a) \
00117       if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )       \
00118       {                                     \
00119         Eigen::no_more_assert = true;       \
00120         throw Eigen::eigen_assert_exception(); \
00121       }
00122 
00123     #define VERIFY_RAISES_ASSERT(a) {                             \
00124         Eigen::no_more_assert = false;                            \
00125         try { a; VERIFY(Eigen::should_raise_an_assert && # a); }  \
00126         catch (Eigen::eigen_assert_exception e) { VERIFY(true); }    \
00127       }
00128 
00129   #endif // EIGEN_DEBUG_ASSERTS
00130 
00131   #define EIGEN_USE_CUSTOM_ASSERT
00132 
00133 #else // EIGEN_NO_ASSERTION_CHECKING
00134 
00135   #define VERIFY_RAISES_ASSERT(a) {}
00136 
00137 #endif // EIGEN_NO_ASSERTION_CHECKING
00138 
00139 
00140 #define EIGEN_INTERNAL_DEBUGGING
00141 #define EIGEN_NICE_RANDOM
00142 #include <Eigen/Array>
00143 
00144 
00145 #define VERIFY(a) do { if (!(a)) { \
00146     std::cerr << "Test " << g_test_stack.back() << " failed in "EI_PP_MAKE_STRING(__FILE__) << " (" << EI_PP_MAKE_STRING(__LINE__) << ")" \
00147       << std::endl << "    " << EI_PP_MAKE_STRING(a) << std::endl << std::endl; \
00148     abort(); \
00149   } } while (0)
00150 
00151 #define VERIFY_IS_APPROX(a, b) VERIFY(test_ei_isApprox(a, b))
00152 #define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_ei_isApprox(a, b))
00153 #define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_ei_isMuchSmallerThan(a, b))
00154 #define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_ei_isMuchSmallerThan(a, b))
00155 #define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_ei_isApproxOrLessThan(a, b))
00156 #define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_ei_isApproxOrLessThan(a, b))
00157 
00158 #define CALL_SUBTEST(FUNC) do { \
00159     g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \
00160     FUNC; \
00161     g_test_stack.pop_back(); \
00162   } while (0)
00163 
00164 namespace Eigen {
00165 
00166 template<typename T> inline typename NumTraits<T>::Real test_precision();
00167 template<> inline int test_precision<int>() { return 0; }
00168 template<> inline float test_precision<float>() { return 1e-3f; }
00169 template<> inline double test_precision<double>() { return 1e-6; }
00170 template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }
00171 template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }
00172 template<> inline long double test_precision<long double>() { return 1e-6; }
00173 
00174 inline bool test_ei_isApprox(const int& a, const int& b)
00175 { return ei_isApprox(a, b, test_precision<int>()); }
00176 inline bool test_ei_isMuchSmallerThan(const int& a, const int& b)
00177 { return ei_isMuchSmallerThan(a, b, test_precision<int>()); }
00178 inline bool test_ei_isApproxOrLessThan(const int& a, const int& b)
00179 { return ei_isApproxOrLessThan(a, b, test_precision<int>()); }
00180 
00181 inline bool test_ei_isApprox(const float& a, const float& b)
00182 { return ei_isApprox(a, b, test_precision<float>()); }
00183 inline bool test_ei_isMuchSmallerThan(const float& a, const float& b)
00184 { return ei_isMuchSmallerThan(a, b, test_precision<float>()); }
00185 inline bool test_ei_isApproxOrLessThan(const float& a, const float& b)
00186 { return ei_isApproxOrLessThan(a, b, test_precision<float>()); }
00187 
00188 inline bool test_ei_isApprox(const double& a, const double& b)
00189 { return ei_isApprox(a, b, test_precision<double>()); }
00190 inline bool test_ei_isMuchSmallerThan(const double& a, const double& b)
00191 { return ei_isMuchSmallerThan(a, b, test_precision<double>()); }
00192 inline bool test_ei_isApproxOrLessThan(const double& a, const double& b)
00193 { return ei_isApproxOrLessThan(a, b, test_precision<double>()); }
00194 
00195 inline bool test_ei_isApprox(const std::complex<float>& a, const std::complex<float>& b)
00196 { return ei_isApprox(a, b, test_precision<std::complex<float> >()); }
00197 inline bool test_ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b)
00198 { return ei_isMuchSmallerThan(a, b, test_precision<std::complex<float> >()); }
00199 
00200 inline bool test_ei_isApprox(const std::complex<double>& a, const std::complex<double>& b)
00201 { return ei_isApprox(a, b, test_precision<std::complex<double> >()); }
00202 inline bool test_ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b)
00203 { return ei_isMuchSmallerThan(a, b, test_precision<std::complex<double> >()); }
00204 
00205 inline bool test_ei_isApprox(const long double& a, const long double& b)
00206 { return ei_isApprox(a, b, test_precision<long double>()); }
00207 inline bool test_ei_isMuchSmallerThan(const long double& a, const long double& b)
00208 { return ei_isMuchSmallerThan(a, b, test_precision<long double>()); }
00209 inline bool test_ei_isApproxOrLessThan(const long double& a, const long double& b)
00210 { return ei_isApproxOrLessThan(a, b, test_precision<long double>()); }
00211 
00212 template<typename Type1, typename Type2>
00213 inline bool test_ei_isApprox(const Type1& a, const Type2& b)
00214 {
00215   return a.isApprox(b, test_precision<typename Type1::Scalar>());
00216 }
00217 
00218 template<typename Derived1, typename Derived2>
00219 inline bool test_ei_isMuchSmallerThan(const MatrixBase<Derived1>& m1,
00220                                    const MatrixBase<Derived2>& m2)
00221 {
00222   return m1.isMuchSmallerThan(m2, test_precision<typename ei_traits<Derived1>::Scalar>());
00223 }
00224 
00225 template<typename Derived>
00226 inline bool test_ei_isMuchSmallerThan(const MatrixBase<Derived>& m,
00227                                    const typename NumTraits<typename ei_traits<Derived>::Scalar>::Real& s)
00228 {
00229   return m.isMuchSmallerThan(s, test_precision<typename ei_traits<Derived>::Scalar>());
00230 }
00231 
00232 } // end namespace Eigen
00233 
00234 template<typename T> struct GetDifferentType;
00235 
00236 template<> struct GetDifferentType<float> { typedef double type; };
00237 template<> struct GetDifferentType<double> { typedef float type; };
00238 template<typename T> struct GetDifferentType<std::complex<T> >
00239 { typedef std::complex<typename GetDifferentType<T>::type> type; };
00240 
00241 // forward declaration of the main test function
00242 void EI_PP_CAT(test_,EIGEN_TEST_FUNC)();
00243 
00244 using namespace Eigen;
00245 
00246 #ifdef EIGEN_TEST_PART_1
00247 #define CALL_SUBTEST_1(FUNC) CALL_SUBTEST(FUNC)
00248 #else
00249 #define CALL_SUBTEST_1(FUNC)
00250 #endif
00251 
00252 #ifdef EIGEN_TEST_PART_2
00253 #define CALL_SUBTEST_2(FUNC) CALL_SUBTEST(FUNC)
00254 #else
00255 #define CALL_SUBTEST_2(FUNC)
00256 #endif
00257 
00258 #ifdef EIGEN_TEST_PART_3
00259 #define CALL_SUBTEST_3(FUNC) CALL_SUBTEST(FUNC)
00260 #else
00261 #define CALL_SUBTEST_3(FUNC)
00262 #endif
00263 
00264 #ifdef EIGEN_TEST_PART_4
00265 #define CALL_SUBTEST_4(FUNC) CALL_SUBTEST(FUNC)
00266 #else
00267 #define CALL_SUBTEST_4(FUNC)
00268 #endif
00269 
00270 #ifdef EIGEN_TEST_PART_5
00271 #define CALL_SUBTEST_5(FUNC) CALL_SUBTEST(FUNC)
00272 #else
00273 #define CALL_SUBTEST_5(FUNC)
00274 #endif
00275 
00276 #ifdef EIGEN_TEST_PART_6
00277 #define CALL_SUBTEST_6(FUNC) CALL_SUBTEST(FUNC)
00278 #else
00279 #define CALL_SUBTEST_6(FUNC)
00280 #endif
00281 
00282 #ifdef EIGEN_TEST_PART_7
00283 #define CALL_SUBTEST_7(FUNC) CALL_SUBTEST(FUNC)
00284 #else
00285 #define CALL_SUBTEST_7(FUNC)
00286 #endif
00287 
00288 #ifdef EIGEN_TEST_PART_8
00289 #define CALL_SUBTEST_8(FUNC) CALL_SUBTEST(FUNC)
00290 #else
00291 #define CALL_SUBTEST_8(FUNC)
00292 #endif
00293 
00294 #ifdef EIGEN_TEST_PART_9
00295 #define CALL_SUBTEST_9(FUNC) CALL_SUBTEST(FUNC)
00296 #else
00297 #define CALL_SUBTEST_9(FUNC)
00298 #endif
00299 
00300 #ifdef EIGEN_TEST_PART_10
00301 #define CALL_SUBTEST_10(FUNC) CALL_SUBTEST(FUNC)
00302 #else
00303 #define CALL_SUBTEST_10(FUNC)
00304 #endif
00305 
00306 #ifdef EIGEN_TEST_PART_11
00307 #define CALL_SUBTEST_11(FUNC) CALL_SUBTEST(FUNC)
00308 #else
00309 #define CALL_SUBTEST_11(FUNC)
00310 #endif
00311 
00312 #ifdef EIGEN_TEST_PART_12
00313 #define CALL_SUBTEST_12(FUNC) CALL_SUBTEST(FUNC)
00314 #else
00315 #define CALL_SUBTEST_12(FUNC)
00316 #endif
00317 
00318 #ifdef EIGEN_TEST_PART_13
00319 #define CALL_SUBTEST_13(FUNC) CALL_SUBTEST(FUNC)
00320 #else
00321 #define CALL_SUBTEST_13(FUNC)
00322 #endif
00323 
00324 #ifdef EIGEN_TEST_PART_14
00325 #define CALL_SUBTEST_14(FUNC) CALL_SUBTEST(FUNC)
00326 #else
00327 #define CALL_SUBTEST_14(FUNC)
00328 #endif
00329 
00330 #ifdef EIGEN_TEST_PART_15
00331 #define CALL_SUBTEST_15(FUNC) CALL_SUBTEST(FUNC)
00332 #else
00333 #define CALL_SUBTEST_15(FUNC)
00334 #endif
00335 
00336 #ifdef EIGEN_TEST_PART_16
00337 #define CALL_SUBTEST_16(FUNC) CALL_SUBTEST(FUNC)
00338 #else
00339 #define CALL_SUBTEST_16(FUNC)
00340 #endif
00341 
00342 
00343 
00344 int main(int argc, char *argv[])
00345 {
00346     bool has_set_repeat = false;
00347     bool has_set_seed = false;
00348     bool need_help = false;
00349     unsigned int seed = 0;
00350     int repeat = DEFAULT_REPEAT;
00351 
00352     for(int i = 1; i < argc; i++)
00353     {
00354       if(argv[i][0] == 'r')
00355       {
00356         if(has_set_repeat)
00357         {
00358           std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
00359           return 1;
00360         }
00361         repeat = std::atoi(argv[i]+1);
00362         has_set_repeat = true;
00363         if(repeat <= 0)
00364         {
00365           std::cout << "Invalid \'repeat\' value " << argv[i]+1 << std::endl;
00366           return 1;
00367         }
00368       }
00369       else if(argv[i][0] == 's')
00370       {
00371         if(has_set_seed)
00372         {
00373           std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
00374           return 1;
00375         }
00376         seed = int(std::strtoul(argv[i]+1, 0, 10));
00377         has_set_seed = true;
00378         bool ok = seed!=0;
00379         if(!ok)
00380         {
00381           std::cout << "Invalid \'seed\' value " << argv[i]+1 << std::endl;
00382           return 1;
00383         }
00384       }
00385       else
00386       {
00387         need_help = true;
00388       }
00389     }
00390 
00391     if(need_help)
00392     {
00393       std::cout << "This test application takes the following optional arguments:" << std::endl;
00394       std::cout << "  rN     Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;
00395       std::cout << "  sN     Use N as seed for random numbers (default: based on current time)" << std::endl;
00396       return 1;
00397     }
00398 
00399     if(!has_set_seed) seed = (unsigned int) std::time(NULL);
00400     if(!has_set_repeat) repeat = DEFAULT_REPEAT;
00401 
00402     std::cout << "Initializing random number generator with seed " << seed << std::endl;
00403         std::srand(seed);
00404     std::cout << "Repeating each test " << repeat << " times" << std::endl;
00405 
00406     Eigen::g_repeat = repeat;
00407     Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC));
00408 
00409     EI_PP_CAT(test_,EIGEN_TEST_FUNC)();
00410     return 0;
00411 }
00412 
00413 
00414 


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:43