testhelper.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright 2008 Gunter Winkler <guwi17@gmx.de>
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef _HPP_TESTHELPER_
  6. #define _HPP_TESTHELPER_
  7. #include <utility>
  8. #include <iostream>
  9. #include <boost/numeric/ublas/vector_expression.hpp>
  10. #include <boost/numeric/ublas/matrix_expression.hpp>
  11. #include <boost/mpl/if.hpp>
  12. #include <boost/type_traits/is_integral.hpp>
  13. #include <boost/numeric/ublas/traits.hpp>
  14. static unsigned _success_counter = 0;
  15. static unsigned _fail_counter = 0;
  16. static inline
  17. void assertTrue(const char* message, bool condition) {
  18. #ifndef NOMESSAGES
  19. std::cout << message;
  20. #else
  21. (void)message;
  22. #endif
  23. if ( condition ) {
  24. ++ _success_counter;
  25. std::cout << "1\n"; // success
  26. } else {
  27. ++ _fail_counter;
  28. std::cout << "0\n"; // failed
  29. }
  30. }
  31. template < class T >
  32. void assertEquals(const char* message, T expected, T actual) {
  33. #ifndef NOMESSAGES
  34. std::cout << message;
  35. #else
  36. (void)message;
  37. #endif
  38. if ( expected == actual ) {
  39. ++ _success_counter;
  40. std::cout << "1\n"; // success
  41. } else {
  42. #ifndef NOMESSAGES
  43. std::cout << " expected " << expected << " actual " << actual << " ";
  44. #endif
  45. ++ _fail_counter;
  46. std::cout << "0\n"; // failed
  47. }
  48. }
  49. inline static
  50. std::pair<unsigned, unsigned> getResults() {
  51. return std::make_pair(_success_counter, _fail_counter);
  52. }
  53. template < class M1, class M2 >
  54. bool compare( const boost::numeric::ublas::matrix_expression<M1> & m1,
  55. const boost::numeric::ublas::matrix_expression<M2> & m2 ) {
  56. if ((m1().size1() != m2().size1()) ||
  57. (m1().size2() != m2().size2())) {
  58. return false;
  59. }
  60. size_t size1 = m1().size1();
  61. size_t size2 = m1().size2();
  62. for (size_t i=0; i < size1; ++i) {
  63. for (size_t j=0; j < size2; ++j) {
  64. if ( m1()(i,j) != m2()(i,j) ) return false;
  65. }
  66. }
  67. return true;
  68. }
  69. template < class M1, class M2 >
  70. bool compare( const boost::numeric::ublas::vector_expression<M1> & m1,
  71. const boost::numeric::ublas::vector_expression<M2> & m2 ) {
  72. if (m1().size() != m2().size()) {
  73. return false;
  74. }
  75. size_t size = m1().size();
  76. for (size_t i=0; i < size; ++i) {
  77. if ( m1()(i) != m2()(i) ) return false;
  78. }
  79. return true;
  80. }
  81. // Compare if two matrices or vectors are equals based on distance.
  82. template <typename T>
  83. struct promote_distance {
  84. typedef typename boost::mpl::if_c<boost::is_integral<T>::value,
  85. long double,
  86. T>::type type;
  87. };
  88. template <typename M1, typename M2 = void>
  89. struct distance {
  90. private:
  91. typedef typename boost::numeric::ublas::promote_traits<typename M1::value_type,
  92. typename M2::value_type>::promote_type value_type;
  93. public:
  94. typedef typename promote_distance<value_type>::type type;
  95. };
  96. template <typename AE>
  97. struct distance<AE, void> {
  98. typedef typename promote_distance<typename AE::value_type>::type type;
  99. };
  100. template <class AE>
  101. typename distance<AE>::type mean_square(const boost::numeric::ublas::matrix_expression<AE> &me) {
  102. typename distance<AE>::type s(0);
  103. typename AE::size_type i, j;
  104. for (i=0; i!= me().size1(); i++) {
  105. for (j=0; j!= me().size2(); j++) {
  106. s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(me()(i,j));
  107. }
  108. }
  109. return s / (me().size1() * me().size2());
  110. }
  111. template <class AE>
  112. typename distance<AE>::type mean_square(const boost::numeric::ublas::vector_expression<AE> &ve) {
  113. // We could have use norm2 here, but ublas' ABS does not support unsigned types.
  114. typename distance<AE>::type s(0);
  115. typename AE::size_type i;
  116. for (i = 0; i != ve().size(); i++) {
  117. s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(ve()(i));
  118. }
  119. return s / ve().size();
  120. }
  121. template < class M1, class M2 >
  122. bool compare_distance( const boost::numeric::ublas::matrix_expression<M1> & m1,
  123. const boost::numeric::ublas::matrix_expression<M2> & m2,
  124. typename distance<M1, M2>::type tolerance = 0 ) {
  125. if ((m1().size1() != m2().size1()) ||
  126. (m1().size2() != m2().size2())) {
  127. return false;
  128. }
  129. return mean_square(m2() - m1()) <= tolerance;
  130. }
  131. template < class M1, class M2 >
  132. bool compare_distance( const boost::numeric::ublas::vector_expression<M1> & m1,
  133. const boost::numeric::ublas::vector_expression<M2> & m2,
  134. typename distance<M1, M2>::type tolerance = 0 ) {
  135. if (m1().size() != m2().size()) {
  136. return false;
  137. }
  138. return mean_square(m2() - m1()) <= tolerance;
  139. }
  140. #endif