bool checkSubStandardDSLQ0( const DSL & D, const typename DSL::Point & A, const typename DSL::Point & B ) { typedef typename DSL::Integer Integer; typedef typename DSL::ConstIterator ConstIterator; typedef ArithmeticalDSSComputer<ConstIterator, Integer, 4> ADSS; DSL S = D.reversedSmartDSS( A, B ); ConstIterator it = D.begin( A ); ConstIterator it_end = D.end( B ); ADSS dss; dss.init( it ); while ( ( dss.end() != it_end ) && ( dss.extendFront() ) ) {} bool ok = S.a() == dss.a() && S.b() == dss.b() && S.mu() == dss.mu(); if ( ! ok ) { trace.info() << "-------------------------------------------------------" << std::endl; trace.info() << "D = " << D // << " U1=" << U1 << " U2=" << U2 << " " << D.pattern().rE() << endl; trace.info() << "S(" << A << "," << B << ") = " << S << " " << S.pattern() << endl; trace.info() << "ArithDSS = " << dss << std::endl; } // if ( ok ) // trace.info() << "========================== OK ========================="; // else // trace.info() << "eeeeeeeeeeeeeeeeeeeeeeeeee KO eeeeeeeeeeeeeeeeeeeeeeeee"; // std::cerr << std::endl; return ok; }
bool checkSubArithmeticDSS( const DSL & D, const typename DSL::Point & A, const typename DSL::Point & B ) { typedef typename DSL::Fraction Fraction; typedef typename DSL::Integer Integer; typedef typename DSL::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; ConstIterator it = D.begin( A ); ConstIterator it_end = D.end( B ); ADSS dss; dss.init( it ); while ( ( dss.end() != it_end ) && ( dss.extendForward() ) ) {} std::cout << D.a() << " " << D.b() << " " << D.mu() << " " << dss.getA() << " " << dss.getB() << " " << dss.getMu() << " " << A[0] << " " << A[1] << " " << B[0] << " " << B[1] << std::endl; return true; }
bool checkSubStandardDSLQ0( const DSL & D, const typename DSL::Point & A, const typename DSL::Point & B ) { typedef typename DSL::Fraction Fraction; typedef typename DSL::Integer Integer; typedef typename DSL::Quotient Quotient; typedef typename DSL::Point Point; typedef typename DSL::ConstIterator ConstIterator; typedef typename DSL::Point2I Point2I; typedef typename DSL::Vector2I Vector2I; DSL S = D.reversedSmartDSS( A, B ); std::cout << D.a() << " " << D.b() << " " << D.mu() << " " << S.a() << " " << S.b() << " " << S.mu() << " " << A[0] << " " << A[1] << " " << B[0] << " " << B[1] << std::endl; return true; }
bool checkSubArithmeticDSS( const DSL & D, const typename DSL::Point & A, const typename DSL::Point & B ) { typedef typename DSL::Integer Integer; typedef typename DSL::ConstIterator ConstIterator; typedef ArithmeticalDSSComputer<ConstIterator, Integer, 4> ADSS; ConstIterator it = D.begin( A ); ConstIterator it_end = D.end( B ); ADSS dss; dss.init( it ); while ( ( dss.end() != it_end ) && ( dss.extendFront() ) ) {} std::cout << D.a() << " " << D.b() << " " << D.mu() << " " << dss.a() << " " << dss.b() << " " << dss.mu() << " " << A[0] << " " << A[1] << " " << B[0] << " " << B[1] << std::endl; return true; }
bool rangeTest(const DSL& dsl) { ASSERT( dsl.mu() == 0 ); typedef typename DSL::Point Point; unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "Range/Iterator services..." ); trace.info() << dsl << std::endl; Point first(0,0); Point last(dsl.b(), dsl.a()); trace.info() << "from " << first << " to " << last << std::endl; if (dsl.isValid()) nbok++; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << std::endl; {//forward pass typedef typename DSL::ConstIterator I; BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> )); BOOST_CONCEPT_ASSERT(( boost_concepts::BidirectionalTraversalConcept<I> )); bool res = true; int c = 0; for (I it = dsl.begin(first), itEnd = dsl.end(last); ( (it != itEnd)&&(res)&&(c<100) ); ++it, ++c) { trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") "; if ( !dsl(*it) ) res = false; } trace.info() << " : " << c << " points " << std::endl; trace.info() << std::endl; if ( (res)&&(c == (dsl.omega()+1)) ) nbok++; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << std::endl; } {//backward pass typedef typename DSL::ConstReverseIterator I; BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> )); BOOST_CONCEPT_ASSERT(( boost_concepts::BidirectionalTraversalConcept<I> )); bool res = true; int c = 0; for (I it = dsl.rbegin(last), itEnd = dsl.rend(first); ( (it != itEnd)&&(res)&&(c<100) ); ++it, ++c) { trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") "; if ( !dsl(*it) ) res = false; } trace.info() << " : " << c << " points " << std::endl; trace.info() << std::endl; if ( (res)&&(c == (dsl.omega()+1)) ) nbok++; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << std::endl; } trace.endBlock(); return nbok == nb; }
bool testDSLSubsegment(Integer modb) { //typedef long double Number; typedef DGtal::DSLSubsegment<Integer,Integer> DSLSubseg; //typedef DGtal::DSLSubsegment<Integer,Number> DSLSubsegD; typedef ArithDSSIterator<Integer,8> DSSIterator; typedef NaiveDSS8<Integer> ArithDSS; typedef typename DSLSubseg::Point Point; typedef StandardDSLQ0<Fraction> DSL; typedef typename DSL::Point PointDSL; DGtal::IntegerComputer<Integer> ic; // Draw random value for b in [0,modb] Integer b( rand() % modb +1); // Draw random value for a in [0,b] Integer a( random() % b +1); // Draw a new a while a and b are not coprime (do not divide by // the gcd so that b remains in the required interval) while(ic.gcd(a,b) !=1) a = rand() %b +1; // Draw random value for mu in [0,2modb] Integer mu = rand() % (2*modb); Integer l = 200; // max length of the DSSs // Draw random values for the subsegment first extremity abscissa Integer xf = rand() % modb; trace.beginBlock("Draw random values for a,b,mu and abscissa of the first point"); trace.info() << "a b mu xf:" << a << " " << b << " " << mu << " " << xf << std::endl; trace.endBlock(); trace.info() << std::endl; int error1 = 0; // Consider the subsegment S of the line (a,b,mu), with xf <= x < xf+l // Test all the subsegments of S trace.beginBlock("Compare DSLSubsegment/Farey fan with ArithmeticalDSS algorithm"); for(unsigned int i = 0; i<l; i++) for(unsigned int j = i+1; j<l; j++) { Integer x1 = xf+i; Integer x2 = xf+j; Integer y1 = ic.floorDiv(a*x1+mu,b); Integer y2 = ic.floorDiv(a*x2+mu,b); Point A = Point(x1,y1); Point B = Point(x2,y2); // DSLSubsegment with Farey Fan (O(log(n)) DSLSubseg DSLsub(a,b,mu,A,B,"farey"); // ArithmeticalDSS recognition algorithm (O(n)) DSSIterator it(a,b,-mu,A); ArithDSS myDSS(*it, *it); ++it; while ( (*it)[0] <=x2 && myDSS.extendFront(*it)) { ++it; } // If results are different, count an error if(DSLsub.getA() != myDSS.a() || DSLsub.getB() != myDSS.b() || DSLsub.getMu() != - myDSS.mu()) error1 ++; } trace.info() << error1 << " errors." << std::endl; trace.endBlock(); trace.info() << std::endl; int error2 = 0; trace.beginBlock("Compare DSLSubsegment/localCH with DSLSubsegment/FareyFan"); for(unsigned int i = 0; i<l; i++) for(unsigned int j = i+1; j<l; j++) { Integer x1 = xf+i; Integer x2 = xf+j; Integer y1 = ic.floorDiv(a*x1+mu,b); Integer y2 = ic.floorDiv(a*x2+mu,b); Point A = Point(x1,y1); Point B = Point(x2,y2); // DSLSubsegment with local CH (O(log(n)) DSLSubseg DSLsubCH(a,b,mu,A,B,"localCH"); // DSLSubsegment with Farey Fan (O(log(n)) DSLSubseg DSLsubF(a,b,mu,A,B,"farey"); // If results are different, count an error if(DSLsubCH.getA() != DSLsubF.getA() || DSLsubCH.getB() != DSLsubF.getB() || DSLsubCH.getMu() != DSLsubF.getMu()) error2 ++; } trace.info() << error2 << " errors." << std::endl; trace.endBlock(); trace.info() << std::endl; int error3 = 0; trace.beginBlock("Compare DSLSubsegment/FareyFan with ReversedSmartDSS for 4-connected DSL"); for(unsigned int i = 0; i<l; i++) for(unsigned int j = i+1; j<l; j++) { Integer x1 = xf+i; Integer x2 = xf+j; DSL D( a, b, mu ); PointDSL AA = D.lowestY( x1 ); PointDSL BB = D.lowestY( x2 ); // ReversedSmartDSS algorithm DSL S = D.reversedSmartDSS(AA,BB); // DSLSubsegment algorithm for 4-connected DSL. // Application of an horizontal shear transform Point A2 = AA; A2[0] += A2[1]; Point B2 = BB; B2[0] += B2[1]; // DSLSubsegment algorithm works with the definition 0 <= ab -by + mu < // b whereas reversedSmartDSS uses mu <= ab-by < mu + b // => -mu is introduced in order to compare the results DSLSubseg D2(a,a+b,-mu,A2,B2,"farey"); // The result is (aa,getB()-aa, nu) // Compare results of DSLsubseg4 and reversedSmartDSS if(!(D2.getA()==S.a() && (D2.getB()-D2.getA())==S.b() && D2.getMu()==-S.mu())) error3 ++; } trace.info() << error3 << " errors." << std::endl; trace.endBlock(); trace.info() << std::endl; return (error1==0 && error2==0 && error3==0); }
bool rangeTest(const DSL& dsl) { typedef typename DSL::Point Point; unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "Range/Iterator services..." ); trace.info() << dsl << std::endl; Point origin = dsl.getPoint(); Point first = Point(origin[0]-dsl.b(), origin[1]-dsl.a()); Point last = Point(first[0]+dsl.b(), first[1]+dsl.a()); trace.info() << "from " << first << " to " << last << std::endl; if (dsl.isValid()) nbok++; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << std::endl; {//forward pass typedef typename DSL::ConstIterator I; BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> )); BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> )); bool res = true; int c = 0; for (I it = dsl.begin(first), itEnd = dsl.end(last); ( (it != itEnd)&&(res)&&(c<100) ); ++it, ++c) { trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") "; if ( !dsl(*it) ) res = false; } trace.info() << " : " << c << " points " << std::endl; trace.info() << std::endl; if ( (res)&&(c == (dsl.omega()+1)) ) nbok++; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << std::endl; } {//backward pass typedef typename DSL::ConstReverseIterator I; BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> )); BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> )); bool res = true; int c = 0; for (I it = dsl.rbegin(last), itEnd = dsl.rend(first); ( (it != itEnd)&&(res)&&(c<100) ); ++it, ++c) { trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") "; if ( !dsl(*it) ) res = false; } trace.info() << " : " << c << " points " << std::endl; trace.info() << std::endl; if ( (res)&&(c == (dsl.omega()+1)) ) nbok++; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << std::endl; } {//random access services typedef typename DSL::ConstIterator I; BOOST_CONCEPT_ASSERT(( boost_concepts::ReadableIteratorConcept<I> )); BOOST_CONCEPT_ASSERT(( boost_concepts::RandomAccessTraversalConcept<I> )); bool res = true; int c = 0; I itBegin = dsl.begin(first); for (I it = itBegin, itEnd = dsl.end(last); ( (it != itEnd)&&(res)&&(c<100) ); ++it, ++c) { trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") " << it.remainder() << ", "; I it2 = ( itBegin + c ); if ( (it != it2) || ((it2 - itBegin) != c) ) res = false; } int n = c; trace.info() << " : " << c << " points " << std::endl; trace.info() << std::endl; if (res) nbok++; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << std::endl; --n; c = 0; for (I it = (itBegin+n), itEnd = itBegin; ( (it!=itEnd)&&(res)&&(c < 100) ); --it, ++c ) { trace.info() << "(" << it->operator[](0) << "," << it->operator[](1) << ") " << it.remainder() << ", "; I it2 = ( (itBegin+n) - c ); if ( (it != it2) || (((itBegin+n) - it2) != c) ) res = false; } if (res) nbok++; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << std::endl; } trace.endBlock(); return nbok == nb; }