• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2018-2019 Cem Bassoy
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See
4 //  accompanying file LICENSE_1_0.txt or copy at
5 //  http://www.boost.org/LICENSE_1_0.txt)
6 //
7 //  The authors gratefully acknowledge the support of
8 //  Fraunhofer and Google in producing this work
9 //  which started as a Google Summer of Code project.
10 //
11 
12 
13 
14 #include <boost/numeric/ublas/tensor/operators_comparison.hpp>
15 #include <boost/numeric/ublas/tensor/operators_arithmetic.hpp>
16 #include <boost/numeric/ublas/tensor/tensor.hpp>
17 #include <boost/test/unit_test.hpp>
18 #include <boost/multiprecision/cpp_bin_float.hpp>
19 #include "utility.hpp"
20 
21 
22 using double_extended = boost::multiprecision::cpp_bin_float_double_extended;
23 
24 using test_types = zip<int,long,float,double,double_extended>::with_t<boost::numeric::ublas::first_order, boost::numeric::ublas::last_order>;
25 
26 struct fixture {
27 	using extents_type = boost::numeric::ublas::basic_extents<std::size_t>;
fixturefixture28 	fixture()
29 	  : extents{
30 				extents_type{},    // 0
31 				extents_type{1,1}, // 1
32 				extents_type{1,2}, // 2
33 				extents_type{2,1}, // 3
34 				extents_type{2,3}, // 4
35 				extents_type{2,3,1}, // 5
36 				extents_type{4,1,3}, // 6
37 				extents_type{1,2,3}, // 7
38 				extents_type{4,2,3}, // 8
39 	      extents_type{4,2,3,5}} // 9
40 	{
41 	}
42 	std::vector<extents_type> extents;
43 };
44 
45 BOOST_AUTO_TEST_SUITE(test_tensor_comparison, * boost::unit_test::depends_on("test_tensor"))
46 
47 
BOOST_FIXTURE_TEST_CASE_TEMPLATE(test_tensor_comparison,value,test_types,fixture)48 BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_comparison, value,  test_types, fixture)
49 {
50 	using namespace boost::numeric;
51 	using value_type  = typename value::first_type;
52 	using layout_type = typename value::second_type;
53 	using tensor_type = ublas::tensor<value_type, layout_type>;
54 
55 
56 	auto check = [](auto const& e)
57 	{
58 		auto t  = tensor_type (e);
59 		auto t2 = tensor_type (e);
60 		auto v  = value_type  {};
61 
62 		std::iota(t.begin(), t.end(), v);
63 		std::iota(t2.begin(), t2.end(), v+2);
64 
65 		BOOST_CHECK( t == t  );
66 		BOOST_CHECK( t != t2 );
67 
68 		if(t.empty())
69 			return;
70 
71 		BOOST_CHECK(!(t < t));
72 		BOOST_CHECK(!(t > t));
73 		BOOST_CHECK( t < t2 );
74 		BOOST_CHECK( t2 > t );
75 		BOOST_CHECK( t <= t );
76 		BOOST_CHECK( t >= t );
77 		BOOST_CHECK( t <= t2 );
78 		BOOST_CHECK( t2 >= t );
79 		BOOST_CHECK( t2 >= t2 );
80 		BOOST_CHECK( t2 >= t );
81 	};
82 
83 	for(auto const& e : extents)
84 		check(e);
85 
86 	auto e0 = extents.at(0);
87 	auto e1 = extents.at(1);
88 	auto e2 = extents.at(2);
89 
90 
91 	auto b = false;
92 	BOOST_CHECK_NO_THROW ( b = (tensor_type(e0) == tensor_type(e0)));
93 	BOOST_CHECK_NO_THROW ( b = (tensor_type(e1) == tensor_type(e2)));
94 	BOOST_CHECK_NO_THROW ( b = (tensor_type(e0) == tensor_type(e2)));
95 	BOOST_CHECK_NO_THROW ( b = (tensor_type(e1) != tensor_type(e2)));
96 
97 	BOOST_CHECK_THROW    ( b = (tensor_type(e1) >= tensor_type(e2)), std::runtime_error  );
98 	BOOST_CHECK_THROW    ( b = (tensor_type(e1) <= tensor_type(e2)), std::runtime_error  );
99 	BOOST_CHECK_THROW    ( b = (tensor_type(e1) <  tensor_type(e2)), std::runtime_error  );
100 	BOOST_CHECK_THROW    ( b = (tensor_type(e1) >  tensor_type(e2)), std::runtime_error  );
101 
102 }
103 
104 
BOOST_FIXTURE_TEST_CASE_TEMPLATE(test_tensor_comparison_with_tensor_expressions,value,test_types,fixture)105 BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_comparison_with_tensor_expressions, value,  test_types, fixture)
106 {
107 	using namespace boost::numeric;
108 	using value_type  = typename value::first_type;
109 	using layout_type = typename value::second_type;
110 	using tensor_type = ublas::tensor<value_type, layout_type>;
111 
112 
113 	auto check = [](auto const& e)
114 	{
115 		auto t  = tensor_type (e);
116 		auto t2 = tensor_type (e);
117 		auto v  = value_type  {};
118 
119 		std::iota(t.begin(), t.end(), v);
120 		std::iota(t2.begin(), t2.end(), v+2);
121 
122 		BOOST_CHECK( t == t  );
123 		BOOST_CHECK( t != t2 );
124 
125 		if(t.empty())
126 			return;
127 
128 		BOOST_CHECK( !(t < t) );
129 		BOOST_CHECK( !(t > t) );
130 		BOOST_CHECK( t < (t2+t) );
131 		BOOST_CHECK( (t2+t) > t );
132 		BOOST_CHECK( t <= (t+t) );
133 		BOOST_CHECK( (t+t2) >= t );
134 		BOOST_CHECK( (t2+t2+2) >= t);
135 		BOOST_CHECK( 2*t2 > t );
136 		BOOST_CHECK( t < 2*t2 );
137 		BOOST_CHECK( 2*t2 > t);
138 		BOOST_CHECK( 2*t2 >= t2 );
139 		BOOST_CHECK( t2 <= 2*t2);
140 		BOOST_CHECK( 3*t2 >= t );
141 
142 	};
143 
144 	for(auto const& e : extents)
145 		check(e);
146 
147 	auto e0 = extents.at(0);
148 	auto e1 = extents.at(1);
149 	auto e2 = extents.at(2);
150 
151 	auto b = false;
152 	BOOST_CHECK_NO_THROW (b = tensor_type(e0) == (tensor_type(e0) + tensor_type(e0))  );
153 	BOOST_CHECK_NO_THROW (b = tensor_type(e1) == (tensor_type(e2) + tensor_type(e2))  );
154 	BOOST_CHECK_NO_THROW (b = tensor_type(e0) == (tensor_type(e2) + 2) );
155 	BOOST_CHECK_NO_THROW (b = tensor_type(e1) != (2 + tensor_type(e2)) );
156 
157 	BOOST_CHECK_NO_THROW (b = (tensor_type(e0) + tensor_type(e0)) == tensor_type(e0) );
158 	BOOST_CHECK_NO_THROW (b = (tensor_type(e2) + tensor_type(e2)) == tensor_type(e1) );
159 	BOOST_CHECK_NO_THROW (b = (tensor_type(e2) + 2)               == tensor_type(e0) );
160 	BOOST_CHECK_NO_THROW (b = (2 + tensor_type(e2))               != tensor_type(e1) );
161 
162 	BOOST_CHECK_THROW    (b = tensor_type(e1) >= (tensor_type(e2) + tensor_type(e2)), std::runtime_error  );
163 	BOOST_CHECK_THROW    (b = tensor_type(e1) <= (tensor_type(e2) + tensor_type(e2)), std::runtime_error  );
164 	BOOST_CHECK_THROW    (b = tensor_type(e1) <  (tensor_type(e2) + tensor_type(e2)), std::runtime_error  );
165 	BOOST_CHECK_THROW    (b = tensor_type(e1) >  (tensor_type(e2) + tensor_type(e2)), std::runtime_error  );
166 
167 	BOOST_CHECK_THROW    (b = tensor_type(e1) >= (tensor_type(e2) + 2), std::runtime_error  );
168 	BOOST_CHECK_THROW    (b = tensor_type(e1) <= (2 + tensor_type(e2)), std::runtime_error  );
169 	BOOST_CHECK_THROW    (b = tensor_type(e1) <  (tensor_type(e2) + 3), std::runtime_error  );
170 	BOOST_CHECK_THROW    (b = tensor_type(e1) >  (4 + tensor_type(e2)), std::runtime_error  );
171 
172 }
173 
174 
175 
BOOST_FIXTURE_TEST_CASE_TEMPLATE(test_tensor_comparison_with_scalar,value,test_types,fixture)176 BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_tensor_comparison_with_scalar, value,  test_types, fixture)
177 {
178 	using namespace boost::numeric;
179 	using value_type  = typename value::first_type;
180 	using layout_type = typename value::second_type;
181 	using tensor_type = ublas::tensor<value_type, layout_type>;
182 
183 
184 	auto check = [](auto const& e)
185 	{
186 
187 		BOOST_CHECK( tensor_type(e,value_type{2}) == tensor_type(e,value_type{2})  );
188 		BOOST_CHECK( tensor_type(e,value_type{2}) != tensor_type(e,value_type{1})  );
189 
190 		if(e.empty())
191 			return;
192 
193 		BOOST_CHECK( !(tensor_type(e,2) <  2) );
194 		BOOST_CHECK( !(tensor_type(e,2) >  2) );
195 		BOOST_CHECK(  (tensor_type(e,2) >= 2) );
196 		BOOST_CHECK(  (tensor_type(e,2) <= 2) );
197 		BOOST_CHECK(  (tensor_type(e,2) == 2) );
198 		BOOST_CHECK(  (tensor_type(e,2) != 3) );
199 
200 		BOOST_CHECK( !(2 >  tensor_type(e,2)) );
201 		BOOST_CHECK( !(2 <  tensor_type(e,2)) );
202 		BOOST_CHECK(  (2 <= tensor_type(e,2)) );
203 		BOOST_CHECK(  (2 >= tensor_type(e,2)) );
204 		BOOST_CHECK(  (2 == tensor_type(e,2)) );
205 		BOOST_CHECK(  (3 != tensor_type(e,2)) );
206 
207 		BOOST_CHECK( !( tensor_type(e,2)+3 <  5) );
208 		BOOST_CHECK( !( tensor_type(e,2)+3 >  5) );
209 		BOOST_CHECK(  ( tensor_type(e,2)+3 >= 5) );
210 		BOOST_CHECK(  ( tensor_type(e,2)+3 <= 5) );
211 		BOOST_CHECK(  ( tensor_type(e,2)+3 == 5) );
212 		BOOST_CHECK(  ( tensor_type(e,2)+3 != 6) );
213 
214 
215 		BOOST_CHECK( !( 5 >  tensor_type(e,2)+3) );
216 		BOOST_CHECK( !( 5 <  tensor_type(e,2)+3) );
217 		BOOST_CHECK(  ( 5 >= tensor_type(e,2)+3) );
218 		BOOST_CHECK(  ( 5 <= tensor_type(e,2)+3) );
219 		BOOST_CHECK(  ( 5 == tensor_type(e,2)+3) );
220 		BOOST_CHECK(  ( 6 != tensor_type(e,2)+3) );
221 
222 
223 		BOOST_CHECK( !( tensor_type(e,2)+tensor_type(e,3) <  5) );
224 		BOOST_CHECK( !( tensor_type(e,2)+tensor_type(e,3) >  5) );
225 		BOOST_CHECK(  ( tensor_type(e,2)+tensor_type(e,3) >= 5) );
226 		BOOST_CHECK(  ( tensor_type(e,2)+tensor_type(e,3) <= 5) );
227 		BOOST_CHECK(  ( tensor_type(e,2)+tensor_type(e,3) == 5) );
228 		BOOST_CHECK(  ( tensor_type(e,2)+tensor_type(e,3) != 6) );
229 
230 
231 		BOOST_CHECK( !( 5 >  tensor_type(e,2)+tensor_type(e,3)) );
232 		BOOST_CHECK( !( 5 <  tensor_type(e,2)+tensor_type(e,3)) );
233 		BOOST_CHECK(  ( 5 >= tensor_type(e,2)+tensor_type(e,3)) );
234 		BOOST_CHECK(  ( 5 <= tensor_type(e,2)+tensor_type(e,3)) );
235 		BOOST_CHECK(  ( 5 == tensor_type(e,2)+tensor_type(e,3)) );
236 		BOOST_CHECK(  ( 6 != tensor_type(e,2)+tensor_type(e,3)) );
237 
238 	};
239 
240 	for(auto const& e : extents)
241 		check(e);
242 
243 }
244 
245 
246 BOOST_AUTO_TEST_SUITE_END()
247