DGtal 2.1.0
Loading...
Searching...
No Matches
AffineGeometry.h
1
17#pragma once
18
31#if defined(AffineGeometry_RECURSES)
32#error Recursive header files inclusion detected in AffineGeometry.h
33#else // defined(AffineGeometry_RECURSES)
35#define AffineGeometry_RECURSES
36
37#if !defined AffineGeometry_h
39#define AffineGeometry_h
40
42// Inclusions
43#include <vector>
44#include "DGtal/base/Common.h"
45#include "DGtal/kernel/IntegerConverter.h"
46#include "DGtal/kernel/PointVector.h"
47#include "DGtal/arithmetic/IntegerComputer.h"
48#include "DGtal/math/linalg/SimpleMatrix.h"
49#include "DGtal/math/linalg/IntegerMatrixFunctions.h"
50
51namespace DGtal
52{
53 // Forward declaration of AffineGeometry (needed for friend declaration).
54 template < typename T > struct AffineGeometry;
55 // Forward declaration of AffineBasis (needed for friend declaration).
56 template < typename T > struct AffineBasis;
57
58 namespace detail {
59
61 // template class AffineGeometryPointOperations
62
67 template < DGtal::Dimension dim,
68 typename TEuclideanRing,
69 typename TContainer=std::array<TEuclideanRing,dim> >
71 {
72 template <typename T> friend struct DGtal::AffineGeometry;
73 template <typename T> friend struct DGtal::AffineBasis;
75 typedef typename Point::Coordinate Scalar;
77 typedef Scalar Integer;
78
79 // ----------------------- internal services --------------------------
80 private:
83
86 template <typename TInteger >
87 static void normalizeVector( Point& w, TInteger )
88 {
89 DGtal::Dimension i = 0;
90 while ( i < Point::dimension && w[ i ] == 0 ) i++;
91 if ( i == Point::dimension ) return;
92 TInteger g = abs( w[ i ] );
93 for ( DGtal::Dimension k = i+1; k < Point::dimension; k++ )
95 for ( DGtal::Dimension k = i; k < Point::dimension; k++ )
96 w[ k ] /= g;
97 }
98
100 template <typename TOtherPoint>
101 static
102 Point cast( const TOtherPoint& other )
103 {
105 }
106 }; // end of class AffineGeometryPointOperations
107
108
114 template < DGtal::Dimension dim,
115 typename TContainer >
116 struct AffineGeometryPointOperations< dim, double, TContainer >
117 {
118 template <typename T> friend struct DGtal::AffineGeometry;
119 template <typename T> friend struct DGtal::AffineBasis;
121 typedef typename Point::Coordinate Scalar;
122
123 // ----------------------- internal services --------------------------
124 private:
127
130 static
131 void normalizeVector( Point& w, double x )
132 {
133 w /= sqrt( x );
134 }
135
137 template <typename TOtherPoint>
138 static
139 Point cast( const TOtherPoint& other )
140 {
141 typedef typename TOtherPoint::Coordinate OtherScalar;
142 Point result;
143 for ( std::size_t i = 0; i < Point::dimension; i++ )
144 result[ i ] = NumberTraits<OtherScalar>::castToDouble( other[ i ] );
145 return result;
146 }
147 }; // end of class AffineGeometryPointOperations
148
154 template < DGtal::Dimension dim,
155 typename TContainer >
156 struct AffineGeometryPointOperations< dim, float, TContainer >
157 {
158 template <typename T> friend struct DGtal::AffineGeometry;
159 template <typename T> friend struct DGtal::AffineBasis;
161 typedef typename Point::Coordinate Scalar;
162
163 // ----------------------- internal services --------------------------
164 private:
167
170 static
171 void normalizeVector( Point& w, float x )
172 {
173 w /= sqrt( x );
174 }
175
177 template <typename TOtherPoint>
178 static
179 Point cast( const TOtherPoint& other )
180 {
181 Point result;
182 for ( std::size_t i = 0; i < Point::dimension; i++ )
183 result[ i ] = float( other[ i ] );
184 return result;
185 }
186 }; // end of class AffineGeometryPointOperations
187
188
189
191 // template class AffineGeometryScalarOperations
192
201 template < typename TScalar >
203 {
204 template <typename T> friend struct DGtal::AffineGeometry;
205 template <typename T> friend struct DGtal::AffineBasis;
206
207 typedef TScalar Scalar;
209 typedef Scalar Integer;
210
211 // ----------------------- internal services --------------------------
212 private:
215
221 static
222 std::pair< Integer, Integer > getMultipliers( Integer a, Integer b )
223 {
224 const Integer g = gcd( a, b );
225 // return std::make_pair( b / g, a / g );
226 // left multiplier should be positive.
227 return (b >= 0)
228 ? std::make_pair( b / g, a / g )
229 : std::make_pair( -b / g, -a / g );
230 }
231
236 static
238 {
239 return IntegerComputer< Integer >::staticGcd( abs( a ), abs( b ) );
240 }
241
246 static
248 {
249 const Integer g = gcd( a, b );
250 return (a / g) * b;
251 }
252
256 static
257 bool isNonZero( Integer x, double )
258 {
259 return x != Integer( 0 );
260 }
261
262 }; // end of class AffineGeometryScalarOperations
263
269 template <>
271 {
272 template <typename T> friend struct DGtal::AffineGeometry;
273 template <typename T> friend struct DGtal::AffineBasis;
274
280 static
281 std::pair< double, double > getMultipliers( double a, double b )
282 {
283 return (b >= 0 )
284 ? std::make_pair( b, a )
285 : std::make_pair( -b, -a );
286 }
287
289 static
290 double gcd( double, double )
291 {
292 return 1.0;
293 }
294
296 static
297 double lcmPositive( double, double )
298 {
299 return 1.0;
300 }
301
302
309 static
310 bool isNonZero( double x, double tol )
311 {
312 return ( x > tol ) || ( x < -tol );
313 }
314
315 }; // end of class AffineGeometryScalarOperations< double >
316
322 template <>
324 {
325 template <typename T> friend struct DGtal::AffineGeometry;
326 template <typename T> friend struct DGtal::AffineBasis;
327
333 static
334 std::pair< float, float > getMultipliers( float a, float b )
335 {
336 return (b >= 0 )
337 ? std::make_pair( b, a )
338 : std::make_pair( -b, -a );
339 }
340
342 static
343 float gcd( float, float )
344 {
345 return 1.0f;
346 }
347
349 static
350 float lcmPositive( float, float )
351 {
352 return 1.0f;
353 }
354
355
362 static
363 bool isNonZero( float x, double tol )
364 {
365 const double dx = double(x);
366 return (dx > tol) || ( dx < -tol );
367 }
368
369 }; // end of class AffineGeometryScalarOperations< float >
370
371 template < typename TScalar, bool Robust >
373 typedef TScalar type;
374 };
375 template <>
377 typedef int64_t type;
378 };
379 template <>
383 template <>
385 typedef int64_t type;
386 };
387 template <>
391 template <>
392 struct AffineGeometryInternalNumber<float, false> {
393 typedef double type;
394 };
395 template <>
396 struct AffineGeometryInternalNumber<float, true> {
397 typedef double type;
398 };
399 template <>
400 struct AffineGeometryInternalNumber<double, false> {
401 typedef double type;
402 };
403 template <>
404 struct AffineGeometryInternalNumber<double, true> {
405 typedef double type;
406 };
407
408 } // namespace detail
409
410} // namespace DGtal
411
412
413namespace DGtal
414{
416 // template class AffineGeometry
417
452 template < typename TPoint >
454 {
455 typedef TPoint Point;
456 typedef typename Point::Coordinate Scalar;
457 typedef typename Point::Container Container;
458 typedef std::size_t Size;
459 typedef std::vector< Point > Points;
460 typedef std::vector< Size > Sizes;
461 static const Size dimension = Point::dimension;
465
466 // ----------------------- standard services --------------------------
467 public:
470
483 template <typename TInputPoint>
484 static
486 affineDimension( const std::vector<TInputPoint>& X, const double tolerance = 1e-12 )
487 {
488 return DGtal::int64_t( affineSubset( X, tolerance ).size() ) - 1;
489 }
490
505 template <typename TInputPoint>
506 static
507 std::vector< Size >
508 affineSubset( const std::vector<TInputPoint>& X, const double tolerance = 1e-12 )
509 {
510 Size m = X.size();
511 // Process trivial cases.
512 if ( m == 0 ) return { };
513 if ( m == 1 ) return { Size( 0 ) };
514 // Process general case.
515 Points basis; //< direction vectors
516 Sizes chosen; //< selected points
517 chosen.push_back( 0 ); //< reference point (first one, as it may be any one)
518 for ( Size i = 1; i < m; i++ )
519 {
520 Point v = transform( X[ i ] - X[ 0 ] );
521 if ( addIfIndependent( basis, v, tolerance ) )
522 chosen.push_back( i );
523 if ( chosen.size() > dimension ) break;
524 }
525 return chosen;
526 }
527
548 template <typename TInputPoint, typename TIndexRange>
549 static
550 std::vector< Size >
551 affineSubset( const std::vector<TInputPoint>& X,
552 const TIndexRange& I,
553 const double tolerance = 1e-12 )
554 {
555 Size m = I.size();
556 // Process trivial cases.
557 if ( m == 0 ) return { };
558 if ( m == 1 ) return { I[ 0 ] };
559 // Process general case.
560 Points basis; //< direction vectors
561 Sizes chosen; //< selected points
562 chosen.push_back( I[ 0 ] ); //< reference point (first one, as it may be any one)
563 for ( Size i = 1; i < m; i++ )
564 {
565 Point v = transform( X[ I[ i ] ] - X[ I[ 0 ] ] );
566 if ( addIfIndependent( basis, v, tolerance ) )
567 chosen.push_back( I[ i ] );
568 if ( chosen.size() > dimension ) break;
569 }
570 return chosen;
571 }
572
586 template <typename TInputPoint>
587 static
588 std::pair< Point, Points >
589 affineBasis( const std::vector<TInputPoint>& X, const double tolerance = 1e-12 )
590 {
591 Points basis; //< direction vectors
592 Size m = X.size();
593 // Process trivial cases.
594 if ( m == 0 ) return std::make_pair( Point::zero, basis );
595 const Point o = transform( X[ 0 ] );
596 if ( m == 1 ) return std::make_pair( o, basis );
597 // Process general case.
598 basis.reserve( dimension );
599 for ( Size i = 1; i < m; i++ )
600 {
601 Point v = transform( X[ i ] ) - o;
602 if ( addIfIndependent( basis, v, tolerance ) )
603 if ( basis.size() >= dimension ) break;
604 }
605 return std::make_pair( o, basis );
606 }
607
624 template < typename TInputPoint, typename TIndexRange >
625 static
626 std::pair< TInputPoint, Points >
627 affineBasis( const std::vector<TInputPoint>& X,
628 const TIndexRange& I,
629 const double tolerance = 1e-12 )
630 {
631 Points basis; //< direction vectors
632 Size m = I.size();
633 // Process trivial cases.
634 if ( m == 0 ) return std::make_pair( TInputPoint::zero, basis );
635 if ( m == 1 ) return std::make_pair( X[ I[ 0 ] ], basis );
636 // Process general case.
637 const Point o = transform( X[ I[ 0 ] ] );
638 basis.reserve( dimension );
639 for ( Size i = 1; i < m; i++ )
640 {
641 Point v = transform( X[ I[ i ] ] ) - o;
642 if ( addIfIndependent( basis, v, tolerance ) )
643 if ( basis.size() > dimension ) break;
644 }
645 return std::make_pair( X[ I[ 0 ] ], basis );
646 }
647
658 static
659 Point
660 independentVector( const Points& basis, const double tolerance = 1e-12 )
661 {
662 // If basis has already d independent vectors, then there is no
663 // other independent vector.
664 if ( basis.size() >= dimension ) return Point::zero;
665 // At least one trivial canonic vector should be independant.
666 Dimension k = 0;
667 for ( ; k < dimension; k++ )
668 {
669 Point e_k = Point::base( k );
670 Point w = reductionOnBasis( e_k, basis, tolerance );
671 Scalar sql2;
673 if ( ScalarOps::isNonZero( sql2, tolerance ) )
674 return e_k;
675 }
676 trace.error() << "[AffineGeometry::independentVector]"
677 << " Unable to find independent vector." << std::endl;
678 return Point::zero;
679 }
680
693 template < typename TOtherPoint >
694 static
695 TOtherPoint
696 independentVector( const Points& basis, const double tolerance = 1e-12 )
697 {
698 // If basis has already d independent vectors, then there is no
699 // other independent vector.
700 if ( basis.size() >= dimension ) return TOtherPoint::zero;
701 // At least one trivial canonic vector should be independant.
702 Dimension k = 0;
703 for ( ; k < dimension; k++ )
704 {
705 Point e_k = Point::base( k );
706 Point w = reductionOnBasis( e_k, basis, tolerance );
707 Scalar sql2;
709 if ( ScalarOps::isNonZero( sql2, tolerance ) )
710 return TOtherPoint::base( k );
711 }
712 trace.error() << "[AffineGeometry::independentVector]"
713 << " Unable to find independent vector." << std::endl;
714 return TOtherPoint::zero;
715 }
716
735 static
736 void
738 bool normal_vector,
739 const double tolerance = 1e-12 )
740 {
741 if ( basis.size() >= dimension ) return;
742 while ( ( basis.size() + 1 ) < dimension )
743 { // add an independent vector
744 const Point u = independentVector( basis, tolerance );
745 basis.push_back( u );
746 }
747 if ( normal_vector )
748 basis.push_back( orthogonalVector( basis ) );
749 else
750 basis.push_back( independentVector( basis, tolerance ) );
751 }
752
765 template < typename TInputPoint >
766 static
767 std::vector< Point >
768 orthogonalLatticeBasis( const TInputPoint& N, bool shortened = false )
769 {
770 std::vector< Scalar > Np( N.begin(), N.end() );
771 Np.resize( Point::dimension );
773 if ( shortened )
775 std::vector< Point > R( B.size() );
776 for ( std::size_t i = 0; i < B.size(); i++ )
777 for ( std::size_t j = 0; j < Point::dimension; j++ )
778 R[ i ][ j ] = B[ i ][ j ];
779 return R;
780 }
781
783
784 // ----------------------- specific services --------------------------
785 public:
789
802 static
803 Point
805 const Points& basis,
806 const double tolerance )
807 {
808 Point w( v );
809 for ( const auto& b : basis ) reduceVector( w, b, tolerance );
810 return w;
811 }
812
833 static
835 const Point& v,
836 const double tolerance )
837 {
838 Point w = reductionOnBasis( v, basis, tolerance );
839 Scalar x;
841 if ( ScalarOps::isNonZero( x, tolerance ) )
842 {
843 // Useful to reduce the norm of vectors for lattice vectors
844 // and necessary for real vectors so that `tolerance` keeps
845 // the same meaning.
847 basis.push_back( w );
848 return true;
849 }
850 return false;
851 }
852
865 static
866 std::pair< Scalar, Scalar >
867 reduceVector( Point& w, const Point& b, const double tolerance )
868 {
869 Scalar mul_w = 0;
870 Scalar mul_b = 0;
871 Size n = w.size();
872 // Find index of first non null pivot in b.
873 Size lead = n;
874 for ( Size j = 0; j < n; j++)
875 if ( ScalarOps::isNonZero( b[j], tolerance ) ) { lead = j; break; }
876 if ( lead == n ) return std::make_pair( mul_w, mul_b ); // b is null vector
877
878 std::tie( mul_w, mul_b ) = ScalarOps::getMultipliers( w[ lead ], b[ lead ] );
879
880 for (Size j = 0; j < n; j++)
881 w[j] = mul_w * w[j] - mul_b * b[j];
882 return std::make_pair( mul_w, mul_b );
883 }
884
898 static
899 std::pair< Scalar, Scalar >
900 reduceVector( Point& w, const Point& b,
901 Dimension start, const double tolerance )
902 {
903 Scalar mul_w = 0;
904 Scalar mul_b = 0;
905 Size n = w.size();
906 // Find index of first non null pivot in b.
907 Size lead = n;
908 for ( Size j = start; j < n; j++)
909 if ( ScalarOps::isNonZero( b[j], tolerance ) ) { lead = j; break; }
910 if ( lead == n ) return std::make_pair( mul_w, mul_b ); // b is null vector
911
912 std::tie( mul_w, mul_b ) = ScalarOps::getMultipliers( w[ lead ], b[ lead ] );
913
914 for (Size j = 0; j < n; j++)
915 w[j] = mul_w * w[j] - mul_b * b[j];
916 return std::make_pair( mul_w, mul_b );
917 }
918
919
927 static
928 const Point&
929 transform( const Point& w )
930 {
931 return w;
932 }
933
940 template <typename TInputPoint>
941 static
942 Point
943 transform( const TInputPoint& w )
944 {
945 return PointOps::cast( w );
946 }
947
960 static
961 Point
962 orthogonalVector( const Points& basis )
963 {
964 Point w;
965 const std::size_t n = dimension;
966 if ( ( basis.size() + 1 ) != dimension ) return w;
967 const std::size_t m = basis.size();
969 for ( std::size_t i = 0; i < m; ++i )
970 for ( std::size_t j = 0; j < n; ++j )
971 A( i, j ) = basis[ i ][ j ];
972 for ( std::size_t col = 0; col < n; ++col)
973 { // construct sub-matrix removing column col
975 for ( std::size_t i = 0; i < m; ++i )
976 {
977 std::size_t c = 0;
978 for ( std::size_t j = 0; j < n; ++j)
979 if ( j != col ) M( i, c++ ) = A( i, j );
980 }
982 if ( (col+dimension) % 2 == 0 ) w[ col ] = -w[ col ];
983 }
984 return simplifiedVector( w );
985 }
986
999 template <typename TInternalNumber>
1000 static
1001 Point
1002 orthogonalVector( const Points& basis )
1003 {
1004 Point w;
1005 typedef PointVector< dimension, TInternalNumber > InternalPoint;
1006 InternalPoint W;
1007 const std::size_t n = dimension;
1008 if ( ( basis.size() + 1 ) != dimension ) return w;
1009 const std::size_t m = basis.size();
1011 for ( std::size_t i = 0; i < m; ++i )
1012 for ( std::size_t j = 0; j < n; ++j )
1013 A( i, j ) = basis[ i ][ j ];
1014 for ( std::size_t col = 0; col < n; ++col)
1015 { // construct sub-matrix removing column col
1017 for ( std::size_t i = 0; i < m; ++i )
1018 {
1019 std::size_t c = 0;
1020 for ( std::size_t j = 0; j < n; ++j)
1021 if ( j != col ) M( i, c++ ) = A( i, j );
1022 }
1023 functions::getDeterminantBareiss( W[ col ], M );
1024 if ( (col+dimension) % 2 == 0 ) W[ col ] = -W[ col ];
1025 }
1027 return transform( W );
1028 }
1029
1038 static
1040 {
1041 Scalar x;
1044 return v;
1045 }
1046
1048
1049 };
1050
1051 namespace functions {
1052
1066 template <typename TPoint>
1068 computeAffineDimension( const std::vector< TPoint >& X, const double tolerance = 1e-12 )
1069 {
1070 return AffineGeometry<TPoint>::affineDimension( X, tolerance );
1071 }
1072
1087 template <typename TPoint>
1088 std::vector< std::size_t >
1089 computeAffineSubset( const std::vector< TPoint >& X, const double tolerance = 1e-12 )
1090 {
1091 return AffineGeometry<TPoint>::affineSubset( X, tolerance );
1092 }
1093
1114 template <typename TPoint, typename TIndexRange>
1115 static
1116 std::vector< std::size_t >
1117 computeAffineSubset( const std::vector<TPoint>& X,
1118 const TIndexRange& I,
1119 const double tolerance = 1e-12 )
1120 {
1121 return AffineGeometry<TPoint>::affineSubset( X, I, tolerance );
1122 }
1123
1124
1143 template <typename TPoint, typename TInputPoint>
1144 void
1145 getAffineBasis( TInputPoint& o,
1146 std::vector< TPoint >& basis,
1147 const std::vector< TInputPoint >& X,
1148 const double tolerance = 1e-12 )
1149 {
1150 std::tie( o, basis ) = AffineGeometry<TPoint>::affineBasis( X, tolerance );
1151 }
1152
1175 template < typename TPoint, typename TInputPoint, typename TIndexRange >
1176 static
1177 void
1178 getAffineBasis( TInputPoint& o,
1179 std::vector< TPoint >& basis,
1180 const std::vector< TInputPoint >& X,
1181 const TIndexRange& I,
1182 const double tolerance = 1e-12 )
1183 {
1184 std::tie( o, basis ) = AffineGeometry<TPoint>::affineBasis( X, I, tolerance );
1185 }
1186
1200 template <typename TPoint>
1201 TPoint
1202 computeIndependentVector( const std::vector< TPoint >& basis,
1203 const double tolerance = 1e-12 )
1204 {
1205 return AffineGeometry<TPoint>::independentVector( basis, tolerance );
1206 }
1207
1232 template <typename TPoint>
1233 static
1234 void
1235 getCompleteBasis( std::vector< TPoint >& basis,
1236 bool normal_vector,
1237 const double tolerance = 1e-12 )
1238 {
1239 AffineGeometry<TPoint>::completeBasis( basis, normal_vector, tolerance );
1240 }
1241
1259 template < typename TPoint >
1260 static
1261 TPoint
1262 computeOrthogonalVectorToBasis( const std::vector<TPoint>& basis )
1263 {
1264 if ( ( basis.size() + 1 ) != TPoint::dimension ) return TPoint::zero;
1266 }
1267
1298 template < typename TPoint, typename TInputPoint, typename TIndexRange >
1299 static
1300 void
1302 const std::vector< TInputPoint >& X,
1303 const TIndexRange& I,
1304 const double tolerance = 1e-12 )
1305 {
1306 typedef AffineGeometry<TPoint> Affine;
1307 w = TPoint::zero;
1308 TInputPoint o;
1309 auto subset = Affine::affineSubset( X, I, tolerance );
1310 if ( ( subset.size() ) != TPoint::dimension ) return;
1311 std::vector<TPoint> basis( TPoint::dimension - 1);
1312 for ( auto i = 0; i < basis.size(); i++ )
1313 basis[ i ] = Affine::transform( X[ subset[ i+1 ] ] - X[ subset[ 0 ] ] );
1314 w = Affine::orthogonalVector( basis );
1315 }
1316
1341 template < typename TPoint, typename TInputPoint>
1342 static
1343 void
1345 const std::vector< TInputPoint >& X,
1346 const double tolerance = 1e-12 )
1347 {
1348 typedef AffineGeometry<TPoint> Affine;
1349 w = TPoint::zero;
1350 TInputPoint o;
1351 auto subset = AffineGeometry<TPoint>::affineSubset( X, tolerance );
1352 if ( ( subset.size() ) != TPoint::dimension ) return;
1353 std::vector<TPoint> basis( TPoint::dimension - 1);
1354 for ( auto i = 0; i < basis.size(); i++ )
1355 basis[ i ] = Affine::transform( X[ subset[ i+1 ] ] - X[ subset[ 0 ] ] );
1356 w = Affine::orthogonalVector( basis );
1357 }
1358
1372 template < typename TPoint, typename TInputPoint>
1373 static
1374 void
1375 getOrthogonalLatticeBasis( std::vector< TPoint >& B,
1376 const TInputPoint& N, bool shortened = false )
1377 {
1379 }
1380
1381
1392 template <typename TPoint>
1393 TPoint
1394 computeSimplifiedVector( const TPoint& v )
1395 {
1397 }
1398
1399 } // namespace functions
1400} // namespace DGtal
1401
1403// Includes inline functions.
1404// //
1406
1407#endif // !defined AffineGeometry_h
1408
1409#undef AffineGeometry_RECURSES
1410#endif // else defined(AffineGeometry_RECURSES)
1411
Aim: This class gathers several types and methods to make computation with integers.
static Integer staticGcd(IntegerParamType a, IntegerParamType b)
Aim: Implements basic operations that will be used in Point and Vector classes.
Component Coordinate
Type for Point elements.
static Dimension size()
static const Dimension dimension
Copy of the static dimension of the Point/Vector.
Aim: implements basic MxN Matrix services (M,N>=1).
std::ostream & error()
static void getOrthogonalLatticeBasis(std::vector< TPoint > &B, const TInputPoint &N, bool shortened=false)
DGtal::int64_t computeAffineDimension(const std::vector< TPoint > &X, const double tolerance=1e-12)
void getAffineBasis(TInputPoint &o, std::vector< TPoint > &basis, const std::vector< TInputPoint > &X, const double tolerance=1e-12)
void getSquaredNormL2(TOutput &n, const std::vector< T > &a)
static void getOrthogonalVector(TPoint &w, const std::vector< TInputPoint > &X, const TIndexRange &I, const double tolerance=1e-12)
std::size_t shortenBasis(std::vector< std::vector< TComponent > > &B)
TPoint computeIndependentVector(const std::vector< TPoint > &basis, const double tolerance=1e-12)
static void getCompleteBasis(std::vector< TPoint > &basis, bool normal_vector, const double tolerance=1e-12)
std::vector< std::vector< TComponent > > computeOrthogonalLattice(std::vector< TComponent > N)
static TPoint computeOrthogonalVectorToBasis(const std::vector< TPoint > &basis)
std::vector< std::size_t > computeAffineSubset(const std::vector< TPoint > &X, const double tolerance=1e-12)
void getDeterminantBareiss(TInternalNumber &result, const SimpleMatrix< TComponent, TN, TN > &matrix)
TPoint computeSimplifiedVector(const TPoint &v)
DGtal is the top-level namespace which contains all DGtal functions and types.
std::int32_t int32_t
signed 32-bit integer.
Definition BasicTypes.h:71
std::int64_t int64_t
signed 94-bit integer.
Definition BasicTypes.h:73
DGtal::uint32_t Dimension
Definition Common.h:119
Trace trace
boost::multiprecision::number< boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off > BigInteger
Definition BasicTypes.h:75
Aim: Utility class to determine the affine geometry of an input set of points. It provides exact resu...
Aim: Utility class to determine the affine geometry of an input set of points. It provides exact resu...
static std::pair< TInputPoint, Points > affineBasis(const std::vector< TInputPoint > &X, const TIndexRange &I, const double tolerance=1e-12)
static const Point & transform(const Point &w)
static std::pair< Scalar, Scalar > reduceVector(Point &w, const Point &b, Dimension start, const double tolerance)
static Point orthogonalVector(const Points &basis)
static std::pair< Scalar, Scalar > reduceVector(Point &w, const Point &b, const double tolerance)
DGtal::detail::AffineGeometryScalarOperations< Scalar > ScalarOps
static std::vector< Size > affineSubset(const std::vector< TInputPoint > &X, const TIndexRange &I, const double tolerance=1e-12)
static Point transform(const TInputPoint &w)
static const Size dimension
static Point independentVector(const Points &basis, const double tolerance=1e-12)
DGtal::detail::AffineGeometryPointOperations< dimension, Scalar, Container > PointOps
static Point orthogonalVector(const Points &basis)
static bool addIfIndependent(Points &basis, const Point &v, const double tolerance)
Point::Coordinate Scalar
static TOtherPoint independentVector(const Points &basis, const double tolerance=1e-12)
static std::vector< Point > orthogonalLatticeBasis(const TInputPoint &N, bool shortened=false)
static DGtal::int64_t affineDimension(const std::vector< TInputPoint > &X, const double tolerance=1e-12)
std::vector< Size > Sizes
type for range of sizes.
Point::Container Container
static void completeBasis(Points &basis, bool normal_vector, const double tolerance=1e-12)
std::vector< Point > Points
type for range of points.
static Point simplifiedVector(Point v)
static Point reductionOnBasis(const Point &v, const Points &basis, const double tolerance)
static std::pair< Point, Points > affineBasis(const std::vector< TInputPoint > &X, const double tolerance=1e-12)
static std::vector< Size > affineSubset(const std::vector< TInputPoint > &X, const double tolerance=1e-12)
static Integer cast(Integer i)
Aim: The traits class for all models of Cinteger.
static Point cast(const TOtherPoint &other)
Specialized version to cast points to other point type.
static Point cast(const TOtherPoint &other)
Specialized version to cast points to other point type.
Aim: Internal class used by AffineGeometry to differentiate operations on lattice points and operatio...
Scalar Integer
In the generic class, the type scalar should be an integral type.
static Point cast(const TOtherPoint &other)
Specialized version to cast points to other point type.
PointVector< dim, TEuclideanRing, TContainer > Point
static void normalizeVector(Point &w, TInteger)
static std::pair< double, double > getMultipliers(double a, double b)
static std::pair< float, float > getMultipliers(float a, float b)
Aim: Internal class used by AffineGeometry to differentiate operations on point coordinates,...
static Integer lcmPositive(Integer a, Integer b)
static bool isNonZero(Integer x, double)
Scalar Integer
In the generic class, the type scalar should be an integral type.
static Integer gcd(Integer a, Integer b)
static std::pair< Integer, Integer > getMultipliers(Integer a, Integer b)
std::mt19937 g(rd())