DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
LighterSternBrocot.ih
1 
32 
33 #include <cstdlib>
34 #include "DGtal/arithmetic/IntegerComputer.h"
36 
38 // IMPLEMENTATION of inline methods.
40 
42 // ----------------------- Standard services ------------------------------
43 
45 // DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Node
46 //-----------------------------------------------------------------------------
47 template <typename TInteger, typename TQuotient, typename TMap>
48 inline
51  Node* _origin )
52  : p( p1 ), q( q1 ), u( u1 ), k( k1 ),
53  myOrigin( _origin )
54 {
55  ASSERT( p >= NumberTraits<Integer>::ONE );
56  // if ( k == 0 )
57  // std::cerr << "(" << p1 << "/" << q1 << "," << u1 << "," << k1 << ")";
58 }
59 //-----------------------------------------------------------------------------
60 template <typename TInteger, typename TQuotient, typename TMap>
61 inline
65 {
66  typedef typename MapQuotientToNode::iterator Iterator;
67  ASSERT( v != NumberTraits<Quotient>::ZERO );
68  if ( v == NumberTraits<Quotient>::ONE )
69  return ( this == instance().myOneOverZero )
71  : this;
72  Iterator itkey = myChildren.find( v );
73  if ( itkey != myChildren.end() )
74  return itkey->second;
75  if ( this == instance().myOneOverZero )
76  {
77  Node* newNode =
78  new Node( (int) NumberTraits<Quotient>::castToInt64_t( v ), // p' = v
80  v, // u' = v
82  this );
83  myChildren[ v ] = newNode;
84  ++( instance().nbFractions );
85  return newNode;
86  }
87  long int _v = NumberTraits<Quotient>::castToInt64_t( v );
88  long int _u = NumberTraits<Quotient>::castToInt64_t( this->u );
89  Integer _pp = origin() == instance().myOneOverZero
91  : origin()->p;
92  Integer _qq = origin() == instance().myOneOverZero
94  : origin()->q;
95  Node* newNode = // p' = v*p - (v-1)*(p-p2)/(u-1)
96  new Node( p * _v - ( _v - 1 ) * ( p - _pp ) / (_u - 1),
97  q * _v - ( _v - 1 ) * ( q - _qq ) / (_u - 1),
98  v, // u' = v
99  k + NumberTraits<Quotient>::ONE, // k' = k+1
100  this );
101  myChildren[ v ] = newNode;
102  ++( instance().nbFractions );
103  return newNode;
104 }
105 //-----------------------------------------------------------------------------
106 template <typename TInteger, typename TQuotient, typename TMap>
107 inline
110 origin() const
111 {
112  return myOrigin;
113 }
114 //-----------------------------------------------------------------------------
115 template <typename TInteger, typename TQuotient, typename TMap>
116 inline
119 ancestor() const
120 {
121  ASSERT( origin() != 0 );
122  Node* prevNode = origin();
123  Quotient _u = prevNode->u;
124  prevNode = prevNode->origin();
125  if ( prevNode == 0 ) return instance().myOneOverZero;
126  return prevNode->child( _u - NumberTraits<Quotient>::ONE );
127 }
128 //-----------------------------------------------------------------------------
129 template <typename TInteger, typename TQuotient, typename TMap>
130 inline
133 father() const
134 {
135  ASSERT( origin() != 0 );
136  Node* prevNode = origin();
137  if ( this->u == NumberTraits<Quotient>::ONE ) // 1/1
138  return instance().myOneOverZero;
139  return prevNode->child( this->u - NumberTraits<Quotient>::ONE );
140 }
141 
143 // DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction
144 //-----------------------------------------------------------------------------
145 template <typename TInteger, typename TQuotient, typename TMap>
146 inline
149 {
150  if ( ( aP == NumberTraits<Integer>::ZERO ) &&
151  ( aQ == NumberTraits<Integer>::ONE ) )
152  this->operator=( zeroOverOne() );
153  else
154  {
155  bool sup1 = aP >= aQ;
156  if ( ! sup1 ) std::swap( aP, aQ );
157  Node* node = instance().myOneOverZero;
158  Integer _quot, _rem;
160  ic.getEuclideanDiv( _quot, _rem, aP, aQ );
162  // std::cerr << "[u=" << v << "]";
163  aP = aQ;
164  aQ = _rem;
165  while ( aQ != NumberTraits<Integer>::ZERO )
166  {
167  node = node->child( v + 1 );
168  ic.getEuclideanDiv( _quot, _rem, aP, aQ );
170  // std::cerr << "[u=" << v << "]";
171  aP = aQ;
172  aQ = _rem;
173  }
174  myNode = node->child( v );
175  mySup1 = sup1;
176  }
177 }
178 //-----------------------------------------------------------------------------
179 template <typename TInteger, typename TQuotient, typename TMap>
180 inline
182 Fraction( Node* sb_node, bool sup1 )
183  : myNode( sb_node ), mySup1( sup1 )
184 {
185 }
186 //-----------------------------------------------------------------------------
187 template <typename TInteger, typename TQuotient, typename TMap>
188 inline
190 Fraction( const Self & other )
191  : myNode( other.myNode ), mySup1( other.mySup1 )
192 {
193 }
194 //-----------------------------------------------------------------------------
195 template <typename TInteger, typename TQuotient, typename TMap>
196 inline
199 operator=( const Self & other )
200 {
201  if ( this != &other )
202  {
203  myNode = other.myNode;
204  mySup1 = other.mySup1;
205  }
206  return *this;
207 }
208 //-----------------------------------------------------------------------------
209 template <typename TInteger, typename TQuotient, typename TMap>
210 inline
211 bool
213 null() const
214 {
215  return myNode == 0;
216 }
217 //-----------------------------------------------------------------------------
218 template <typename TInteger, typename TQuotient, typename TMap>
219 inline
222 p() const
223 {
224  return myNode ? ( mySup1 ? myNode->p : myNode->q ) : 0;
225 }
226 //-----------------------------------------------------------------------------
227 template <typename TInteger, typename TQuotient, typename TMap>
228 inline
231 q() const
232 {
233  return myNode ? ( mySup1 ? myNode->q : myNode->p ) : 0;
234 }
235 //-----------------------------------------------------------------------------
236 template <typename TInteger, typename TQuotient, typename TMap>
237 inline
240 u() const
241 {
242  ASSERT( myNode != 0 );
243  return myNode == instance().myOneOverZero
245  : myNode->u;
246 }
247 //-----------------------------------------------------------------------------
248 template <typename TInteger, typename TQuotient, typename TMap>
249 inline
252 k() const
253 {
254  ASSERT( myNode != 0 );
255  // The default of this approach is that node 1/1 has two possible depths !
256  return mySup1
257  ? myNode->k
258  : myNode->k + NumberTraits<Quotient>::ONE;
259  // JOL: 2012/11/21: I left these lines in comments because I am not
260  // sure yet if my correction above has no other side effects.
261  //
262  // return ( mySup1 || ( myNode == instance().myOneOverOne ) )
263  // ? myNode->k
264  // : myNode->k + NumberTraits<Quotient>::ONE;
265 }
266 //-----------------------------------------------------------------------------
267 template <typename TInteger, typename TQuotient, typename TMap>
268 inline
269 bool
271 equals( Integer p1, Integer q1 ) const
272 {
273  return ( this->p() == p1 ) && ( this->q() == q1 );
274 }
275 //-----------------------------------------------------------------------------
276 template <typename TInteger, typename TQuotient, typename TMap>
277 inline
278 bool
280 lessThan( Integer p1, Integer q1 ) const
281 {
282  Integer d = p() * q1 - q() * p1;
283  return d < NumberTraits<Integer>::ZERO;
284 }
285 //-----------------------------------------------------------------------------
286 template <typename TInteger, typename TQuotient, typename TMap>
287 inline
288 bool
290 moreThan( Integer p1, Integer q1 ) const
291 {
292  Integer d = p() * q1 - q() * p1;
293  return d > NumberTraits<Integer>::ZERO;
294 }
295 //-----------------------------------------------------------------------------
296 template <typename TInteger, typename TQuotient, typename TMap>
297 inline
298 bool
300 operator==( const Fraction & other ) const
301 {
302  if ( mySup1 == other.mySup1 )
303  return ( myNode == other.myNode );
304  else
305  return ( ( myNode->p == other.myNode->q )
306  && ( myNode->q == other.myNode->p ) );
307 }
308 //-----------------------------------------------------------------------------
309 template <typename TInteger, typename TQuotient, typename TMap>
310 inline
311 bool
313 operator!=( const Fraction & other ) const
314 {
315  return ! this->operator==( other );
316 }
317 //-----------------------------------------------------------------------------
318 template <typename TInteger, typename TQuotient, typename TMap>
319 inline
320 bool
322 operator<( const Fraction & other ) const
323 {
324  return this->lessThan( other.p(), other.q() );
325 }
326 //-----------------------------------------------------------------------------
327 template <typename TInteger, typename TQuotient, typename TMap>
328 inline
329 bool
331 operator>( const Fraction & other ) const
332 {
333  return this->moreThan( other.p(), other.q() );
334 }
335 //-----------------------------------------------------------------------------
338 template <typename TInteger, typename TQuotient, typename TMap>
339 inline
342 next( Quotient v ) const
343 {
344  ASSERT( ! this->null() );
345  typedef typename MapQuotientToNode::iterator Iterator;
346  if ( v == NumberTraits<Quotient>::ZERO )
347  return *this;
348  Node* node = myNode->origin()->child( u() + NumberTraits<Quotient>::ONE );
349  return Fraction( node->child( v ), mySup1 );
350 }
351 //-----------------------------------------------------------------------------
352 template <typename TInteger, typename TQuotient, typename TMap>
353 inline
356 left() const
357 {
358  ASSERT( ! this->null() );
359  Node* node;
360  if ( myNode == instance().myOneOverZero )
361  return oneOverOne();
362  node = ( myNode->isSameDepthLeft() )
363  ? myNode->origin()->child( u() + NumberTraits<Quotient>::ONE )
364  : myNode->child( 2 );
365  return Fraction( node, mySup1 );
366 }
367 //-----------------------------------------------------------------------------
368 template <typename TInteger, typename TQuotient, typename TMap>
369 inline
372 right() const
373 {
374  ASSERT( ! this->null() );
375  Node* node;
376  if ( myNode == instance().myOneOverZero )
377  return oneOverOne();
378  node = ( ! myNode->isSameDepthLeft() )
379  ? myNode->origin()->child( u() + NumberTraits<Quotient>::ONE )
380  : myNode->child( 2 );
381  return Fraction( node, mySup1 );
382 }
383 //-----------------------------------------------------------------------------
384 template <typename TInteger, typename TQuotient, typename TMap>
385 inline
386 bool
388 even() const
389 {
390  return NumberTraits<Quotient>::even( k() );
391 }
392 //-----------------------------------------------------------------------------
393 template <typename TInteger, typename TQuotient, typename TMap>
394 inline
395 bool
397 odd() const
398 {
399  return NumberTraits<Quotient>::odd( k() );
400 }
401 //-----------------------------------------------------------------------------
402 template <typename TInteger, typename TQuotient, typename TMap>
403 inline
406 origin() const
407 {
408  return Fraction( myNode->origin(), mySup1 );
409 }
410 //-----------------------------------------------------------------------------
411 template <typename TInteger, typename TQuotient, typename TMap>
412 inline
415 child( Quotient v ) const
416 {
417  return Fraction( myNode->child( v ), mySup1 );
418 }
419 //-----------------------------------------------------------------------------
420 template <typename TInteger, typename TQuotient, typename TMap>
421 inline
424 ancestor() const
425 {
426  return Fraction( myNode->ancestor(), mySup1 );
427 }
428 //-----------------------------------------------------------------------------
429 template <typename TInteger, typename TQuotient, typename TMap>
430 inline
431 bool
434 {
435  return myNode->k == myNode->ancestor()->k + NumberTraits<Quotient>::ONE;
436 }
437 //-----------------------------------------------------------------------------
438 template <typename TInteger, typename TQuotient, typename TMap>
439 inline
442 father() const
443 {
444  return Fraction( myNode->father(), mySup1 );
445 }
446 //-----------------------------------------------------------------------------
447 template <typename TInteger, typename TQuotient, typename TMap>
448 inline
451 father( Quotient m ) const
452 {
453  if ( m >= NumberTraits<Quotient>::ONE ) // >= 1
454  return Fraction( myNode->origin()->child( m ), mySup1 );
455  else
456  return reduced( 2 );
457 }
458 //-----------------------------------------------------------------------------
459 template <typename TInteger, typename TQuotient, typename TMap>
460 inline
464 {
465  return ancestor();
466 }
467 //-----------------------------------------------------------------------------
468 template <typename TInteger, typename TQuotient, typename TMap>
469 inline
472 inverse() const
473 {
474  return ( ( myNode->k == NumberTraits<Quotient>::ZERO )
475  && ( myNode->u == NumberTraits<Quotient>::ONE ) )
476  ? *this
477  : Fraction( myNode, ! mySup1 );
478 }
479 //-----------------------------------------------------------------------------
480 template <typename TInteger, typename TQuotient, typename TMap>
481 inline
484 partial( Quotient kp ) const
485 {
486  ASSERT( ( ((Quotient)-2) <= kp ) && ( kp <= k() ) );
487  return reduced( k() - kp );
488 }
489 //-----------------------------------------------------------------------------
490 template <typename TInteger, typename TQuotient, typename TMap>
491 inline
494 reduced( Quotient i ) const
495 {
496  ASSERT( ( ((Quotient)0) <= i ) && ( i <= ( k()+((Quotient)2) ) ) );
497  if ( i == NumberTraits<Quotient>::ZERO )
498  return *this;
499  if ( i > myNode->k )
500  {
501  Quotient m = i - k();
502  return NumberTraits<Quotient>::odd( m )
503  ? oneOverZero()
504  : zeroOverOne();
505  }
506  // reduced( [0, ...], n ) = [0]
507  if ( ! mySup1 && ( i == k() ) )
508  return zeroOverOne();
509  // reduced( z_n, k ), for k <= n
510  Node* node = myNode;
511  for ( ; i != NumberTraits<Quotient>::ZERO; --i )
512  node = node->origin();
513  Quotient _u = node->u;
514  node = node->origin()->child( _u - NumberTraits<Quotient>::ONE );
515  return Fraction( node, mySup1 );
516 }
517 //-----------------------------------------------------------------------------
518 template <typename TInteger, typename TQuotient, typename TMap>
519 inline
520 void
522 push_back( const std::pair<Quotient, Quotient> & quotient )
523 {
524  pushBack( quotient );
525 }
526 //-----------------------------------------------------------------------------
527 template <typename TInteger, typename TQuotient, typename TMap>
528 inline
529 void
531 pushBack( const std::pair<Quotient, Quotient> & quotient )
532 {
533  // std::vector<Quotient> quots;
534  // if ( ! null() )
535  // {
536  // this->getCFrac( quots );
537  // std::cerr << "F[";
538  // for ( unsigned int i = 0; i < quots.size(); ++i )
539  // std::cerr << " " << quots[ i ];
540  // }
541  // else std::cerr << "[";
542  // std::cerr << "] + " << "(" << quotient.first
543  // << "," << quotient.second << ")";
544  if ( null() )
545  {
546  ASSERT( quotient.second <= NumberTraits<Quotient>::ZERO );
547  if ( quotient.second < NumberTraits<Quotient>::ZERO )
548  this->operator=( oneOverZero() );
549  else if ( quotient.first == NumberTraits<Quotient>::ZERO ) // (0,0)
550  this->operator=( zeroOverOne() );
551  else
552  this->operator=( oneOverZero().child( quotient.first ) );
553  }
554  else if ( this->myNode == instance().myOneOverZero )
555  {
556  if ( this->mySup1 ) // 1/0
557  {
558  ASSERT( quotient.second == NumberTraits<Quotient>::ZERO );
559  if ( quotient.first == NumberTraits<Quotient>::ZERO ) // (0,0)
560  this->operator=( zeroOverOne() );
561  else
562  this->operator=( oneOverZero().child( quotient.first ) );
563  }
564  else // 0/1
565  {
566  ASSERT( quotient.second == NumberTraits<Quotient>::ONE );
567  this->operator=( oneOverZero().child( quotient.first ).inverse() );
568  }
569  }
570  else
571  { // Generic case.
572  if ( quotient.second == this->k() + NumberTraits<Quotient>::ONE )
573  this->operator=( origin().child( u() + NumberTraits<Quotient>::ONE )
574  .child( quotient.first ) );
575  else if ( ( this->k() == NumberTraits<Quotient>::ZERO )
576  && ( this->u() == NumberTraits<Quotient>::ONE ) ) // (1/1)
577  {
578  this->operator=( oneOverZero().child( 2 ).inverse() ); // (1/(1+1))
579  if ( quotient.first > NumberTraits<Quotient>::ONE )
580  this->operator=( child( quotient.first ) ); // (1/(1+1/q))
581  }
582  else // preceding node was [....,u_k,1]
583  this->operator=( child( 2 ).child( quotient.first ) );
584  }
585  // quots.clear();
586  // this->getCFrac( quots );
587  // std::cerr << " => F[";
588  // for ( unsigned int i = 0; i < quots.size(); ++i )
589  // std::cerr << " " << quots[ i ];
590  // std::cerr << "]" << std::endl;
591 }
592 //-----------------------------------------------------------------------------
593 template <typename TInteger, typename TQuotient, typename TMap>
594 inline
595 void
597 getSplit( Fraction & f1, Fraction & f2 ) const
598 {
599  if ( odd() )
600  {
601  f1 = ancestor();
602  f2 = father();
603  }
604  else
605  {
606  f1 = father();
607  f2 = ancestor();
608  }
609 }
610 //-----------------------------------------------------------------------------
611 template <typename TInteger, typename TQuotient, typename TMap>
612 inline
613 void
616  Fraction & f2, Quotient & nb2 ) const
617 {
618  if ( odd() )
619  {
620  f1 = ancestor();
621  f2 = reduced( 2 );
622  nb1 = this->u();
623  nb2 = 1;
624  }
625  else
626  {
627  f1 = reduced( 2 );
628  f2 = ancestor();
629  nb1 = 1;
630  nb2 = this->u();
631  }
632 }
633 //-----------------------------------------------------------------------------
634 template <typename TInteger, typename TQuotient, typename TMap>
635 inline
636 void
638 getCFrac( std::vector<Quotient> & quotients ) const
639 {
640  ASSERT( k() >= NumberTraits<Quotient>::ZERO );
642  if ( null() ) return;
643  quotients.resize( i + 1 );
644  Fraction f( *this );
645  quotients[ i-- ] = f.u();
646  f = f.origin();
647  if ( i >= 0 )
648  {
649  for ( ; i >= 1; --i )
650  {
651  quotients[ i ] = f.u() - NumberTraits<Quotient>::ONE;
652  f = f.origin();
653  }
654  quotients[ 0 ] = mySup1 ? f.u() - NumberTraits<Quotient>::ONE
656  }
657 }
658 //-----------------------------------------------------------------------------
659 template <typename TInteger, typename TQuotient, typename TMap>
660 inline
663 begin() const
664 {
665  CFracSequence* seq = new CFracSequence;
666  this->getCFrac( *seq );
667  return ConstIterator( seq, seq->begin() );
668 }
669 //-----------------------------------------------------------------------------
670 template <typename TInteger, typename TQuotient, typename TMap>
671 inline
674 end() const
675 {
676  static CFracSequence dummy;
677  return ConstIterator( 0, dummy.end() );
678 }
679 //-----------------------------------------------------------------------------
680 template <typename TInteger, typename TQuotient, typename TMap>
681 inline
682 void
684 selfDisplay( std::ostream & out ) const
685 {
686  if ( this->null() ) out << "[Fraction null]";
687  else
688  {
689  out << "[Fraction f=" << this->p()
690  << "/" << this->q()
691  << " u=" << this->u()
692  << " k=" << this->k()
693  << std::flush;
694  std::vector<Quotient> quotients;
695  if ( this->k() >= 0 )
696  {
697  this->getCFrac( quotients );
698  out << " [" << quotients[ 0 ];
699  for ( unsigned int i = 1; i < quotients.size(); ++i )
700  out << "," << quotients[ i ];
701  out << "]";
702  }
703  out << " ]";
704  }
705 }
706 
708 // DGtal::LighterSternBrocot<TInteger, TQuotient, TMap>
709 
710 //-----------------------------------------------------------------------------
711 template <typename TInteger, typename TQuotient, typename TMap>
712 inline
714 {
715  if ( myOneOverOne != 0 ) delete myOneOverOne;
716  if ( myOneOverZero != 0 ) delete myOneOverZero;
717 }
718 //-----------------------------------------------------------------------------
719 template <typename TInteger, typename TQuotient, typename TMap>
720 inline
722 {
727  0 );
732  myOneOverZero );
734  nbFractions = 2;
735 }
736 //-----------------------------------------------------------------------------
737 template <typename TInteger, typename TQuotient, typename TMap>
738 inline
741 {
742  if ( singleton == 0 )
744  return *singleton;
745 }
746 
747 //-----------------------------------------------------------------------------
748 template <typename TInteger, typename TQuotient, typename TMap>
749 inline
752 {
753  return Fraction( instance().myOneOverZero, false );
754 }
755 //-----------------------------------------------------------------------------
756 template <typename TInteger, typename TQuotient, typename TMap>
757 inline
760 {
761  return Fraction( instance().myOneOverZero, true );
762 }
763 //-----------------------------------------------------------------------------
764 template <typename TInteger, typename TQuotient, typename TMap>
765 inline
768 {
769  return Fraction( instance().myOneOverOne, true );
770 }
771 
773 // Interface - public :
774 
779 template <typename TInteger, typename TQuotient, typename TMap>
780 inline
781 void
783  const Fraction & f )
784 {
785  if ( f.null() ) out << "[Fraction null]";
786  else
787  {
788  out << "[Fraction f=" << f.p()
789  << "/" << f.q()
790  << " u=" << f.u()
791  << " k=" << f.k()
792  // << " s1=" << f.isSup1()
793  << std::flush;
794  std::vector<Quotient> quotients;
795  if ( f.k() >= 0 )
796  {
797  f.getCFrac( quotients );
798  out << " [" << quotients[ 0 ];
799  for ( unsigned int i = 1; i < quotients.size(); ++i )
800  out << "," << quotients[ i ];
801  out << "]";
802  }
803  out << " ]";
804  }
805 }
806 
811 template <typename TInteger, typename TQuotient, typename TMap>
812 inline
813 bool
815 {
816  return true;
817 }
818 
820 // class LighterSternBrocot
822 template <typename TInteger, typename TQuotient, typename TMap>
823 inline
827  Fraction // ancestor
828  )
829 {
830  return Fraction( p, q );
831 }
832 
833 
835 // Implementation of inline functions //
836 
837 // JOL: invalid overloading
838 // template <typename TInteger, typename TQuotient, typename TMap>
839 // inline
840 // std::ostream&
841 // DGtal::operator<< ( std::ostream & out,
842 // const typename LighterSternBrocot<TInteger, TQuotient, TMap>::Fraction & object )
843 // {
844 // typedef LighterSternBrocot<TInteger, TQuotient, TMap> SB;
845 // SB::display( out, object );
846 // return out;
847 // }
848 
849 // //
851 
852