DGtal 2.1.0
Loading...
Searching...
No Matches
DGtal::AffineBasis< TPoint > Struct Template Reference

Aim: Utility class to determine the affine geometry of an input set of points. It provides exact results when the input is composed of lattice points, and may determine a basis, the dimension, or an orthogonal vector. More...

#include <DGtal/geometry/tools/AffineBasis.h>

Inheritance diagram for DGtal::AffineBasis< TPoint >:
[legend]

Public Types

enum struct  Type { INVALID = 0 , ECHELON_REDUCED , SHORTEST_ECHELON_REDUCED , LLL_REDUCED }
 
typedef AffineBasis< TPoint > Self
 
typedef TPoint Point
 
typedef Point::Coordinate Scalar
 
typedef std::vector< PointPoints
 
typedef AffineGeometry< PointAffine
 

Public Member Functions

standard services
 AffineBasis (const double tolerance=1e-12)
 
template<typename TInputPoint >
 AffineBasis (const std::vector< TInputPoint > &points, AffineBasis::Type type, const double delta=0.99, const double tolerance=1e-12)
 
template<typename TInputPoint >
 AffineBasis (const TInputPoint &origin, const std::vector< TInputPoint > &basis, AffineBasis::Type type, bool is_reduced=false, const double delta=0.99, const double tolerance=1e-12)
 
template<typename TInputPoint >
 AffineBasis (const TInputPoint &origin, const TInputPoint &normal, AffineBasis::Type type=Type::ECHELON_REDUCED, const double tolerance=1e-12)
 
void reduce (AffineBasis::Type type, double delta)
 
Dimension dimension () const
 
const Pointorigin () const
 
const Pointsbasis () const
 
debug and I/O services
void selfDisplay (std::ostream &out) const
 
bool isValid () const
 
std::string reductionTypeName () const
 

Data Fields

public data
Point first
 the origin of the affine basis
 
Points second
 the vector basis
 
double epsilon {1e-12}
 the accepted value below which a floating-point number is 0.
 
AffineBasis::Type _type
 the type of reduction of the basis.
 

Protected Member Functions

protected services
void normalize ()
 
void reduceAsEchelon (Type type)
 
void orderEchelonBasis ()
 Guarantees that the basis is in echelon form.
 
void reduceAsLLL (double delta, Scalar)
 
template<typename TInputPoint >
void initBasis (const std::vector< TInputPoint > &basis)
 
void sortBasis ()
 
std::size_t findIndexWithSmallestNonNullComponent (Dimension k, std::size_t i, const std::vector< Point > &basis)
 

geometry services

bool isParallel (const Self &other) const
 
std::pair< Scalar, PointrationalCoordinates (const Point &p) const
 
bool isOnAffineSpace (const Point &p) const
 
bool isParallel (const Point &w) const
 
Point recompose (Scalar d, const Point &lambda, const Point &r=Point::zero) const
 
Point recomposeVector (Scalar d, const Point &lambda, const Point &r=Point::zero) const
 
std::tuple< Scalar, Point, Pointdecompose (const Point &p) const
 
std::tuple< Scalar, Point, PointdecomposeVector (Point w) const
 
template<typename ProjectedPoint >
Scalar projectPoints (std::vector< ProjectedPoint > &result, const Points &input)
 
template<typename OtherPoint >
static void transform (OtherPoint &pp, const Point &p)
 
template<typename OtherPoint >
static void dilatedTransform (OtherPoint &pp, const Point &p, Scalar m)
 

Detailed Description

template<typename TPoint>
struct DGtal::AffineBasis< TPoint >

Aim: Utility class to determine the affine geometry of an input set of points. It provides exact results when the input is composed of lattice points, and may determine a basis, the dimension, or an orthogonal vector.

Description of template class 'AffineBasis'

Note
Useful for algorithms that requires the exact dimensionality of a set of points before processing, like QuickHull.
Warning
You can use this class to test the dimensionality of a set of points with floating point coordinates, but this approach is less robust than singular value decomposition.
Template Parameters
TPointthe type for points, which may be lattice points or points with floating-point coordinates.
#include <iostream>
#include <vector>
#include "DGtal/base/Common.h"
#include "DGtal/kernel/SpaceND.h"
#include "DGtal/geometry/tools/AffineBasis.h"
...
typedef Space::Point Point;
std::vector<Point> X = { Point{1, 0, 0}, Point{2, 1, 0}, Point{3, 2, 0}, Point{3, 1, 1}, Point{5, 2, 2}, Point{4, 2, 1} };
auto I = Affine::affineSubset( X );
auto B = Affine::affineBasis( X );
auto d = Affine::affineDimension( X );
Aim: Utility class to determine the affine geometry of an input set of points. It provides exact resu...
Definition AffineBasis.h:89
AffineGeometry< Point > Affine
Definition AffineBasis.h:94
static DGtal::int64_t affineDimension(const std::vector< TInputPoint > &X, const double tolerance=1e-12)
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)
See also
testAffineBasis.cpp

Definition at line 88 of file AffineBasis.h.

Member Typedef Documentation

◆ Affine

template<typename TPoint >
typedef AffineGeometry< Point > DGtal::AffineBasis< TPoint >::Affine

Definition at line 94 of file AffineBasis.h.

◆ Point

template<typename TPoint >
typedef TPoint DGtal::AffineBasis< TPoint >::Point

Definition at line 91 of file AffineBasis.h.

◆ Points

template<typename TPoint >
typedef std::vector< Point > DGtal::AffineBasis< TPoint >::Points

Definition at line 93 of file AffineBasis.h.

◆ Scalar

template<typename TPoint >
typedef Point::Coordinate DGtal::AffineBasis< TPoint >::Scalar

Definition at line 92 of file AffineBasis.h.

◆ Self

template<typename TPoint >
typedef AffineBasis<TPoint> DGtal::AffineBasis< TPoint >::Self

Definition at line 90 of file AffineBasis.h.

Member Enumeration Documentation

◆ Type

template<typename TPoint >
enum struct DGtal::AffineBasis::Type
strong
Enumerator
INVALID 

invalid basis

ECHELON_REDUCED 

echelon matrix

SHORTEST_ECHELON_REDUCED 

echelon matrix starting from shortest vectors

LLL_REDUCED 

delta-LLL reduced matrix

Definition at line 96 of file AffineBasis.h.

96 {
97 INVALID = 0,
101 };
@ SHORTEST_ECHELON_REDUCED
echelon matrix starting from shortest vectors
@ LLL_REDUCED
delta-LLL reduced matrix
@ ECHELON_REDUCED
echelon matrix
@ INVALID
invalid basis

Constructor & Destructor Documentation

◆ AffineBasis() [1/4]

template<typename TPoint >
DGtal::AffineBasis< TPoint >::AffineBasis ( const double  tolerance = 1e-12)
inline

Default constructor. This create the identity basis of the space.

Parameters
[in]tolerancethe accepted oo-norm below which the vector is null (used only for points with float/double coordinates).

Definition at line 114 of file AffineBasis.h.

115 : epsilon( tolerance )
116 {
117 first = Point::zero;
118 second.resize( Point::dimension );
119 for ( auto k = 0; k < Point::dimension; k++ )
120 second[ k ] = Point::base( k );
122 }
AffineBasis::Type _type
the type of reduction of the basis.
Points second
the vector basis
double epsilon
the accepted value below which a floating-point number is 0.
Point first
the origin of the affine basis

References DGtal::AffineBasis< TPoint >::_type, DGtal::AffineBasis< TPoint >::first, DGtal::AffineBasis< TPoint >::second, and DGtal::AffineBasis< TPoint >::SHORTEST_ECHELON_REDUCED.

◆ AffineBasis() [2/4]

template<typename TPoint >
template<typename TInputPoint >
DGtal::AffineBasis< TPoint >::AffineBasis ( const std::vector< TInputPoint > &  points,
AffineBasis< TPoint >::Type  type,
const double  delta = 0.99,
const double  tolerance = 1e-12 
)
inline

Constructor from points.

Parameters
[in]pointsthe range of points belonging to the affine space.
[in]typeif Type::ECHELON_REDUCED or Type::SHORTEST_ECHELON_REDUCED, reduces the basis so that it forms a echelon matrix, otherwise computes its delta-LLL-lattice.
[in]deltathe parameter \( \delta \) of LLL-algorithm, which should be between 0.25 and 1 (value 0.99 is default in sagemath).
[in]tolerancethe accepted oo-norm below which the vector is null (used only for points with float/double coordinates).

Definition at line 141 of file AffineBasis.h.

145 : epsilon( tolerance )
146 {
147 if ( points.size() == 0 ) return;
148 first = Affine::transform( points[ 0 ] );
149 std::vector< TInputPoint > basis( points.size() - 1 );
150 for ( std::size_t i = 0; i < basis.size(); i++ )
151 basis[ i ] = ( points[ i+1 ] - first );
152 initBasis( basis );
153 reduce( type, delta );
154 }
void reduce(AffineBasis::Type type, double delta)
const Points & basis() const
void initBasis(const std::vector< TInputPoint > &basis)
static const Point & transform(const Point &w)

References DGtal::AffineBasis< TPoint >::basis(), DGtal::AffineBasis< TPoint >::first, DGtal::AffineBasis< TPoint >::initBasis(), DGtal::AffineBasis< TPoint >::reduce(), and DGtal::AffineGeometry< TPoint >::transform().

◆ AffineBasis() [3/4]

template<typename TPoint >
template<typename TInputPoint >
DGtal::AffineBasis< TPoint >::AffineBasis ( const TInputPoint &  origin,
const std::vector< TInputPoint > &  basis,
AffineBasis< TPoint >::Type  type,
bool  is_reduced = false,
const double  delta = 0.99,
const double  tolerance = 1e-12 
)
inline

Constructor from origin and basis.

Parameters
[in]originthe origin of the affine basis
[in]basisthe range of vectors forming the basis
[in]typeif Type::ECHELON_REDUCED or Type::SHORTEST_ECHELON_REDUCED, reduces the basis so that it forms a echelon matrix, otherwise computes its delta-LLL-lattice.
[in]is_reducedwhen 'true', assumes that the given basis is already reduced, otherwise it forces the reduction of the basis.
[in]deltathe parameter \( \delta \) of LLL-algorithm, which should be between 0.25 and 1 (value 0.99 is default in sagemath).
[in]tolerancethe accepted oo-norm below which the vector is null (used only for points with float/double coordinates).

Definition at line 178 of file AffineBasis.h.

184 : epsilon( tolerance )
185 {
187 initBasis( basis );
188 if ( ! is_reduced ) reduce( type, delta );
189 else _type = type;
190 }
const Point & origin() const

References DGtal::AffineBasis< TPoint >::_type, DGtal::AffineBasis< TPoint >::basis(), DGtal::AffineBasis< TPoint >::first, DGtal::AffineBasis< TPoint >::initBasis(), DGtal::AffineBasis< TPoint >::origin(), DGtal::AffineBasis< TPoint >::reduce(), and DGtal::AffineGeometry< TPoint >::transform().

◆ AffineBasis() [4/4]

template<typename TPoint >
template<typename TInputPoint >
DGtal::AffineBasis< TPoint >::AffineBasis ( const TInputPoint &  origin,
const TInputPoint &  normal,
AffineBasis< TPoint >::Type  type = Type::ECHELON_REDUCED,
const double  tolerance = 1e-12 
)
inline

Creates an affine basis going through origin and orthogonal to the lattice vector normal.

Parameters
[in]originthe origin of the affine basis
[in]normalthe lattice normal vector.
[in]typeif Type::ECHELON_REDUCED or Type::SHORTEST_ECHELON_REDUCED, then the basis will be in echelon form, otherwise it will make the vectors as short as possible, but the matrix won't be in echelon form.
[in]tolerancethe accepted oo-norm below which the vector is null (used only for points with float/double coordinates).

Definition at line 207 of file AffineBasis.h.

211 : epsilon( tolerance )
212 {
214 // basis is shortened is type is LLL.
216 _type = ( type == Type::LLL_REDUCED )
218 }
static std::vector< Point > orthogonalLatticeBasis(const TInputPoint &N, bool shortened=false)

References DGtal::AffineBasis< TPoint >::_type, DGtal::AffineBasis< TPoint >::ECHELON_REDUCED, DGtal::AffineBasis< TPoint >::first, DGtal::AffineBasis< TPoint >::LLL_REDUCED, DGtal::AffineBasis< TPoint >::origin(), DGtal::AffineGeometry< TPoint >::orthogonalLatticeBasis(), DGtal::AffineBasis< TPoint >::second, and DGtal::AffineGeometry< TPoint >::transform().

Member Function Documentation

◆ basis()

template<typename TPoint >
const Points & DGtal::AffineBasis< TPoint >::basis ( ) const
inline

◆ decompose()

template<typename TPoint >
std::tuple< Scalar, Point, Point > DGtal::AffineBasis< TPoint >::decompose ( const Point p) const
inline

Decompose p as d * (p - o) = l[0]b[0] + ... l[i]b[i] + r, where r is independent from this basis B=(b[0],...,b[i]).

Parameters
[in]pany point.
Returns
(d,l,r) where d is a scalar, l/d are the rational coordinates of (p-o) in the basis, r is the remainer vector if p does not belong to the affine space.

Definition at line 378 of file AffineBasis.h.

379 {
380 return decomposeVector( p - first );
381 }
std::tuple< Scalar, Point, Point > decomposeVector(Point w) const

References DGtal::AffineBasis< TPoint >::decomposeVector(), and DGtal::AffineBasis< TPoint >::first.

Referenced by DGtal::AffineBasis< TPoint >::isOnAffineSpace(), DGtal::AffineBasis< TPoint >::projectPoints(), and DGtal::AffineBasis< TPoint >::rationalCoordinates().

◆ decomposeVector()

template<typename TPoint >
std::tuple< Scalar, Point, Point > DGtal::AffineBasis< TPoint >::decomposeVector ( Point  w) const
inline

Decompose w as d * w = l[0]b[0] + ... l[i]b[i] + r, where r is independent from B=(b[0],...,b[i]).

Parameters
[in]wany vector.
Returns
(d,l,r) where d is a scalar, l/d are the rational coordinates of w in the basis, r is the remainer vector if w does not belong to the affine space.

Definition at line 391 of file AffineBasis.h.

392 {
393 Point r;
394 Scalar alphas = 1;
395 for ( auto i = 0; i < second.size(); i++ )
396 {
397 std::pair< Scalar, Scalar > c
398 = Affine::reduceVector( w, second[ i ], i, epsilon );
399 for ( auto j = 0; j < i; j++ )
400 r[ j ] *= c.first;
401 r[ i ] = c.second;
402 alphas *= c.first;
403 }
404 return alphas >= 0
405 ? std::make_tuple( alphas, r, w )
406 : std::make_tuple( -alphas, -r, -w );
407 }
STL namespace.
static std::pair< Scalar, Scalar > reduceVector(Point &w, const Point &b, const double tolerance)

References DGtal::AffineBasis< TPoint >::epsilon, DGtal::AffineGeometry< TPoint >::reduceVector(), and DGtal::AffineBasis< TPoint >::second.

Referenced by DGtal::AffineBasis< TPoint >::decompose(), and DGtal::AffineBasis< TPoint >::isParallel().

◆ dilatedTransform()

template<typename TPoint >
template<typename OtherPoint >
static void DGtal::AffineBasis< TPoint >::dilatedTransform ( OtherPoint &  pp,
const Point p,
Scalar  m 
)
inlinestatic

Transforms the type of an input point into another one, while dilating it by a factor m.

Template Parameters
OtherPointa type of point of dimension at most Point::dimension.
Parameters
[out]ppthe output restricted point.
[in]pthe input point.
[in]mthe dilation factor.

Definition at line 469 of file AffineBasis.h.

470 {
471 BOOST_STATIC_ASSERT( OtherPoint::dimension <= Point::dimension );
472 for ( std::size_t i = 0; i < pp.dimension; ++i )
473 pp[ i ] = m * Scalar( p[ i ] );
474 }
Point::Coordinate Scalar
Definition AffineBasis.h:92

Referenced by DGtal::AffineBasis< TPoint >::projectPoints().

◆ dimension()

template<typename TPoint >
Dimension DGtal::AffineBasis< TPoint >::dimension ( ) const
inline
Returns
the affine dimension of the basis
Precondition
the basis is reduced.

Definition at line 248 of file AffineBasis.h.

249 {
250 return second.size();
251 }

References DGtal::AffineBasis< TPoint >::second.

Referenced by DGtal::AffineBasis< TPoint >::isParallel().

◆ findIndexWithSmallestNonNullComponent()

template<typename TPoint >
std::size_t DGtal::AffineBasis< TPoint >::findIndexWithSmallestNonNullComponent ( Dimension  k,
std::size_t  i,
const std::vector< Point > &  basis 
)
inlineprotected

Given a range of points basis, starting from rank i, find the index of the point with lowest non null k-th coefficient in absolute value, or basis.size() if every point had its k-th component null.

Parameters
[in]kthe component/coordinate of interest
[in]ithe starting index
[in]basisa range of points/vectors
Returns
starting from rank i, the index of the point with lowest non null k-th coefficient in absolute value, or basis.size() if every point had its k-th component null.

Definition at line 685 of file AffineBasis.h.

688 {
689 ASSERT( ! basis.empty() );
690 ASSERT( k < Point::dimension );
691 std::size_t index = i;
692 Scalar v = 0;
693 for ( ; index < basis.size(); index++ )
694 {
695 v = abs( basis[ index ][ k ] );
696 if ( Affine::ScalarOps::isNonZero( v, epsilon ) )
697 break;
698 }
699 for ( auto j = index + 1; j < basis.size(); j++ )
700 {
701 Scalar vj = abs( basis[ j ][ k ] );
702 if ( vj != 0 && vj < v )
703 {
704 index = j;
705 v = vj;
706 }
707 }
708 return index;
709 }
unsigned int index(DGtal::uint32_t n, unsigned int b)
Definition testBits.cpp:44

References DGtal::AffineBasis< TPoint >::basis(), DGtal::AffineBasis< TPoint >::epsilon, and index().

Referenced by DGtal::AffineBasis< TPoint >::reduceAsEchelon().

◆ initBasis()

template<typename TPoint >
template<typename TInputPoint >
void DGtal::AffineBasis< TPoint >::initBasis ( const std::vector< TInputPoint > &  basis)
inlineprotected

Removes null vectors from input set of vectors and sets the initial basis.

Template Parameters
TInputPointthe type of input points
Parameters
[in]basisa set of arbitrary vectors

Definition at line 637 of file AffineBasis.h.

638 {
639 second.reserve( basis.size() );
640 for ( auto i = 0; i < basis.size(); i++ )
641 {
642 Point b = Affine::transform( basis[ i ] );
643 if ( b != Point::zero ) second.push_back( b );
644 }
645 }

References DGtal::AffineBasis< TPoint >::basis(), DGtal::AffineBasis< TPoint >::second, and DGtal::AffineGeometry< TPoint >::transform().

Referenced by DGtal::AffineBasis< TPoint >::AffineBasis(), and DGtal::AffineBasis< TPoint >::AffineBasis().

◆ isOnAffineSpace()

template<typename TPoint >
bool DGtal::AffineBasis< TPoint >::isOnAffineSpace ( const Point p) const
inline
Parameters
[in]pany lattice point
Returns
'true' if and only if the point belongs to the affine space spanned by 'this'.

Definition at line 303 of file AffineBasis.h.

304 {
305 const auto [d, lambda, r] = decompose( p );
306 return ! Affine::ScalarOps::isNonZero( r.normInfinity(), epsilon );
307 }
std::tuple< Scalar, Point, Point > decompose(const Point &p) const

References DGtal::AffineBasis< TPoint >::decompose(), and DGtal::AffineBasis< TPoint >::epsilon.

◆ isParallel() [1/2]

template<typename TPoint >
bool DGtal::AffineBasis< TPoint >::isParallel ( const Point w) const
inline
Parameters
[in]wany lattice vector
Returns
'true' if and only if the vector w is parallel to the affine space spanned by 'this'.

Definition at line 313 of file AffineBasis.h.

314 {
315 const auto [d, lambda, r] = decomposeVector( w );
316 return ! Affine::ScalarOps::isNonZero( r.normInfinity(), epsilon );
317 }

References DGtal::AffineBasis< TPoint >::decomposeVector(), and DGtal::AffineBasis< TPoint >::epsilon.

◆ isParallel() [2/2]

template<typename TPoint >
bool DGtal::AffineBasis< TPoint >::isParallel ( const Self other) const
inline
Parameters
[in]otheran other affine basis
Returns
'true' if and only if every vector of 'this' basis is parallel to every vector of the other given basis.

Definition at line 276 of file AffineBasis.h.

277 {
278 if ( dimension() != other.dimension() ) return false;
279 if ( ( _type != Type::ECHELON_REDUCED )
281 trace.error() << "[AffineBasis::isParallel] Requires type=*_ECHELON_REDUCED\n"
282 << " type=" << reductionTypeName() << "\n" ;
283 for ( const auto& b : other.second )
284 if ( ! isParallel( b ) ) return false;
285 return true;
286 }
std::ostream & error()
Trace trace
bool isParallel(const Self &other) const
Dimension dimension() const
std::string reductionTypeName() const

References DGtal::AffineBasis< TPoint >::_type, DGtal::AffineBasis< TPoint >::dimension(), DGtal::AffineBasis< TPoint >::ECHELON_REDUCED, DGtal::Trace::error(), DGtal::AffineBasis< TPoint >::isParallel(), DGtal::AffineBasis< TPoint >::reductionTypeName(), DGtal::AffineBasis< TPoint >::second, DGtal::AffineBasis< TPoint >::SHORTEST_ECHELON_REDUCED, and DGtal::trace.

Referenced by DGtal::AffineBasis< TPoint >::isParallel().

◆ isValid()

template<typename TPoint >
bool DGtal::AffineBasis< TPoint >::isValid ( ) const
inline
Returns
'true' if and only if this object is in a consistent state. Here it means that the matrix is echelon or LLL-reduced.

Definition at line 497 of file AffineBasis.h.

498 {
499 return _type != Type::INVALID;
500 }

References DGtal::AffineBasis< TPoint >::_type, and DGtal::AffineBasis< TPoint >::INVALID.

◆ normalize()

template<typename TPoint >
void DGtal::AffineBasis< TPoint >::normalize ( )
inlineprotected

If the basis is an integer lattice, reduces the basis vectors by their gcd, otherwise normalize vectors to have 1 L2-norm.

Definition at line 531 of file AffineBasis.h.

532 {
533 for ( auto& v : second )
534 v = Affine::simplifiedVector( v );
535 }

References DGtal::AffineBasis< TPoint >::second, and DGtal::AffineGeometry< TPoint >::simplifiedVector().

Referenced by DGtal::AffineBasis< TPoint >::sortBasis().

◆ orderEchelonBasis()

template<typename TPoint >
void DGtal::AffineBasis< TPoint >::orderEchelonBasis ( )
inlineprotected

Guarantees that the basis is in echelon form.

Definition at line 573 of file AffineBasis.h.

574 {
575 auto compare = [this] ( const Point& v, const Point& w ) -> bool
576 {
577 // Note: curiously std::sort sometimes test v against itself
578 // and must return false in this case.
579 for ( auto k = 0; k < Point::dimension; ++k )
580 {
581 bool v_non_null = Affine::ScalarOps::isNonZero( v[ k ], epsilon );
582 bool w_non_null = Affine::ScalarOps::isNonZero( w[ k ], epsilon );
583 if ( v_non_null && ! w_non_null ) return true;
584 else if ( ! v_non_null && w_non_null ) return false;
585 else if ( v_non_null && w_non_null ) return false; // ==
586 }
587 return false; // 0 == 0
588 };
589 std::sort( second.begin(), second.end(), compare );
590 }
bool compare(const Range1 &pts, const Range2 &groundTruth)
Definition testFP.cpp:98

References compare(), DGtal::AffineBasis< TPoint >::epsilon, and DGtal::AffineBasis< TPoint >::second.

Referenced by DGtal::AffineBasis< TPoint >::reduceAsEchelon().

◆ origin()

template<typename TPoint >
const Point & DGtal::AffineBasis< TPoint >::origin ( ) const
inline
Returns
the origin of this affine basis.

Definition at line 254 of file AffineBasis.h.

255 {
256 return first;
257 }

References DGtal::AffineBasis< TPoint >::first.

Referenced by DGtal::AffineBasis< TPoint >::AffineBasis(), and DGtal::AffineBasis< TPoint >::AffineBasis().

◆ projectPoints()

template<typename TPoint >
template<typename ProjectedPoint >
Scalar DGtal::AffineBasis< TPoint >::projectPoints ( std::vector< ProjectedPoint > &  result,
const Points input 
)
inline

Projects the range of points input onto the affine basis and outputs it in result. A consistent choice for ProjectedPoint is to match the affine dimension.

Template Parameters
ProjectedPointa type of point that matches the affine dimension.
Parameters
[out]resultthe range of projected points.
[in]inputthe range of input points
Returns
the maximum dilation of projected rational coordinates that was used to create integer coordinates.

Definition at line 421 of file AffineBasis.h.

423 {
424 Scalar lcm = 1;
425 std::vector< Scalar > denoms ( input.size() );
426 std::vector< Point > lambdas( input.size() );
427 Point r;
428 // get points rational coordinates.
429 for ( std::size_t i = 0; i < input.size(); i++ )
430 std::tie( denoms[ i ], lambdas[ i ], r ) = decompose( input[ i ] );
431 // compute ppcm
432 for ( std::size_t i = 0; i < denoms.size(); i++ )
433 {
434 const Scalar d = denoms[ i ];
435 if ( d == 1 ) continue;
436 lcm = Affine::ScalarOps::lcmPositive( lcm, d );
437 }
438 // project points
439 result.resize( input.size() );
440 for ( std::size_t i = 0; i < input.size(); i++ )
441 dilatedTransform( result[ i ], lambdas[ i ], lcm / denoms[ i ] );
442 return lcm;
443 }
static void dilatedTransform(OtherPoint &pp, const Point &p, Scalar m)

References DGtal::AffineBasis< TPoint >::decompose(), and DGtal::AffineBasis< TPoint >::dilatedTransform().

◆ rationalCoordinates()

template<typename TPoint >
std::pair< Scalar, Point > DGtal::AffineBasis< TPoint >::rationalCoordinates ( const Point p) const
inline
Parameters
[in]pany lattice point
Returns
its rational coordinates L/d as a pair (d, L) in this affine basis, where L is a lattice vector and d is the common denominator for the components of L.

Definition at line 293 of file AffineBasis.h.

294 {
295 const auto [d, lambda, remainder] = decompose( p );
296 return std::make_pair( d, lambda );
297 }

References DGtal::AffineBasis< TPoint >::decompose().

◆ recompose()

template<typename TPoint >
Point DGtal::AffineBasis< TPoint >::recompose ( Scalar  d,
const Point lambda,
const Point r = Point::zero 
) const
inline

Given (d, lambda, r), recompose the point p such that d * (p - o) = l[0]b[0] + ... l[i]b[i] + r. Given only the rational coordinates (d,lambda), the point is assumed to lie on this affine space (i.e. r == 0 ).

Parameters
[in]dthe common denominator that defines the rational coordinates with lambda.
[in]lambdathe numerators that defines the rational coordinates with d.
[in]rthe remainder vector (r is independent from this basis B=(b[0],...,b[i])), which represents the displacement from p to this affine space.
Returns
the point p such that d * (p - o) = B lambda + r, for B the vectors of this basis (arranged as rows in matrix) and o its origin.

Definition at line 337 of file AffineBasis.h.

339 {
340 return first + recomposeVector( d, lambda, r );
341 }
Point recomposeVector(Scalar d, const Point &lambda, const Point &r=Point::zero) const

References DGtal::AffineBasis< TPoint >::first, and DGtal::AffineBasis< TPoint >::recomposeVector().

◆ recomposeVector()

template<typename TPoint >
Point DGtal::AffineBasis< TPoint >::recomposeVector ( Scalar  d,
const Point lambda,
const Point r = Point::zero 
) const
inline

Given (d, lambda, r), recompose the vector w such that d * w = l[0]b[0] + ... l[i]b[i] + r. Given only the rational coordinates (d,lambda), the vector is assumed to be parallel to this affine space (i.e. r == 0 ).

Parameters
[in]dthe common denominator that defines the rational coordinates with lambda.
[in]lambdathe numerators that defines the rational coordinates with d.
[in]rthe remainder vector (r is independent from this basis B=(b[0],...,b[i])), which represents the displacement vector to this vector space.
Returns
the point p such that d * w = B lambda + r, for B the vectors of this basis (arranged as rows in matrix) and o its origin.

Definition at line 361 of file AffineBasis.h.

363 {
364 Point w = r;
365 for ( std::size_t i = 0; i < second.size(); i++ )
366 w += lambda[ i ] * second[ i ];
367 return w / d;
368 }

References DGtal::AffineBasis< TPoint >::second.

Referenced by DGtal::AffineBasis< TPoint >::recompose().

◆ reduce()

template<typename TPoint >
void DGtal::AffineBasis< TPoint >::reduce ( AffineBasis< TPoint >::Type  type,
double  delta 
)
inline

Reduces the basis into a set of a linearly independent vectors, and in the desired reduced form.

Parameters
[in]typethe desired type of matrix reduction.
[in]deltathe parameter \( \delta \) of LLL-algorithm, which should be between 0.25 and 1 (value 0.99 is default in sagemath).

Definition at line 229 of file AffineBasis.h.

230 {
231 if ( type == Type::SHORTEST_ECHELON_REDUCED )
232 sortBasis();
234 reduceAsEchelon( type );
235 else if ( type == Type::LLL_REDUCED )
236 {
237 std::vector< Point > X( second.size()+1 );
238 X[ 0 ] = first;
239 for ( auto i = 0; i < second.size(); i++ )
240 X[ i+1 ] = second[ i ] + first;
242 reduceAsLLL( delta, (Scalar) 0 );
243 }
244 }
void reduceAsEchelon(Type type)
void reduceAsLLL(double delta, Scalar)

References DGtal::AffineGeometry< TPoint >::affineBasis(), DGtal::AffineBasis< TPoint >::ECHELON_REDUCED, DGtal::AffineBasis< TPoint >::epsilon, DGtal::AffineBasis< TPoint >::first, DGtal::AffineBasis< TPoint >::LLL_REDUCED, DGtal::AffineBasis< TPoint >::reduceAsEchelon(), DGtal::AffineBasis< TPoint >::reduceAsLLL(), DGtal::AffineBasis< TPoint >::second, DGtal::AffineBasis< TPoint >::SHORTEST_ECHELON_REDUCED, and DGtal::AffineBasis< TPoint >::sortBasis().

Referenced by DGtal::AffineBasis< TPoint >::AffineBasis(), and DGtal::AffineBasis< TPoint >::AffineBasis().

◆ reduceAsEchelon()

template<typename TPoint >
void DGtal::AffineBasis< TPoint >::reduceAsEchelon ( Type  type)
inlineprotected

Reduces the basis so that each basis vector is normalized, removes linearly dependent vectors, and builds a echelon matrix.

Definition at line 539 of file AffineBasis.h.

540 {
541 std::vector< bool > is_independent( second.size(), false );
542 std::vector< std::vector< Scalar > > U( second.size() );
543 Dimension k = 0; // the current column to put in echelon form.
544 for ( std::size_t i = 0; i < second.size(); i++ )
545 {
546 std::size_t row = findIndexWithSmallestNonNullComponent( k, i, second );
547 if ( row != i && row != second.size() )
548 std::swap( second[ i ], second[ row ] );
549 Point& w = second[ i ];
550 // check if this vector is independent from the previous ones
551 is_independent[ i ] = true;
552 for ( std::size_t j = 0; j < i; j++ )
553 if ( is_independent[ j ] )
555 if ( ! Affine::ScalarOps::isNonZero( w.normInfinity(), epsilon ) )
556 is_independent[ i ] = false; // not independent, forget it
557 else
558 { // independent, make sure it is reduced.
560 k++;
561 }
562 }
563 Points new_basis;
564 for ( std::size_t i = 0; i < second.size(); i++ )
565 if ( is_independent[ i ] )
566 new_basis.push_back( second[ i ] );
567 std::swap( second, new_basis );
569 _type = type;
570 }
DGtal::uint32_t Dimension
Definition Common.h:119
std::vector< Point > Points
Definition AffineBasis.h:93
void orderEchelonBasis()
Guarantees that the basis is in echelon form.
std::size_t findIndexWithSmallestNonNullComponent(Dimension k, std::size_t i, const std::vector< Point > &basis)
static Point simplifiedVector(Point v)

References DGtal::AffineBasis< TPoint >::_type, DGtal::AffineBasis< TPoint >::epsilon, DGtal::AffineBasis< TPoint >::findIndexWithSmallestNonNullComponent(), DGtal::AffineBasis< TPoint >::orderEchelonBasis(), DGtal::AffineGeometry< TPoint >::reduceVector(), DGtal::AffineBasis< TPoint >::second, and DGtal::AffineGeometry< TPoint >::simplifiedVector().

Referenced by DGtal::AffineBasis< TPoint >::reduce().

◆ reduceAsLLL()

template<typename TPoint >
void DGtal::AffineBasis< TPoint >::reduceAsLLL ( double  delta,
Scalar   
)
inlineprotected

Reduces the basis so that each basis vector is normalized, then computes its delta-LLL-reduction lattice, and removes linearly dependent vectors.

Parameters
[in]deltathe parameter \( \delta \) of LLL-algorithm, which should be between 0.25 and 1 (value 0.99 is default in sagemath).

keep only independent vectors in basis

Definition at line 599 of file AffineBasis.h.

600 {
601 if constexpr( std::is_floating_point< Scalar >::value == true )
602 {
603 trace.error() << "[AffineBasis::reduceAsLLL]"
604 << " It has no meaning to use LLL algorithm on matrix with double coefficients\n";
606 return;
607 }
608 for ( auto& v : second )
609 v = Affine::simplifiedVector( v );
610 std::vector< std::vector< Scalar > > B( second.size() );
611 for ( auto i = 0; i < second.size(); i++ )
612 {
613 B[ i ] = std::vector< Scalar >( Point::dimension );
614 for ( auto j = 0; j < Point::dimension; j++ )
615 B[ i ][ j ] = second[ i ][ j ];
616 }
619 second.clear();
620 for ( std::size_t i = 0; i < B.size(); i++ )
621 {
622 Point b;
623 for ( auto j = 0; j < Point::dimension; j++ )
624 b[ j ] = B[ i ][ j ];
625 if ( b != Point::zero )
626 second.push_back( Affine::simplifiedVector( b ) );
627 }
629 }
void reduceBasisWithLLL(std::vector< std::vector< TComponent > > &B, TDouble delta=0.75)

References DGtal::AffineBasis< TPoint >::_type, DGtal::Trace::error(), DGtal::AffineBasis< TPoint >::INVALID, DGtal::AffineBasis< TPoint >::LLL_REDUCED, DGtal::functions::reduceBasisWithLLL(), DGtal::AffineBasis< TPoint >::second, DGtal::AffineGeometry< TPoint >::simplifiedVector(), and DGtal::trace.

Referenced by DGtal::AffineBasis< TPoint >::reduce().

◆ reductionTypeName()

template<typename TPoint >
std::string DGtal::AffineBasis< TPoint >::reductionTypeName ( ) const
inline
Returns
the type of matrix as a string

Definition at line 503 of file AffineBasis.h.

504 {
505 if ( _type == Type::INVALID ) return "INVALID";
506 else if ( _type == Type::ECHELON_REDUCED ) return "ECHELON_REDUCED";
507 else if ( _type == Type::SHORTEST_ECHELON_REDUCED ) return "SHORTEST_ECHELON_REDUCED";
508 else if ( _type == Type::LLL_REDUCED ) return "LLL_REDUCED";
509 else return "";
510 }

References DGtal::AffineBasis< TPoint >::_type, DGtal::AffineBasis< TPoint >::ECHELON_REDUCED, DGtal::AffineBasis< TPoint >::INVALID, DGtal::AffineBasis< TPoint >::LLL_REDUCED, and DGtal::AffineBasis< TPoint >::SHORTEST_ECHELON_REDUCED.

Referenced by DGtal::AffineBasis< TPoint >::isParallel(), and DGtal::AffineBasis< TPoint >::selfDisplay().

◆ selfDisplay()

template<typename TPoint >
void DGtal::AffineBasis< TPoint >::selfDisplay ( std::ostream &  out) const
inline

Displays this object on the output stream.

Parameters
[in,out]outany output stream.

Definition at line 486 of file AffineBasis.h.

487 {
488 out << "[ AffineBasis o=" << first
489 << " type=" << reductionTypeName()
490 << " B=";
491 for ( auto b : second ) std::cout << "\n " << b;
492 out << " ]";
493 }

References DGtal::AffineBasis< TPoint >::first, DGtal::AffineBasis< TPoint >::reductionTypeName(), and DGtal::AffineBasis< TPoint >::second.

Referenced by DGtal::operator<<().

◆ sortBasis()

template<typename TPoint >
void DGtal::AffineBasis< TPoint >::sortBasis ( )
inlineprotected

Simplifies vectors, removes duplicates and puts smallest candidate basis vectors before longest.

Definition at line 649 of file AffineBasis.h.

650 {
651 // Reduces all vectors
652 normalize();
653 // Purge duplicates
654 std::sort( second.begin(), second.end() );
655 second.erase( std::unique( second.begin(), second.end() ), second.end() );
656 // Sort according to size of components.
657 auto compare = []( const Point& u, const Point& v ) -> bool
658 {
659 const auto n1_u = u.norm1();
660 const auto n1_v = v.norm1();
661 if ( n1_u < n1_v ) return true;
662 else if ( n1_v < n1_u ) return false;
663 const auto noo_u = u.normInfinity();
664 const auto noo_v = v.normInfinity();
665 if ( noo_u < noo_v ) return true;
666 else if ( noo_v < noo_u ) return false;
667 return u < v;
668 };
669 std::sort( second.begin(), second.end(), compare );
670 }

References compare(), DGtal::AffineBasis< TPoint >::normalize(), and DGtal::AffineBasis< TPoint >::second.

Referenced by DGtal::AffineBasis< TPoint >::reduce().

◆ transform()

template<typename TPoint >
template<typename OtherPoint >
static void DGtal::AffineBasis< TPoint >::transform ( OtherPoint &  pp,
const Point p 
)
inlinestatic

Transforms the type of an input point into another one.

Template Parameters
OtherPointa type of point of dimension at most Point::dimension.
Parameters
[out]ppthe output restricted point.
[in]pthe input point.

Definition at line 452 of file AffineBasis.h.

453 {
454 BOOST_STATIC_ASSERT( OtherPoint::dimension <= Point::dimension );
455 typedef typename OtherPoint::Coordinate Scalar;
456 for ( std::size_t i = 0; i < pp.dimension; ++i )
457 pp[ i ] = Scalar( p[ i ] );
458 }

Field Documentation

◆ _type

◆ epsilon

◆ first

◆ second


The documentation for this struct was generated from the following file: