bool testSubStandardDSLQ0( unsigned int nbtries, 
                           typename Fraction::Integer moda, 
                           typename Fraction::Integer modb, 
                           typename Fraction::Integer modx )
{
  typedef StandardDSLQ0<Fraction> DSL;
  typedef typename Fraction::Integer Integer;
  typedef typename DSL::Point Point;
  IntegerComputer<Integer> ic;

  std::cout << "# a b mu a1 b1 mu1 Ax Ay Bx By" << std::endl;
  for ( unsigned int i = 0; i < nbtries; ++i )
    {
      Integer a( random() % moda + 1 );
      Integer b( random() % modb + 1 );
      if ( ic.gcd( a, b ) == 1 )
        {
          for ( Integer mu = 0; mu < 5; ++mu )
            {
              DSL D( a, b, random() % (moda+modb) );
              for ( Integer x = 0; x < 10; ++x )
                {
                  Integer x1 = random() % modx;
                  Integer x2 = x1 + 1 + ( random() % modx );
                  Point A = D.lowestY( x1 );
                  Point B = D.lowestY( x2 );
                  checkSubArithmeticDSS<DSL>( D, A, B );
                }
            }
        }
    }
  return true;
}
bool testInitFraction()
{
  typedef typename SB::Integer Integer;
  typedef typename SB::Fraction Fraction;
  unsigned int nbok = 0;
  unsigned int nb = 0;
  Integer p = random() / 10000;
  Integer q = random() / 10000;
  trace.beginBlock ( "Testing block: init fraction." );
  IntegerComputer<Integer> ic;
  Integer g = ic.gcd( p, q );
  p /= g;
  q /= g;
  Fraction f1 = SB::fraction( p, q );
  trace.info() << "p / q = " << p << " / " << q << std::endl;
  trace.info() << "f1 = ";
  SB::display( trace.info(), f1 );
  trace.info() << std::endl;
  nbok += ( ( p == f1.p() ) && ( q == f1.q() ) ) ? 1 : 0;
  ++nb;
  trace.info() << "(" << nbok << "/" << nb << ") " 
               << "( ( p == f1.p() ) && ( q == f1.q() ) )"
               << std::endl;
  trace.info() << "- nbFractions = " << SB::instance().nbFractions << std::endl;
  trace.endBlock();

  return nbok == nb;
}
bool testReducedFraction()
{
  typedef typename SB::Integer Integer;
  typedef typename SB::Quotient Quotient;
  typedef typename SB::Fraction Fraction;
  unsigned int nbok = 0;
  unsigned int nb = 0;
  Integer p = random() / 10000;
  Integer q = random() / 10000;
  trace.beginBlock ( "Testing block: reduced fraction." );
  IntegerComputer<Integer> ic;
  Integer g = ic.gcd( p, q );
  p /= g;
  q /= g;
  IntegerComputer<Quotient> ics;
  Quotient sp = NumberTraits<Integer>::castToInt64_t( p );
  Quotient sq = NumberTraits<Integer>::castToInt64_t( q );
  std::vector<Quotient> cf1;
  ics.getCFrac( cf1, sp, sq );
  Fraction f1 = SB::fraction( p, q );
  std::vector<Quotient> cf1_bis;
  f1.getCFrac( cf1_bis );
  bool ok = equalCFrac<Quotient>( cf1, cf1_bis );
  trace.info() << "  - p / q = " << p << " / " << q << std::endl;
  trace.info() << "  - f1 = ";
  SB::display( trace.info(), f1 );
  trace.info() << std::endl;
  ++nb, nbok += ok ? 1 : 0;
  trace.info() << "(" << nbok << "/" << nb << ") " 
               << " cfrac"
               << std::endl;
  unsigned int depth = cf1.size();
  for ( unsigned int k = 1; k < depth; ++k )
    {
      std::vector<Quotient> cf1_red;
      Fraction fr = f1.reduced( k );
      fr.getCFrac( cf1_red );
      cf1.resize( depth - k );
      ok = equalCFrac<Quotient>( cf1, cf1_red );
      ++nb, nbok += ok ? 1 : 0;
      trace.info() << "(" << nbok << "/" << nb << ") " 
                   << "reduced(" << k << ")=";
      SB::display( trace.info(), fr );
      std::cerr << std::endl;
    }

  //trace.info() << "- nbFractions = " << SB::instance().nbFractions << std::endl;
  trace.endBlock();
  return nbok == nb;
}
bool testSubStandardDSLQ0( unsigned int nbtries, 
                           typename Fraction::Integer moda, 
                           typename Fraction::Integer modb, 
                           typename Fraction::Integer modx )
{
  typedef StandardDSLQ0<Fraction> DSL;
  typedef typename Fraction::Integer Integer;
  typedef typename DSL::Point Point;
  IntegerComputer<Integer> ic;

  //std::cout << "# a b mu a1 b1 mu1 Ax Ay Bx By" << std::endl;
  
  clock_t timeBegin, timeEnd;
  timeBegin = clock();

  for ( unsigned int i = 0; i < nbtries; ++i )
    {
      Integer b( rand() % modb + 1 );
      Integer a( rand() % b + 1 );
      if ( ic.gcd( a, b ) == 1 )
        {
          for ( Integer mu = 0; mu < 5; ++mu )
            {
              DSL D( a, b, rand() % (moda+modb) );
              for ( Integer x = 0; x < 10; ++x )
                {
                  Integer x1 = rand() % modx;
                  Integer x2 = x1 + 1 + ( rand() % modx );
                  Point A = D.lowestY( x1 );
                  Point B = D.lowestY( x2 );
                  checkSubStandardDSLQ0<DSL>( D, A, B );
                }
            }
        }
    }
  
  timeEnd = clock();
  long double CPUTime;
  CPUTime =  ((double)timeEnd-(double)timeBegin)/((double)CLOCKS_PER_SEC);  
  
  //std::cout << "SmartDSS: CPU Time ellapsed = " << CPUTime << " - Time/test = = " << (long double) CPUTime/(nbtries*5*10) << std::endl;
 
  std::cout << modx  << " " << (long double) CPUTime/(nbtries*5*10) << std::endl;
  
 
return true;
}
bool testSubStandardDSLQ0()
{
  typedef StandardDSLQ0<Fraction> DSL;
  typedef typename Fraction::Integer Integer;
  typedef typename Fraction::Quotient Quotient;
  typedef typename DSL::Point Point;
  typedef typename DSL::ConstIterator ConstIterator;
  typedef typename DSL::Point2I Point2I;
  typedef typename DSL::Vector2I Vector2I;
  typedef ArithmeticalDSS<ConstIterator, Integer, 4> ADSS;
  IntegerComputer<Integer> ic;
  unsigned int nbok = 0;
  unsigned int nb = 0;

  trace.beginBlock( "Check ReversedSmartDSS == ArithmeticDSS" );
  for ( unsigned int i = 0; i < 100; ++i )
    {
      Integer a( random() % 12000 + 1 );
      Integer b( random() % 12000 + 1 );
      if ( ic.gcd( a, b ) == 1 )
        {
          trace.info() << "(" << i << ")"
                       << " Test DSL has slope " << a << "/" << b << std::endl;
          for ( Integer mu = 0; mu < 5; ++mu )
            {
              DSL D( a, b, random() % 10000 );
              for ( Integer x = 0; x < 10; ++x )
                {
                  Integer x1 = random() % 1000;
                  Integer x2 = x1 + 1 + ( random() % 1000 );
                  Point A = D.lowestY( x1 );
                  Point B = D.lowestY( x2 );
                  ++nb, nbok += checkSubStandardDSLQ0<DSL>( D, A, B ) ? 1 : 0;
                  if ( nb != nbok )
                    trace.info() << "(" << nbok << "/" << nb << ") correct reversedSmartDSS."
                                 << std::endl;
                  if ( nbok != nb ) assert(false);
                }
            }
        }
    }
  trace.info() << "(" << nbok << "/" << nb << ") correct reversedSmartDSS."
               << std::endl;
  trace.endBlock();
  return nbok == nb;
}
bool
testPatterns()
{
  unsigned int nbtests = 100;
  unsigned int nb = 0;
  unsigned int nbok = 0;
  Fraction1 f1;
  f1 = Fraction1( 5, 8 );
  ++nb, nbok += testPattern<Fraction1,Fraction2>( f1 ) ? 1 : 0;
  std::cerr << "(" << nbok << "/" << nb << ") f1=";
  f1.selfDisplay( std::cerr );
  std::cerr << endl;
  f1 = Fraction1( 31, 24 );
  ++nb, nbok += testPattern<Fraction1,Fraction2>( f1 ) ? 1 : 0;
  std::cerr << "(" << nbok << "/" << nb << ") f1=";
  f1.selfDisplay( std::cerr );
  std::cerr << endl;
  f1 = Fraction1( 5, 13 );
  ++nb, nbok += testPattern<Fraction1,Fraction2>( f1 ) ? 1 : 0;
  std::cerr << "(" << nbok << "/" << nb << ") f1=";
  f1.selfDisplay( std::cerr );
  std::cerr << endl;
  IntegerComputer<unsigned  int > ic;

  for ( unsigned int i = 0; i < nbtests; ++i )
    {
      unsigned int p = std::rand() % 999+1;
      unsigned int q = std::rand() % 999+1;
      unsigned int g = ic.gcd( p, q );
      p /= g; q /= g;
      std::cerr << "*- p / q = " << p << "/" << q << std::endl;
      f1 = Fraction1( p, q );
      ++nb;
	  nbok += testPattern<Fraction1,Fraction2>( f1 ) ? 1 : 0;
      std::cerr << "(" << nbok << "/" << nb << ") f1=";
      f1.selfDisplay( std::cerr );
      std::cerr << endl;
    }
  return nbok == nb;
}