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 LighterSternBrocot.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
21 * @author Xavier Provençal (\c xavier.provencal@univ-savoie.fr )
22 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
26 * Implementation of inline methods defined in SternBrocot.h
28 * This file is part of the DGtal library.
32 //////////////////////////////////////////////////////////////////////////////
34 #include "DGtal/arithmetic/IntegerComputer.h"
35 //////////////////////////////////////////////////////////////////////////////
37 ///////////////////////////////////////////////////////////////////////////////
38 // DEFINITION of static data members
39 ///////////////////////////////////////////////////////////////////////////////
41 template <typename TInteger, typename TQuotient, typename TMap>
42 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>*
43 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::singleton = 0;
45 ///////////////////////////////////////////////////////////////////////////////
46 // IMPLEMENTATION of inline methods.
47 ///////////////////////////////////////////////////////////////////////////////
50 ///////////////////////////////////////////////////////////////////////////////
51 // ----------------------- Standard services ------------------------------
53 ///////////////////////////////////////////////////////////////////////////////
54 // DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node
55 //-----------------------------------------------------------------------------
56 template <typename TInteger, typename TQuotient, typename TMap>
58 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node::
59 Node( Integer p1, Integer q1, Quotient u1, Quotient k1,
61 : p( p1 ), q( q1 ), u( u1 ), k( k1 ),
64 ASSERT( p >= NumberTraits<Integer>::ONE );
66 //-----------------------------------------------------------------------------
67 template <typename TInteger, typename TQuotient, typename TMap>
69 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node*
70 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node::
73 typedef typename MapQuotientToNode::iterator Iterator;
74 ASSERT( v != NumberTraits<Quotient>::ZERO );
75 if ( v == NumberTraits<Quotient>::ONE )
76 return ( this == instance().myOneOverZero )
77 ? instance().myOneOverOne
79 Iterator itkey = myChildren.find( v );
80 if ( itkey != myChildren.end() )
82 if ( this == instance().myOneOverZero )
85 new Node( (int) NumberTraits<Quotient>::castToInt64_t( v ), // p' = v
86 NumberTraits<Integer>::ONE, // q' = 1
88 NumberTraits<Quotient>::ZERO, // k' = 0
90 myChildren[ v ] = newNode;
91 ++( instance().nbFractions );
94 long int _v = static_cast<long int>(NumberTraits<Quotient>::castToInt64_t( v ));
95 long int _u = static_cast<long int>(NumberTraits<Quotient>::castToInt64_t( this->u ));
96 Integer _pp = origin() == instance().myOneOverZero
97 ? NumberTraits<Integer>::ONE
99 Integer _qq = origin() == instance().myOneOverZero
100 ? NumberTraits<Integer>::ONE
102 Node* newNode = // p' = v*p - (v-1)*(p-p2)/(u-1)
103 new Node( p * _v - ( _v - 1 ) * ( p - _pp ) / (_u - 1),
104 q * _v - ( _v - 1 ) * ( q - _qq ) / (_u - 1),
106 k + NumberTraits<Quotient>::ONE, // k' = k+1
108 myChildren[ v ] = newNode;
109 ++( instance().nbFractions );
112 //-----------------------------------------------------------------------------
113 template <typename TInteger, typename TQuotient, typename TMap>
115 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node*
116 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node::
121 //-----------------------------------------------------------------------------
122 template <typename TInteger, typename TQuotient, typename TMap>
124 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node*
125 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node::
128 ASSERT( origin() != 0 );
129 Node* prevNode = origin();
130 Quotient _u = prevNode->u;
131 prevNode = prevNode->origin();
132 if ( prevNode == 0 ) return instance().myOneOverZero;
133 return prevNode->child( _u - NumberTraits<Quotient>::ONE );
135 //-----------------------------------------------------------------------------
136 template <typename TInteger, typename TQuotient, typename TMap>
138 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node*
139 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node::
142 ASSERT( origin() != 0 );
143 Node* prevNode = origin();
144 if ( this->u == NumberTraits<Quotient>::ONE ) // 1/1
145 return instance().myOneOverZero;
146 return prevNode->child( this->u - NumberTraits<Quotient>::ONE );
149 ///////////////////////////////////////////////////////////////////////////////
150 // DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
151 //-----------------------------------------------------------------------------
152 template <typename TInteger, typename TQuotient, typename TMap>
154 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
155 Fraction( Integer aP, Integer aQ, Fraction )
157 if ( ( aP == NumberTraits<Integer>::ZERO ) &&
158 ( aQ == NumberTraits<Integer>::ONE ) )
159 this->operator=( zeroOverOne() );
162 bool sup1 = aP >= aQ;
163 if ( ! sup1 ) std::swap( aP, aQ );
164 Node* node = instance().myOneOverZero;
166 IntegerComputer<Integer> ic;
167 ic.getEuclideanDiv( _quot, _rem, aP, aQ );
168 Quotient v = static_cast<Quotient>(NumberTraits<Integer>::castToInt64_t( _quot ));
169 // std::cerr << "[u=" << v << "]";
172 while ( aQ != NumberTraits<Integer>::ZERO )
174 node = node->child( v + 1 );
175 ic.getEuclideanDiv( _quot, _rem, aP, aQ );
176 v = static_cast<Quotient>(NumberTraits<Integer>::castToInt64_t( _quot ));
181 myNode = node->child( v );
185 //-----------------------------------------------------------------------------
186 template <typename TInteger, typename TQuotient, typename TMap>
188 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
189 Fraction( Node* sb_node, bool sup1 )
190 : myNode( sb_node ), mySup1( sup1 )
193 //-----------------------------------------------------------------------------
194 template <typename TInteger, typename TQuotient, typename TMap>
196 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
197 Fraction( const Self & other )
198 : myNode( other.myNode ), mySup1( other.mySup1 )
201 //-----------------------------------------------------------------------------
202 template <typename TInteger, typename TQuotient, typename TMap>
204 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction &
205 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
206 operator=( const Self & other )
208 if ( this != &other )
210 myNode = other.myNode;
211 mySup1 = other.mySup1;
215 //-----------------------------------------------------------------------------
216 template <typename TInteger, typename TQuotient, typename TMap>
219 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
224 //-----------------------------------------------------------------------------
225 template <typename TInteger, typename TQuotient, typename TMap>
227 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Integer
228 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
231 return myNode ? ( mySup1 ? myNode->p : myNode->q ) : 0;
233 //-----------------------------------------------------------------------------
234 template <typename TInteger, typename TQuotient, typename TMap>
236 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Integer
237 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
240 return myNode ? ( mySup1 ? myNode->q : myNode->p ) : 0;
242 //-----------------------------------------------------------------------------
243 template <typename TInteger, typename TQuotient, typename TMap>
245 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Quotient
246 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
249 ASSERT( myNode != 0 );
250 return myNode == instance().myOneOverZero
251 ? ( mySup1 ? NumberTraits<Quotient>::ONE : NumberTraits<Quotient>::ZERO )
254 //-----------------------------------------------------------------------------
255 template <typename TInteger, typename TQuotient, typename TMap>
257 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Quotient
258 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
261 ASSERT( myNode != 0 );
262 // The default of this approach is that node 1/1 has two possible depths !
265 : myNode->k + NumberTraits<Quotient>::ONE;
266 // JOL: 2012/11/21: I left these lines in comments because I am not
267 // sure yet if my correction above has no other side effects.
269 // return ( mySup1 || ( myNode == instance().myOneOverOne ) )
271 // : myNode->k + NumberTraits<Quotient>::ONE;
273 //-----------------------------------------------------------------------------
274 template <typename TInteger, typename TQuotient, typename TMap>
277 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
278 equals( Integer p1, Integer q1 ) const
280 return ( this->p() == p1 ) && ( this->q() == q1 );
282 //-----------------------------------------------------------------------------
283 template <typename TInteger, typename TQuotient, typename TMap>
286 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
287 lessThan( Integer p1, Integer q1 ) const
289 Integer d = p() * q1 - q() * p1;
290 return d < NumberTraits<Integer>::ZERO;
292 //-----------------------------------------------------------------------------
293 template <typename TInteger, typename TQuotient, typename TMap>
296 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
297 moreThan( Integer p1, Integer q1 ) const
299 Integer d = p() * q1 - q() * p1;
300 return d > NumberTraits<Integer>::ZERO;
302 //-----------------------------------------------------------------------------
303 template <typename TInteger, typename TQuotient, typename TMap>
306 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
307 operator==( const Fraction & other ) const
309 if ( mySup1 == other.mySup1 )
310 return ( myNode == other.myNode );
312 return ( ( myNode->p == other.myNode->q )
313 && ( myNode->q == other.myNode->p ) );
315 //-----------------------------------------------------------------------------
316 template <typename TInteger, typename TQuotient, typename TMap>
319 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
320 operator!=( const Fraction & other ) const
322 return ! this->operator==( other );
324 //-----------------------------------------------------------------------------
325 template <typename TInteger, typename TQuotient, typename TMap>
328 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
329 operator<( const Fraction & other ) const
331 return this->lessThan( other.p(), other.q() );
333 //-----------------------------------------------------------------------------
334 template <typename TInteger, typename TQuotient, typename TMap>
337 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
338 operator>( const Fraction & other ) const
340 return this->moreThan( other.p(), other.q() );
342 //-----------------------------------------------------------------------------
343 /// @return the fraction [u_0, ..., u_n, v] if [u_0, ..., u_n]
344 /// is the current fraction. Construct it if it does not exist yet.
345 template <typename TInteger, typename TQuotient, typename TMap>
347 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
348 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
349 next( Quotient v ) const
351 ASSERT( ! this->null() );
352 if ( v == NumberTraits<Quotient>::ZERO )
354 Node* node = myNode->origin()->child( u() + NumberTraits<Quotient>::ONE );
355 return Fraction( node->child( v ), mySup1 );
357 //-----------------------------------------------------------------------------
358 template <typename TInteger, typename TQuotient, typename TMap>
360 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
361 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
364 ASSERT( ! this->null() );
366 if ( myNode == instance().myOneOverZero )
368 node = ( myNode->isSameDepthLeft() )
369 ? myNode->origin()->child( u() + NumberTraits<Quotient>::ONE )
370 : myNode->child( 2 );
371 return Fraction( node, mySup1 );
373 //-----------------------------------------------------------------------------
374 template <typename TInteger, typename TQuotient, typename TMap>
376 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
377 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
380 ASSERT( ! this->null() );
382 if ( myNode == instance().myOneOverZero )
384 node = ( ! myNode->isSameDepthLeft() )
385 ? myNode->origin()->child( u() + NumberTraits<Quotient>::ONE )
386 : myNode->child( 2 );
387 return Fraction( node, mySup1 );
389 //-----------------------------------------------------------------------------
390 template <typename TInteger, typename TQuotient, typename TMap>
393 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
396 return NumberTraits<Quotient>::even( k() );
398 //-----------------------------------------------------------------------------
399 template <typename TInteger, typename TQuotient, typename TMap>
402 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
405 return NumberTraits<Quotient>::odd( k() );
407 //-----------------------------------------------------------------------------
408 template <typename TInteger, typename TQuotient, typename TMap>
410 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
411 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
414 return Fraction( myNode->origin(), mySup1 );
416 //-----------------------------------------------------------------------------
417 template <typename TInteger, typename TQuotient, typename TMap>
419 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
420 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
421 child( Quotient v ) const
423 return Fraction( myNode->child( v ), mySup1 );
425 //-----------------------------------------------------------------------------
426 template <typename TInteger, typename TQuotient, typename TMap>
428 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
429 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
432 return Fraction( myNode->ancestor(), mySup1 );
434 //-----------------------------------------------------------------------------
435 template <typename TInteger, typename TQuotient, typename TMap>
438 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
439 isAncestorDirect() const
441 return myNode->k == myNode->ancestor()->k + NumberTraits<Quotient>::ONE;
443 //-----------------------------------------------------------------------------
444 template <typename TInteger, typename TQuotient, typename TMap>
446 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
447 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
450 return Fraction( myNode->father(), mySup1 );
452 //-----------------------------------------------------------------------------
453 template <typename TInteger, typename TQuotient, typename TMap>
455 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
456 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
457 father( Quotient m ) const
459 if ( m >= NumberTraits<Quotient>::ONE ) // >= 1
460 return Fraction( myNode->origin()->child( m ), mySup1 );
464 //-----------------------------------------------------------------------------
465 template <typename TInteger, typename TQuotient, typename TMap>
467 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
468 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
469 previousPartial() const
473 //-----------------------------------------------------------------------------
474 template <typename TInteger, typename TQuotient, typename TMap>
476 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
477 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
480 return ( ( myNode->k == NumberTraits<Quotient>::ZERO )
481 && ( myNode->u == NumberTraits<Quotient>::ONE ) )
483 : Fraction( myNode, ! mySup1 );
485 //-----------------------------------------------------------------------------
486 template <typename TInteger, typename TQuotient, typename TMap>
488 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
489 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
490 partial( Quotient kp ) const
492 ASSERT( ( ((Quotient)-2) <= kp ) && ( kp <= k() ) );
493 return reduced( k() - kp );
495 //-----------------------------------------------------------------------------
496 template <typename TInteger, typename TQuotient, typename TMap>
498 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
499 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
500 reduced( Quotient i ) const
502 ASSERT( ( ((Quotient)0) <= i ) && ( i <= ( k()+((Quotient)2) ) ) );
503 if ( i == NumberTraits<Quotient>::ZERO )
507 Quotient m = i - k();
508 return NumberTraits<Quotient>::odd( m )
512 // reduced( [0, ...], n ) = [0]
513 if ( ! mySup1 && ( i == k() ) )
514 return zeroOverOne();
515 // reduced( z_n, k ), for k <= n
517 for ( ; i != NumberTraits<Quotient>::ZERO; --i )
518 node = node->origin();
519 Quotient _u = node->u;
520 node = node->origin()->child( _u - NumberTraits<Quotient>::ONE );
521 return Fraction( node, mySup1 );
523 //-----------------------------------------------------------------------------
524 template <typename TInteger, typename TQuotient, typename TMap>
527 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
528 push_back( const std::pair<Quotient, Quotient> & quotient )
530 pushBack( quotient );
532 //-----------------------------------------------------------------------------
533 template <typename TInteger, typename TQuotient, typename TMap>
536 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
537 pushBack( const std::pair<Quotient, Quotient> & quotient )
539 // std::vector<Quotient> quots;
542 // this->getCFrac( quots );
543 // std::cerr << "F[";
544 // for ( unsigned int i = 0; i < quots.size(); ++i )
545 // std::cerr << " " << quots[ i ];
547 // else std::cerr << "[";
548 // std::cerr << "] + " << "(" << quotient.first
549 // << "," << quotient.second << ")";
552 ASSERT( quotient.second <= NumberTraits<Quotient>::ZERO );
553 if ( quotient.second < NumberTraits<Quotient>::ZERO )
554 this->operator=( oneOverZero() );
555 else if ( quotient.first == NumberTraits<Quotient>::ZERO ) // (0,0)
556 this->operator=( zeroOverOne() );
558 this->operator=( oneOverZero().child( quotient.first ) );
560 else if ( this->myNode == instance().myOneOverZero )
562 if ( this->mySup1 ) // 1/0
564 ASSERT( quotient.second == NumberTraits<Quotient>::ZERO );
565 if ( quotient.first == NumberTraits<Quotient>::ZERO ) // (0,0)
566 this->operator=( zeroOverOne() );
568 this->operator=( oneOverZero().child( quotient.first ) );
572 ASSERT( quotient.second == NumberTraits<Quotient>::ONE );
573 this->operator=( oneOverZero().child( quotient.first ).inverse() );
578 if ( quotient.second == this->k() + NumberTraits<Quotient>::ONE )
579 this->operator=( origin().child( u() + NumberTraits<Quotient>::ONE )
580 .child( quotient.first ) );
581 else if ( ( this->k() == NumberTraits<Quotient>::ZERO )
582 && ( this->u() == NumberTraits<Quotient>::ONE ) ) // (1/1)
584 this->operator=( oneOverZero().child( 2 ).inverse() ); // (1/(1+1))
585 if ( quotient.first > NumberTraits<Quotient>::ONE )
586 this->operator=( child( quotient.first ) ); // (1/(1+1/q))
588 else // preceding node was [....,u_k,1]
589 this->operator=( child( 2 ).child( quotient.first ) );
592 // this->getCFrac( quots );
593 // std::cerr << " => F[";
594 // for ( unsigned int i = 0; i < quots.size(); ++i )
595 // std::cerr << " " << quots[ i ];
596 // std::cerr << "]" << std::endl;
598 //-----------------------------------------------------------------------------
599 template <typename TInteger, typename TQuotient, typename TMap>
602 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
603 getSplit( Fraction & f1, Fraction & f2 ) const
616 //-----------------------------------------------------------------------------
617 template <typename TInteger, typename TQuotient, typename TMap>
620 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
621 getSplitBerstel( Fraction & f1, Quotient & nb1,
622 Fraction & f2, Quotient & nb2 ) const
639 //-----------------------------------------------------------------------------
640 template <typename TInteger, typename TQuotient, typename TMap>
643 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
644 getCFrac( std::vector<Quotient> & quotients ) const
646 ASSERT( k() >= NumberTraits<Quotient>::ZERO );
647 int64_t i = NumberTraits<Quotient>::castToInt64_t( k() );
648 if ( null() ) return;
649 quotients.resize( i + 1 );
651 quotients[ i-- ] = f.u();
655 for ( ; i >= 1; --i )
657 quotients[ i ] = f.u() - NumberTraits<Quotient>::ONE;
660 quotients[ 0 ] = mySup1 ? f.u() - NumberTraits<Quotient>::ONE
661 : NumberTraits<Quotient>::ZERO;
664 //-----------------------------------------------------------------------------
665 template <typename TInteger, typename TQuotient, typename TMap>
667 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::ConstIterator
668 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
671 CFracSequence* seq = new CFracSequence;
672 this->getCFrac( *seq );
673 return ConstIterator( seq, seq->begin() );
675 //-----------------------------------------------------------------------------
676 template <typename TInteger, typename TQuotient, typename TMap>
678 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::ConstIterator
679 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
682 static CFracSequence dummy;
683 return ConstIterator( 0, dummy.end() );
685 //-----------------------------------------------------------------------------
686 template <typename TInteger, typename TQuotient, typename TMap>
689 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
690 selfDisplay( std::ostream & out ) const
692 if ( this->null() ) out << "[Fraction null]";
695 out << "[Fraction f=" << this->p()
697 << " u=" << this->u()
698 << " k=" << this->k()
700 std::vector<Quotient> quotients;
701 if ( this->k() >= 0 )
703 this->getCFrac( quotients );
704 out << " [" << quotients[ 0 ];
705 for ( unsigned int i = 1; i < quotients.size(); ++i )
706 out << "," << quotients[ i ];
713 ///////////////////////////////////////////////////////////////////////////////
714 // DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>
716 //-----------------------------------------------------------------------------
717 template <typename TInteger, typename TQuotient, typename TMap>
719 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::~LighterSternBrocot()
721 if ( myOneOverOne != 0 ) delete myOneOverOne;
722 if ( myOneOverZero != 0 ) delete myOneOverZero;
724 //-----------------------------------------------------------------------------
725 template <typename TInteger, typename TQuotient, typename TMap>
727 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::LighterSternBrocot()
729 myOneOverZero = new Node( NumberTraits<Integer>::ONE,
730 NumberTraits<Integer>::ZERO,
731 NumberTraits<Quotient>::ONE,
732 -NumberTraits<Quotient>::ONE,
734 myOneOverOne = new Node( NumberTraits<Integer>::ONE,
735 NumberTraits<Integer>::ONE,
736 NumberTraits<Quotient>::ONE,
737 NumberTraits<Quotient>::ZERO,
739 myOneOverZero->myChildren[ NumberTraits<Quotient>::ONE ] = myOneOverOne;
743 //-----------------------------------------------------------------------------
744 template <typename TInteger, typename TQuotient, typename TMap>
746 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap> &
747 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::instance()
749 if ( singleton == 0 )
750 singleton = new LighterSternBrocot;
754 //-----------------------------------------------------------------------------
755 template <typename TInteger, typename TQuotient, typename TMap>
757 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
758 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::zeroOverOne()
760 return Fraction( instance().myOneOverZero, false );
762 //-----------------------------------------------------------------------------
763 template <typename TInteger, typename TQuotient, typename TMap>
765 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
766 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::oneOverZero()
768 return Fraction( instance().myOneOverZero, true );
770 //-----------------------------------------------------------------------------
771 template <typename TInteger, typename TQuotient, typename TMap>
773 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
774 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::oneOverOne()
776 return Fraction( instance().myOneOverOne, true );
779 ///////////////////////////////////////////////////////////////////////////////
780 // Interface - public :
783 * Writes/Displays the object on an output stream.
784 * @param out the output stream where the object is written.
786 template <typename TInteger, typename TQuotient, typename TMap>
789 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::display( std::ostream & out,
792 if ( f.null() ) out << "[Fraction null]";
795 out << "[Fraction f=" << f.p()
799 // << " s1=" << f.isSup1()
801 std::vector<Quotient> quotients;
804 f.getCFrac( quotients );
805 out << " [" << quotients[ 0 ];
806 for ( unsigned int i = 1; i < quotients.size(); ++i )
807 out << "," << quotients[ i ];
815 * Checks the validity/consistency of the object.
816 * @return 'true' if the object is valid, 'false' otherwise.
818 template <typename TInteger, typename TQuotient, typename TMap>
821 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::isValid() const
826 ///////////////////////////////////////////////////////////////////////////////
827 // class LighterSternBrocot
828 ///////////////////////////////////////////////////////////////////////////////
829 template <typename TInteger, typename TQuotient, typename TMap>
831 typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
832 DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::fraction
833 ( Integer p, Integer q,
837 return Fraction( p, q );
841 ///////////////////////////////////////////////////////////////////////////////
842 // Implementation of inline functions //
844 // JOL: invalid overloading
845 // template <typename TInteger, typename TQuotient, typename TMap>
848 // DGtal::operator<< ( std::ostream & out,
849 // const typename LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction & object )
851 // typedef LighterSternBrocot<TInteger, TQuotient, TMap> SB;
852 // SB::display( out, object );
857 ///////////////////////////////////////////////////////////////////////////////