| // Copyright 2008 Gunter Winkler <guwi17@gmx.de> |
| // 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 <utility> |
| #include <iostream> |
| #include <boost/numeric/ublas/vector_expression.hpp> |
| #include <boost/numeric/ublas/matrix_expression.hpp> |
| #include <boost/mpl/if.hpp> |
| #include <boost/type_traits/is_integral.hpp> |
| #include <boost/numeric/ublas/traits.hpp> |
| |
| 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<unsigned, unsigned> getResults() { |
| return std::make_pair(_success_counter, _fail_counter); |
| } |
| |
| template < class M1, class M2 > |
| bool compare( const boost::numeric::ublas::matrix_expression<M1> & m1, |
| const boost::numeric::ublas::matrix_expression<M2> & 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> & m1, |
| const boost::numeric::ublas::vector_expression<M2> & 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 <typename T> |
| struct promote_distance { |
| typedef typename boost::mpl::if_c<boost::is_integral<T>::value, |
| long double, |
| T>::type type; |
| }; |
| |
| template <typename M1, typename M2 = void> |
| struct distance { |
| private: |
| typedef typename boost::numeric::ublas::promote_traits<typename M1::value_type, |
| typename M2::value_type>::promote_type value_type; |
| |
| public: |
| typedef typename promote_distance<value_type>::type type; |
| }; |
| |
| template <typename AE> |
| struct distance<AE, void> { |
| typedef typename promote_distance<typename AE::value_type>::type type; |
| }; |
| |
| |
| template <class AE> |
| typename distance<AE>::type mean_square(const boost::numeric::ublas::matrix_expression<AE> &me) { |
| typename distance<AE>::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<typename AE::value_type>::type_abs(me()(i,j)); |
| } |
| } |
| return s / (me().size1() * me().size2()); |
| } |
| |
| template <class AE> |
| typename distance<AE>::type mean_square(const boost::numeric::ublas::vector_expression<AE> &ve) { |
| // We could have use norm2 here, but ublas' ABS does not support unsigned types. |
| typename distance<AE>::type s(0); |
| typename AE::size_type i; |
| for (i = 0; i != ve().size(); i++) { |
| s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(ve()(i)); |
| } |
| return s / ve().size(); |
| } |
| |
| template < class M1, class M2 > |
| bool compare_distance( const boost::numeric::ublas::matrix_expression<M1> & m1, |
| const boost::numeric::ublas::matrix_expression<M2> & m2, |
| typename distance<M1, M2>::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> & m1, |
| const boost::numeric::ublas::vector_expression<M2> & m2, |
| typename distance<M1, M2>::type tolerance = 0 ) { |
| if (m1().size() != m2().size()) { |
| return false; |
| } |
| |
| return mean_square(m2() - m1()) <= tolerance; |
| } |
| |
| |
| #endif |