DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testLighterSternBrocot.cpp
1 
30 
31 #include <cstdlib>
32 #include <iostream>
33 #include <vector>
34 #include <iterator>
35 #include <map>
36 #include "DGtal/base/Common.h"
37 #include "DGtal/kernel/CPointPredicate.h"
38 #include "DGtal/arithmetic/CPositiveIrreducibleFraction.h"
39 #include "DGtal/arithmetic/IntegerComputer.h"
40 #include "DGtal/arithmetic/LighterSternBrocot.h"
41 #include "DGtal/arithmetic/LightSternBrocot.h"
42 #include "DGtal/arithmetic/Pattern.h"
43 #include "DGtal/arithmetic/StandardDSLQ0.h"
44 #include "DGtal/geometry/curves/ArithmeticalDSS.h"
46 
47 using namespace std;
48 using namespace DGtal;
49 
51 // Functions for testing class LighterSternBrocot.
53 
54 template <typename Quotient>
55 bool
56 equalCFrac( const std::vector<Quotient> & c1, const std::vector<Quotient> & c2 )
57 {
58  unsigned int s = c1.size() < c2.size() ? c1.size() : c2.size();
59  if ( ( s != c1.size() ) && ( c1.back() != NumberTraits<Quotient>::ONE ) )
60  return false;
61  if ( ( s != c2.size() ) && ( c2.back() != NumberTraits<Quotient>::ONE ) )
62  return false;
63  for ( unsigned int i = 0; i < s; ++i )
64  {
65  Quotient q1 = c1[ i ];
66  if ( ( s != c1.size() ) && ( i == s - 1 ) ) q1 += c1.back();
67  Quotient q2 = c2[ i ];
68  if ( ( s != c2.size() ) && ( i == s - 1 ) ) q2 += c2.back();
69  if ( q1 != q2 ) return false;
70  }
71  return true;
72 }
73 
74 template <typename SB>
75 bool testReducedFraction()
76 {
77  typedef typename SB::Integer Integer;
78  typedef typename SB::Quotient Quotient;
79  typedef typename SB::Fraction Fraction;
80  unsigned int nbok = 0;
81  unsigned int nb = 0;
82  Integer p = random() / 10000;
83  Integer q = random() / 10000;
84  trace.beginBlock ( "Testing block: reduced fraction." );
86  Integer g = ic.gcd( p, q );
87  p /= g;
88  q /= g;
90  Quotient sp = NumberTraits<Integer>::castToInt64_t( p );
91  Quotient sq = NumberTraits<Integer>::castToInt64_t( q );
92  std::vector<Quotient> cf1;
93  ics.getCFrac( cf1, sp, sq );
94  Fraction f1 = SB::fraction( p, q );
95  std::vector<Quotient> cf1_bis;
96  f1.getCFrac( cf1_bis );
97  bool ok = equalCFrac<Quotient>( cf1, cf1_bis );
98  trace.info() << " - p / q = " << p << " / " << q << std::endl;
99  trace.info() << " - f1 = ";
100  SB::display( trace.info(), f1 );
101  trace.info() << std::endl;
102  ++nb, nbok += ok ? 1 : 0;
103  trace.info() << "(" << nbok << "/" << nb << ") "
104  << " cfrac"
105  << std::endl;
106  unsigned int depth = cf1.size();
107  for ( unsigned int k = 1; k < depth; ++k )
108  {
109  std::vector<Quotient> cf1_red;
110  Fraction fr = f1.reduced( k );
111  fr.getCFrac( cf1_red );
112  cf1.resize( depth - k );
113  ok = equalCFrac<Quotient>( cf1, cf1_red );
114  ++nb, nbok += ok ? 1 : 0;
115  trace.info() << "(" << nbok << "/" << nb << ") "
116  << "reduced(" << k << ")=";
117  SB::display( trace.info(), fr );
118  std::cerr << std::endl;
119  }
120 
121  //trace.info() << "- nbFractions = " << SB::instance().nbFractions << std::endl;
122  trace.endBlock();
123  return nbok == nb;
124 }
125 
126 template <typename SB>
127 bool testInitFraction()
128 {
129  typedef typename SB::Integer Integer;
130  typedef typename SB::Fraction Fraction;
131  unsigned int nbok = 0;
132  unsigned int nb = 0;
133  Integer p = random() / 10000;
134  Integer q = random() / 10000;
135  trace.beginBlock ( "Testing block: init fraction." );
137  Integer g = ic.gcd( p, q );
138  p /= g;
139  q /= g;
140  Fraction f1 = SB::fraction( p, q );
141  trace.info() << "p / q = " << p << " / " << q << std::endl;
142  trace.info() << "f1 = ";
143  SB::display( trace.info(), f1 );
144  trace.info() << std::endl;
145  nbok += ( ( p == f1.p() ) && ( q == f1.q() ) ) ? 1 : 0;
146  ++nb;
147  trace.info() << "(" << nbok << "/" << nb << ") "
148  << "( ( p == f1.p() ) && ( q == f1.q() ) )"
149  << std::endl;
150  trace.info() << "- nbFractions = " << SB::instance().nbFractions << std::endl;
151  trace.endBlock();
152 
153  return nbok == nb;
154 }
155 
156 template <typename SB>
157 bool testPattern()
158 {
159  typedef typename SB::Integer Integer;
160  typedef typename SB::Quotient Quotient;
161  typedef typename SB::Fraction Fraction;
162  typedef Pattern<Fraction> MyPattern;
163  typedef typename MyPattern::Vector2I Vector2I;
164  unsigned int nbok = 0;
165  unsigned int nb = 0;
166  Integer p = random() / 10000;
167  Integer q = random() / 10000;
168  MyPattern pattern( p*6, q*6 );
169  trace.info() << pattern << endl;
170 
171  // ODD PATTERN
172  trace.beginBlock ( "Testing block: Smallest covering subpatterns of ODD pattern." );
173  MyPattern pat_odd( 5, 12 );
174  trace.info() << "ODD " << pat_odd << " " << pat_odd.rE() << endl;
175  MyPattern sp;
176  Quotient np;
177  Vector2I start;
178 
179  // Left Subpatterns
180  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
181  0, 17 );
182  trace.info() << "sub(0,17) = " << sp << " " << sp.rE() << "^" << np << endl;
183  ++nb, nbok += sp.slope() == SB::fraction( 5, 12 ) ? 1 : 0;
184  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
185  1, 17 );
186  trace.info() << "sub(1,17) = " << sp << " " << sp.rE() << "^" << np << endl;
187  ++nb, nbok += sp.slope() == SB::fraction( 5, 12 ) ? 1 : 0;
188  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
189  7, 17 );
190  trace.info() << "sub(7,17) = " << sp << " " << sp.rE() << "^" << np << endl;
191  ++nb, nbok += sp.slope() == SB::fraction( 3, 7 ) ? 1 : 0;
192  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
193  8, 17 );
194  trace.info() << "sub(8,17) = " << sp << " " << sp.rE() << "^" << np << endl;
195  ++nb, nbok += sp.slope() == SB::fraction( 3, 7 ) ? 1 : 0;
196  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
197  13, 17 );
198  trace.info() << "sub(13,17) = " << sp << " " << sp.rE() << "^" << np << endl;
199  ++nb, nbok += sp.slope() == SB::fraction( 3, 7 ) ? 1 : 0;
200  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
201  14, 17 );
202  trace.info() << "sub(14,17) = " << sp << " " << sp.rE() << "^" << np << endl;
203  ++nb, nbok += sp.slope() == SB::fraction( 1, 2 ) ? 1 : 0;
204  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
205  15, 17 );
206  trace.info() << "sub(15,17) = " << sp << " " << sp.rE() << "^" << np << endl;
207  ++nb, nbok += sp.slope() == SB::fraction( 1, 2 ) ? 1 : 0;
208 
209  trace.info() << "(" << nbok << "/" << nb << ") covering left Subpatterns." << endl;
210 
211  // Right Subpatterns
212  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
213  0, 16 );
214  trace.info() << "sub(0,16) = " << sp << " " << sp.rE() << "^" << np << endl;
215  ++nb, nbok += sp.slope() == SB::fraction( 5, 12 ) ? 1 : 0;
216  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
217  0, 15 );
218  trace.info() << "sub(0,15) = " << sp << " " << sp.rE() << "^" << np << endl;
219  ++nb, nbok += sp.slope() == SB::fraction( 5, 12 ) ? 1 : 0;
220  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
221  0, 14 );
222  trace.info() << "sub(0,14) = " << sp << " " << sp.rE() << "^" << np << endl;
223  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 2 ? 1 : 0;
224  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
225  0, 8 );
226  trace.info() << "sub(0,8) = " << sp << " " << sp.rE() << "^" << np << endl;
227  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 2 ? 1 : 0;
228  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
229  0, 7 );
230  trace.info() << "sub(0,7) = " << sp << " " << sp.rE() << "^" << np << endl;
231  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
232  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
233  0, 1 );
234  trace.info() << "sub(0,1) = " << sp << " " << sp.rE() << "^" << np << endl;
235  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
236 
237  trace.info() << "(" << nbok << "/" << nb << ") covering right Subpatterns." << endl;
238 
239  // Middle Subpatterns
240  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
241  1, 16 );
242  trace.info() << "sub(1,16) = " << sp << " " << sp.rE() << "^" << np << endl;
243  ++nb, nbok += sp.slope() == SB::fraction( 5, 12 ) ? 1 : 0;
244  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
245  2, 14 );
246  trace.info() << "sub(2,14) = " << sp << " " << sp.rE() << "^" << np << endl;
247  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 2 ? 1 : 0;
248  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
249  7, 15 );
250  trace.info() << "sub(7,15) = " << sp << " " << sp.rE() << "^" << np << endl;
251  ++nb, nbok += sp.slope() == SB::fraction( 3, 7 ) && np == 1 ? 1 : 0;
252  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
253  7, 14 );
254  trace.info() << "sub(7,14) = " << sp << " " << sp.rE() << "^" << np << endl;
255  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
256  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
257  3, 6 );
258  trace.info() << "sub(3,6) = " << sp << " " << sp.rE() << "^" << np << endl;
259  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
260  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
261  6, 8 );
262  trace.info() << "sub(6,8) = " << sp << " " << sp.rE() << "^" << np << endl;
263  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 2 ? 1 : 0;
264  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
265  8, 12 );
266  trace.info() << "sub(8,12) = " << sp << " " << sp.rE() << "^" << np << endl;
267  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
268  pat_odd.getSmallestCoveringSubpattern( sp, np, start,
269  15, 16 );
270  trace.info() << "sub(15,16) = " << sp << " " << sp.rE() << "^" << np << endl;
271  ++nb, nbok += sp.slope() == SB::fraction( 1, 2 ) && np == 1 ? 1 : 0;
272 
273  trace.info() << "(" << nbok << "/" << nb << ") covering middle Subpatterns." << endl;
274  trace.endBlock();
275 
276  // EVEN PATTERN
277  trace.beginBlock ( "Testing block: Smallest covering subpatterns of EVEN pattern." );
278  MyPattern pat_even( 12, 17 );
279  trace.info() << "EVEN " << pat_even << " " << pat_even.rE() << endl;
280 
281  // Left Subpatterns
282  pat_even.getSmallestCoveringSubpattern( sp, np, start,
283  0, 29 );
284  trace.info() << "sub(0,29) = " << sp << " " << sp.rE() << "^" << np << endl;
285  ++nb, nbok += sp.slope() == SB::fraction( 12, 17 ) ? 1 : 0;
286  pat_even.getSmallestCoveringSubpattern( sp, np, start,
287  0, 25 );
288  trace.info() << "sub(0,25) = " << sp << " " << sp.rE() << "^" << np << endl;
289  ++nb, nbok += sp.slope() == SB::fraction( 12, 17 ) ? 1 : 0;
290  pat_even.getSmallestCoveringSubpattern( sp, np, start,
291  0, 17 );
292  trace.info() << "sub(0,17) = " << sp << " " << sp.rE() << "^" << np << endl;
293  ++nb, nbok += sp.slope() == SB::fraction( 7, 10 ) ? 1 : 0;
294  pat_even.getSmallestCoveringSubpattern( sp, np, start,
295  0, 6 );
296  trace.info() << "sub(0,6) = " << sp << " " << sp.rE() << "^" << np << endl;
297  ++nb, nbok += sp.slope() == SB::fraction( 7, 10 ) ? 1 : 0;
298  pat_even.getSmallestCoveringSubpattern( sp, np, start,
299  0, 5 );
300  trace.info() << "sub(0,5) = " << sp << " " << sp.rE() << "^" << np << endl;
301  ++nb, nbok += sp.slope() == SB::fraction( 2, 3 ) ? 1 : 0;
302  trace.info() << "(" << nbok << "/" << nb << ") covering left Subpatterns." << endl;
303 
304  // Right Subpatterns
305  pat_even.getSmallestCoveringSubpattern( sp, np, start,
306  4, 29 );
307  trace.info() << "sub(4,29) = " << sp << " " << sp.rE() << "^" << np << endl;
308  ++nb, nbok += sp.slope() == SB::fraction( 12, 17 ) ? 1 : 0;
309  pat_even.getSmallestCoveringSubpattern( sp, np, start,
310  5, 29 );
311  trace.info() << "sub(5,29) = " << sp << " " << sp.rE() << "^" << np << endl;
312  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 2 ? 1 : 0;
313  pat_even.getSmallestCoveringSubpattern( sp, np, start,
314  16, 29 );
315  trace.info() << "sub(16,29) = " << sp << " " << sp.rE() << "^" << np << endl;
316  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 2 ? 1 : 0;
317  pat_even.getSmallestCoveringSubpattern( sp, np, start,
318  17, 29 );
319  trace.info() << "sub(17,29) = " << sp << " " << sp.rE() << "^" << np << endl;
320  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
321  trace.info() << "(" << nbok << "/" << nb << ") covering right Subpatterns." << endl;
322 
323  // Middle Subpatterns
324  pat_even.getSmallestCoveringSubpattern( sp, np, start,
325  1, 27 );
326  trace.info() << "sub(1,27) = " << sp << " " << sp.rE() << "^" << np << endl;
327  ++nb, nbok += sp.slope() == SB::fraction( 12, 17 ) ? 1 : 0;
328  pat_even.getSmallestCoveringSubpattern( sp, np, start,
329  5, 24 );
330  trace.info() << "sub(5,24) = " << sp << " " << sp.rE() << "^" << np << endl;
331  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 2 ? 1 : 0;
332  pat_even.getSmallestCoveringSubpattern( sp, np, start,
333  4, 17 );
334  trace.info() << "sub(4,17) = " << sp << " " << sp.rE() << "^" << np << endl;
335  ++nb, nbok += sp.slope() == SB::fraction( 7, 10 ) && np == 1 ? 1 : 0;
336  pat_even.getSmallestCoveringSubpattern( sp, np, start,
337  5, 17 );
338  trace.info() << "sub(5,17) = " << sp << " " << sp.rE() << "^" << np << endl;
339  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
340  pat_even.getSmallestCoveringSubpattern( sp, np, start,
341  7, 12 );
342  trace.info() << "sub(7,12) = " << sp << " " << sp.rE() << "^" << np << endl;
343  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
344  pat_even.getSmallestCoveringSubpattern( sp, np, start,
345  1, 4 );
346  trace.info() << "sub(1,4) = " << sp << " " << sp.rE() << "^" << np << endl;
347  ++nb, nbok += sp.slope() == SB::fraction( 2, 3 ) && np == 1 ? 1 : 0;
348  pat_even.getSmallestCoveringSubpattern( sp, np, start,
349  18, 25 );
350  trace.info() << "sub(18,20) = " << sp << " " << sp.rE() << "^" << np << endl;
351  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
352  trace.info() << "(" << nbok << "/" << nb << ") covering middle Subpatterns." << endl;
353  trace.endBlock();
354 
355 
356  // GREATEST INCLUDED SUBPATTERN
357  // ODD PATTERN
358  trace.beginBlock ( "Testing block: greatest included subpatterns of ODD pattern." );
359  trace.info() << "ODD " << pat_odd << " " << pat_odd.rE() << endl;
360 
361  // Left Subpatterns
362  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
363  0, 17 );
364  trace.info() << "sub(0,17) = " << sp << " " << sp.rE() << "^" << np << endl;
365  ++nb, nbok += sp.slope() == SB::fraction( 5, 12 ) ? 1 : 0;
366  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
367  1, 17 );
368  trace.info() << "sub(1,17) = " << sp << " " << sp.rE() << "^" << np << endl;
369  ++nb, nbok += sp.slope() == SB::fraction( 3, 7 ) ? 1 : 0;
370  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
371  7, 17 );
372  trace.info() << "sub(7,17) = " << sp << " " << sp.rE() << "^" << np << endl;
373  ++nb, nbok += sp.slope() == SB::fraction( 3, 7 ) ? 1 : 0;
374  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
375  8, 17 );
376  trace.info() << "sub(8,17) = " << sp << " " << sp.rE() << "^" << np << endl;
377  ++nb, nbok += sp.slope() == SB::fraction( 1, 2 ) ? 1 : 0;
378  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
379  13, 17 );
380  trace.info() << "sub(13,17) = " << sp << " " << sp.rE() << "^" << np << endl;
381  ++nb, nbok += sp.slope() == SB::fraction( 1, 2 ) ? 1 : 0;
382  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
383  14, 17 );
384  trace.info() << "sub(14,17) = " << sp << " " << sp.rE() << "^" << np << endl;
385  ++nb, nbok += sp.slope() == SB::fraction( 1, 2 ) ? 1 : 0;
386  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
387  15, 17 );
388  trace.info() << "sub(15,17) = " << sp << " " << sp.rE() << "^" << np << endl;
389  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
390 
391  trace.info() << "(" << nbok << "/" << nb << ") covering left Subpatterns." << endl;
392 
393  // Right Subpatterns
394  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
395  0, 15 );
396  trace.info() << "sub(0,15) = " << sp << " " << sp.rE() << "^" << np << endl;
397  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 2 ? 1 : 0;
398  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
399  0, 14 );
400  trace.info() << "sub(0,14) = " << sp << " " << sp.rE() << "^" << np << endl;
401  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 2 ? 1 : 0;
402  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
403  0, 13 );
404  trace.info() << "sub(0,13) = " << sp << " " << sp.rE() << "^" << np << endl;
405  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
406  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
407  0, 7 );
408  trace.info() << "sub(0,7) = " << sp << " " << sp.rE() << "^" << np << endl;
409  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
410  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
411  0, 6 );
412  trace.info() << "sub(0,6) = " << sp << " " << sp.rE() << "^" << np << endl;
413  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
414  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
415  0, 1 );
416  trace.info() << "sub(0,1) = " << sp << " " << sp.rE() << "^" << np << endl;
417  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
418 
419  trace.info() << "(" << nbok << "/" << nb << ") covering right Subpatterns." << endl;
420 
421  // Middle Subpatterns
422  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
423  1, 16 );
424  trace.info() << "sub(1,16) = " << sp << " " << sp.rE() << "^" << np << endl;
425  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) ? 1 : 0;
426  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
427  2, 14 );
428  trace.info() << "sub(2,14) = " << sp << " " << sp.rE() << "^" << np << endl;
429  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
430  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
431  7, 15 );
432  trace.info() << "sub(7,15) = " << sp << " " << sp.rE() << "^" << np << endl;
433  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
434  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
435  7, 14 );
436  trace.info() << "sub(7,14) = " << sp << " " << sp.rE() << "^" << np << endl;
437  ++nb, nbok += sp.slope() == SB::fraction( 2, 5 ) && np == 1 ? 1 : 0;
438  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
439  3, 6 );
440  trace.info() << "sub(3,6) = " << sp << " " << sp.rE() << "^" << np << endl;
441  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
442  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
443  6, 8 );
444  trace.info() << "sub(6,8) = " << sp << " " << sp.rE() << "^" << np << endl;
445  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
446  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
447  8, 12 );
448  trace.info() << "sub(8,12) = " << sp << " " << sp.rE() << "^" << np << endl;
449  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
450  pat_odd.getGreatestIncludedSubpattern( sp, np, start,
451  15, 16 );
452  trace.info() << "sub(15,16) = " << sp << " " << sp.rE() << "^" << np << endl;
453  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
454 
455  trace.info() << "(" << nbok << "/" << nb << ") covering middle Subpatterns." << endl;
456  trace.endBlock();
457 
458  // EVEN PATTERN
459  trace.beginBlock ( "Testing block: Greatest included subpatterns of EVEN pattern." );
460  trace.info() << "EVEN " << pat_even << " " << pat_even.rE() << endl;
461 
462  // Left Subpatterns
463  pat_even.getGreatestIncludedSubpattern( sp, np, start,
464  0, 29 );
465  trace.info() << "sub(0,29) = " << sp << " " << sp.rE() << "^" << np << endl;
466  ++nb, nbok += sp.slope() == SB::fraction( 12, 17 ) ? 1 : 0;
467  pat_even.getGreatestIncludedSubpattern( sp, np, start,
468  0, 25 );
469  trace.info() << "sub(0,25) = " << sp << " " << sp.rE() << "^" << np << endl;
470  ++nb, nbok += sp.slope() == SB::fraction( 7, 10 ) ? 1 : 0;
471  pat_even.getGreatestIncludedSubpattern( sp, np, start,
472  0, 17 );
473  trace.info() << "sub(0,17) = " << sp << " " << sp.rE() << "^" << np << endl;
474  ++nb, nbok += sp.slope() == SB::fraction( 7, 10 ) ? 1 : 0;
475  pat_even.getGreatestIncludedSubpattern( sp, np, start,
476  0, 16 );
477  trace.info() << "sub(0,16) = " << sp << " " << sp.rE() << "^" << np << endl;
478  ++nb, nbok += sp.slope() == SB::fraction( 2, 3 ) ? 1 : 0;
479  pat_even.getGreatestIncludedSubpattern( sp, np, start,
480  0, 6 );
481  trace.info() << "sub(0,6) = " << sp << " " << sp.rE() << "^" << np << endl;
482  ++nb, nbok += sp.slope() == SB::fraction( 2, 3 ) ? 1 : 0;
483  pat_even.getGreatestIncludedSubpattern( sp, np, start,
484  0, 5 );
485  trace.info() << "sub(0,5) = " << sp << " " << sp.rE() << "^" << np << endl;
486  ++nb, nbok += sp.slope() == SB::fraction( 2, 3 ) ? 1 : 0;
487  pat_even.getGreatestIncludedSubpattern( sp, np, start,
488  0, 4 );
489  trace.info() << "sub(0,4) = " << sp << " " << sp.rE() << "^" << np << endl;
490  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
491  trace.info() << "(" << nbok << "/" << nb << ") covering left Subpatterns." << endl;
492 
493  // Right Subpatterns
494  pat_even.getGreatestIncludedSubpattern( sp, np, start,
495  4, 29 );
496  trace.info() << "sub(4,29) = " << sp << " " << sp.rE() << "^" << np << endl;
497  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 2 ? 1 : 0;
498  pat_even.getGreatestIncludedSubpattern( sp, np, start,
499  5, 29 );
500  trace.info() << "sub(5,29) = " << sp << " " << sp.rE() << "^" << np << endl;
501  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 2 ? 1 : 0;
502  pat_even.getGreatestIncludedSubpattern( sp, np, start,
503  16, 29 );
504  trace.info() << "sub(16,29) = " << sp << " " << sp.rE() << "^" << np << endl;
505  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
506  pat_even.getGreatestIncludedSubpattern( sp, np, start,
507  17, 29 );
508  trace.info() << "sub(17,29) = " << sp << " " << sp.rE() << "^" << np << endl;
509  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
510  pat_even.getGreatestIncludedSubpattern( sp, np, start,
511  18, 29 );
512  trace.info() << "sub(18,29) = " << sp << " " << sp.rE() << "^" << np << endl;
513  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
514  trace.info() << "(" << nbok << "/" << nb << ") covering right Subpatterns." << endl;
515 
516  // Middle Subpatterns
517  pat_even.getGreatestIncludedSubpattern( sp, np, start,
518  1, 27 );
519  trace.info() << "sub(1,27) = " << sp << " " << sp.rE() << "^" << np << endl;
520  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
521  pat_even.getGreatestIncludedSubpattern( sp, np, start,
522  5, 24 );
523  trace.info() << "sub(5,24) = " << sp << " " << sp.rE() << "^" << np << endl;
524  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
525  pat_even.getGreatestIncludedSubpattern( sp, np, start,
526  4, 17 );
527  trace.info() << "sub(4,17) = " << sp << " " << sp.rE() << "^" << np << endl;
528  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
529  pat_even.getGreatestIncludedSubpattern( sp, np, start,
530  5, 17 );
531  trace.info() << "sub(5,17) = " << sp << " " << sp.rE() << "^" << np << endl;
532  ++nb, nbok += sp.slope() == SB::fraction( 5, 7 ) && np == 1 ? 1 : 0;
533  pat_even.getGreatestIncludedSubpattern( sp, np, start,
534  7, 16 );
535  trace.info() << "sub(5,16) = " << sp << " " << sp.rE() << "^" << np << endl;
536  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
537  pat_even.getGreatestIncludedSubpattern( sp, np, start,
538  1, 4 );
539  trace.info() << "sub(1,4) = " << sp << " " << sp.rE() << "^" << np << endl;
540  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
541  pat_even.getGreatestIncludedSubpattern( sp, np, start,
542  18, 25 );
543  trace.info() << "sub(18,20) = " << sp << " " << sp.rE() << "^" << np << endl;
544  ++nb, nbok += sp.slope() == Fraction() ? 1 : 0;
545  trace.info() << "(" << nbok << "/" << nb << ") covering middle Subpatterns." << endl;
546  trace.endBlock();
547 
548  trace.info() << "Odd pattern " << pat_odd << endl;
549  trace.info() << " U(0)=" << pat_odd.U( 0 )
550  << " L(0)=" << pat_odd.L( 0 )
551  << " U(1)=" << pat_odd.U( 1 )
552  << " L(1)=" << pat_odd.L( 1 ) << endl;
553 
554  trace.info() << "Even pattern " << pat_even << endl;
555  trace.info() << " U(0)=" << pat_even.U( 0 )
556  << " L(0)=" << pat_even.L( 0 )
557  << " U(1)=" << pat_even.U( 1 )
558  << " L(1)=" << pat_even.L( 1 ) << endl;
559 
560  return nbok == nb;
561 }
562 
563 template <typename Fraction>
564 bool testStandardDSLQ0()
565 {
566  typedef StandardDSLQ0<Fraction> DSL;
567  typedef typename Fraction::Integer Integer;
568  typedef typename Fraction::Quotient Quotient;
569  typedef typename DSL::Point Point;
570  typedef typename DSL::Point2I Point2I;
571  typedef typename DSL::Vector2I Vector2I;
572 
573  BOOST_CONCEPT_ASSERT(( CPointPredicate< DSL > ));
574  unsigned int nbok = 0;
575  unsigned int nb = 0;
576 
577  for ( Integer mu = -5; mu < 30; ++mu )
578  {
579  DSL D1( 5, 12, mu );
580  trace.info() << "DSL D1=" << D1 << endl;
581  Point U = D1.U();
582  Point L = D1.L();
583  trace.info() << "- U=" << U << " r(U)=" << D1.r( U )
584  << ", L=" << L << " r(L)=" << D1.r( L ) << endl;
585  ++nb, nbok += D1.r( U ) == D1.mu() ? 1 : 0;
586  ++nb, nbok += D1.r( L ) == D1.mup() ? 1 : 0;
587  }
588 
589  DSL D2( 12, 17, 5 );
590  for ( Integer x = -5; x < 30; ++x )
591  {
592  Point P = D2.lowestY( x );
593  ++nb, nbok += D2( P ) && ( ! D2( P - Vector2I(0,1) ) ) ? 1 : 0;
594  trace.info() << "(" << nbok << "/" << nb << ") "
595  << "D2(P) && ! D2(P-y) P=" << P << " r(P)=" << D2.r( P )
596  << endl;
597  P = D2.uppermostY( x );
598  ++nb, nbok += D2( P ) && ( ! D2( P + Vector2I(0,1) ) ) ? 1 : 0;
599  trace.info() << "(" << nbok << "/" << nb << ") "
600  << "D2(P) && ! D2(P+y) P=" << P << " r(P)=" << D2.r( P )
601  << endl;
602  }
603  for ( Integer y = -5; y < 30; ++y )
604  {
605  Point P = D2.lowestX( y );
606  ++nb, nbok += D2( P ) && ( ! D2( P - Vector2I(1,0) ) ) ? 1 : 0;
607  trace.info() << "(" << nbok << "/" << nb << ") "
608  << "D2(P) && ! D2(P-x) P=" << P << " r(P)=" << D2.r( P )
609  << endl;
610  P = D2.uppermostX( y );
611  ++nb, nbok += D2( P ) && ( ! D2( P + Vector2I(1,0) ) ) ? 1 : 0;
612  trace.info() << "(" << nbok << "/" << nb << ") "
613  << "D2(P) && ! D2(P+x) P=" << P << " r(P)=" << D2.r( P )
614  << endl;
615  }
616 
617  return nbok == nb;
618 }
619 
620 template <typename DSL>
621 bool checkSubStandardDSLQ0( const DSL & D,
622  const typename DSL::Point & A,
623  const typename DSL::Point & B )
624 {
625  typedef typename DSL::Fraction Fraction;
626  typedef typename DSL::Integer Integer;
627  typedef typename DSL::Quotient Quotient;
628  typedef typename DSL::Point Point;
629  typedef typename DSL::ConstIterator ConstIterator;
630  typedef typename DSL::Point2I Point2I;
631  typedef typename DSL::Vector2I Vector2I;
633 
634  DSL S = D.reversedSmartDSS( A, B );
635  ConstIterator it = D.begin( A );
636  ConstIterator it_end = D.end( B );
637  ADSS dss;
638  dss.init( it );
639  while ( ( dss.end() != it_end )
640  && ( dss.extendForward() ) ) {}
641  bool ok = S.a() == dss.getA()
642  && S.b() == dss.getB()
643  && S.mu() == dss.getMu();
644  if ( ! ok )
645  {
646  trace.info() << "-------------------------------------------------------"
647  << std::endl;
648  trace.info() << "D = " << D // << " U1=" << U1 << " U2=" << U2
649  << " " << D.pattern().rE() << endl;
650  trace.info() << "S(" << A << "," << B << ") = "
651  << S << " " << S.pattern() << endl;
652  trace.info() << "ArithDSS = " << dss << std::endl;
653  }
654  // if ( ok )
655  // trace.info() << "========================== OK =========================";
656  // else
657  // trace.info() << "eeeeeeeeeeeeeeeeeeeeeeeeee KO eeeeeeeeeeeeeeeeeeeeeeeee";
658  // std::cerr << std::endl;
659  return ok;
660 }
661 
662 template <typename Fraction>
663 bool testSubStandardDSLQ0()
664 {
665  typedef StandardDSLQ0<Fraction> DSL;
666  typedef typename Fraction::Integer Integer;
667  typedef typename Fraction::Quotient Quotient;
668  typedef typename DSL::Point Point;
669  typedef typename DSL::ConstIterator ConstIterator;
670  typedef typename DSL::Point2I Point2I;
671  typedef typename DSL::Vector2I Vector2I;
674  unsigned int nbok = 0;
675  unsigned int nb = 0;
676 
677  trace.beginBlock( "Check ReversedSmartDSS == ArithmeticDSS" );
678  for ( unsigned int i = 0; i < 100; ++i )
679  {
680  Integer a( random() % 12000 + 1 );
681  Integer b( random() % 12000 + 1 );
682  if ( ic.gcd( a, b ) == 1 )
683  {
684  trace.info() << "(" << i << ")"
685  << " Test DSL has slope " << a << "/" << b << std::endl;
686  for ( Integer mu = 0; mu < 5; ++mu )
687  {
688  DSL D( a, b, random() % 10000 );
689  for ( Integer x = 0; x < 10; ++x )
690  {
691  Integer x1 = random() % 1000;
692  Integer x2 = x1 + 1 + ( random() % 1000 );
693  Point A = D.lowestY( x1 );
694  Point B = D.lowestY( x2 );
695  ++nb, nbok += checkSubStandardDSLQ0<DSL>( D, A, B ) ? 1 : 0;
696  if ( nb != nbok )
697  trace.info() << "(" << nbok << "/" << nb << ") correct reversedSmartDSS."
698  << std::endl;
699  if ( nbok != nb ) assert(false);
700  }
701  }
702  }
703  }
704  trace.info() << "(" << nbok << "/" << nb << ") correct reversedSmartDSS."
705  << std::endl;
706  trace.endBlock();
707  return nbok == nb;
708 }
709 
714 bool testLighterSternBrocot()
715 {
716  unsigned int nbtests = 10;
717  unsigned int nbok = 0;
718  unsigned int nb = 0;
719  typedef DGtal::BigInteger Integer;
721  typedef SB::Fraction Fraction;
722  trace.beginBlock ( "Testing block: init fractions." );
723  for ( unsigned int i = 0; i < nbtests; ++i )
724  {
725  nbok += testInitFraction<SB>() ? 1 : 0;
726  nb++;
727  }
728  trace.info() << "(" << nbok << "/" << nb << ") init fractions." << endl;
729  trace.endBlock();
730 
731  trace.beginBlock ( "Testing block: reduced fractions." );
732  for ( unsigned int i = 0; i < nbtests; ++i )
733  {
734  nbok += testReducedFraction<SB>() ? 1 : 0;
735  nb++;
736  }
737  trace.info() << "(" << nbok << "/" << nb << ") reduced fractions." << endl;
738  trace.endBlock();
739 
740  trace.beginBlock ( "Testing block: number of fractions." );
741  trace.info() << "- nbFractions = " << SB::instance().nbFractions << endl;
742  trace.endBlock();
743 
744  return nbok == nb;
745 }
746 
747 
748 template <typename SB>
749 bool testContinuedFraction()
750 {
751  typedef typename SB::Integer Integer;
752  typedef typename SB::Quotient Quotient;
753  typedef typename SB::Fraction Fraction;
754  typedef typename SB::Fraction::ConstIterator ConstIterator;
755 
756  Fraction f;
757  std::vector<Quotient> quotients;
758  std::vector<Quotient> qcfrac;
759  std::back_insert_iterator< Fraction > itout =
760  std::back_inserter( f );
761  unsigned int size = ( random() % 20 ) + 10;
762  for ( unsigned int i = 0; i < size; ++i )
763  {
764  Quotient q = ( i == 0 )
765  ? ( random() % 5 )
766  : ( random() % 5 ) + 1;
767  *itout++ = std::make_pair( q, (Quotient) i );
768  quotients.push_back( q );
769  }
770  for ( ConstIterator it = f.begin(), it_end = f.end();
771  it != it_end; ++it )
772  qcfrac.push_back( (*it).first );
773  // f.getCFrac( qcfrac );
774  bool ok = equalCFrac( quotients, qcfrac );
775 
776  trace.info() << ( ok ? "(OK)" : "(ERR)" );
777  for ( unsigned int i = 0; i < quotients.size(); ++i )
778  std::cerr << " " << quotients[ i ];
779  trace.info() << std::endl;
780  trace.info() << " f=";
781  f.selfDisplay( std::cerr );
782  trace.info() << std::endl;
783  return ok;
784 }
785 
786 template <typename SB>
787 bool testContinuedFractions()
788 {
789  typedef typename SB::Integer Integer;
790  typedef typename SB::Quotient Quotient;
791  typedef typename SB::Fraction Fraction;
792  unsigned int nbtests = 1000;
793  unsigned int nbok = 0;
794  unsigned int nb = 0;
795  trace.beginBlock ( "Testing block: continued fraction." );
796  for ( unsigned int i = 0; i < nbtests; ++i )
797  {
798  ++nb, nbok += testContinuedFraction<SB>() ? 1 : 0;
799  trace.info() << "(" << nbok << "/" << nb << ")"
800  << " continued fractions." << std::endl;
801  }
802  trace.endBlock();
803  return nbok == nb;
804 }
805 
806 template <typename LSB>
807 bool
808 testTrivial( const string & lsb )
809 {
810  typedef typename LSB::Fraction Fraction;
811  typedef Pattern<Fraction> Pattern;
812 
813  std::cerr << "SB = " << lsb << std::endl;
814  {
815  Pattern pat( 2, 3 );
816  std::cerr << "pat = " << pat.rE() << " depth=" << pat.slope().k()
817  << std::endl;
818  Pattern spat = pat.previousPattern();
819  std::cerr << "spat= " << spat.rE() << " depth=" << spat.slope().k()
820  << std::endl;
821  Pattern sspat = spat.previousPattern();
822  std::cerr << "sspat= " << sspat.rE() << " depth=" << sspat.slope().k()
823  << std::endl;
824  }
825  {
826  Pattern pat( 3, 2 );
827  std::cerr << "pat = " << pat.rE() << " depth=" << pat.slope().k()
828  << std::endl;
829  Pattern spat = pat.previousPattern();
830  std::cerr << "spat= " << spat.rE() << " depth=" << spat.slope().k()
831  << std::endl;
832  Pattern sspat = spat.previousPattern();
833  std::cerr << "sspat= " << sspat.rE() << " depth=" << sspat.slope().k()
834  << std::endl;
835  }
836  return true;
837 }
838 
842 template <typename SB>
843 bool
844 testAncestors()
845 {
846  typedef typename SB::Fraction Fraction;
847  typedef typename Fraction::Integer Integer;
848  typedef StandardDSLQ0<Fraction> DSL;
849  typedef typename DSL::Point Point;
850 
851  // Instanciation d'un DSL
852  DSL D(1077,1495,6081);
853 
854  // Definition du sous-segment [AB] et calcul des caractéristiques
855  Point A(3,-3);
856  Point B(4,-2);
857  ASSERT( D( A ) && "Point A belongs to D." );
858  ASSERT( D( B ) && "Point A belongs to D." );
859  DSL D1 = D.reversedSmartDSS(A,B); // may raise an assert.
860  std::cerr << D1 << std::endl;
861  return D1.slope() == Fraction( 1, 1 );
862 }
863 
865 // Standard services - public :
866 
867 int main( int , char** )
868 {
873  typedef SB::Fraction Fraction;
874  typedef Fraction::ConstIterator ConstIterator;
875 
876  BOOST_CONCEPT_ASSERT(( CPositiveIrreducibleFraction< Fraction > ));
877  BOOST_CONCEPT_ASSERT(( boost::InputIterator< ConstIterator > ));
878 
879  testTrivial<SB>( "LrSB" );
880  testTrivial<SB2>( "LSB" );
881  testTrivial<SB3>( "SB" );
882 
883  trace.beginBlock ( "Testing class LighterSternBrocot" );
884  bool res = testLighterSternBrocot()
885  && testPattern<SB>()
886  && testSubStandardDSLQ0<Fraction>()
887  && testContinuedFractions<SB>()
888  && testAncestors<SB>();
889  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
890  trace.endBlock();
891 
892  return res ? 0 : 1;
893 }
894 // //