34 #include "DGtal/arithmetic/IntegerComputer.h"
47 template <
typename TInteger,
typename TQuotient,
typename TMap>
52 : p( p1 ), q( q1 ), u( u1 ), k( k1 ),
53 ascendant( _ascendant )
62 template <
typename TInteger,
typename TQuotient,
typename TMap>
75 if ( sup1 ) std::swap( aP, aQ );
79 bool prec_was_one =
false;
98 template <
typename TInteger,
typename TQuotient,
typename TMap>
102 : myNode( sb_node ), mySup1( sup1 )
106 template <
typename TInteger,
typename TQuotient,
typename TMap>
110 : myNode( other.myNode ), mySup1( other.mySup1 )
114 template <
typename TInteger,
typename TQuotient,
typename TMap>
120 if (
this != &other )
128 template <
typename TInteger,
typename TQuotient,
typename TMap>
137 template <
typename TInteger,
typename TQuotient,
typename TMap>
143 return myNode ? ( mySup1 ? myNode->q : myNode->p ) : 0;
146 template <
typename TInteger,
typename TQuotient,
typename TMap>
152 return myNode ? ( mySup1 ? myNode->p : myNode->q ) : 0;
155 template <
typename TInteger,
typename TQuotient,
typename TMap>
161 ASSERT( myNode != 0 );
165 template <
typename TInteger,
typename TQuotient,
typename TMap>
171 ASSERT( myNode != 0 );
186 ASSERT( ( myNode->k != 0 )
189 ASSERT( ( myNode->k != -1 )
203 template <
typename TInteger,
typename TQuotient,
typename TMap>
209 return ( this->p() == p1 ) && ( this->q() == q1 );
212 template <
typename TInteger,
typename TQuotient,
typename TMap>
218 Integer d = p() * q1 - q() * p1;
219 return d < NumberTraits<Integer>::ZERO;
222 template <
typename TInteger,
typename TQuotient,
typename TMap>
228 Integer d = p() * q1 - q() * p1;
232 template <
typename TInteger,
typename TQuotient,
typename TMap>
238 if ( mySup1 == other.
mySup1 )
239 return ( myNode == other.
myNode );
241 return ( ( myNode->p == other.
myNode->
q )
242 && ( myNode->q == other.
myNode->
p ) );
245 template <
typename TInteger,
typename TQuotient,
typename TMap>
254 template <
typename TInteger,
typename TQuotient,
typename TMap>
260 return this->lessThan( other.
p(), other.
q() );
263 template <
typename TInteger,
typename TQuotient,
typename TMap>
269 return this->moreThan( other.
p(), other.
q() );
274 template <
typename TInteger,
typename TQuotient,
typename TMap>
280 typedef typename MapQuotientToNode::iterator Iterator;
281 ASSERT( ! this->null() );
288 bool anc_direct = isAncestorDirect();
289 Iterator itkey = anc_direct
290 ? myNode->ascendant->descendant.find( v )
291 : myNode->ascendant->descendant2.find( v );
292 Iterator itend = anc_direct
293 ? myNode->ascendant->descendant.end()
294 : myNode->ascendant->descendant2.end();
295 if ( itkey != itend )
296 return Fraction( itkey->second, mySup1 );
297 Node* new_node =
new Node( myNode->p + myNode->ascendant->p,
298 myNode->q + myNode->ascendant->q,
299 v, myNode->k, myNode->ascendant );
300 if (anc_direct ) myNode->ascendant->descendant[ v ] = new_node;
303 return Fraction( new_node, mySup1 );
307 Iterator itkey = myNode->descendant.find( v );
308 if ( itkey != myNode->descendant.end() )
310 return Fraction( itkey->second, mySup1 );
313 new Node( myNode->p * v + myNode->ascendant->p,
314 myNode->q * v + myNode->ascendant->q,
315 v, myNode->k + 1, myNode );
316 myNode->descendant[ v ] = new_node;
318 return Fraction( new_node, mySup1 );
324 template <
typename TInteger,
typename TQuotient,
typename TMap>
330 typedef typename MapQuotientToNode::iterator Iterator;
331 ASSERT( ! this->null() );
337 if ( f.
myNode->
k == myNode->k )
338 return father().next( 2 );
340 return father().next1( 2 );
344 Iterator itkey = myNode->descendant2.find( v );
345 if ( itkey != myNode->descendant2.end() )
346 return Fraction( itkey->second, mySup1 );
348 =
new Node( myNode->p * v + myNode->p - myNode->ascendant->p,
349 myNode->q * v + myNode->q - myNode->ascendant->q,
350 v, myNode->k + 2, myNode );
351 myNode->descendant2[ v ] = new_node;
353 return Fraction( new_node, mySup1 );
357 template <
typename TInteger,
typename TQuotient,
typename TMap>
363 if ( myNode->isSameDepthLeft() )
370 template <
typename TInteger,
typename TQuotient,
typename TMap>
376 if ( ! myNode->isSameDepthLeft() )
383 template <
typename TInteger,
typename TQuotient,
typename TMap>
392 template <
typename TInteger,
typename TQuotient,
typename TMap>
401 template <
typename TInteger,
typename TQuotient,
typename TMap>
407 return Fraction( myNode->ascendant, mySup1 );
410 template <
typename TInteger,
typename TQuotient,
typename TMap>
419 template <
typename TInteger,
typename TQuotient,
typename TMap>
425 if ( isAncestorDirect() )
431 template <
typename TInteger,
typename TQuotient,
typename TMap>
439 return isAncestorDirect()
440 ? ancestor().next( m )
441 : ancestor().next1( m );
450 template <
typename TInteger,
typename TQuotient,
typename TMap>
459 template <
typename TInteger,
typename TQuotient,
typename TMap>
465 return Fraction( myNode, ! mySup1 );
468 template <
typename TInteger,
typename TQuotient,
typename TMap>
474 ASSERT( ( ((
Quotient)-2) <= kp ) && ( kp <= myNode->k ) );
475 return reduced( myNode->k - kp );
478 template <
typename TInteger,
typename TQuotient,
typename TMap>
495 template <
typename TInteger,
typename TQuotient,
typename TMap>
499 push_back(
const std::pair<Quotient, Quotient> & quotient )
501 pushBack( quotient );
504 template <
typename TInteger,
typename TQuotient,
typename TMap>
511 &&
"UNIMPLEMENTED. Use SternBrocot::Fraction or LighterSternBrocot::Fraction instead." );
514 template <
typename TInteger,
typename TQuotient,
typename TMap>
532 template <
typename TInteger,
typename TQuotient,
typename TMap>
556 template <
typename TInteger,
typename TQuotient,
typename TMap>
560 getCFrac( std::vector<Quotient> & quotients )
const
564 if ( null() )
return;
565 if ( mySup1 && ( i > 0 ) ) --i;
566 quotients.resize( i + 1 );
569 while ( i >= 0 && ( f.
myNode->
k >= 0 ) )
577 template <
typename TInteger,
typename TQuotient,
typename TMap>
584 this->getCFrac( *seq );
588 template <
typename TInteger,
typename TQuotient,
typename TMap>
598 template <
typename TInteger,
typename TQuotient,
typename TMap>
604 if ( this->null() ) out <<
"[Fraction null]";
607 out <<
"[Fraction f=" << this->p()
609 <<
" u=" << this->u()
610 <<
" k=" << this->k()
612 std::vector<Quotient> quotients;
613 if ( this->k() >= 0 )
615 this->getCFrac( quotients );
616 out <<
" [" << quotients[ 0 ];
617 for (
unsigned int i = 1; i < quotients.size(); ++i )
618 out <<
"," << quotients[ i ];
629 template <
typename TInteger,
typename TQuotient,
typename TMap>
638 template <
typename TInteger,
typename TQuotient,
typename TMap>
687 template <
typename TInteger,
typename TQuotient,
typename TMap>
698 template <
typename TInteger,
typename TQuotient,
typename TMap>
706 template <
typename TInteger,
typename TQuotient,
typename TMap>
721 template <
typename TInteger,
typename TQuotient,
typename TMap>
727 if ( f.
null() ) out <<
"[Fraction null]";
730 out <<
"[Fraction f=" << f.
p()
736 std::vector<Quotient> quotients;
740 out <<
" [" << quotients[ 0 ];
741 for (
unsigned int i = 1; i < quotients.size(); ++i )
742 out <<
"," << quotients[ i ];
753 template <
typename TInteger,
typename TQuotient,
typename TMap>
764 template <
typename TInteger,
typename TQuotient,
typename TMap>