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