DGtal  1.4.beta
testPointVector.cpp
Go to the documentation of this file.
1 
32 #include <cstdio>
33 #include <cmath>
34 #include <iostream>
35 #include <fstream>
36 #include <vector>
37 #include <type_traits>
38 #include <functional>
39 
40 #include "DGtal/base/Common.h"
41 #include "DGtal/kernel/PointVector.h"
42 
43 #include "DGtalCatch.h"
44 
45 using namespace DGtal;
46 using namespace std;
47 
48 // Compare the value of the two parameters and also their component type.
49 #define COMPARE_VALUE_AND_TYPE(expr, check) \
50  REQUIRE( (expr) == (check) ); \
51  REQUIRE( ( std::is_same<decltype(expr)::Component, decltype(check)::Component>::value ) );
52 
53 TEST_CASE( "2D Point Vector Unit tests" )
54 {
55  using Real = double;
56  using Integer = DGtal::int32_t;
57 
58  typedef PointVector<2, Integer> Point2D;
59  typedef PointVector<2, Real> RealPoint2D;
60  typedef PointVector<3, Integer> Point3D;
62 
63  Integer t1[] = {1,2};
64  Integer t2[] = {5,4};
65  Real t3[] = {1.5,2.5};
66  Real t4[] = {5.5,4.5};
67 
68  Point2D p1( t1 );
69  Point2D p2( t2 );
70  RealPoint2D p3(t3);
71  RealPoint2D p4(t4);
72 
73  Point3D p1_3d( p1[0], p1[1] );
74  Point3D p2_3d( p2[0], p2[1] );
75  RealPoint3D p3_3d( p3[0], p3[1] );
76  RealPoint3D p4_3d( p4[0], p4[1] );
77 
78  SECTION("Cross products with integers")
79  {
80  COMPARE_VALUE_AND_TYPE( p1.crossProduct(p2), p1_3d.crossProduct(p2_3d) );
81  COMPARE_VALUE_AND_TYPE( crossProduct(p1, p2), crossProduct(p1_3d, p2_3d) );
82  COMPARE_VALUE_AND_TYPE( p2.crossProduct(p1), p2_3d.crossProduct(p1_3d) );
83  COMPARE_VALUE_AND_TYPE( crossProduct(p2, p1), crossProduct(p2_3d, p1_3d) );
84  }
85 
86  SECTION("Cross products with reals")
87  {
88  COMPARE_VALUE_AND_TYPE( p3.crossProduct(p4), p3_3d.crossProduct(p4_3d) );
89  COMPARE_VALUE_AND_TYPE( crossProduct(p3, p4), crossProduct(p3_3d, p4_3d) );
90  COMPARE_VALUE_AND_TYPE( p4.crossProduct(p3), p4_3d.crossProduct(p3_3d) );
91  COMPARE_VALUE_AND_TYPE( crossProduct(p4, p3), crossProduct(p4_3d, p3_3d) );
92  }
93 
94  SECTION("Cross products with mixed integers/reals")
95  {
96  COMPARE_VALUE_AND_TYPE( p1.crossProduct(p3), p1_3d.crossProduct(p3_3d) );
97  COMPARE_VALUE_AND_TYPE( crossProduct(p1, p3), crossProduct(p1_3d, p3_3d) );
98  COMPARE_VALUE_AND_TYPE( p3.crossProduct(p1), p3_3d.crossProduct(p1_3d) );
99  COMPARE_VALUE_AND_TYPE( crossProduct(p3, p1), crossProduct(p3_3d, p1_3d) );
100  }
101  SECTION("Access data() of internal container")
102  {
103  const auto d = p1_3d.data();
104  CHECK(d[0] == p1[0]);
105  CHECK(d[1] == p1[1]);
106  }
107 }
108 
109 TEST_CASE( "3D Point Vector Unit tests" )
110 {
111  using Real = double;
112  using Integer = DGtal::int32_t;
113 
116 
117  Integer t1[] = {1,2,3};
118  Integer t2[] = {5,4,3};
119  Real t3[] = {1.5,2.5,3.5};
120  Real t4[] = {5.5,4.5,3.5};
121 
122  Point p1( t1 );
123  Point p2( t2 );
124  RealPoint p3(t3);
125  RealPoint p4(t4);
126 
127  SECTION("Cross products with integers")
128  {
129  COMPARE_VALUE_AND_TYPE( p1.crossProduct(p2), Point(-6, 12, -6) );
130  COMPARE_VALUE_AND_TYPE( crossProduct(p1, p2), Point(-6, 12, -6) );
131  COMPARE_VALUE_AND_TYPE( p2.crossProduct(p1), Point(6, -12, 6) );
132  COMPARE_VALUE_AND_TYPE( crossProduct(p2, p1), Point(6, -12, 6) );
133  }
134 
135  SECTION("Cross products with reals")
136  {
137  COMPARE_VALUE_AND_TYPE( p3.crossProduct(p4), RealPoint(-7., 14., -7.) );
138  COMPARE_VALUE_AND_TYPE( crossProduct(p3, p4), RealPoint(-7., 14., -7.) );
139  COMPARE_VALUE_AND_TYPE( p4.crossProduct(p3), RealPoint(7., -14., 7.) );
140  COMPARE_VALUE_AND_TYPE( crossProduct(p4, p3), RealPoint(7., -14., 7.) );
141  }
142 
143  SECTION("Cross products with mixed integers/reals")
144  {
145  COMPARE_VALUE_AND_TYPE( p1.crossProduct(p3), RealPoint(-0.5, 1., -0.5) );
146  COMPARE_VALUE_AND_TYPE( crossProduct(p1, p3), RealPoint(-0.5, 1., -0.5) );
147  COMPARE_VALUE_AND_TYPE( p3.crossProduct(p1), RealPoint(0.5, -1., 0.5) );
148  COMPARE_VALUE_AND_TYPE( crossProduct(p3, p1), RealPoint(0.5, -1., 0.5) );
149  }
150 }
151 
152 TEST_CASE( "4D Point Vector Unit tests" )
153 {
154  using Real = double;
155  using Integer = DGtal::int32_t;
156 
159 
160  const Real pi = std::acos(Real(-1));
161 
162  Integer t1[] = {1,2,3,4};
163  Integer t2[] = {5,4,3,2};
164  Real t3[] = {1.0,-1.0,2.0,-2.0};
165  Real t4[] = {5.5,-4.5,3.5,2.5};
166 
167  Point p1( t1 );
168  Point p1bis( t1 );
169  Point p2( t2 );
170  RealPoint p3(t3);
171  RealPoint p4(t4);
172  RealPoint p1r(p1);
173  RealPoint p2r(p2);
174 
175  SECTION("Construction")
176  {
177  REQUIRE( p1 == Point( {1, 2, 3, 4} ) );
178  REQUIRE( p1r == RealPoint( {1., 2., 3., 4.} ) );
179 
180  REQUIRE( p1 == Point( p1r ) );
181  REQUIRE( p1 == Point( RealPoint( {0.5, 2.1, 3.1, 3.9} ), DGtal::functors::Round<>() ) );
182  REQUIRE( p1 == Point( Point(0, 0, 1, 3), Point(1, 2, 2, 1), std::plus<Integer>() ) );
183  }
184 
185  SECTION("Assignments")
186  {
187  Point dummy1;
188  dummy1 = p1;
189  REQUIRE( p1 == dummy1 );
190 
191  Point dummy2(1, 3, 3, 5);
192  dummy2.partialCopy( Point(0, 2, 0, 4), {1, 3} );
193  REQUIRE( p1 == dummy2 );
194 
195  Point dummy3(2, 2, 1, 4);
196  dummy3.partialCopyInv( Point(1, 0, 3, 0), {1, 3} );
197  REQUIRE( p1 == dummy3 );
198 
199  RealPoint dummy1r;
200  dummy1r = p1;
201  REQUIRE( p1r == dummy1r );
202 
203  RealPoint dummy2r(1, 3, 3, 5);
204  dummy2r.partialCopy( Point(0, 2, 0, 4), {1, 3} );
205  REQUIRE( p1r == dummy2r );
206 
207  RealPoint dummy3r(2, 2, 1, 4);
208  dummy3r.partialCopyInv( Point(1, 0, 3, 0), {1, 3} );
209  REQUIRE( p1r == dummy3r );
210 
211  Point dummy4(1, 3, 3, 5);
212  dummy4.partialCopy( RealPoint(0, 1.5, 0, 4.1), {1, 3}, DGtal::functors::Round<>() );
213  REQUIRE( p1 == dummy4 );
214 
215  Point dummy5(2, 2, 1, 4);
216  dummy5.partialCopyInv( RealPoint(1.1, 0, 2.5, 0), {1, 3}, DGtal::functors::Round<>() );
217  REQUIRE( p1 == dummy5 );
218  }
219 
220  SECTION("Comparisons")
221  {
222  // Partial equality
223  REQUIRE( p1.partialEqual( RealPoint(0, 2, 0, 4), {1, 3} ) );
224  REQUIRE( ! p1.partialEqual( RealPoint(0, 1, 0, 4), {1, 3} ) );
225  REQUIRE( p1.partialEqualInv( RealPoint(1, 0, 3, 0), {1, 3} ) );
226  REQUIRE( ! p1.partialEqualInv( RealPoint(1, 0, 2, 0), {1, 3} ) );
227 
228  // Two equal points of same type
229  REQUIRE( p1 == p1bis );
230  REQUIRE( p1bis == p1 );
231  REQUIRE( ! (p1 != p1bis) );
232  REQUIRE( ! (p1bis != p1) );
233  REQUIRE( p1 <= p1bis );
234  REQUIRE( p1 >= p1bis );
235  REQUIRE( p1bis >= p1 );
236  REQUIRE( p1bis <= p1 );
237  REQUIRE( ! (p1 < p1bis) );
238  REQUIRE( ! (p1 > p1bis) );
239  REQUIRE( ! (p1bis > p1) );
240  REQUIRE( ! (p1bis < p1) );
241 
242  // Two equal points of different types
243  REQUIRE( p1 == p1r );
244  REQUIRE( p1r == p1 );
245  REQUIRE( ! (p1 != p1r) );
246  REQUIRE( ! (p1r != p1) );
247  REQUIRE( p1 <= p1r );
248  REQUIRE( p1 >= p1r );
249  REQUIRE( p1r >= p1 );
250  REQUIRE( p1r <= p1 );
251  REQUIRE( ! (p1 < p1r) );
252  REQUIRE( ! (p1 > p1r) );
253  REQUIRE( ! (p1r > p1) );
254  REQUIRE( ! (p1r < p1) );
255 
256  // Two ordered points of same type
257  REQUIRE( ! (p1 == p2) );
258  REQUIRE( ! (p2 == p1) );
259  REQUIRE( p1 != p2 );
260  REQUIRE( p2 != p1 );
261  REQUIRE( p1 <= p2 );
262  REQUIRE( ! (p1 >= p2) );
263  REQUIRE( p2 >= p1 );
264  REQUIRE( ! (p2 <= p1) );
265  REQUIRE( p1 < p2 );
266  REQUIRE( ! (p1 > p2) );
267  REQUIRE( p2 > p1 );
268  REQUIRE( ! (p2 < p1) );
269 
270  // Two ordered points of different types
271  REQUIRE( ! (p1 == p2r) );
272  REQUIRE( ! (p2r == p1) );
273  REQUIRE( p1 != p2r );
274  REQUIRE( p2r != p1 );
275  REQUIRE( p1 <= p2r );
276  REQUIRE( ! (p1 >= p2r) );
277  REQUIRE( p2r >= p1 );
278  REQUIRE( ! (p2r <= p1) );
279  REQUIRE( p1 < p2r );
280  REQUIRE( ! (p1 > p2r) );
281  REQUIRE( p2r > p1 );
282  REQUIRE( ! (p2r < p1) );
283  }
284 
285  SECTION("Min/Max of vector components")
286  {
287  REQUIRE( p3.max() == 2.0 );
288  REQUIRE( p3.min() == -2.0 );
289  REQUIRE( *p3.maxElement() == 2.0 );
290  REQUIRE( *p3.minElement() == -2.0 );
291  }
292 
293  Point aPoint;
294  aPoint[ 3 ] = 0;
295  aPoint[ 2 ] = 2;
296  aPoint[ 1 ] = -1;
297  aPoint[ 0 ] = 3;
298 
299  SECTION("Testing norms")
300  {
301  RealPoint normalized = aPoint.getNormalized();
302  CAPTURE( normalized );
303  REQUIRE( aPoint.norm ( Point::L_1 ) == 6 );
304  REQUIRE( aPoint.norm ( Point::L_infty ) == 3 );
305  REQUIRE( aPoint.squaredNorm() == Approx(aPoint.norm()*aPoint.norm()) );
306  REQUIRE( normalized[0] == Approx( 0.801784) );
307  REQUIRE( normalized[1] == Approx( -0.267261) );
308  REQUIRE( normalized[2] == Approx( 0.534522) );
309  REQUIRE( normalized[3] == Approx( 0.0) );
310  }
311 
312  SECTION("PointVector Iterator")
313  {
314  PointVector<25,int> aPoint25;
315  for (unsigned int i=0;i<25;++i)
316  aPoint25[i] = i;
317 
318  int sum = 0;
319  for (PointVector<25,int>::ConstIterator it = aPoint25.begin() ; it != aPoint25.end(); ++it)
320  sum += (*it);
321 
322  CAPTURE(aPoint25);
323  CAPTURE(sum);
324  REQUIRE( sum == 300 );
325  }
326 
327  SECTION("Arithmetical operators with integers")
328  {
329  COMPARE_VALUE_AND_TYPE( p1 + p2, Point(6,6,6,6) );
330  COMPARE_VALUE_AND_TYPE( p1 - p2, Point(-4,-2,0,2) );
331  COMPARE_VALUE_AND_TYPE( p1 * p2, Point(5,8,9,8) );
332  COMPARE_VALUE_AND_TYPE( p2 / p1, Point(5,2,1,0) );
333 
334  COMPARE_VALUE_AND_TYPE( p1 + 2, Point(3,4,5,6) );
335  COMPARE_VALUE_AND_TYPE( 2 + p1, Point(3,4,5,6) );
336  COMPARE_VALUE_AND_TYPE( p1 - 2, Point(-1,0,1,2) );
337  COMPARE_VALUE_AND_TYPE( 2 - p1, Point(1,0,-1,-2) );
338  COMPARE_VALUE_AND_TYPE( p1 * 2, Point(2,4,6,8) );
339  COMPARE_VALUE_AND_TYPE( 2 * p1, Point(2,4,6,8) );
340  COMPARE_VALUE_AND_TYPE( p1 / 2, Point(0,1,1,2) );
341  COMPARE_VALUE_AND_TYPE( 2 / p1, Point(2,1,0,0) );
342 
343  COMPARE_VALUE_AND_TYPE( -p1, Point(-1,-2,-3,-4) );
344 
345  p1 *= 2; COMPARE_VALUE_AND_TYPE( p1, Point(2,4,6,8) );
346  p1 += 2; COMPARE_VALUE_AND_TYPE( p1, Point(4,6,8,10) );
347  p1 -= 2; COMPARE_VALUE_AND_TYPE( p1, Point(2,4,6,8) );
348  p1 /= 2; COMPARE_VALUE_AND_TYPE( p1, Point(1,2,3,4) );
349 
350  p1 *= p2; COMPARE_VALUE_AND_TYPE( p1, Point(5,8,9,8) );
351  p1 += p2; COMPARE_VALUE_AND_TYPE( p1, Point(10,12,12,10) );
352  p1 -= p2; COMPARE_VALUE_AND_TYPE( p1, Point(5,8,9,8) );
353  p1 /= p2; COMPARE_VALUE_AND_TYPE( p1, Point(1,2,3,4) );
354  }
355 
356  SECTION("Other operators with integers")
357  {
358  COMPARE_VALUE_AND_TYPE( p1.inf(p2), Point(1,2,3,2) );
359  COMPARE_VALUE_AND_TYPE( p1.sup(p2), Point(5,4,3,4) );
360  COMPARE_VALUE_AND_TYPE( inf(p1, p2), Point(1,2,3,2) );
361  COMPARE_VALUE_AND_TYPE( sup(p1, p2), Point(5,4,3,4) );
362 
363  REQUIRE( p1.dot(p2) == 30 );
364  REQUIRE( dotProduct(p1, p2) == 30 );
365 
366  REQUIRE( p1.cosineSimilarity(p1) == Approx(0.).margin(0.000001));
367  REQUIRE( p1.cosineSimilarity(-p1) == Approx(pi).margin(0.000001));
368  REQUIRE( p1.cosineSimilarity( Point(-2,1,-4,3) ) == Approx(pi/2).margin(0.000001) );
369  REQUIRE( cosineSimilarity(p1, p1) == Approx(0.).margin(0.000001) );
370  REQUIRE( cosineSimilarity(p1, -p1) == Approx(pi).margin(0.000001) );
371  REQUIRE( cosineSimilarity(p1, Point(-2,1,-4,3)) == Approx(pi/2).margin(0.000001) );
372 
373  REQUIRE( p1.isLower(p2) == false );
374  REQUIRE( isLower(p1, p2) == false );
375  REQUIRE( p2.isUpper(p1) == false );
376  REQUIRE( isUpper(p2, p1) == false );
377  p1[3] = 2;
378  REQUIRE( p1.isLower(p2) == true );
379  REQUIRE( isLower(p1, p2) == true );
380  REQUIRE( p2.isUpper(p1) == true );
381  REQUIRE( isUpper(p2, p1) == true );
382  }
383 
384  SECTION("Arithmetical Operators with reals")
385  {
386  COMPARE_VALUE_AND_TYPE( p3 + p4, RealPoint(6.5,-5.5,5.5,0.5) );
387  COMPARE_VALUE_AND_TYPE( p3 - p4, RealPoint(-4.5,3.5,-1.5,-4.5) );
388  COMPARE_VALUE_AND_TYPE( p3 * p4, RealPoint(5.5,4.5,7.0,-5.0) );
389  COMPARE_VALUE_AND_TYPE( p4 / p3, RealPoint(5.5,4.5,1.75,-1.25) );
390 
391  COMPARE_VALUE_AND_TYPE( p3 + 2., RealPoint(3.,1.,4.,0.) );
392  COMPARE_VALUE_AND_TYPE( 2. + p3, RealPoint(3.,1.,4.,0.) );
393  COMPARE_VALUE_AND_TYPE( p3 - 2., RealPoint(-1.,-3.,0.,-4.) );
394  COMPARE_VALUE_AND_TYPE( 2. - p3, RealPoint(1.,3.,0.,4.) );
395  COMPARE_VALUE_AND_TYPE( p3 * 2., RealPoint(2.,-2.,4.,-4.) );
396  COMPARE_VALUE_AND_TYPE( 2. * p3, RealPoint(2.,-2.,4.,-4.) );
397  COMPARE_VALUE_AND_TYPE( p3 / 2., RealPoint(0.5,-0.5,1.,-1.) );
398  COMPARE_VALUE_AND_TYPE( 2. / p3, RealPoint(2.,-2.,1.,-1.) );
399 
400  COMPARE_VALUE_AND_TYPE( -p3, RealPoint(-1.,1.,-2.,2.) );
401 
402  p3 *= 2.5; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2.5, -2.5, 5., -5.) );
403  p3 += 2.5; COMPARE_VALUE_AND_TYPE( p3, RealPoint(5., 0., 7.5, -2.5) );
404  p3 -= 2.5; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2.5, -2.5, 5., -5.) );
405  p3 /= 2.5; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -1., 2., -2.) );
406 
407  p3 *= p4; COMPARE_VALUE_AND_TYPE( p3, RealPoint(5.5, 4.5, 7., -5.) );
408  p3 += p4; COMPARE_VALUE_AND_TYPE( p3, RealPoint(11, 0., 10.5, -2.5) );
409  p3 -= p4; COMPARE_VALUE_AND_TYPE( p3, RealPoint(5.5, 4.5, 7., -5.) );
410  p3 /= p4; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -1., 2., -2.) );
411  }
412 
413  SECTION("Other operators with reals")
414  {
415  COMPARE_VALUE_AND_TYPE( p3.inf(p4), RealPoint(1.,-4.5,2.,-2.) );
416  COMPARE_VALUE_AND_TYPE( p3.sup(p4), RealPoint(5.5,-1.,3.5,2.5) );
417  COMPARE_VALUE_AND_TYPE( inf(p3, p4), RealPoint(1.,-4.5,2.,-2.) );
418  COMPARE_VALUE_AND_TYPE( sup(p3, p4), RealPoint(5.5,-1.,3.5,2.5) );
419 
420  REQUIRE( p3.dot(p4) == 12. );
421  REQUIRE( dotProduct(p3, p4) == 12. );
422 
423  REQUIRE( p3.cosineSimilarity(p3) == Approx(0.).margin(0.000001) );
424  REQUIRE( p3.cosineSimilarity(-p3) == Approx(pi).margin(0.000001) );
425  REQUIRE( p3.cosineSimilarity( RealPoint(1.0,1.0,2.0,2.0) ) == Approx(pi/2).margin(0.000001) );
426  REQUIRE( cosineSimilarity(p3, p3) == Approx(0.).margin(0.000001) );
427  REQUIRE( cosineSimilarity(p3, -p3) == Approx(pi).margin(0.000001) );
428  REQUIRE( cosineSimilarity(p3, RealPoint(1.0,1.0,2.0,2.0)) == Approx(pi/2).margin(0.000001) );
429 
430  REQUIRE( p3.isLower(p4) == false );
431  REQUIRE( isLower(p3, p4) == false );
432  REQUIRE( p4.isUpper(p3) == false );
433  REQUIRE( isUpper(p4, p3) == false );
434  p4[1] = -p4[1];
435  REQUIRE( p3.isLower(p4) == true );
436  REQUIRE( isLower(p3, p4) == true );
437  REQUIRE( p4.isUpper(p3) == true );
438  REQUIRE( isUpper(p4, p3) == true );
439  }
440 
441  SECTION("Arithmetical Operators with mixed integers/reals")
442  {
443  COMPARE_VALUE_AND_TYPE( p1 + p4, RealPoint(6.5,-2.5,6.5,6.5) );
444  COMPARE_VALUE_AND_TYPE( p4 + p1, RealPoint(6.5,-2.5,6.5,6.5) );
445  COMPARE_VALUE_AND_TYPE( p1 - p4, RealPoint(-4.5,6.5,-0.5,1.5) );
446  COMPARE_VALUE_AND_TYPE( p4 - p1, RealPoint(4.5,-6.5,0.5,-1.5) );
447  COMPARE_VALUE_AND_TYPE( p1 * p4, RealPoint(5.5,-9.0,10.5,10.0) );
448  COMPARE_VALUE_AND_TYPE( p4 * p1, RealPoint(5.5,-9.0,10.5,10.0) );
449  COMPARE_VALUE_AND_TYPE( p1 / p3, RealPoint(1.,-2.,1.5,-2.0) );
450  COMPARE_VALUE_AND_TYPE( p3 / p1, RealPoint(1.,-0.5,2./3.,-0.5) );
451 
452  COMPARE_VALUE_AND_TYPE( p3 + 2, RealPoint(3.,1.,4.,0.) );
453  COMPARE_VALUE_AND_TYPE( 2 + p3, RealPoint(3.,1.,4.,0.) );
454  COMPARE_VALUE_AND_TYPE( p3 - 2, RealPoint(-1.,-3.,0.,-4.) );
455  COMPARE_VALUE_AND_TYPE( 2 - p3, RealPoint(1.,3.,0.,4.) );
456  COMPARE_VALUE_AND_TYPE( p3 * 2, RealPoint(2.,-2.,4.,-4.) );
457  COMPARE_VALUE_AND_TYPE( 2 * p3, RealPoint(2.,-2.,4.,-4.) );
458  COMPARE_VALUE_AND_TYPE( p3 / 2, RealPoint(0.5,-0.5,1.,-1.) );
459  COMPARE_VALUE_AND_TYPE( 2 / p3, RealPoint(2.,-2.,1.,-1.) );
460 
461  COMPARE_VALUE_AND_TYPE( p1 + 2.5, RealPoint(3.5,4.5,5.5,6.5) );
462  COMPARE_VALUE_AND_TYPE( 2.5 + p1, RealPoint(3.5,4.5,5.5,6.5) );
463  COMPARE_VALUE_AND_TYPE( p1 - 2.5, RealPoint(-1.5,-0.5,0.5,1.5) );
464  COMPARE_VALUE_AND_TYPE( 2.5 - p1, RealPoint(1.5,0.5,-0.5,-1.5) );
465  COMPARE_VALUE_AND_TYPE( p1 * 2.5, RealPoint(2.5,5.,7.5,10.) );
466  COMPARE_VALUE_AND_TYPE( 2.5 * p1, RealPoint(2.5,5.,7.5,10.) );
467  COMPARE_VALUE_AND_TYPE( p1 / 0.5, RealPoint(2.,4.,6.,8.) );
468  COMPARE_VALUE_AND_TYPE( 2. / p1, RealPoint(2.,1.,2./3.,0.5) );
469 
470  p3 *= 2; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2, -2, 4., -4.) );
471  p3 += 2; COMPARE_VALUE_AND_TYPE( p3, RealPoint(4., 0., 6., -2.) );
472  p3 -= 2; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2, -2, 4., -4.) );
473  p3 /= 2; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -1., 2., -2.) );
474 
475  p3 *= p1; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -2., 6., -8.) );
476  p3 += p1; COMPARE_VALUE_AND_TYPE( p3, RealPoint(2., 0., 9., -4.) );
477  p3 -= p1; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -2., 6., -8.) );
478  p3 /= p1; COMPARE_VALUE_AND_TYPE( p3, RealPoint(1., -1., 2., -2.) );
479  }
480 
481  SECTION("Other operators with mixed integers/reals")
482  {
483  COMPARE_VALUE_AND_TYPE( p1.inf(p3), RealPoint(1.,-1.,2.,-2.) );
484  COMPARE_VALUE_AND_TYPE( p3.inf(p1), RealPoint(1.,-1.,2.,-2.) );
485  COMPARE_VALUE_AND_TYPE( p1.sup(p3), RealPoint(1.,2.,3.,4.) );
486  COMPARE_VALUE_AND_TYPE( p3.sup(p1), RealPoint(1.,2.,3.,4.) );
487  COMPARE_VALUE_AND_TYPE( inf(p1, p3), RealPoint(1.,-1.,2.,-2.) );
488  COMPARE_VALUE_AND_TYPE( inf(p3, p1), RealPoint(1.,-1.,2.,-2.) );
489  COMPARE_VALUE_AND_TYPE( sup(p1, p3), RealPoint(1.,2.,3.,4.) );
490  COMPARE_VALUE_AND_TYPE( sup(p3, p1), RealPoint(1.,2.,3.,4.) );
491 
492  REQUIRE( p4.dot(p1) == 17.0 );
493  REQUIRE( dotProduct(p4, p1) == 17.0 );
494  REQUIRE( dotProduct(p1, p4) == 17.0 );
495 
496  REQUIRE( p1.cosineSimilarity(RealPoint(p1)) == Approx(0.).margin(0.000001) );
497  REQUIRE( p1.cosineSimilarity(-RealPoint(p1)) == Approx(pi).margin(0.000001) );
498  REQUIRE( p1.cosineSimilarity( RealPoint(-2,1,-4,3) ) == Approx(pi/2).margin(0.000001) );
499  REQUIRE( cosineSimilarity(p1, RealPoint(p1)) == Approx(0.).margin(0.000001) );
500  REQUIRE( cosineSimilarity(p1, -RealPoint(p1)) == Approx(pi).margin(0.000001) );
501  REQUIRE( cosineSimilarity(p1, RealPoint(-2,1,-4,3)) == Approx(pi/2).margin(0.000001) );
502 
503  REQUIRE( p3.cosineSimilarity(Point(1,-1,2,-2)) == Approx(0.).margin(0.000001) );
504  REQUIRE( p3.cosineSimilarity(-Point(1,-1,2,-2)) == Approx(pi).margin(0.000001) );
505  REQUIRE( p3.cosineSimilarity( Point(1,1,2,2) ) == Approx(pi/2).margin(0.000001) );
506  REQUIRE( cosineSimilarity(p3, Point(1,-1,2,-2)) == Approx(0.).margin(0.000001) );
507  REQUIRE( cosineSimilarity(p3, -Point(1,-1,2,-2)) == Approx(pi).margin(0.000001) );
508  REQUIRE( cosineSimilarity(p3, Point(1,1,2,2)) == Approx(pi/2).margin(0.000001) );
509 
510  REQUIRE( p2.isLower(p4) == false );
511  REQUIRE( isLower(p2, p4) == false );
512  REQUIRE( p4.isUpper(p2) == false );
513  REQUIRE( isUpper(p4, p2) == false );
514  p4[1] = -p4[1];
515  REQUIRE( p2.isLower(p4) == true );
516  REQUIRE( isLower(p2, p4) == true );
517  REQUIRE( p4.isUpper(p2) == true );
518  REQUIRE( isUpper(p4, p2) == true );
519  }
520 
521 }
522 
523 
524 TEST_CASE("Benchmarking","[.benchmark]")
525 {
526  using Integer = DGtal::int32_t;
528  Point p1 = {1,2,3,4};
529  Point p2 = {3,4,5,6};
530 
531  using Real = double;
532  typedef PointVector<3, Real> RPoint;
533  RPoint rp1 = {1,2,3,4};
534  RPoint rp2 = {3,4,5,6};
535 
536  CHECK(p1.dot(p2) == 26);
537  CHECK(rp1.dot(rp2) == Approx(26));
538 
539  BENCHMARK("Dot product int")
540  {
541  return p1.dot(p2);
542  };
543 
544  BENCHMARK("Dot product double (with int->double cast)")
545  {
546  return rp1.dot(p2);
547  };
548 
549  BENCHMARK("Dot product double")
550  {
551  return rp1.dot(rp2);
552  };
553 
554 }
555 
Component max() const
bool isLower(const PointVector< dim, OtherComponent, OtherStorage > &p) const
Return true if this point is below a given point.
auto dot(const PointVector< dim, OtherComponent, OtherStorage > &v) const -> decltype(DGtal::dotProduct(*this, v))
Dot product with a PointVector.
Iterator maxElement()
auto inf(const PointVector< dim, OtherComponent, OtherStorage > &aPoint) const -> decltype(DGtal::inf(*this, aPoint))
Implements the infimum (or greatest lower bound).
Self & partialCopy(const PointVector< dim, OtherComponent, OtherContainer > &pv, const std::vector< Dimension > &dimensions)
Partial copy of a given PointVector.
auto sup(const PointVector< dim, OtherComponent, OtherStorage > &aPoint) const -> decltype(DGtal::sup(*this, aPoint))
Implements the supremum (or least upper bound).
auto crossProduct(const PointVector< dim, OtherComponent, OtherStorage > &v) const -> decltype(DGtal::crossProduct(*this, v))
Cross product with a PointVector.
bool isUpper(const PointVector< dim, OtherComponent, OtherStorage > &p) const
Return true if this point is upper a given point.
Component min() const
Self & partialCopyInv(const PointVector< dim, OtherComponent, OtherContainer > &pv, const std::vector< Dimension > &dimensions)
Partial copy of a given PointVector.
Container::const_iterator ConstIterator
Constant iterator type.
Definition: PointVector.h:641
double cosineSimilarity(const PointVector< dim, OtherComponent, OtherStorage > &v) const
Positive angle between two vectors, deduced from their scalar product.
Iterator minElement()
DGtal is the top-level namespace which contains all DGtal functions and types.
DGtal::ArithmeticConversionType< LeftEuclideanRing, RightEuclideanRing > dotProduct(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs)
Dot product between two points/vectors.
auto crossProduct(PointVector< 3, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< 3, RightEuclideanRing, RightContainer > const &rhs) -> decltype(DGtal::constructFromArithmeticConversion(lhs, rhs))
Cross product of two 3D Points/Vectors.
bool isUpper(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs)
Return true if the first point is upper the second point.
double cosineSimilarity(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs)
Positive angle between two vectors, deduced from their scalar product.
auto inf(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs) -> decltype(DGtal::constructFromArithmeticConversion(lhs, rhs))
Implements the infimum (or greatest lower bound).
boost::int32_t int32_t
signed 32-bit integer.
Definition: BasicTypes.h:72
auto sup(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs) -> decltype(DGtal::constructFromArithmeticConversion(lhs, rhs))
Implements the supremum (or least upper bound).
bool isLower(PointVector< ptDim, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< ptDim, RightEuclideanRing, RightContainer > const &rhs)
Return true if the first point is below the second point.
Z3i::RealPoint RealPoint3D
Functor that rounds to the nearest integer.
BENCHMARK(BM_StringCreation)
MyPointD Point
Definition: testClone2.cpp:383
CAPTURE(thicknessHV)
TEST_CASE("2D Point Vector Unit tests")
#define COMPARE_VALUE_AND_TYPE(expr, check)
const Point aPoint(3, 4)
SECTION("Testing constant forward iterators")
REQUIRE(domain.isInside(aPoint))
PointVector< 3, double > RealPoint