DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
OrderedAlphabet.cpp
1 
31 
32 #include "DGtal/base/OrderedAlphabet.h"
33 #include "DGtal/arithmetic/ModuloComputer.h"
35 
36 using namespace std;
37 
39 // class OrderedAlphabet
41 
43 // Standard services - public :
44 
49 {
50  if ( myOrder != 0 )
51  delete[ ] myOrder;
52 }
53 
57 string
59 {
60  char *tbl;
61  tbl = (char *)malloc((myNb + 1)*sizeof(char));
62  for ( unsigned int i = 0; i < myNb; ++i )
63  {
64  tbl[ myOrder[ i ] ] = myFirst + i;
65  }
66  tbl[ myNb ] = '\0';
67  string s( tbl );
68  free(tbl);
69  return s;
70 }
71 
75 void
77 {
78  unsigned int* p = myOrder;
79  unsigned int* q = myOrder + myNb;
80  while ( p != q )
81  {
82  unsigned int k = *p;
83  *p = ( k == 0 ) ? myNb - 1 : k - 1;
84  ++p;
85  }
86 }
87 
91 void
93 {
94  unsigned int* p = myOrder;
95  unsigned int* q = myOrder + myNb;
96  while ( p != q )
97  {
98  unsigned int k = *p + 1;
99  *p = ( k == myNb ) ? 0 : k;
100  ++p;
101  }
102 }
103 
107 void
109 {
110  unsigned int* p = myOrder;
111  unsigned int* q = myOrder + myNb;
112  while ( p != q )
113  {
114  *p = myNb - 1 - *p;
115  ++p;
116  }
117 }
118 
122 void
124 {
125  unsigned int* p = myOrder;
126  unsigned int* q = myOrder + myNb;
127  while ( p != q )
128  {
129  *p = ( myNb + 3 - *p ) % myNb;
130  ++p;
131  }
132 }
133 
134 
135 
136 
150 void
152 ( size_t & len, size_t & nb,
153  const std::string & w,
154  index_t s, index_t e ) const
155 {
156  index_t i = s;
157  index_t j = s+1;
158  while ( ( j < e ) && ( lessOrEqual( w[ i ], w[ j ] ) ) )
159  {
160  if ( equal( w[ i ], w[ j ] ) )
161  ++i;
162  else
163  i = s;
164  ++j;
165  }
166  len = (size_t) j - i;
167  nb = ( (size_t) ( j - s ) ) / len;
168 }
169 
170 
184 void
186 ( size_t & len, size_t & nb,
187  const std::string & w,
188  index_t s, index_t e ) const
189 {
190  size_t modulo = (DGtal::OrderedAlphabet::size_t)w.size();
191  ModuloComputer< Integer > mc( modulo );
192  index_t i = s;
193  index_t j = mc.next( s );
194  while ( ( j != e ) && ( lessOrEqual( w[ i ], w[ j ] ) ) )
195  {
196  if ( equal( w[ i ], w[ j ] ) )
197  mc.increment( i );
198  else
199  i = s;
200  mc.increment( j );
201  }
202  len = j >= i ? (size_t) ( j - i )
203  : (size_t) ( j + modulo - i );
204  nb = ( (size_t) ( ( j + modulo - s ) % modulo ) ) / len;
205 }
206 
207 
218 bool DGtal::OrderedAlphabet::duvalPP( size_t & len, size_t & nb,
219  const std::string & w, index_t s, index_t e) const
220 {
221  ASSERT( ( order( w[ s ] ) == 1 ) || ( order( w[ s ] ) == 2 ) );
222  index_t i = s;
223  index_t j = s+1;
224  index_t p = s;
225  index_t q = s+1;
226  while ( ( j < e ) && ( lessOrEqual( w[ i ], w[ j ] ) ) )
227  {
228  if ( equal( w[ i ], w[ j ] ) )
229  {
230  if ( j == q )
231  q += (p-s+1);
232  ++i;
233  }
234  else
235  {
236  if ( ( j != q ) || ( order ( w[ j ] ) != 2 ) )
237  {
238  len = j-s; nb = 0;
239  return false;
240  }
241  index_t tmp = p;
242  p = q;
243  q += q - tmp;
244  i = s;
245  }
246  ++j;
247  }
248  len = (size_t) j - i;
249  nb = ( (size_t) (j-s) ) / len;
250  return true;
251 }
252 
275 bool
277 ( size_t & len, size_t & nb,
278  unsigned int & n1, unsigned int & n2,
279  unsigned int & lf1, unsigned int & lf2,
280  const std::string & w,
281  index_t s, index_t e
282  ) const
283 {
284  ASSERT( ( order( w[ s ] ) == 1 ) || ( order( w[ s ] ) == 2 ) );
285  index_t i = s;
286  index_t j = s+1;
287  index_t p = s;
288  index_t q = s+1;
289  unsigned int slope1 = (order( w[ i ] ) == 1) ? 1 : 0;
290  unsigned int slope2 = (order( w[ i ] ) == 2) ? 1 : 0;
291  lf1 = n1 = slope1;
292  lf2 = n2 = slope2;
293  nb = 1;
294  //cerr << "input : " << w << endl;
295 
296  // Convex is not used so I comment it
298  while ( ( j < e ) && ( lessOrEqual( w[ i ], w[ j ] ) ) ) {
299 
300  //cerr << "i=" << i << " j=" << j << " p=" << p << " q="
301  // << q << " nb=" << nb << " n1=" << n1 << " n2=" << n2
302  // << " lf1=" << lf1 << " lf2=" << lf2 << endl;g
303 
304  //This 'if/else if' is added to compute the vector defined by
305  //the Christoffel word, this is usefull in order to compute the
306  //leaning points.
307  if (order( w[ j ] ) == 1)
308  ++slope1;
309  else if (order( w[ j ] ) == 2)
310  ++slope2;
311 
312  if ( equal( w[ i ], w[ j ] ) ) {
313  if ( j == q ) {
314  q += (p-s+1);
315 
316  //A repetition is read when j==s+(nb+1)*(p-s+1)-1
317  }
318  if ( j == nb * (p-s+1) + p ) {
319  ++nb;
320  }
321  ++i;
322  } else {
323  if ( ( j != q ) || ( order ( w[ j ] ) != 2 ) ) {
324  // convex = false;
325  break;
326  }
327  index_t tmp = p;
328  p = q;
329  q += q - tmp;
330  i = s;
331 
332  // Extra information to compute the leaning points
333  lf1 = lf1 + (nb-1)*n1;
334  lf2 = lf2 + (nb-1)*n2;
335  n1 = slope1;
336  n2 = slope2;
337  nb = 1;
338  }
339  ++j;
340  }
341  len = (size_t) j - i;
342  //cerr << "Termine" << endl;
343  //cerr << "i=" << i << " j=" << j << " p=" << p << " q="
344  // << q << " nb=" << nb << " n1=" << n1 << " n2=" << n2
345  // << " lf1=" << lf1 << " lf2=" << lf2 << endl;
346 
347  if ( nb != (size_t) (j-s) / len)
348  cout << "ASSERT(" << nb << " == (" << j << "-" << s << ") / "<<len << ")" << endl;
349  ASSERT( nb == (size_t) (j-s) / len);
350  //nb = (size_t) (j-s) / len;
351  return true;
352 }
353 
354 
377 bool
378 DGtal::OrderedAlphabet::duvalPPMod( size_t & len, size_t & nb,
379  const std::string & w,
380  index_t s, index_t e ) const
381 {
382  ASSERT( ( order( w[ s ] ) == 1 )
383  || ( order( w[ s ] ) == 2 ) );
384  size_t modulo = (DGtal::OrderedAlphabet::size_t)w.size();
385  ModuloComputer< Integer > mc( modulo );
387  index_t j = mc.next( s );
388  unsigned int p = 1;
389  unsigned int q = 2;
390  while ( ( j != e ) && ( lessOrEqual( w[ i ], w[ j ] ) ) )
391  {
392  // cerr << "i=" << i << " j=" << j << " p=" << p << " q=" << q << endl;
393  if ( equal( w[ i ], w[ j ] ) )
394  {
395  if ( j == mc.cast( s + q - 1 ) )
396  q += p;
397  mc.increment( i );
398  }
399  else
400  {
401  if ( ( j != mc.cast( s + q - 1 ) ) || ( order ( w[ j ] ) != 2 ) )
402  {
403  len = j; nb = 0;
404  return false;
405  }
406  unsigned int tmp = p;
407  p = q;
408  q += q - tmp;
409  i = s;
410  }
411  mc.increment( j );
412  }
413  len = j >= i ? (size_t) ( j - i )
414  : (size_t) ( j + modulo - i );
415  nb = ( (size_t) ( ( j + modulo - s ) % modulo ) ) / len;
416  return true;
417 }
418 
419 
421 // Interface - public :
422 
427 void
428 DGtal::OrderedAlphabet::selfDisplay ( std::ostream & out ) const
429 {
430  out << "[OrderedAlphabet]";
431  out << " " << orderedAlphabet() << endl;
432 }
433 
438 bool
440 {
441  return true;
442 }
443 
444 
445 
447 // ----------------------- MLP services ------------------------------
448 
471  size_t & nb_a2,
472  std::string & w,
473  index_t & s,
474  bool & cvx )
475 {
476  ModuloComputer< Integer > mc( (const unsigned int)w.size() );
477  size_t l;
478  size_t len;
479  size_t nb;
480  bool inC = duvalPPMod( len, nb, w, s, s );
481  if ( ! inC )
482  // case : change of convexity
483  {
484 // cerr << "Convexity change" << orderedAlphabet() ;
485 // cerr << " (" << w[ len ] << "==" << letter( 2 ) << ")";
486  // JOL : temporary change of letter w[ s ]
487  char tmp = w[ s ];
488  index_t tmp_s = s;
489  w[ s ] = letter( 2 ); // a3
490  this->reverseAround12();
491  cvx = ! cvx;
492 // cerr << " => " << orderedAlphabet() << endl;
493  l = nextEdge( nb_a1, nb_a2, w, s, cvx );
494  // JOL : former letter is put back in string.
495  w[ tmp_s ] = tmp;
496  }
497  else if ( ( len == 1 ) && ( order( w[ s ] ) == 1 ) )
498  // case u=a1 => Quadrant change
499  {
500 // cerr << "Quadrant change " << orderedAlphabet() ;
501  this->shiftRight();
502 // cerr << " => " << orderedAlphabet() << endl;
503  s = mc.cast( s + nb );
504  nb_a1 = 0;
505  nb_a2 = nb - 1;
506  l = nb;
507  }
508  else
509  { // standard (convex) case.
510 // cerr << "standard (convex) case " << orderedAlphabet() << endl;
511  l = len * nb;
512  char a2 = letter( 2 );
513  nb_a1 = len;
514  nb_a2 = 0;
515  index_t ss = s;
516  s = mc.cast( s + l );
517  while ( len != 0 )
518  {
519  if ( w[ ss ] == a2 ) ++nb_a2;
520  mc.increment( ss );
521  --len;
522  }
523  nb_a1 -= nb_a2;
524  nb_a1 *= nb;
525  nb_a2 *= nb;
526  }
527  return l;
528 }
529 
530 
532 // Internals - private :
533 
534 // //