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///////////////////////////////////////////////////////////////////////////////
41template <typename TInteger, typename TQuotient, typename TMap>
42DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>*
43DGtal::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//-----------------------------------------------------------------------------
56template <typename TInteger, typename TQuotient, typename TMap>
58DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node::
59Node( Integer p1, Integer q1, Quotient u1, Quotient k1,
61 : p( p1 ), q( q1 ), u( u1 ), k( k1 ),
64 ASSERT( p >= NumberTraits<Integer>::ONE );
66//-----------------------------------------------------------------------------
67template <typename TInteger, typename TQuotient, typename TMap>
69typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node*
70DGtal::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//-----------------------------------------------------------------------------
113template <typename TInteger, typename TQuotient, typename TMap>
115typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node*
116DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node::
121//-----------------------------------------------------------------------------
122template <typename TInteger, typename TQuotient, typename TMap>
124typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node*
125DGtal::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//-----------------------------------------------------------------------------
136template <typename TInteger, typename TQuotient, typename TMap>
138typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node*
139DGtal::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//-----------------------------------------------------------------------------
152template <typename TInteger, typename TQuotient, typename TMap>
154DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
155Fraction( 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//-----------------------------------------------------------------------------
186template <typename TInteger, typename TQuotient, typename TMap>
188DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
189Fraction( Node* sb_node, bool sup1 )
190 : myNode( sb_node ), mySup1( sup1 )
193//-----------------------------------------------------------------------------
194template <typename TInteger, typename TQuotient, typename TMap>
196DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
197Fraction( const Self & other )
198 : myNode( other.myNode ), mySup1( other.mySup1 )
201//-----------------------------------------------------------------------------
202template <typename TInteger, typename TQuotient, typename TMap>
204typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction &
205DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
206operator=( const Self & other )
208 if ( this != &other )
210 myNode = other.myNode;
211 mySup1 = other.mySup1;
215//-----------------------------------------------------------------------------
216template <typename TInteger, typename TQuotient, typename TMap>
219DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
224//-----------------------------------------------------------------------------
225template <typename TInteger, typename TQuotient, typename TMap>
227typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Integer
228DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
231 return myNode ? ( mySup1 ? myNode->p : myNode->q ) : 0;
233//-----------------------------------------------------------------------------
234template <typename TInteger, typename TQuotient, typename TMap>
236typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Integer
237DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
240 return myNode ? ( mySup1 ? myNode->q : myNode->p ) : 0;
242//-----------------------------------------------------------------------------
243template <typename TInteger, typename TQuotient, typename TMap>
245typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Quotient
246DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
249 ASSERT( myNode != 0 );
250 return myNode == instance().myOneOverZero
251 ? ( mySup1 ? NumberTraits<Quotient>::ONE : NumberTraits<Quotient>::ZERO )
254//-----------------------------------------------------------------------------
255template <typename TInteger, typename TQuotient, typename TMap>
257typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Quotient
258DGtal::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//-----------------------------------------------------------------------------
274template <typename TInteger, typename TQuotient, typename TMap>
277DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
278equals( Integer p1, Integer q1 ) const
280 return ( this->p() == p1 ) && ( this->q() == q1 );
282//-----------------------------------------------------------------------------
283template <typename TInteger, typename TQuotient, typename TMap>
286DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
287lessThan( Integer p1, Integer q1 ) const
289 Integer d = p() * q1 - q() * p1;
290 return d < NumberTraits<Integer>::ZERO;
292//-----------------------------------------------------------------------------
293template <typename TInteger, typename TQuotient, typename TMap>
296DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
297moreThan( Integer p1, Integer q1 ) const
299 Integer d = p() * q1 - q() * p1;
300 return d > NumberTraits<Integer>::ZERO;
302//-----------------------------------------------------------------------------
303template <typename TInteger, typename TQuotient, typename TMap>
306DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
307operator==( 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//-----------------------------------------------------------------------------
316template <typename TInteger, typename TQuotient, typename TMap>
319DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
320operator!=( const Fraction & other ) const
322 return ! this->operator==( other );
324//-----------------------------------------------------------------------------
325template <typename TInteger, typename TQuotient, typename TMap>
328DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
329operator<( const Fraction & other ) const
331 return this->lessThan( other.p(), other.q() );
333//-----------------------------------------------------------------------------
334template <typename TInteger, typename TQuotient, typename TMap>
337DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
338operator>( 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.
345template <typename TInteger, typename TQuotient, typename TMap>
347typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
348DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
349next( 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//-----------------------------------------------------------------------------
358template <typename TInteger, typename TQuotient, typename TMap>
360typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
361DGtal::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//-----------------------------------------------------------------------------
374template <typename TInteger, typename TQuotient, typename TMap>
376typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
377DGtal::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//-----------------------------------------------------------------------------
390template <typename TInteger, typename TQuotient, typename TMap>
393DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
396 return NumberTraits<Quotient>::even( k() );
398//-----------------------------------------------------------------------------
399template <typename TInteger, typename TQuotient, typename TMap>
402DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
405 return NumberTraits<Quotient>::odd( k() );
407//-----------------------------------------------------------------------------
408template <typename TInteger, typename TQuotient, typename TMap>
410typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
411DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
414 return Fraction( myNode->origin(), mySup1 );
416//-----------------------------------------------------------------------------
417template <typename TInteger, typename TQuotient, typename TMap>
419typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
420DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
421child( Quotient v ) const
423 return Fraction( myNode->child( v ), mySup1 );
425//-----------------------------------------------------------------------------
426template <typename TInteger, typename TQuotient, typename TMap>
428typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
429DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
432 return Fraction( myNode->ancestor(), mySup1 );
434//-----------------------------------------------------------------------------
435template <typename TInteger, typename TQuotient, typename TMap>
438DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
439isAncestorDirect() const
441 return myNode->k == myNode->ancestor()->k + NumberTraits<Quotient>::ONE;
443//-----------------------------------------------------------------------------
444template <typename TInteger, typename TQuotient, typename TMap>
446typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
447DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
450 return Fraction( myNode->father(), mySup1 );
452//-----------------------------------------------------------------------------
453template <typename TInteger, typename TQuotient, typename TMap>
455typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
456DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
457father( Quotient m ) const
459 if ( m >= NumberTraits<Quotient>::ONE ) // >= 1
460 return Fraction( myNode->origin()->child( m ), mySup1 );
464//-----------------------------------------------------------------------------
465template <typename TInteger, typename TQuotient, typename TMap>
467typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
468DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
469previousPartial() const
473//-----------------------------------------------------------------------------
474template <typename TInteger, typename TQuotient, typename TMap>
476typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
477DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
480 return ( ( myNode->k == NumberTraits<Quotient>::ZERO )
481 && ( myNode->u == NumberTraits<Quotient>::ONE ) )
483 : Fraction( myNode, ! mySup1 );
485//-----------------------------------------------------------------------------
486template <typename TInteger, typename TQuotient, typename TMap>
488typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
489DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
490partial( Quotient kp ) const
492 ASSERT( ( ((Quotient)-2) <= kp ) && ( kp <= k() ) );
493 return reduced( k() - kp );
495//-----------------------------------------------------------------------------
496template <typename TInteger, typename TQuotient, typename TMap>
498typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
499DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
500reduced( 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//-----------------------------------------------------------------------------
524template <typename TInteger, typename TQuotient, typename TMap>
527DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
528push_back( const std::pair<Quotient, Quotient> & quotient )
530 pushBack( quotient );
532//-----------------------------------------------------------------------------
533template <typename TInteger, typename TQuotient, typename TMap>
536DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
537pushBack( 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//-----------------------------------------------------------------------------
599template <typename TInteger, typename TQuotient, typename TMap>
602DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
603getSplit( Fraction & f1, Fraction & f2 ) const
616//-----------------------------------------------------------------------------
617template <typename TInteger, typename TQuotient, typename TMap>
620DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
621getSplitBerstel( Fraction & f1, Quotient & nb1,
622 Fraction & f2, Quotient & nb2 ) const
639//-----------------------------------------------------------------------------
640template <typename TInteger, typename TQuotient, typename TMap>
643DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
644getCFrac( 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//-----------------------------------------------------------------------------
665template <typename TInteger, typename TQuotient, typename TMap>
667typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::ConstIterator
668DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
671 CFracSequence* seq = new CFracSequence;
672 this->getCFrac( *seq );
673 return ConstIterator( seq, seq->begin() );
675//-----------------------------------------------------------------------------
676template <typename TInteger, typename TQuotient, typename TMap>
678typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::ConstIterator
679DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
682 static CFracSequence dummy;
683 return ConstIterator( 0, dummy.end() );
685//-----------------------------------------------------------------------------
686template <typename TInteger, typename TQuotient, typename TMap>
689DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction::
690selfDisplay( 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//-----------------------------------------------------------------------------
717template <typename TInteger, typename TQuotient, typename TMap>
719DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::~LighterSternBrocot()
721 if ( myOneOverOne != 0 ) delete myOneOverOne;
722 if ( myOneOverZero != 0 ) delete myOneOverZero;
724//-----------------------------------------------------------------------------
725template <typename TInteger, typename TQuotient, typename TMap>
727DGtal::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//-----------------------------------------------------------------------------
744template <typename TInteger, typename TQuotient, typename TMap>
746DGtal::LighterSternBrocot<TInteger, TQuotient, TMap> &
747DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::instance()
749 if ( singleton == 0 )
750 singleton = new LighterSternBrocot;
754//-----------------------------------------------------------------------------
755template <typename TInteger, typename TQuotient, typename TMap>
757typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
758DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::zeroOverOne()
760 return Fraction( instance().myOneOverZero, false );
762//-----------------------------------------------------------------------------
763template <typename TInteger, typename TQuotient, typename TMap>
765typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
766DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::oneOverZero()
768 return Fraction( instance().myOneOverZero, true );
770//-----------------------------------------------------------------------------
771template <typename TInteger, typename TQuotient, typename TMap>
773typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
774DGtal::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.
786template <typename TInteger, typename TQuotient, typename TMap>
789DGtal::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.
818template <typename TInteger, typename TQuotient, typename TMap>
821DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::isValid() const
826///////////////////////////////////////////////////////////////////////////////
827// class LighterSternBrocot
828///////////////////////////////////////////////////////////////////////////////
829template <typename TInteger, typename TQuotient, typename TMap>
831typename DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
832DGtal::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///////////////////////////////////////////////////////////////////////////////