DGtal 1.4.0
Loading...
Searching...
No Matches
testLatticeSetByIntervals.cpp
Go to the documentation of this file.
1
31#include <iostream>
32#include <vector>
33#include <algorithm>
34#include "DGtal/base/Common.h"
35#include "DGtal/helpers/StdDefs.h"
36#include "DGtal/kernel/LatticeSetByIntervals.h"
37#include "DGtalCatch.h"
39
40using namespace std;
41using namespace DGtal;
42
43
45// Functions for testing class LatticeSetByIntervals.
47
48SCENARIO( "LatticeSetByIntervals< int > unit tests", "[lattice_set]" )
49{
51 typedef Space::Point Point;
52 typedef LatticeSetByIntervals< Space > LatticeSet;
53
54 WHEN( "Inserting many points" ) {
55 std::set< Point > S;
56 LatticeSet L;
57 unsigned int nb = 10000;
58 for ( unsigned int i = 0; i < nb; i++ )
59 {
60 Point p( rand() % 20, rand() % 20, rand() % 20 );
61 S.insert( p );
62 L.insert( p );
63 }
64 auto mem_L = L.memory_usage();
65 auto mem_S = ( L.size() * ( sizeof( Point ) + sizeof( void* ) ) );
66 auto vec_L = L.toPointRange();
67 std::sort( vec_L.begin(), vec_L.end() );
68 std::vector< Point > vec_S( S.begin(), S.end() );
69 for ( size_t i = 0; i < vec_L.size(); i++ )
70 {
71 if ( vec_L[ i ] != vec_S[ i ] )
72 std::cout << i << " " << vec_L[ i ] << " != " << vec_S[ i ]
73 << std::endl;
74 }
75 THEN( "The lattice set contains the same points as std::set< Point >" ) {
76 REQUIRE( S.size() == L.size() );
77 REQUIRE( L.size() == vec_L.size() );
78 REQUIRE( std::equal( vec_L.begin(), vec_L.end(), vec_S.begin() ) );
79 }
80 THEN( "The lattice set is less costly to store than std::set< Point >" ) {
81 REQUIRE( mem_L < mem_S );
82 }
83 THEN( "One can create directly a lattice set from a range" ) {
84 LatticeSet L2( S.begin(), S.end() );
85 REQUIRE( L2.size() == S.size() );
86 }
87 THEN( "When erasing all elements from the lattice set, it becomes empty" ) {
88 LatticeSet L2( S.begin(), S.end() );
89 for ( auto&& p : S )
90 L2.erase( p );
91 REQUIRE( L2.empty() );
92 REQUIRE( L2.data().empty() );
93 }
94 }
95}
96
97SCENARIO( "LatticeSetByIntervals< int > set operations tests", "[lattice_set]" )
98{
100 typedef Space::Point Point;
101 typedef LatticeSetByIntervals< Space > LatticeSet;
102
103 std::set< Point > X,Y;
104 int nb = 300000;
105 int R = 50;
106 for ( auto i = 0; i < nb; i++ )
107 {
108 Point p( rand() % R, rand() % R, rand() % R );
109 X.insert( p );
110 Point q( rand() % R, rand() % R, rand() % R );
111 Y.insert( q );
112 }
113 LatticeSet A( X.cbegin(), X.cend() );
114 LatticeSet B( Y.cbegin(), Y.cend() );
115 std::vector< Point > X_cup_Y, X_cap_Y, X_minus_Y, X_delta_Y;
116 Clock c;
117 c.startClock();
118 std::set_union( X.cbegin(), X.cend(), Y.cbegin(), Y.cend(),
119 std::back_inserter( X_cup_Y ) );
120 std::set_intersection( X.cbegin(), X.cend(), Y.cbegin(), Y.cend(),
121 std::back_inserter( X_cap_Y ) );
122 std::set_difference( X.cbegin(), X.cend(), Y.cbegin(), Y.cend(),
123 std::back_inserter( X_minus_Y ) );
124 std::set_symmetric_difference( X.cbegin(), X.cend(), Y.cbegin(), Y.cend(),
125 std::back_inserter( X_delta_Y ) );
126 auto tv = c.stopClock();
127
128 c.startClock();
129 LatticeSet A_cup_B = A.set_union( B );
130 LatticeSet A_cap_B = A.set_intersection( B );
131 LatticeSet A_minus_B = A.set_difference( B );
132 LatticeSet A_delta_B = A.set_symmetric_difference( B );
133 auto tl = c.stopClock();
134 THEN( "Lattice sets can be constructed from sets" ) {
135 REQUIRE( X.size() == A.size() );
136 REQUIRE( Y.size() == B.size() );
137 }
138 THEN( "Set operations on lattice sets are correct" ) {
139 REQUIRE( X_cup_Y.size() == A_cup_B.size() );
140 REQUIRE( X_cap_Y.size() == A_cap_B.size() );
141 REQUIRE( X_minus_Y.size() == A_minus_B.size() );
142 REQUIRE( X_delta_Y.size() == A_delta_B.size() );
143 }
144 THEN( "Set operations on lattice sets are faster" ) {
145 REQUIRE( tl < tv );
146 }
147 THEN( "Inclusions are correct" ) {
148 REQUIRE( ! A.equals( B ) );
149 REQUIRE( A_cup_B.equals( A_cup_B ) );
150 REQUIRE( A_cup_B.includes( A_cup_B ) );
151 REQUIRE( A_cup_B.includes( A ) );
152 REQUIRE( ! A_cup_B.equals( A ) );
153 REQUIRE( ! A.includes( A_cup_B ) );
154 REQUIRE( A_cup_B.includes( B ) );
155 REQUIRE( ! B.includes( A_cup_B ) );
156 REQUIRE( ! A_cup_B.equals( B ) );
157 REQUIRE( A_cup_B.includes( A_cap_B ) );
158 REQUIRE( ! A_cap_B.includes( A_cup_B ) );
159 REQUIRE( A.includes( A_minus_B ) );
160 REQUIRE( ! A_minus_B.includes( A ) );
161 REQUIRE( A_cup_B.includes( A_delta_B ) );
162 REQUIRE( ! A_delta_B.includes( A_cup_B ) );
163 REQUIRE( ! A.includes( A_delta_B ) );
164 REQUIRE( ! B.includes( A_delta_B ) );
165 }
166}
167
168SCENARIO( "LatticeSetByIntervals< int > 3d topology operations tests", "[lattice_set][3d]" )
169{
170 typedef DGtal::Z3i::Space Space;
171 typedef Space::Point Point;
172 typedef LatticeSetByIntervals< Space > LatticeSet;
173 WHEN( "Computing the star of n isolated points, the number of cells is 27*n, and taking its skel brings back the n points" ) {
174 std::vector< Point > X { {0,0,0}, {10,0,0}, {5,5,0}, {0,0,8} };
175 LatticeSet P( X.cbegin(), X.cend() );
176 auto StarP = P.starOfPoints();
177 auto SkelStarP = StarP.skeletonOfCells();
178 REQUIRE( P.size() == X.size() );
179 REQUIRE( StarP.size() == 27 * X.size() );
180 REQUIRE( SkelStarP.size() == X.size() );
181 }
182 WHEN( "Computing the star of n points consecutive along space diagonal, the number of cells is 26*n+1, and taking its skel brings back the n points" ) {
183 std::vector< Point > X { {0,0,0}, {1,1,1}, {2,2,2}, {3,3,3} };
184 LatticeSet P( X.cbegin(), X.cend() );
185 auto StarP = P.starOfPoints();
186 auto SkelStarP = StarP.skeletonOfCells();
187 REQUIRE( P.size() == X.size() );
188 REQUIRE( StarP.size() == ( 26 * X.size() + 1 ) );
189 REQUIRE( SkelStarP.size() == X.size() );
190 }
191 WHEN( "Computing the star of n points consecutive along any axis, the number of cells is 18*n+9, and taking its skel brings back the n points" ) {
192 std::vector< Point > X { {0,0,0}, {1,0,0}, {2,0,0}, {3,0,0} };
193 for ( Dimension a = 0; a < 3; a++ )
194 {
195 LatticeSet P( X.cbegin(), X.cend(), a );
196 auto StarP = P.starOfPoints();
197 auto SkelStarP = StarP.skeletonOfCells();
198 CAPTURE( StarP.toPointRange() );
199 CAPTURE( SkelStarP.toPointRange() );
200 CAPTURE( a );
201 REQUIRE( P.size() == X.size() );
202 REQUIRE( StarP.size() == ( 18 * X.size() + 9 ) );
203 REQUIRE( SkelStarP.size() == X.size() );
204 }
205 }
206 WHEN( "Computing the skeleton of the star of a random set of points X, Skel(Star(X)) = X" ) {
207 std::vector< Point > X;
208 for ( int i = 0; i < 1000; i++ )
209 X.push_back( Point( rand() % 10, rand() % 10, rand() % 10 ) );
210 for ( Dimension a = 0; a < 3; a++ )
211 {
212 LatticeSet P( X.cbegin(), X.cend(), a );
213 auto StarP = P.starOfPoints();
214 auto SkelStarP = StarP.skeletonOfCells();
215 REQUIRE( SkelStarP.size() == P.size() );
216 }
217 }
218 WHEN( "Computing the skeleton of an open random set of cells O, O = Star(O), Skel(O) subset O and O = Star(Skel(O))" ) {
219 std::vector< Point > X;
220 for ( int i = 0; i < 50; i++ )
221 X.push_back( Point( rand() % 5, rand() % 5, rand() % 5 ) );
222 for ( Dimension a = 0; a < 3; a++ )
223 {
224 LatticeSet C( X.cbegin(), X.cend(), a );
225 auto O = C.starOfCells();
226 auto StarO = O.starOfCells();
227 auto SkelO = O.skeletonOfCells();
228 auto StarSkelO = SkelO.starOfCells();
229 CAPTURE( O.axis() );
230 CAPTURE( O.size() );
231 CAPTURE( SkelO.size() );
232 CAPTURE( StarSkelO.size() );
233 CAPTURE( StarO.size() );
234 REQUIRE( O.includes( SkelO ) );
235 REQUIRE( StarSkelO.equals( O ) );
236 REQUIRE( StarO.equals( O ) );
237 }
238 }
239 WHEN( "Computing the skeleton of a random set of cells C, C subset Star(C), Skel(C) subset C, C subset Star(Skel(C)), Star(C) = Star(Skel(Star(C)))" ) {
240 std::vector< Point > X;
241 for ( int i = 0; i < 50; i++ )
242 X.push_back( Point( rand() % 5, rand() % 5, rand() % 5 ) );
243 for ( Dimension a = 0; a < 3; a++ )
244 {
245 LatticeSet C( X.cbegin(), X.cend(), a );
246 auto StarC = C.starOfCells();
247 auto SkelC = C.skeletonOfCells();
248 auto StarSkelC = SkelC.starOfCells();
249 auto StarSkelStarC = StarC.skeletonOfCells().starOfCells();
250 CAPTURE( C.axis() );
251 CAPTURE( C.size() );
252 CAPTURE( SkelC.size() );
253 CAPTURE( StarSkelC.size() );
254 CAPTURE( StarC.size() );
255 CAPTURE( StarSkelStarC.size() );
256 REQUIRE( StarC.includes( C ) );
257 REQUIRE( C.includes( SkelC) );
258 REQUIRE( StarSkelC.includes( C ) );
259 REQUIRE( StarSkelStarC.equals( StarC ) );
260 }
261 }
262}
263
264SCENARIO( "LatticeSetByIntervals< int > 2d topology operations tests", "[lattice_set][2d]" )
265{
266 typedef DGtal::Z2i::Space Space;
267 typedef Space::Point Point;
268 typedef LatticeSetByIntervals< Space > LatticeSet;
269 WHEN( "Computing the skeleton of an open random set of cells O, O = Star(O), Skel(O) subset O and O = Star(Skel(O))" ) {
270 std::vector< Point > X;
271 for ( int i = 0; i < 30; i++ )
272 X.push_back( Point( rand() % 10, rand() % 10 ) );
273 for ( Dimension a = 0; a < 2; a++ )
274 {
275 LatticeSet C( X.cbegin(), X.cend(), a );
276 auto O = C.starOfCells();
277 auto StarO = O.starOfCells();
278 auto SkelO = O.skeletonOfCells();
279 auto StarSkelO = SkelO.starOfCells();
280 auto debug = StarO.set_symmetric_difference( O );
281 CAPTURE( O.axis() );
282 CAPTURE( O.size() );
283 CAPTURE( StarO.size() );
284 CAPTURE( SkelO.size() );
285 CAPTURE( StarSkelO.size() );
286 CAPTURE( O.toPointRange() );
287 CAPTURE( StarO.toPointRange() );
288 CAPTURE( SkelO.toPointRange() );
289 CAPTURE( StarSkelO.toPointRange() );
290 CAPTURE( debug.toPointRange() );
291 REQUIRE( O.includes( SkelO ) );
292 REQUIRE( StarSkelO.equals( O ) );
293 REQUIRE( StarO.equals( O ) );
294 }
295 }
296 WHEN( "Computing the skeleton of a random set of cells C, C subset Star(C), Skel(C) subset C, C subset Star(Skel(C)), Star(C) = Star(Skel(Star(C)))" ) {
297 std::vector< Point > X;
298 for ( int i = 0; i < 10; i++ )
299 X.push_back( Point( rand() % 10, rand() % 10 ) );
300 for ( Dimension a = 0; a < 2; a++ )
301 {
302 LatticeSet C( X.cbegin(), X.cend(), a );
303 auto StarC = C.starOfCells();
304 auto SkelC = C.skeletonOfCells();
305 auto StarSkelC = SkelC.starOfCells();
306 auto StarSkelStarC = StarC.skeletonOfCells().starOfCells();
307 CAPTURE( C.axis() );
308 CAPTURE( C.size() );
309 CAPTURE( SkelC.size() );
310 CAPTURE( StarSkelC.size() );
311 CAPTURE( StarC.size() );
312 CAPTURE( StarSkelStarC.size() );
313 REQUIRE( StarC.includes( C ) );
314 REQUIRE( C.includes( SkelC) );
315 REQUIRE( StarSkelC.includes( C ) );
316 REQUIRE( StarSkelStarC.equals( StarC ) );
317 }
318 WHEN( "Computing the extrema of a set of cells C, extremas are correct" ) {
319 std::vector< Point > XX;
320 XX.push_back( Point(10,-2) );
321 XX.push_back( Point(5,5) );
322 XX.push_back( Point(4,5) );
323 XX.push_back( Point(3,5) );
324 XX.push_back( Point(2,1) );
325 XX.push_back( Point(2,3) );
326 XX.push_back( Point(1,1) );
327 XX.push_back( Point(-2,3) );
328 XX.push_back( Point(-3,2) );
329 LatticeSet C( XX.cbegin(), XX.cend(), 0 );
330 auto ExtrC = C.extremaOfCells();
331 CAPTURE( C.toPointRange() );
332 CAPTURE( ExtrC );
333 REQUIRE( ExtrC.size() == 14 );
334 }
335 }
336}
void startClock()
DGtal is the top-level namespace which contains all DGtal functions and types.
DGtal::uint32_t Dimension
Definition Common.h:136
STL namespace.
MyPointD Point
CAPTURE(thicknessHV)
REQUIRE(domain.isInside(aPoint))
SCENARIO("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")