2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * @file BoundedRationalPolytope.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
24 * Implementation of inline methods defined in BoundedRationalPolytope.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 #include "DGtal/math/linalg/SimpleMatrix.h"
33 //////////////////////////////////////////////////////////////////////////////
35 ///////////////////////////////////////////////////////////////////////////////
36 // IMPLEMENTATION of inline methods.
37 ///////////////////////////////////////////////////////////////////////////////
39 ///////////////////////////////////////////////////////////////////////////////
40 // ----------------------- Standard services ------------------------------
42 //-----------------------------------------------------------------------------
43 template <typename TSpace>
44 DGtal::BoundedRationalPolytope<TSpace>::
45 BoundedRationalPolytope()
46 : q( NumberTraits<Integer>::ZERO ),
47 rationalD( Point::zero, Point::zero ),
48 latticeD( Point::zero, Point::zero ),
49 myValidEdgeConstraints( false )
52 //-----------------------------------------------------------------------------
53 template <typename TSpace>
55 DGtal::BoundedRationalPolytope<TSpace>::
61 myValidEdgeConstraints = false;
62 rationalD = Domain( Point::zero, Point::zero );
63 latticeD = Domain( Point::zero, Point::zero );
67 //-----------------------------------------------------------------------------
68 template <typename TSpace>
69 DGtal::BoundedRationalPolytope<TSpace>::
70 BoundedRationalPolytope( std::initializer_list<Point> l )
72 myValidEdgeConstraints = false;
76 Integer denom = (*it++)[ 0 ];
77 init( denom, it, l.end() );
81 //-----------------------------------------------------------------------------
82 template <typename TSpace>
83 template <typename PointIterator>
84 DGtal::BoundedRationalPolytope<TSpace>::
85 BoundedRationalPolytope( Integer denom, PointIterator itB, PointIterator itE )
87 myValidEdgeConstraints = false;
88 init( denom, itB, itE );
91 //-----------------------------------------------------------------------------
92 template <typename TSpace>
93 template <typename HalfSpaceIterator>
94 DGtal::BoundedRationalPolytope<TSpace>::
95 BoundedRationalPolytope( Integer denom,
97 HalfSpaceIterator itB, HalfSpaceIterator itE,
98 bool valid_edge_constraints )
99 : myValidEdgeConstraints( valid_edge_constraints )
101 init( denom, domain, itB, itE );
104 //-----------------------------------------------------------------------------
105 template <typename TSpace>
106 template <typename HalfSpaceIterator>
108 DGtal::BoundedRationalPolytope<TSpace>::
110 const Domain& domain,
111 HalfSpaceIterator itB, HalfSpaceIterator itE,
112 bool valid_edge_constraints )
116 myValidEdgeConstraints = valid_edge_constraints;
117 const Dimension d = dimension;
118 const Point lo = domain.lowerBound();
119 const Point hi = domain.upperBound();
120 rationalD = Domain( lo, hi );
121 latticeD = computeLatticeDomain( rationalD );
122 // Add constraints related to sup/inf in x.
123 for ( Dimension s = 0; s < d; ++s )
125 Vector z = Vector::zero;
128 B.push_back( hi[ s ] );
131 B.push_back( -lo[ s ] );
133 // Add other halfplanes
135 for ( auto it = itB; itB != itE; ++it, ++nb_hp ) {
136 // Checks that is not inside.
139 auto itF = std::find( A.begin(), A.begin()+2*d, a );
140 if ( itF == A.end() )
142 A.push_back( q * a );
147 auto k = itF - A.begin();
148 B[ k ] = std::min( B[ k ], b );
151 I = std::vector<bool>( 2 * d + nb_hp, true ); // inequalities are large
154 //-----------------------------------------------------------------------------
155 template <typename TSpace>
157 DGtal::BoundedRationalPolytope<TSpace>::
158 internalInitFromTriangle3D( Point a, Point b, Point c )
163 Vector n = detail::BoundedRationalPolytopeSpecializer< dimension, Integer >::
164 crossProduct( ab, bc );
165 if ( n == Vector::zero ) { clear(); return false; }
166 A.push_back( q * n );
167 B.push_back( a.dot( n ) );
168 A.push_back( -q * n );
169 B.push_back( -a.dot( n ) );
170 Vector abn = detail::BoundedRationalPolytopeSpecializer< dimension, Integer >::
171 crossProduct( ab, n );
172 A.push_back( q * abn );
173 B.push_back( a.dot( abn ) );
174 Vector bcn = detail::BoundedRationalPolytopeSpecializer< dimension, Integer >::
175 crossProduct( bc, n );
176 A.push_back( q * bcn );
177 B.push_back( b.dot( bcn ) );
178 Vector can = detail::BoundedRationalPolytopeSpecializer< dimension, Integer >::
179 crossProduct( ca, n );
180 A.push_back( q * can );
181 B.push_back( c.dot( can ) );
182 I = std::vector<bool>( 2*3+5, true ); // inequalities are large
186 //-----------------------------------------------------------------------------
187 template <typename TSpace>
189 DGtal::BoundedRationalPolytope<TSpace>::
190 internalInitFromSegment3D( Point a, Point b )
193 if ( ab == Vector::zero ) return true; // domain and constraints already computed
195 Vector n = detail::BoundedRationalPolytopeSpecializer< dimension, Integer >::
196 crossProduct( ab, t );
197 if ( n == Vector::zero )
199 t = Vector( 0, 1, 0 );
200 n = detail::BoundedRationalPolytopeSpecializer< dimension, Integer >::
201 crossProduct( ab, t );
203 A.push_back( q * n );
204 B.push_back( a.dot( n ) );
205 A.push_back( -q * n );
206 B.push_back( -a.dot( n ) );
207 Vector w = detail::BoundedRationalPolytopeSpecializer< dimension, Integer >::
208 crossProduct( ab, n );
209 A.push_back( q * w );
210 B.push_back( a.dot( w ) );
211 A.push_back( -q * w );
212 B.push_back( -a.dot( w ) );
213 I = std::vector<bool>( 2*3+4, true ); // inequalities are large
217 //-----------------------------------------------------------------------------
218 template <typename TSpace>
220 DGtal::BoundedRationalPolytope<TSpace>::
221 internalInitFromSegment2D( Point a, Point b )
224 if ( ab == Vector::zero ) return true; // domain and constraints already computed
225 Vector n( -ab[ 1 ], ab[ 0 ] );
226 A.push_back( q * n );
227 B.push_back( a.dot( n ) );
228 A.push_back( -q * n );
229 B.push_back( -a.dot( n ) );
230 I = std::vector<bool>( 2*2+2, true ); // inequalities are large
234 //-----------------------------------------------------------------------------
235 template <typename TSpace>
236 typename DGtal::BoundedRationalPolytope<TSpace>::Domain
237 DGtal::BoundedRationalPolytope<TSpace>::
238 computeLatticeDomain( const Domain& d )
241 for ( Dimension i = 0; i < Space::dimension; i++ )
243 lo[ i ] = d.lowerBound()[ i ] / q;
244 hi[ i ] = d.upperBound()[ i ] / q;
246 return Domain( lo, hi );
248 //-----------------------------------------------------------------------------
249 template <typename TSpace>
250 typename DGtal::BoundedRationalPolytope<TSpace>::Domain
251 DGtal::BoundedRationalPolytope<TSpace>::
252 computeRationalDomain( const Domain& d )
255 for ( Dimension i = 0; i < Space::dimension; i++ )
257 lo[ i ] = d.lowerBound()[ i ] * q;
258 hi[ i ] = d.upperBound()[ i ] * q;
260 return Domain( lo, hi );
263 //-----------------------------------------------------------------------------
264 template <typename TSpace>
265 template <typename PointIterator>
267 DGtal::BoundedRationalPolytope<TSpace>::
268 init( Integer denom, PointIterator itB, PointIterator itE )
270 typedef SimpleMatrix<Integer,dimension,dimension> Matrix;
273 const Dimension d = dimension;
274 std::vector<Point> pts;
275 for ( ; itB != itE; ++itB ) pts.push_back( *itB );
278 for ( Dimension s = 1; s < pts.size(); ++s )
280 lo = lo.inf( pts[ s ] );
281 hi = hi.sup( pts[ s ] );
283 // Add constraints related to sup/inf in x.
284 for ( Dimension s = 0; s < d; ++s )
286 Vector z = Vector::zero;
289 B.push_back( hi[ s ] );
292 B.push_back( -lo[ s ] );
294 rationalD = Domain( lo, hi );
295 latticeD = computeLatticeDomain( rationalD );
296 if ( pts.size() != d+1 )
297 { // Some degenerated cases are taken into account.
298 myValidEdgeConstraints = true;
300 if ( pts.size() == 3 )
301 return internalInitFromTriangle3D( pts[ 0 ], pts[ 1 ], pts[ 2 ] );
302 else if ( pts.size() == 2 )
303 return internalInitFromSegment3D( pts[ 0 ], pts[ 1 ] );
304 } else if ( d == 2 ) {
305 if ( pts.size() == 2 )
306 return internalInitFromSegment2D( pts[ 0 ], pts[ 1 ] );
308 I = std::vector<bool>( 2*2, true ); // inequalities are large
309 if ( pts.size() == 1 ) return true;
313 // Build Matrix A and Vector b through cofactors
314 I = std::vector<bool>( 3*d+1, true ); // inequalities are large
317 for ( Dimension s = 0; s <= d; ++s )
319 // Build matrix v composed of p_i and vectors p_k - p_i for i and k != p
321 Dimension p = (s+1) % (d+1);
322 for ( Dimension j = 0; j < d; ++j )
323 V.setComponent( 0, j, pts[ p ][ j ] - pts[ s ][ j ] );
324 for ( Dimension k = 1; k < d; ++k )
326 Dimension l = (p+k) % (d+1);
327 for ( Dimension j = 0; j < d; ++j )
328 V.setComponent( k, j, pts[ l ][ j ] - pts[ p ][ j ] );
336 // Form vector [b, 0, ..., 0]
337 Vector z = Vector::zero;
339 a = V.cofactor().transpose() * z;
340 b += a.dot( pts[ s ] );
342 if ( a.dot( pts[ s ] ) > b ) { a *= (Integer) -1; b *= (Integer) -1; }
343 A.push_back( q * a );
346 myValidEdgeConstraints = true;
347 if ( dimension >= 3 )
348 { // One should add edges
349 for ( unsigned int i = 0; i < pts.size(); ++i )
350 for ( unsigned int j = i+1; j < pts.size(); ++j ) {
351 detail::BoundedRationalPolytopeSpecializer< dimension, Integer >::addEdgeConstraint
352 ( *this, i, j, pts );
354 if ( dimension >= 4 )
355 { // Not implemented yet
356 myValidEdgeConstraints = false;
363 //-----------------------------------------------------------------------------
364 template <typename TSpace>
365 DGtal::BoundedRationalPolytope<TSpace>
366 DGtal::BoundedRationalPolytope<TSpace>::
367 interiorPolytope() const
369 BoundedRationalPolytope P( *this );
370 P.I = std::vector<bool>( P.A.size(), false );
371 // for ( auto it = P.I.begin(), itE = P.I.end(); it != itE; ++it )
376 //-----------------------------------------------------------------------------
377 template <typename TSpace>
379 DGtal::BoundedRationalPolytope<TSpace>::
380 cut( Dimension k, bool pos, Integer b, bool large )
382 ASSERT( k < dimension );
383 auto i = 2*k + (pos ? 0 : 1);
384 B[ i ] = std::min( B[ i ], b );
386 Point L = rationalD.lowerBound();
387 Point U = rationalD.upperBound();
388 if ( pos ) U[ k ] = B[ i ];
389 else L[ k ] = -B[ i ];
390 rationalD = Domain( L, U );
391 latticeD = computeLatticeDomain( rationalD );
395 //-----------------------------------------------------------------------------
396 template <typename TSpace>
398 DGtal::BoundedRationalPolytope<TSpace>::
399 cut( const Vector& a, Integer b, bool large, bool valid_edge_constraint )
401 // Checks that is not inside.
402 auto it = std::find( A.begin(), A.end(), a );
405 A.push_back( q * a );
407 I.push_back( large );
408 myValidEdgeConstraints = myValidEdgeConstraints && valid_edge_constraint; // a cut might invalidate an edge constraint
413 auto k = it - A.begin();
414 B[ k ] = std::min( B[ k ], b );
416 myValidEdgeConstraints = myValidEdgeConstraints && valid_edge_constraint; // a cut might invalidate an edge constraint
420 //-----------------------------------------------------------------------------
421 template <typename TSpace>
423 DGtal::BoundedRationalPolytope<TSpace>::
424 cut( const HalfSpace& hs, bool large, bool valid_edge_constraint )
428 return cut( a, b, large, valid_edge_constraint );
431 //-----------------------------------------------------------------------------
432 template <typename TSpace>
434 DGtal::BoundedRationalPolytope<TSpace>::
435 swap( BoundedRationalPolytope & other )
440 std::swap( rationalD, other.rationalD );
441 std::swap( latticeD, other.latticeD );
442 std::swap( myValidEdgeConstraints, other.myValidEdgeConstraints );
443 std::swap( q, other.q );
446 //-----------------------------------------------------------------------------
447 template <typename TSpace>
449 DGtal::BoundedRationalPolytope<TSpace>::
450 isInside( const Point& p ) const
453 for ( Dimension i = 0; i < A.size(); ++i )
457 ? A[ i ].dot( p ) <= B[ i ]
458 : A[ i ].dot( p ) < B[ i ];
459 if ( ! in_half_space ) return false;
464 //-----------------------------------------------------------------------------
465 template <typename TSpace>
467 DGtal::BoundedRationalPolytope<TSpace>::
468 isDomainPointInside( const Point& p ) const
471 for ( Dimension i = 2*dimension; i < A.size(); ++i )
475 ? A[ i ].dot( p ) <= B[ i ]
476 : A[ i ].dot( p ) < B[ i ];
477 if ( ! in_half_space ) return false;
482 //-----------------------------------------------------------------------------
483 template <typename TSpace>
485 DGtal::BoundedRationalPolytope<TSpace>::
486 isInterior( const Point& p ) const
489 for ( Dimension i = 0; i < A.size(); ++i )
491 bool in_half_space = A[ i ].dot( p ) < B[ i ];
492 if ( ! in_half_space ) return false;
497 //-----------------------------------------------------------------------------
498 template <typename TSpace>
500 DGtal::BoundedRationalPolytope<TSpace>::
501 isBoundary( const Point& p ) const
504 bool is_boundary = false;
505 for ( Dimension i = 0; i < A.size(); ++i )
507 auto Ai_dot_p = A[ i ].dot( p );
508 if ( Ai_dot_p == B[ i ] ) is_boundary = true;
509 if ( Ai_dot_p > B[ i ] ) return false;
514 //-----------------------------------------------------------------------------
515 template <typename TSpace>
516 typename DGtal::BoundedRationalPolytope<TSpace>::Self&
517 DGtal::BoundedRationalPolytope<TSpace>::
518 operator*=( Integer t )
520 const Integer g = IntegerComputer< Integer >::staticGcd( q, t );
521 const Integer f = t / g;
522 for ( Integer& b : B ) b *= f;
523 for ( Vector& a : A ) a /= g;
524 rationalD = Domain( rationalD.lowerBound() * f, rationalD.upperBound() * f );
526 latticeD = computeLatticeDomain( rationalD );
530 //-----------------------------------------------------------------------------
531 template <typename TSpace>
532 typename DGtal::BoundedRationalPolytope<TSpace>::Self&
533 DGtal::BoundedRationalPolytope<TSpace>::
534 operator*=( Rational r )
536 const Integer g = IntegerComputer< Integer >::staticGcd( q * r.q, r.p );
537 const Integer f = r.p / g;
538 for ( Integer& b : B ) { b *= f; }
539 for ( Vector& a : A ) { a *= r.q; a /= g; }
540 rationalD = Domain( rationalD.lowerBound() * f, rationalD.upperBound() * f );
543 latticeD = computeLatticeDomain( rationalD );
547 //-----------------------------------------------------------------------------
548 template <typename TSpace>
549 typename DGtal::BoundedRationalPolytope<TSpace>::Self&
550 DGtal::BoundedRationalPolytope<TSpace>::
551 operator+=( UnitSegment s )
553 for ( Dimension i = 0; i < A.size(); ++i )
555 if ( A[ i ][ s.k ] > NumberTraits<Integer>::ZERO )
556 B[ i ] += A[ i ][ s.k ];
558 Vector z = Vector::zero;
559 z[ s.k ] = NumberTraits<Integer>::ONE;
560 rationalD = Domain( rationalD.lowerBound(), rationalD.upperBound() + q * z );
561 latticeD = Domain( latticeD.lowerBound(), latticeD.upperBound() + z );
566 //-----------------------------------------------------------------------------
567 template <typename TSpace>
568 typename DGtal::BoundedRationalPolytope<TSpace>::Self&
569 DGtal::BoundedRationalPolytope<TSpace>::
570 operator+=( UnitCell c )
572 for ( Dimension i = 0; i < c.dims.size(); ++i )
573 *this += UnitSegment( c.dims[ i ] );
578 //-----------------------------------------------------------------------------
579 template <typename TSpace>
580 typename DGtal::BoundedRationalPolytope<TSpace>::Integer
581 DGtal::BoundedRationalPolytope<TSpace>::
585 for ( const Point & p : latticeD )
586 nb += isDomainPointInside( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
590 //-----------------------------------------------------------------------------
591 template <typename TSpace>
592 typename DGtal::BoundedRationalPolytope<TSpace>::Integer
593 DGtal::BoundedRationalPolytope<TSpace>::
594 countInterior() const
597 for ( const Point & p : latticeD )
598 nb += isInterior( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
601 //-----------------------------------------------------------------------------
602 template <typename TSpace>
603 typename DGtal::BoundedRationalPolytope<TSpace>::Integer
604 DGtal::BoundedRationalPolytope<TSpace>::
605 countBoundary() const
608 for ( const Point & p : latticeD )
609 nb += isBoundary( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
612 //-----------------------------------------------------------------------------
613 template <typename TSpace>
614 typename DGtal::BoundedRationalPolytope<TSpace>::Integer
615 DGtal::BoundedRationalPolytope<TSpace>::
616 countWithin( Point lo, Point hi ) const
619 Domain D1( lo.sup( latticeD.lowerBound() ), hi.inf( latticeD.upperBound() ) );
620 for ( const Point & p : D1 )
621 nb += isDomainPointInside( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
624 //-----------------------------------------------------------------------------
625 template <typename TSpace>
626 typename DGtal::BoundedRationalPolytope<TSpace>::Integer
627 DGtal::BoundedRationalPolytope<TSpace>::
628 countUpTo( Integer max) const
631 for ( const Point & p : latticeD ) {
632 nb += isDomainPointInside( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
633 if ( nb >= max ) return max;
637 //-----------------------------------------------------------------------------
638 template <typename TSpace>
640 DGtal::BoundedRationalPolytope<TSpace>::
641 getPoints( std::vector<Point>& pts ) const
644 for ( const Point & p : latticeD )
645 if ( isDomainPointInside( p ) ) pts.push_back( p );
647 //-----------------------------------------------------------------------------
648 template <typename TSpace>
649 template <typename PointSet>
651 DGtal::BoundedRationalPolytope<TSpace>::
652 insertPoints( PointSet& pts_set ) const
654 for ( const Point & p : latticeD )
655 if ( isDomainPointInside( p ) ) pts_set.insert( p );
657 //-----------------------------------------------------------------------------
658 template <typename TSpace>
660 DGtal::BoundedRationalPolytope<TSpace>::
661 getInteriorPoints( std::vector<Point>& pts ) const
664 for ( const Point & p : latticeD )
665 if ( isInterior( p ) ) pts.push_back( p );
667 //-----------------------------------------------------------------------------
668 template <typename TSpace>
670 DGtal::BoundedRationalPolytope<TSpace>::
671 getBoundaryPoints( std::vector<Point>& pts ) const
674 for ( const Point & p : latticeD )
675 if ( isBoundary( p ) ) pts.push_back( p );
678 //-----------------------------------------------------------------------------
679 template <typename TSpace>
680 const typename DGtal::BoundedRationalPolytope<TSpace>::Domain&
681 DGtal::BoundedRationalPolytope<TSpace>::getDomain() const
686 //-----------------------------------------------------------------------------
687 template <typename TSpace>
688 const typename DGtal::BoundedRationalPolytope<TSpace>::Domain&
689 DGtal::BoundedRationalPolytope<TSpace>::getLatticeDomain() const
694 //-----------------------------------------------------------------------------
695 template <typename TSpace>
696 const typename DGtal::BoundedRationalPolytope<TSpace>::Domain&
697 DGtal::BoundedRationalPolytope<TSpace>::getRationalDomain() const
702 //-----------------------------------------------------------------------------
703 template <typename TSpace>
705 DGtal::BoundedRationalPolytope<TSpace>::nbHalfSpaces() const
710 //-----------------------------------------------------------------------------
711 template <typename TSpace>
712 typename DGtal::BoundedRationalPolytope<TSpace>::Integer
713 DGtal::BoundedRationalPolytope<TSpace>::denominator() const
719 //-----------------------------------------------------------------------------
720 template <typename TSpace>
721 const typename DGtal::BoundedRationalPolytope<TSpace>::Vector&
722 DGtal::BoundedRationalPolytope<TSpace>::getA( unsigned int i ) const
724 ASSERT( i < nbHalfSpaces() );
728 //-----------------------------------------------------------------------------
729 template <typename TSpace>
730 typename DGtal::BoundedRationalPolytope<TSpace>::Integer
731 DGtal::BoundedRationalPolytope<TSpace>::getB( unsigned int i ) const
733 ASSERT( i < nbHalfSpaces() );
737 //-----------------------------------------------------------------------------
738 template <typename TSpace>
740 DGtal::BoundedRationalPolytope<TSpace>::isLarge( unsigned int i ) const
742 ASSERT( i < nbHalfSpaces() );
746 //-----------------------------------------------------------------------------
747 template <typename TSpace>
748 const typename DGtal::BoundedRationalPolytope<TSpace>::InequalityMatrix&
749 DGtal::BoundedRationalPolytope<TSpace>::getA() const
754 //-----------------------------------------------------------------------------
755 template <typename TSpace>
756 const typename DGtal::BoundedRationalPolytope<TSpace>::InequalityVector&
757 DGtal::BoundedRationalPolytope<TSpace>::getB() const
762 //-----------------------------------------------------------------------------
763 template <typename TSpace>
764 const std::vector<bool>&
765 DGtal::BoundedRationalPolytope<TSpace>::getI() const
770 //-----------------------------------------------------------------------------
771 template <typename TSpace>
773 DGtal::BoundedRationalPolytope<TSpace>::canBeSummed() const
775 return myValidEdgeConstraints;
778 ///////////////////////////////////////////////////////////////////////////////
779 // Interface - public :
782 * Writes/Displays the object on an output stream.
783 * @param out the output stream where the object is written.
785 template <typename TSpace>
788 DGtal::BoundedRationalPolytope<TSpace>::selfDisplay ( std::ostream & out ) const
790 out << "[BoundedRationalPolytope<" << Space::dimension << "> A.rows=" << A.size()
791 << " valid_edge_constraints=" << myValidEdgeConstraints
792 << " denom=" << q << "]" << std::endl;
793 for ( Dimension i = 0; i < A.size(); ++i )
796 for ( Dimension j = 0; j < dimension; ++j )
797 out << " " << A[ i ][ j ];
798 out << " ] . x <= " << B[ i ] << std::endl;
803 * Checks the validity/consistency of the object.
804 * @return 'true' if the object is valid, 'false' otherwise.
806 template <typename TSpace>
809 DGtal::BoundedRationalPolytope<TSpace>::isValid() const
811 return q > 0 && ! rationalD.isEmpty();
813 //-----------------------------------------------------------------------------
814 template <typename TSpace>
817 DGtal::BoundedRationalPolytope<TSpace>::className
820 return "BoundedRationalPolytope";
825 ///////////////////////////////////////////////////////////////////////////////
826 // Implementation of inline functions //
828 //-----------------------------------------------------------------------------
829 template <typename TSpace>
832 DGtal::operator<< ( std::ostream & out,
833 const BoundedRationalPolytope<TSpace> & object )
835 object.selfDisplay( out );
838 //-----------------------------------------------------------------------------
839 template <typename TSpace>
840 DGtal::BoundedRationalPolytope<TSpace>
841 DGtal::operator* ( typename BoundedRationalPolytope<TSpace>::Integer t,
842 const BoundedRationalPolytope<TSpace> & P )
844 BoundedRationalPolytope<TSpace> Q = P;
848 //-----------------------------------------------------------------------------
849 template <typename TSpace>
850 DGtal::BoundedRationalPolytope<TSpace>
851 DGtal::operator* ( typename BoundedRationalPolytope<TSpace>::Rational r,
852 const BoundedRationalPolytope<TSpace> & P )
854 BoundedRationalPolytope<TSpace> Q = P;
858 //-----------------------------------------------------------------------------
859 template <typename TSpace>
860 DGtal::BoundedRationalPolytope<TSpace>
861 DGtal::operator+ ( const BoundedRationalPolytope<TSpace> & P,
862 typename BoundedRationalPolytope<TSpace>::UnitSegment s )
864 BoundedRationalPolytope<TSpace> Q = P;
868 //-----------------------------------------------------------------------------
869 template <typename TSpace>
870 DGtal::BoundedRationalPolytope<TSpace>
871 DGtal::operator+ ( const BoundedRationalPolytope<TSpace> & P,
872 typename BoundedRationalPolytope<TSpace>::UnitCell c )
874 BoundedRationalPolytope<TSpace> Q = P;
880 ///////////////////////////////////////////////////////////////////////////////