DGtal  1.2.0
testSetFunctions.cpp
1 
31 #include <iostream>
32 #include <vector>
33 #include <set>
34 #include <random>
35 #include <unordered_set>
36 #include "DGtal/base/Common.h"
37 #include "DGtal/base/SetFunctions.h"
38 #include "DGtalCatch.h"
40 
41 using namespace DGtal;
42 using namespace DGtal::functions;
43 //using DGtal::functions::setops::operator|;
44 using DGtal::functions::setops::operator&;
45 using DGtal::functions::setops::operator-;
46 using DGtal::functions::setops::operator^;
47 
48 
50 TEMPLATE_TEST_CASE( "SetFunctions module unit tests", "[set_functions]",
51  std::vector<int>,
52  std::list<int>,
53  std::set<int>,
54  std::unordered_set<int> )
55 
56 {
57  int S1[ 10 ] = { 4, 15, 20, 17, 9, 7, 13, 12, 1, 3 };
58  int S2[ 6 ] = { 17, 14, 19, 2, 3, 4 };
59  TestType C1( S1, S1 + 10 );
60  TestType C2( S2, S2 + 6 );
61  TestType C1_minus_C2 = C1 - C2;
62  REQUIRE( C1_minus_C2.size() == 7 );
63  TestType C2_minus_C1 = C2 - C1;
64  REQUIRE( C2_minus_C1.size() == 3 );
65  REQUIRE( ( C1_minus_C2 - C1 ).size() == 0 );
66  REQUIRE( ( C2_minus_C1 - C2 ).size() == 0 );
67  REQUIRE( ( C1_minus_C2 - C2 ).size() == C1_minus_C2.size() );
68  REQUIRE( ( C2_minus_C1 - C1 ).size() == C2_minus_C1.size() );
69  TestType C1_union_C2 = DGtal::functions::setops::operator|(C1 , C2);
70  TestType C2_union_C1 = DGtal::functions::setops::operator|(C2 , C1);
71  REQUIRE( C1_union_C2.size() == 13 );
72  REQUIRE( C1_union_C2.size() == C2_union_C1.size() );
73  REQUIRE( ( DGtal::functions::setops::operator|(C1_minus_C2 , C2) ).size() == (DGtal::functions::setops::operator|(C2_minus_C1 , C1) ).size() );
74 
75  TestType C1_intersection_C2 = C1 & C2;
76  TestType C2_intersection_C1 = C2 & C1;
77  REQUIRE( C1_intersection_C2.size() == 3 );
78  REQUIRE( C1_intersection_C2.size() == C2_intersection_C1.size() );
79 
80  REQUIRE( ( DGtal::functions::setops::operator|(DGtal::functions::setops::operator|(C1_minus_C2 , C1_intersection_C2) , C2_minus_C1) ).size() == C1_union_C2.size() );
81 
82  TestType C1_symdiff_C2 = C1 ^ C2;
83  TestType C2_symdiff_C1 = C2 ^ C1;
84  REQUIRE( C1_symdiff_C2.size() == C2_symdiff_C1.size() );
85  REQUIRE( C1_symdiff_C2.size() == ( C1_union_C2 - C1_intersection_C2 ).size() );
86  REQUIRE( C1_symdiff_C2.size() == ( DGtal::functions::setops::operator|(C1_minus_C2 , C2_minus_C1) ).size() );
87 
88  REQUIRE( isEqual( C1_symdiff_C2, C1_union_C2 - C1_intersection_C2 ) );
89  REQUIRE( isEqual( C1_symdiff_C2, DGtal::functions::setops::operator|(C1_minus_C2 , C2_minus_C1) ) );
90  REQUIRE( isEqual( DGtal::functions::setops::operator|(DGtal::functions::setops::operator|(C1_minus_C2 , C1_intersection_C2) , C2_minus_C1), C1_union_C2 ) );
91  REQUIRE( isSubset( C1_minus_C2, C1 ) );
92  REQUIRE( ! isSubset( C1_minus_C2, C2 ) );
93  REQUIRE( isSubset( C2_minus_C1, C2 ) );
94  REQUIRE( ! isSubset( C2_minus_C1, C1 ) );
95  REQUIRE( isSubset( C1, C1_union_C2 ) );
96  REQUIRE( isSubset( C2, C1_union_C2 ) );
97  REQUIRE( isSubset( C1_intersection_C2, C1 ) );
98  REQUIRE( isSubset( C1_intersection_C2, C2 ) );
99  REQUIRE( isSubset( C1_symdiff_C2, C1_union_C2 ) );
100  REQUIRE( ! isSubset( C1, C1_symdiff_C2 ) );
101  REQUIRE( ! isSubset( C2, C1_symdiff_C2 ) );
102 }
103 
104 
105 static const int NB = 10000;
106 static std::default_random_engine generator;
107 static std::uniform_int_distribution<int> distribution(1,NB);
108 
109 int randomNB( )
110 {
111  return distribution(generator);
112 }
113 
115 TEMPLATE_TEST_CASE( "SetFunctions benchmark operator | (sequences)", "[set_functions]",
116  std::vector<int> )
117 {
118  typedef typename TestType::size_type Size;
119  std::set<int> S1;
120  std::set<int> S2;
121  for ( int i = 0; i < NB; ++i ) S1.insert( randomNB( ) );
122  for ( int i = 0; i < NB; ++i ) S2.insert( randomNB( ) );
123  TestType A( S1.begin(), S1.end() );
124  TestType B( S2.begin(), S2.end() );
125  TestType AorB;
126 
127  std::random_shuffle( A.begin(), A.end() );
128  std::random_shuffle( B.begin(), B.end() );
129 
130  SECTION( " - benchmark set operators |" )
131  {
133  }
134  Size size_A = A.size();
135  Size size_B = B.size();
136  Size size_AorB = AorB.size();
137  REQUIRE( size_AorB >= std::max( size_A, size_B ) );
138 }
139 
140 TEMPLATE_TEST_CASE( "SetFunctions benchmark operator | (sets)", "[set_functions]",
141  std::set<int>,
142  std::unordered_set<int> )
143 {
144  typedef typename TestType::size_type Size;
145  std::set<int> S1;
146  for ( int i = 0; i < NB; ++i ) S1.insert( randomNB( ) );
147  std::set<int> S2;
148  for ( int i = 0; i < NB; ++i ) S2.insert( randomNB( ) );
149  TestType A( S1.begin(), S1.end() );
150  TestType B( S2.begin(), S2.end() );
151  TestType AorB;
152 
153  SECTION( " - benchmark set operators |" )
154  {
156  }
157  Size size_A = A.size();
158  Size size_B = B.size();
159  Size size_AorB = AorB.size();
160  REQUIRE( size_AorB >= std::max( size_A, size_B ) );
161 }
162 
164 TEMPLATE_TEST_CASE( "SetFunctions benchmark operator & (sequences)", "[set_functions]",
165  std::vector<int> )
166 {
167  typedef typename TestType::size_type Size;
168  std::set<int> S1;
169  for ( int i = 0; i < NB; ++i ) S1.insert( randomNB( ) );
170  std::set<int> S2;
171  for ( int i = 0; i < NB; ++i ) S2.insert( randomNB( ) );
172  TestType A( S1.begin(), S1.end() );
173  TestType B( S2.begin(), S2.end() );
174  TestType AandB;
175 
176  std::random_shuffle( A.begin(), A.end() );
177  std::random_shuffle( B.begin(), B.end() );
178 
179  SECTION( " - benchmark set operators &" )
180  {
181  AandB = A & B;
182  }
183  Size size_A = A.size();
184  Size size_B = B.size();
185  Size size_AandB = AandB.size();
186  REQUIRE( size_AandB <= std::min( size_A, size_B ) );
187 }
188 
189 TEMPLATE_TEST_CASE( "SetFunctions benchmark operator & (sets)", "[set_functions]",
190  std::set<int>,
191  std::unordered_set<int> )
192 {
193  typedef typename TestType::size_type Size;
194  std::set<int> S1;
195  for ( int i = 0; i < NB; ++i ) S1.insert( randomNB( ) );
196  std::set<int> S2;
197  for ( int i = 0; i < NB; ++i ) S2.insert( randomNB( ) );
198  TestType A( S1.begin(), S1.end() );
199  TestType B( S2.begin(), S2.end() );
200  TestType AandB;
201 
202  SECTION( " - benchmark set operators &" )
203  {
204  AandB = A & B;
205  }
206  Size size_A = A.size();
207  Size size_B = B.size();
208  Size size_AandB = AandB.size();
209  REQUIRE( size_AandB <= std::min( size_A, size_B ) );
210 }
211 
212 
214 TEMPLATE_TEST_CASE( "SetFunctions benchmark operator - (sequences)", "[set_functions]",
215  std::vector<int> )
216 {
217  typedef typename TestType::size_type Size;
218  std::set<int> S1;
219  for ( int i = 0; i < NB; ++i ) S1.insert( randomNB( ) );
220  std::set<int> S2;
221  for ( int i = 0; i < NB; ++i ) S2.insert( randomNB( ) );
222  TestType A( S1.begin(), S1.end() );
223  TestType B( S2.begin(), S2.end() );
224  TestType AminusB;
225 
226  std::random_shuffle( A.begin(), A.end() );
227  std::random_shuffle( B.begin(), B.end() );
228 
229  SECTION( " - benchmark set operators -" )
230  {
231  AminusB = A - B;
232  }
233  Size size_A = A.size();
234  Size size_B = B.size();
235  Size size_AminusB = AminusB.size();
236  REQUIRE( size_AminusB <= size_A );
237  boost::ignore_unused_variable_warning(size_B);
238 }
239 
240 TEMPLATE_TEST_CASE( "SetFunctions benchmark operator - (sets)", "[set_functions]",
241  std::set<int>,
242  std::unordered_set<int> )
243 {
244  typedef typename TestType::size_type Size;
245  std::set<int> S1;
246  for ( int i = 0; i < NB; ++i ) S1.insert( randomNB( ) );
247  std::set<int> S2;
248  for ( int i = 0; i < NB; ++i ) S2.insert( randomNB( ) );
249  TestType A( S1.begin(), S1.end() );
250  TestType B( S2.begin(), S2.end() );
251  TestType AminusB;
252 
253  SECTION( " - benchmark set operators -" )
254  {
255  AminusB = A - B;
256  }
257  Size size_A = A.size();
258  Size size_B = B.size();
259  Size size_AminusB = AminusB.size();
260  REQUIRE( size_AminusB <= size_A );
261  boost::ignore_unused_variable_warning(size_B);
262 }
263 
264 
266 TEMPLATE_TEST_CASE( "SetFunctions benchmark operator ^ (sequences)", "[set_functions]",
267  std::vector<int> )
268 {
269  typedef typename TestType::size_type Size;
270  std::set<int> S1;
271  for ( int i = 0; i < NB; ++i ) S1.insert( randomNB( ) );
272  std::set<int> S2;
273  for ( int i = 0; i < NB; ++i ) S2.insert( randomNB( ) );
274  TestType A( S1.begin(), S1.end() );
275  TestType B( S2.begin(), S2.end() );
276  TestType AxorB;
277 
278  std::random_shuffle( A.begin(), A.end() );
279  std::random_shuffle( B.begin(), B.end() );
280 
281  SECTION( " - benchmark set operators ^" )
282  {
283  AxorB = A ^ B;
284  }
285  Size size_A = A.size();
286  Size size_B = B.size();
287  Size size_AxorB = AxorB.size();
288  REQUIRE( size_AxorB <= std::max( size_A, size_B ) );
289 }
290 
291 TEMPLATE_TEST_CASE( "SetFunctions benchmark operator ^ (sets)", "[set_functions]",
292  std::set<int>,
293  std::unordered_set<int> )
294 {
295  typedef typename TestType::size_type Size;
296  std::set<int> S1;
297  for ( int i = 0; i < NB; ++i ) S1.insert( randomNB( ) );
298  std::set<int> S2;
299  for ( int i = 0; i < NB; ++i ) S2.insert( randomNB( ) );
300  TestType A( S1.begin(), S1.end() );
301  TestType B( S2.begin(), S2.end() );
302  TestType AxorB;
303 
304  SECTION( " - benchmark set operators ^" )
305  {
306  AxorB = A ^ B;
307  }
308  Size size_A = A.size();
309  Size size_B = B.size();
310  Size size_AxorB = AxorB.size();
311  REQUIRE( size_AxorB <= std::max( size_A, size_B ) );
312 }
313 
314 
315 
316 
Container operator|(const Container &S1, const Container &S2)
functions namespace gathers all DGtal functionsxs.
Definition: SetFunctions.h:768
bool isEqual(const Container &S1, const Container &S2)
Definition: SetFunctions.h:789
bool isSubset(const Container &S1, const Container &S2)
Definition: SetFunctions.h:845
DGtal is the top-level namespace which contains all DGtal functions and types.
int max(int a, int b)
HalfEdgeDataStructure::Size Size
TEMPLATE_TEST_CASE("Star shapes", "move() method", AccFlower, Astroid, Ball, Ellipse, Flower, Lemniscate, NGon, BallImplicit, HyperCubeImplicit, Norm1BallImplicit, RoundedHyperCubeImplicit)
SECTION("Testing constant forward iterators")
REQUIRE(domain.isInside(aPoint))