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 OneBalancedWordComputer.ih
19 * @author Xavier Provençal (\c xavier.provencal@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
24 * Implementation of inline methods defined in OneBalancedWordComputer.h
26 * This file is part of the DGtal library.
30//////////////////////////////////////////////////////////////////////////////
32//////////////////////////////////////////////////////////////////////////////
34///////////////////////////////////////////////////////////////////////////////
35// IMPLEMENTATION of inline methods.
36///////////////////////////////////////////////////////////////////////////////
40///////////////////////////////////////////////////////////////////////////////
41// ----------------------- Standard services ------------------------------
43// ------------------------------------------------------------------------
44template < typename TConstIterator, typename TInteger >
46DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::OneBalancedWordComputer()
50// ------------------------------------------------------------------------
51template < typename TConstIterator, typename TInteger >
53DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::~OneBalancedWordComputer()
59// ------------------------------------------------------------------------
60template < typename TConstIterator, typename TInteger >
63DGtal::OneBalancedWordComputer<TConstIterator, TInteger>::init(
64 const ConstIterator & it,
66 Vector (*displacements) (Code) )
68 myCodeHandler.init( it );
78 myLeftPatternLength = 0;
83 myDisplacements = displacements;
86 myLastPoint = myFirstPoint + displacement( getCode( myFirstLetter) );
92// ------------------------------------------------------------------------
93template < typename TConstIterator, typename TInteger >
95void DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::init(const ConstPointIterator & i)
97 *this = *( i.getDSS() );
102// ------------------------------------------------------------------------
103template < typename TConstIterator, typename TInteger >
105void DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::init(const FreemanChainCode & fc)
107 init( fc.chain.begin(), fc.firstPoint(), FreemanChainCode::displacement );
112// ------------------------------------------------------------------------
113template < typename TConstIterator, typename TInteger >
115void DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::init(const typename FreemanChainCode::ConstIterator& it)
117 std::string::const_iterator string_it = it.getChain()->chain.begin();
118 string_it += it.position();
119 init( string_it, *it, FreemanChainCode::displacement );
122// ------------------------------------------------------------------------
123template < typename TConstIterator, typename TInteger >
125DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::OneBalancedWordComputer ( const Self & other ) :
126 myCodeHandler ( other.myCodeHandler ),
127 myBegin ( other.myBegin ),
128 myEnd ( other.myEnd ),
129 myFirstPoint ( other.myFirstPoint ),
130 myLastPoint ( other.myLastPoint ),
131 myFirstLetter ( other.myFirstLetter ),
132 myLastLetter ( other.myLastLetter ),
133 myNbRepeat ( other.myNbRepeat ),
134 myPatternBegin ( other.myPatternBegin ),
135 myPatternEnd ( other.myPatternEnd ),
136 myLeftPatternLength ( other.myLeftPatternLength ),
137 myNextBefore ( other.myNextBefore ),
138 myNextAfter ( other.myNextAfter ),
139 myDisplacements ( other.myDisplacements )
143// ------------------------------------------------------------------------
144template < typename TConstIterator, typename TInteger >
146DGtal::OneBalancedWordComputer<TConstIterator,TInteger> &
147DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::operator= ( const Self & other )
149 myCodeHandler = other.myCodeHandler;
150 myBegin = other.myBegin;
152 myFirstPoint = other.myFirstPoint;
153 myLastPoint = other.myLastPoint;
154 myFirstLetter = other.myFirstLetter;
155 myLastLetter = other.myLastLetter;
156 myNbRepeat = other.myNbRepeat;
157 myPatternBegin = other.myPatternBegin ;
158 myPatternEnd = other.myPatternEnd;
159 myLeftPatternLength = other.myLeftPatternLength;
160 myNextBefore = other.myNextBefore;
161 myNextAfter = other.myNextAfter;
162 myDisplacements = other.myDisplacements;
167// ------------------------------------------------------------------------
168template < typename TConstIterator, typename TInteger >
170typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Self
171DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getSelf( ) const
173 return OneBalancedWordComputer( );
176// ------------------------------------------------------------------------
177template < typename TConstIterator, typename TInteger >
179bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::operator==( const Self & other ) const
181 return ( ( begin() == other.begin() ) && ( end() == other.end() ) );
185// ------------------------------------------------------------------------
186template < typename TConstIterator, typename TInteger >
188bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::operator!=( const Self & other ) const
190 return !(*this == other);
194// ------------------------------------------------------------------------
195template < typename TConstIterator, typename TInteger >
197typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Reverse
198DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getReverse() const
205// ------------------------------------------------------------------------
206template < typename TConstIterator, typename TInteger >
208bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::extendFront()
210 Code letterRead = getCode( myLastLetter + 1 );
211 Code letterExpected = getCode( myNextAfter );
213 // Test if the new letter forms a longer prefix of the main pattern
214 // If the new letter is not what was expected, either the main pattern
215 // has to grow or either the DSS may not be extended.
216 if ( letterRead == letterExpected ) {
217 // Test if it is a complete repetition of the main pattern
218 if ( myNextAfter == myPatternEnd ) {
220 myNextAfter = myPatternBegin;
225 } else if ( isTrivial() ) {
226 myLeftPatternLength = 1;
228 myPatternEnd = myLastLetter + 1;
229 myNextBefore = myPatternEnd;
231 } else if ( nextIsLL( myNextAfter ) && ( letterRead == getBigLetter() ) ) {
232 // The previous main pattern is now the left subpattern
233 myLeftPatternLength = mainPatternLength();
235 Size myOldSuffixLength = suffixLength();
236 myPatternEnd = myLastLetter + 1;
237 myNextBefore = myPatternEnd - myOldSuffixLength;
238 myNextAfter = myPatternBegin;
240 } else if ( isUL( myNextAfter ) && ( letterRead == getSmallLetter() ) ) {
241 //In this case thw whole main pattern is modified! Not only complexified.
242 Size myOldLeftPatternLength = myLeftPatternLength;
243 Size myOldSuffixLength = suffixLength();
245 myLeftPatternLength = mainPatternLength();
246 myPatternEnd = myLastLetter + 1;
248 // test if the suffix is long enough to contain the new first upper
249 // leaning point (beginning of the main pattern)
250 if ( myOldSuffixLength < myOldLeftPatternLength ) {
251 myPatternBegin = myPatternBegin + myLeftPatternLength
252 - myOldLeftPatternLength;
253 myNextBefore = myPatternEnd - myLeftPatternLength +
254 myOldLeftPatternLength - myOldSuffixLength;
257 myPatternBegin = myPatternBegin - myOldLeftPatternLength;
258 myNextBefore = myPatternEnd - (myOldSuffixLength - myOldLeftPatternLength);
260 myNextAfter = myPatternBegin;
267 myLastPoint += displacement( getCode( myLastLetter ) );
272// ------------------------------------------------------------------------
273template < typename TConstIterator, typename TInteger >
275bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::extendBack()
277 Code letterRead = getCode( myFirstLetter - 1 );
278 Code letterExpected = getCode( myNextBefore );
280 // Test if the new letter forms a longer suffix of the main pattern
281 // If the new letter is not what was expected, either the main pattern
282 // has to grow or either the DSS may not be extended.
283 if ( letterRead == letterExpected ) {
284 // Test if it forms a complete repetition of the main pattern
285 if ( myNextBefore == myPatternBegin ) {
286 //cout << "Case 1" << endl;
288 // Move main pattern one iteration backward, nb 'myNextBefore' is
289 // already one iteration before.
290 Size mpl = mainPatternLength();
291 myPatternBegin -= mpl;
294 myNextBefore = myPatternEnd;
297 //cout << "Case 2" << endl;
301 } else if ( isTrivial() ) {
302 //cout << "Case 3" << endl;
303 myLeftPatternLength = myNbRepeat;
304 myPatternEnd += myNbRepeat-1;
306 myPatternBegin = myFirstLetter - 1;
307 myNextBefore = myPatternEnd;
308 myNextAfter = myPatternBegin;
310 } else if ( previousIsLL( myNextBefore ) && ( letterRead == getSmallLetter() ) ) {
311 //cout << "Case 4" << endl;
312 // The previous main pattern is now the left subpattern
313 Size myOldMainPatternLength = mainPatternLength();
314 Size myOldLeftPatternLength = myLeftPatternLength;
315 //Size myOldRightPatternLength = myOldMainPatternLength - myOldLeftPatternLength;
317 myPatternBegin = myFirstLetter - 1;
318 myPatternEnd += (myNbRepeat-1) * myOldMainPatternLength;
319 myLeftPatternLength = mainPatternLength() - myOldMainPatternLength;
321 myNextBefore = myPatternEnd;
322 myNextAfter -= myOldLeftPatternLength;
324 } else if ( isUL( myNextBefore ) && ( letterRead == getBigLetter() ) ) {
325 //In this case the whole main pattern is modified! Not only complexified.
326 Size myOldMainPatternLength = mainPatternLength();
327 Size myOldRightPatternLength = myOldMainPatternLength - myLeftPatternLength;
328 Size myOldPrefixLength = prefixLength();
330 myPatternBegin = myFirstLetter - 1;
332 // test if the prefix is long enough to contain the new Last Upper
334 if ( myOldPrefixLength < myOldRightPatternLength ) {
335 //cout << "Case 5" << endl;
336 myNextAfter = myNextAfter - myOldMainPatternLength + myLeftPatternLength;
337 myPatternEnd = myPatternEnd
338 + (myNbRepeat - 1)*myOldMainPatternLength
339 - myLeftPatternLength;
342 //cout << "Case 6" << endl;
343 myNextAfter = myNextAfter - myOldMainPatternLength - myOldRightPatternLength;
344 myPatternEnd = myPatternEnd
345 + myNbRepeat*myOldMainPatternLength
346 - myLeftPatternLength;
349 myNextBefore = myPatternEnd;
350 myLeftPatternLength = mainPatternLength() - myOldMainPatternLength;
353 //cout << "Case 7" << endl;
358 myFirstPoint -= displacement( getCode( myFirstLetter ) );
364// ------------------------------------------------------------------------
365template < typename TConstIterator, typename TInteger >
367bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::retractBack()
370 if ( myNextBefore != myPatternEnd ) {
372 //cout << "Case 1" << endl;
375 } else if ( isTrivial() ) {
376 // In this case, it can be shorten only if there is more than one
378 //cout << "Case 2" << endl;
379 if ( myNbRepeat == 1 ) return false;
380 myPatternBegin = myPatternEnd = myNextBefore = ++myNextAfter;
383 } else if ( myNbRepeat >= 2 ) {
384 // Got more than one repetition, it suffices to consider the next
385 // repetition of the main pattern with one less repetition.
386 //cout << "Case 3" << endl;
387 Size myOldMainPatternLength = mainPatternLength();
388 myPatternBegin += myOldMainPatternLength;
389 myPatternEnd += myOldMainPatternLength;
390 myNextAfter += myOldMainPatternLength;
391 myNextBefore = myPatternBegin;
395 //Only one repetition, the slope is modified.
396 Size myOldMainPatternLength = mainPatternLength();
397 Size myOldLeftPatternLength = myLeftPatternLength;
398 Size myOldRightPatternLength = myOldMainPatternLength - myOldLeftPatternLength;
400 if ( prefixLength() >= myOldRightPatternLength ) {
401 // A second Lower Leaning Point has been read in the prefix at
402 // the end of the main pattern. The slope is simply reversed.
403 //cout << "Case 4" << endl;
404 myLeftPatternLength = myOldRightPatternLength;
405 myPatternBegin += myOldRightPatternLength;
406 myPatternEnd += myOldRightPatternLength;
407 myNextBefore = myPatternEnd - myOldRightPatternLength + 1;
409 } else if ( myOldLeftPatternLength < myOldRightPatternLength ) {
410 // Remove one repetition of the left Berstel pattern.
411 //cout << "Case 5" << endl;
412 myPatternBegin += myOldLeftPatternLength;
413 myNextBefore -= ( myOldLeftPatternLength - 1 );
414 myNextAfter += myOldLeftPatternLength;
416 } else if ( myOldLeftPatternLength > myOldRightPatternLength ) {
417 // The complexity of the slope is modified.
418 //cout << "Case 6" << endl;
419 Size myNbBerstelRight = (myOldRightPatternLength > 1) ?
420 myOldMainPatternLength / myOldRightPatternLength :
421 myOldMainPatternLength - 1;
422 Size myBerstelLeftLength = myOldMainPatternLength -
423 ( myNbBerstelRight * myOldRightPatternLength );
424 // Right subpattern becomes the main pattern
425 myNbRepeat = myNbBerstelRight;
426 myPatternBegin += myBerstelLeftLength;
427 myPatternEnd = myPatternBegin + myOldRightPatternLength - 1;
428 myNextBefore = myPatternEnd - myBerstelLeftLength + 1;
429 myNextAfter += myBerstelLeftLength;
430 myLeftPatternLength = (myPatternBegin == myPatternEnd) ?
431 0 : myBerstelLeftLength;
434 // Special case of slope 1/1 with no prefix read, only a trivial
436 //cout << "Case 7" << endl;
437 myNextBefore = myNextAfter = myPatternBegin = myPatternEnd;
438 myLeftPatternLength = 0;
443 myFirstPoint += displacement( getCode( myFirstLetter ) );
449// ------------------------------------------------------------------------
450template < typename TConstIterator, typename TInteger >
452bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::retractFront()
454 if ( myNextAfter != myPatternBegin ) {
456 //cout << "Case 1" << endl;
459 } else if ( isTrivial() ) {
460 // In this case, it can be shorten only if there is more than one
462 //cout << "Case 2" << endl;
463 if ( myNbRepeat == 1 ) return false;
466 } else if ( myNbRepeat >= 2 ) {
467 // Got more than one repetition, it suffices to consider the next
468 // repetition of the main pattern with one less repetition.
469 //cout << "Case 3" << endl;
471 myNextAfter = myPatternEnd;
474 //Only one repetition, the slope is modified.
475 Size myOldMainPatternLength = mainPatternLength();
476 Size myOldLeftPatternLength = myLeftPatternLength;
477 Size myOldRightPatternLength = myOldMainPatternLength -
478 myOldLeftPatternLength;
480 if ( suffixLength() >= myOldLeftPatternLength ) {
481 // A second Lower Leaning Point has been read in the suffix at
482 // the front of the main pattern. The slope is simply reversed.
483 //cout << "Case 4" << endl;
484 myLeftPatternLength = myOldRightPatternLength;
485 myPatternBegin -= myOldLeftPatternLength;
486 myPatternEnd -= myOldLeftPatternLength;
487 myNextAfter = myPatternBegin + myOldLeftPatternLength - 1;
489 } else if ( myOldLeftPatternLength > myOldRightPatternLength ) {
490 // Remove one repetition of the right Berstel pattern.
491 //cout << "Case 5" << endl;
492 myPatternEnd -= myOldRightPatternLength;
493 myNextAfter += ( myOldRightPatternLength - 1 );
494 myNextBefore -= myOldRightPatternLength;
495 myLeftPatternLength -= myOldRightPatternLength;
497 } else if ( myOldLeftPatternLength < myOldRightPatternLength ) {
498 // The complexity of the slope is modified.
499 //cout << "Case 6" << endl;
500 Size myNbBerstelLeft = (myOldLeftPatternLength > 1) ?
501 myOldMainPatternLength / myOldLeftPatternLength :
502 myOldMainPatternLength - 1;
503 Size myBerstelRightLength = myOldMainPatternLength -
504 ( myNbBerstelLeft * myOldLeftPatternLength );
505 Size myOldSuffixLength = suffixLength();
507 // Left subpattern becomes the main pattern.
508 myNbRepeat = myNbBerstelLeft;
509 myLeftPatternLength = myOldLeftPatternLength - myBerstelRightLength;
510 myPatternEnd = myPatternBegin + myOldLeftPatternLength - 1;
511 myNextBefore = myPatternEnd - myOldSuffixLength;
512 myNextAfter = myPatternBegin + myBerstelRightLength - 1;
515 // Special case of slope 1/1 with no prefix read, only a trivial
517 //cout << "Case 7" << endl;
518 myNextBefore = myNextAfter = myPatternEnd = myPatternBegin;
519 myLeftPatternLength = 0;
523 myLastPoint -= displacement( getCode( myLastLetter ) );
529// ------------------------------------------------------------------------
530template < typename TConstIterator, typename TInteger >
532bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::isExtendableFront()
534 Code letterRead = getCode( myLastLetter + 1 );
535 Code letterExpected = getCode( myNextAfter );
536 if ( letterRead == letterExpected )
540 else if ( isTrivial() )
544 else if ( nextIsLL( myNextAfter ) && ( letterRead == getBigLetter() ) )
548 else if ( isUL( myNextAfter ) && ( letterRead == getSmallLetter() ) )
557// ------------------------------------------------------------------------
558template < typename TConstIterator, typename TInteger >
560bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::isExtendableBack()
562 Code letterRead = getCode( myFirstLetter - 1);
563 Code letterExpected = getCode( myNextBefore );
564 if ( letterRead == letterExpected )
568 else if ( isTrivial() )
572 else if ( previousIsLL( myNextBefore ) && ( letterRead == getSmallLetter() ) )
576 else if ( isUL( myNextBefore ) && ( letterRead == getBigLetter() ) )
583// ------------------------------------------------------------------------
584template < typename TConstIterator, typename TInteger >
586void DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::setPosition(
587 const typename DGtal::OneBalancedWordComputer<TConstIterator, TInteger>::Point & p )
589 Vector v = myLastPoint - myFirstPoint;
595// ------------------------------------------------------------------------
596template < typename TConstIterator, typename TInteger >
598void DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::translate(
599 const typename DGtal::OneBalancedWordComputer<TConstIterator, TInteger>::Vector & v )
606// ------------------------------------------------------------------------
607template < typename TConstIterator, typename TInteger >
609bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::isValid() const
612 ( myFirstLetter <= myPatternBegin ) &&
613 ( myPatternBegin <= myPatternEnd ) &&
614 ( myPatternEnd <= myLastLetter ) &&
615 ( myNextBefore >= myPatternBegin ) &&
616 ( myNextBefore <= myPatternEnd ) &&
617 ( myNextAfter >= myPatternBegin ) &&
618 ( myNextAfter <= myPatternEnd ) &&
619 ( (myLeftPatternLength == 0 ) ||
620 (myLeftPatternLength < mainPatternLength() ) ) );
623///////////////////////////////////////////////////////////////////////////////
624// Interface - public :
626// ------------------------------------------------------------------------
627template < typename TConstIterator, typename TInteger >
630DGtal::OneBalancedWordComputer<TConstIterator, TInteger >::selfDisplay ( std::ostream & out ) const
633 for (int i=myFirstLetter; i<= myLastLetter; i++)
636 for (int i=myLastLetter+1; i<myLastLetter+4 ; i++)
638 out << "[OneBalancedWordComputer]\n";
639 out << "myCodes = " << s << "\n";
640 out << "myFirstPoint = " << myFirstPoint << "\n";
641 out << "myLastPoint = " << myLastPoint << "\n";
642 out << "myFirstLetter = " << myFirstLetter << "\n";
643 out << "myLastLetter = " << myLastLetter << "\n";
644 out << "myNbRepeat = " << myNbRepeat << "\n";
645 out << "myPatternBegin = " << myPatternBegin << "\n";
646 out << "myPatternEnd = " << myPatternEnd << "\n";
647 out << "myLeftPatternLength = " << myLeftPatternLength << "\n";
648 out << "myNextBefore = " << myNextBefore << "\n";
649 out << "myNextAfter = " << myNextAfter << "\n";
650 DSL d = getArithmeticalDescription();
651 out << "(a,b,mu,omega) = (" << d.a() << ", " << d.b() << ", "
652 << d.mu() << ", " << d.omega() << ")\n";
653 out << "[End OneBalancedWordComputer]" << std::endl;
657// ------------------------------------------------------------------------
658template < typename TConstIterator, typename TInteger >
660typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Code
661DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getSmallLetter() const
663 return getCode( myPatternBegin );
667// ------------------------------------------------------------------------
668template < typename TConstIterator, typename TInteger >
670typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Code
671DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getBigLetter() const
673 return getCode( myPatternEnd );
678// ------------------------------------------------------------------------
679template < typename TConstIterator, typename TInteger >
681typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Code
682DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getCode(Index pos)
684 return myCodeHandler.getCode( pos );
687// ------------------------------------------------------------------------
688template < typename TConstIterator, typename TInteger >
690typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Code
691DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getCode(Index pos) const
693 return myCodeHandler.getCode( pos );
698// ------------------------------------------------------------------------
699template < typename TConstIterator, typename TInteger >
701typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Size
702DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::mainPatternLength() const
704 return myPatternEnd - myPatternBegin + 1;
707template < typename TConstIterator, typename TInteger >
709typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Vector
710DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::mainPatternVector() const
712 ConstPointIterator it = pointBegin();
713 while ( ! isUL ( it.getIndex() ) )
716 ++it; /* At least one letter in the pattern */
719 while ( ! isUL ( it.getIndex() ) )
727// ------------------------------------------------------------------------
728template < typename TConstIterator, typename TInteger >
730typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Size
731DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::suffixLength() const
733 return ( myPatternEnd - myNextBefore );
737// ------------------------------------------------------------------------
738template < typename TConstIterator, typename TInteger >
740typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Size
741DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::prefixLength() const
743 return ( myNextAfter - myPatternBegin );
746// ------------------------------------------------------------------------
747template < typename TConstIterator, typename TInteger >
749bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::isUL ( Index pos ) const
751 return ( (pos == myPatternBegin) || ( pos == myPatternEnd ) );
756// ------------------------------------------------------------------------
757template < typename TConstIterator, typename TInteger >
759bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::nextIsLL ( Index pos ) const
761 return ( (pos - myPatternBegin) == mainPatternLength() - myLeftPatternLength - 1) ;
764// ------------------------------------------------------------------------
765template < typename TConstIterator, typename TInteger >
767bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::previousIsLL ( Index pos ) const
769 return ( (pos - myPatternBegin) == mainPatternLength() - myLeftPatternLength ) ;
773// ------------------------------------------------------------------------
774template < typename TConstIterator, typename TInteger >
776bool DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::isTrivial() const
778 // If there is no left subpattern, then the DSS is trivial.
779 return ( myLeftPatternLength == 0 );
783// ------------------------------------------------------------------------
784template < typename TConstIterator, typename TInteger >
786typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::ConstIterator
787DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::begin() const
792// ------------------------------------------------------------------------
793template < typename TConstIterator, typename TInteger >
795typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::ConstIterator
796DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::end() const
802// ------------------------------------------------------------------------
803template < typename TConstIterator, typename TInteger >
805typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::ConstPointIterator
806DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::pointBegin() const
808 return ConstPointIterator( this, myFirstLetter, myFirstPoint );
812// ------------------------------------------------------------------------
813template < typename TConstIterator, typename TInteger >
815typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::ConstPointIterator
816DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::pointEnd() const
818 ConstPointIterator it ( this, myLastLetter+1, myLastPoint );
825// ------------------------------------------------------------------------
826template < typename TConstIterator, typename TInteger >
828typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Integer
829DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getA() const
831 return getArithmeticalDescription().a();
834// ------------------------------------------------------------------------
835template < typename TConstIterator, typename TInteger >
837typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Integer
838DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getB() const
840 return getArithmeticalDescription().b();
844// ------------------------------------------------------------------------
845template < typename TConstIterator, typename TInteger >
847typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Integer
848DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getMu() const
850 return getArithmeticalDescription().mu();
854// ------------------------------------------------------------------------
855template < typename TConstIterator, typename TInteger >
857typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Integer
858DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getOmega() const
860 return getArithmeticalDescription().omega();
864// ------------------------------------------------------------------------
865template < typename TConstIterator, typename TInteger >
867typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::DSL
868DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::getArithmeticalDescription() const
870 DGtal::IntegerComputer<TInteger> ic;
872 ConstPointIterator itBegin = pointBegin();
873 while ( itBegin.getIndex() != myPatternBegin )
875 ConstPointIterator itEnd = pointEnd();
876 while ( itEnd.getIndex() != myPatternEnd+1 )
878 ConstPointIterator it;
879 Size myRightPatternLenght = mainPatternLength() - myLeftPatternLength;
881 for (int i=0; i<myRightPatternLenght; i++)
888 Integer r1 = v[1]*pb[0] - v[0]*pb[1];
889 Integer r2 = v[1]*po[0] - v[0]*po[1];
890 Integer bound = ic.min (r1, r2);
892 return DSL(v[1], v[0], bound);
896// ------------------------------------------------------------------------
897template < typename TConstIterator, typename TInteger >
899void DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::computeLeaningPoints(
900 Point & uf, Point & ul,
901 Point & lf, Point & ll ) const
903 ConstPointIterator it = pointBegin();
904 while ( ! isUL ( it.getIndex() ) )
908 Vector v = mainPatternVector();
909 ul = uf + v*static_cast<Integer>(myNbRepeat);
911 while ( ! previousIsLL ( it.getIndex() ) )
913 lf = ( suffixLength() >= myLeftPatternLength ) ? *it - mainPatternVector() : *it;
915 int nbLowerRepeats = ( prefixLength() >= mainPatternLength() - myLeftPatternLength )
916 ? myNbRepeat : myNbRepeat - 1;
917 ll = *it + v*nbLowerRepeats;
919 if ( remainder( uf ) > remainder( lf ) )
929// ------------------------------------------------------------------------
930template < typename TConstIterator, typename TInteger >
932typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Point
933DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Uf() const
935 Point uf, ul, lf, ll;
936 computeLeaningPoints( uf, ul, lf, ll );
940// ------------------------------------------------------------------------
941template < typename TConstIterator, typename TInteger >
943typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Point
944DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Ul() const
946 Point uf, ul, lf, ll;
947 computeLeaningPoints( uf, ul, lf, ll );
951// ------------------------------------------------------------------------
952template < typename TConstIterator, typename TInteger >
954typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Point
955DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Lf() const
957 Point uf, ul, lf, ll;
958 computeLeaningPoints( uf, ul, lf, ll );
963// ------------------------------------------------------------------------
964template < typename TConstIterator, typename TInteger >
966typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Point
967DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Ll() const
969 Point uf, ul, lf, ll;
970 computeLeaningPoints( uf, ul, lf, ll );
975// ------------------------------------------------------------------------
976template < typename TConstIterator, typename TInteger >
978typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Vector
979DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::displacement( Code c ) const
981 return this->myDisplacements( c );
985// ------------------------------------------------------------------------
986template < typename TConstIterator, typename TInteger >
988typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Integer
989DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::remainder(const Point & aPoint) const
991 DSL d = getArithmeticalDescription();
992 return (d.a()*aPoint[0] - d.b()*aPoint[1]);
996// ----------------------- Accessors --------------------------------------
999template < typename TConstIterator, typename TInteger >
1001typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Point
1002DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::back() const
1004 return myFirstPoint;
1008// ------------------------------------------------------------------------
1009template < typename TConstIterator, typename TInteger >
1011typename DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::Point
1012DGtal::OneBalancedWordComputer<TConstIterator,TInteger>::front() const
1018///////////////////////////////////////////////////////////////////////////////
1019// Implementation of inline functions //
1021template < typename TConstIterator, typename TInteger >
1024DGtal::operator<< ( std::ostream & out,
1025 const OneBalancedWordComputer<TConstIterator, TInteger> & object )
1027 object.selfDisplay( out );
1032///////////////////////////////////////////////////////////////////////////////