// Copyright 2008 Gunter Winkler // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef _HPP_TESTHELPER_ #define _HPP_TESTHELPER_ #include #include #include #include #include #include #include static unsigned _success_counter = 0; static unsigned _fail_counter = 0; static inline void assertTrue(const char* message, bool condition) { #ifndef NOMESSAGES std::cout << message; #else (void)message; #endif if ( condition ) { ++ _success_counter; std::cout << "1\n"; // success } else { ++ _fail_counter; std::cout << "0\n"; // failed } } template < class T > void assertEquals(const char* message, T expected, T actual) { #ifndef NOMESSAGES std::cout << message; #else (void)message; #endif if ( expected == actual ) { ++ _success_counter; std::cout << "1\n"; // success } else { #ifndef NOMESSAGES std::cout << " expected " << expected << " actual " << actual << " "; #endif ++ _fail_counter; std::cout << "0\n"; // failed } } inline static std::pair getResults() { return std::make_pair(_success_counter, _fail_counter); } template < class M1, class M2 > bool compare( const boost::numeric::ublas::matrix_expression & m1, const boost::numeric::ublas::matrix_expression & m2 ) { if ((m1().size1() != m2().size1()) || (m1().size2() != m2().size2())) { return false; } size_t size1 = m1().size1(); size_t size2 = m1().size2(); for (size_t i=0; i < size1; ++i) { for (size_t j=0; j < size2; ++j) { if ( m1()(i,j) != m2()(i,j) ) return false; } } return true; } template < class M1, class M2 > bool compare( const boost::numeric::ublas::vector_expression & m1, const boost::numeric::ublas::vector_expression & m2 ) { if (m1().size() != m2().size()) { return false; } size_t size = m1().size(); for (size_t i=0; i < size; ++i) { if ( m1()(i) != m2()(i) ) return false; } return true; } // Compare if two matrices or vectors are equals based on distance. template struct promote_distance { typedef typename boost::mpl::if_c::value, long double, T>::type type; }; template struct distance { private: typedef typename boost::numeric::ublas::promote_traits::promote_type value_type; public: typedef typename promote_distance::type type; }; template struct distance { typedef typename promote_distance::type type; }; template typename distance::type mean_square(const boost::numeric::ublas::matrix_expression &me) { typename distance::type s(0); typename AE::size_type i, j; for (i=0; i!= me().size1(); i++) { for (j=0; j!= me().size2(); j++) { s += boost::numeric::ublas::scalar_traits::type_abs(me()(i,j)); } } return s / (me().size1() * me().size2()); } template typename distance::type mean_square(const boost::numeric::ublas::vector_expression &ve) { // We could have use norm2 here, but ublas' ABS does not support unsigned types. typename distance::type s(0); typename AE::size_type i; for (i = 0; i != ve().size(); i++) { s += boost::numeric::ublas::scalar_traits::type_abs(ve()(i)); } return s / ve().size(); } template < class M1, class M2 > bool compare_distance( const boost::numeric::ublas::matrix_expression & m1, const boost::numeric::ublas::matrix_expression & m2, typename distance::type tolerance = 0 ) { if ((m1().size1() != m2().size1()) || (m1().size2() != m2().size2())) { return false; } return mean_square(m2() - m1()) <= tolerance; } template < class M1, class M2 > bool compare_distance( const boost::numeric::ublas::vector_expression & m1, const boost::numeric::ublas::vector_expression & m2, typename distance::type tolerance = 0 ) { if (m1().size() != m2().size()) { return false; } return mean_square(m2() - m1()) <= tolerance; } #endif