• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
6 
7 #ifndef _HPP_TESTHELPER_
8 #define _HPP_TESTHELPER_
9 
10 #include <utility>
11 #include <iostream>
12 #include <boost/numeric/ublas/vector_expression.hpp>
13 #include <boost/numeric/ublas/matrix_expression.hpp>
14 #include <boost/mpl/if.hpp>
15 #include <boost/type_traits/is_integral.hpp>
16 #include <boost/numeric/ublas/traits.hpp>
17 
18 static unsigned _success_counter = 0;
19 static unsigned _fail_counter    = 0;
20 
21 static inline
assertTrue(const char * message,bool condition)22 void assertTrue(const char* message, bool condition) {
23 #ifndef NOMESSAGES
24   std::cout << message;
25 #else
26   (void)message;
27 #endif
28   if ( condition ) {
29     ++ _success_counter;
30     std::cout << "1\n"; // success
31   } else {
32     ++ _fail_counter;
33     std::cout << "0\n"; // failed
34   }
35 }
36 
37 template < class T >
assertEquals(const char * message,T expected,T actual)38 void assertEquals(const char* message, T expected, T actual) {
39 #ifndef NOMESSAGES
40   std::cout << message;
41 #else
42   (void)message;
43 #endif
44   if ( expected == actual ) {
45     ++ _success_counter;
46     std::cout << "1\n"; // success
47   } else {
48     #ifndef NOMESSAGES
49       std::cout << " expected " << expected << " actual " << actual << " ";
50     #endif
51     ++ _fail_counter;
52     std::cout << "0\n"; // failed
53   }
54 }
55 
56 inline static
getResults()57 std::pair<unsigned, unsigned> getResults() {
58   return std::make_pair(_success_counter, _fail_counter);
59 }
60 
61 template < class M1, class M2 >
compare(const boost::numeric::ublas::matrix_expression<M1> & m1,const boost::numeric::ublas::matrix_expression<M2> & m2)62 bool compare( const boost::numeric::ublas::matrix_expression<M1> & m1,
63               const boost::numeric::ublas::matrix_expression<M2> & m2 ) {
64   if ((m1().size1() != m2().size1()) ||
65       (m1().size2() != m2().size2())) {
66     return false;
67   }
68 
69   size_t size1 = m1().size1();
70   size_t size2 = m1().size2();
71   for (size_t i=0; i < size1; ++i) {
72     for (size_t j=0; j < size2; ++j) {
73       if ( m1()(i,j) != m2()(i,j) ) return false;
74     }
75   }
76   return true;
77 }
78 
79 template < class M1, class M2 >
compare(const boost::numeric::ublas::vector_expression<M1> & m1,const boost::numeric::ublas::vector_expression<M2> & m2)80 bool compare( const boost::numeric::ublas::vector_expression<M1> & m1,
81               const boost::numeric::ublas::vector_expression<M2> & m2 ) {
82   if (m1().size() != m2().size()) {
83     return false;
84   }
85 
86   size_t size = m1().size();
87   for (size_t i=0; i < size; ++i) {
88     if ( m1()(i) != m2()(i) ) return false;
89   }
90   return true;
91 }
92 
93 // Compare if two matrices or vectors are equals based on distance.
94 
95 template <typename T>
96 struct promote_distance {
97     typedef typename boost::mpl::if_c<boost::is_integral<T>::value,
98                                       long double,
99                                       T>::type type;
100 };
101 
102 template <typename M1, typename M2 = void>
103 struct distance {
104 private:
105     typedef typename boost::numeric::ublas::promote_traits<typename M1::value_type,
106                                                            typename M2::value_type>::promote_type value_type;
107 
108 public:
109     typedef typename promote_distance<value_type>::type type;
110 };
111 
112 template <typename AE>
113 struct distance<AE, void> {
114     typedef typename promote_distance<typename AE::value_type>::type type;
115 };
116 
117 
118 template <class AE>
mean_square(const boost::numeric::ublas::matrix_expression<AE> & me)119 typename distance<AE>::type mean_square(const boost::numeric::ublas::matrix_expression<AE> &me) {
120     typename distance<AE>::type s(0);
121     typename AE::size_type i, j;
122     for (i=0; i!= me().size1(); i++) {
123         for (j=0; j!= me().size2(); j++) {
124             s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(me()(i,j));
125         }
126     }
127     return s / (me().size1() * me().size2());
128 }
129 
130 template <class AE>
mean_square(const boost::numeric::ublas::vector_expression<AE> & ve)131 typename distance<AE>::type mean_square(const boost::numeric::ublas::vector_expression<AE> &ve) {
132     // We could have use norm2 here, but ublas' ABS does not support unsigned types.
133     typename distance<AE>::type s(0);
134     typename AE::size_type i;
135     for (i = 0; i != ve().size(); i++) {
136         s += boost::numeric::ublas::scalar_traits<typename AE::value_type>::type_abs(ve()(i));
137     }
138     return s / ve().size();
139 }
140 
141 template < class M1, class M2 >
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)142 bool compare_distance( const boost::numeric::ublas::matrix_expression<M1> & m1,
143                       const boost::numeric::ublas::matrix_expression<M2> & m2,
144                       typename distance<M1, M2>::type tolerance = 0 ) {
145     if ((m1().size1() != m2().size1()) ||
146         (m1().size2() != m2().size2())) {
147         return false;
148     }
149 
150     return mean_square(m2() - m1()) <= tolerance;
151 }
152 
153 template < class M1, class M2 >
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)154 bool compare_distance( const boost::numeric::ublas::vector_expression<M1> & m1,
155                        const boost::numeric::ublas::vector_expression<M2> & m2,
156                        typename distance<M1, M2>::type tolerance = 0 ) {
157     if (m1().size() != m2().size()) {
158         return false;
159     }
160 
161     return mean_square(m2() - m1()) <= tolerance;
162 }
163 
164 
165 #endif
166