#ifndef CHECK_SOLVER_H #define CHECK_SOLVER_H #include #include #include #include struct True{}; struct False{}; template class Check_solver { public: typedef typename K::Root_stack Root_stack; typedef typename K::Root_container Root_container; typedef std::vector DV; typedef typename K::Root Rt; typedef typename K::Function Fn; typedef typename Fn::NT NT; typedef K Kernel; K k_; bool verbose; typename K::Construct_function cf_; double total_time; unsigned int num_roots; double ce_time; unsigned int nce; Check_solver(const K& k, bool verbose): k_(k), verbose(verbose), cf_(k_.construct_function_object()){} /*void time_estimate(const Fn &, const Rt& , False){ } void time_estimate(const Fn &q, const Rt& start, True){ Root_stack s= k_.root_stack_object(q, start, std::numeric_limits::infinity()); CGAL::Timer timer; timer.start(); do { s.compute_estimate(start); ++nce; } while (timer.time() <3 && !verbose); timer.stop(); ce_time= timer.time(); }*/ template void check_polynomial(const Fn &q, It roots_b, It roots_e, const Rt& start = Rt(-1000.0), const Rt& end = Rt(1000.0) ) { CGAL::Timer timer; //typename K::Is_even_multiplicity iem = k_.is_even_multiplicity_object(q); //int current_root=0; if (verbose) { std::cout << "Polynomial: " << q << std::endl; std::cout << "Window: ["; std::cout<< CGAL::to_double(start); std::cout << ", "; std::cout << CGAL::to_double(end); std::cout << ")" << std::endl; std::cout << "Solution: "; for (It c= roots_b; c!= roots_e; ++c) { /*if (CGAL::to_double(start) >= a[i]-.00001){ ++current_root; } else if (CGAL::to_double(end) <= a[i]){ } else {*/ std::cout << "<" << *c << "> "; //} } std::cout << std::endl; std::cout << "Solver: "; } std::vector roots; DV comp; int reps=0; timer.start(); int total_roots=0; do { Root_stack s= k_.root_stack_object(q, start, end); Rt last_root= -Rt(1000.0); while (!s.empty()) { if (reps==0 && verbose) { //comp.push_back(CGAL::to_double(r)); if (last_root > s.top()) { std::cerr << "WARNING last root was " << last_root << " and current root is " << s.top() << std::endl; } CGAL_assertion(last_root<= s.top()); last_root=s.top(); //Rt cur= s.top(); //if (cur != std::numeric_limits::infinity()) { /*if (cur == std::numeric_limits::infinity() || cur > 10000){ int i=0; }*/ roots.push_back(s.top()); std::cout << "<" << CGAL::to_double(s.top()); //if (iem(s.top())) { std::cout <<"E";} std::cout << "> " << std::flush; /*} else { }*/ } s.pop(); ++total_roots; } ++total_roots; if (reps==0 && verbose && CA) { std::vector taken_maple(roots_e-roots_b, false), taken_solver(roots.size(), false); for (unsigned int i=0; i< roots.size(); ++i) { double rd= CGAL::to_double(roots[i]); //bool ie= iem(roots[i]); int mult=1; //if (ie) mult=2; for (int k=0; k(num_roots) ; if (ce_time != 0) { std::cout << "(" << 1000000.0*ce_time/static_cast(nce) << ")"; } std::cout << " & "; } } void cleaned() { { // polynomials whose roots have been filtered based on derivitives Fn q= cf_(-16.614835192865492,19.540659228538015,-4); DV a; a.push_back(3.788873605); check_polynomial(q,a.begin(), a.end(), 1.096291202); } { Fn q= cf_(16.614835192865492,-19.540659228538015,4); DV a; a.push_back(1.09630); a.push_back(3.788873605); check_polynomial(q,a.begin(), a.end(), 1.096291202); } { Fn q= cf_(3.788873605, -3.788873605); DV a; a.push_back(1.0); check_polynomial(q,a.begin(), a.end(), 1); } { Fn q= cf_(-3.788873605, 3.788873605); DV a; check_polynomial(q,a.begin(), a.end(), 1); } { Fn q= cf_(-2295485086.0,2072822157.0, 116461914.2, -116175036.5, -10063149.87, -196007.0344, 3460.886000, 136.9100396, 1.0); DV a; a.push_back(-79.34012316); a.push_back(-45.32403162); a.push_back(-32.43524488); a.push_back(-22.45230969); a.push_back(-5.239841933); a.push_back(1.123932833); a.push_back(3.435646759); a.push_back(43.32193209); check_polynomial(q, a.begin(), a.end(), Rt(-79.34012316)); check_polynomial(q, a.begin()+2, a.end(), Rt(-45.32403162)); } } void wilkinson() { clear_timings(); unsigned int max_root = 20; CGAL_POLYNOMIAL_NS::Wilkinson_generator gen(k_); Fn q=gen(max_root); DV a; for (unsigned int i = 1; i <= max_root; i++) { a.push_back(i); } check_polynomial(q,a.begin(), a.end()); write_timings(); } void mignotte() { clear_timings(); unsigned int degree = 50; CGAL_POLYNOMIAL_NS::Mignotte_generator gen(k_); Fn q=gen(degree); DV a; a.push_back(-1.0925395143411487); a.push_back(0.20000000000000001); a.push_back(0.20000000000000001); a.push_back(1.0756542734086822); check_polynomial(q,a.begin(), a.end()); write_timings(); } void square_free() { clear_timings(); { Fn q= cf_(1,3,-4,-7); DV a; a.push_back(-0.8746784187); a.push_back(-0.2800178096); a.push_back(0.5832676569); check_polynomial(q,a.begin(), a.end()); } { Fn q= cf_(2,0,1); DV a; check_polynomial(q,a.begin(), a.end()); } /* { Fn q= Fn::make(0); DV a; check_square_free_polynomial(q,a.begin(), a.end(),print_multiplicity); } { Fn q= Fn::make(-3); DV a; check_square_free_polynomial(q,a.begin(), a.end(),print_multiplicity); } */ { Fn q= cf_(2,-1); DV a; a.push_back(2); check_polynomial(q,a.begin(), a.end()); } { Fn q= cf_(1,3,-4); DV a;a.push_back(-.25); a.push_back(1); check_polynomial(q,a.begin(), a.end()); } { Fn q= cf_(2,5,-4,-7,8,-14); DV a;a.push_back(0.7382979184); check_polynomial(q,a.begin(), a.end()); } { Fn q= cf_(2, 0, -1, 1, -3, -2); DV a;a.push_back(-1.833007477); a.push_back(-.8474637161); a.push_back(.7987710980); check_polynomial(q,a.begin(), a.end()); } write_timings(); } void small_intervals() { clear_timings(); Fn q= cf_(-2295485086.0,2072822157.0, 116461914.2, -116175036.5, -10063149.87, -196007.0344, 3460.886000, 136.9100396, 1.0); DV a; a.push_back(-79.34012316); a.push_back(-45.32403162); a.push_back(-32.43524488); a.push_back(-22.45230969); a.push_back(-5.239841933); a.push_back(1.123932833); a.push_back(3.435646759); a.push_back(43.32193209); check_polynomial(q, a.begin()+7, a.end()-1, Rt(5.0), Rt(40.0)); check_polynomial(q, a.begin()+5, a.end(), Rt(0.0), Rt(45.0)); check_polynomial(q, a.begin()+6, a.end()-1, Rt(1.123932834), Rt(20.0)); write_timings(); } void non_simple() { clear_timings(); { Fn q= cf_(-4365900, -5040, 1274073, 72979, -87647, -1045, 2275, -79, -17, 1); // -9., -5., -3., -3., 2., 7., 7., 10., 11. /*DV a;a.push_back(RP(-9,1)); a.push_back(RP(-5,1)); a.push_back(RP(-3,2 )); a.push_back(RP(2,1)); a.push_back(RP(7,2)); a.push_back(RP(10,1)); a.push_back(RP(11,1));*/ DV a;a.push_back(-9); a.push_back(-5); a.push_back(-3); a.push_back(-3); a.push_back(2); a.push_back(7); a.push_back(7); a.push_back(10); a.push_back(11); check_polynomial(q,a.begin(), a.end()); check_polynomial(q,a.begin()+2, a.end()-2, Rt(-4), Rt(9)); check_polynomial(q,a.begin()+2, a.end()-4, Rt(-4), Rt(7)); check_polynomial(q,a.begin()+2, a.end()-2, Rt(-3), Rt(9)); check_polynomial(q,a.begin()+2, a.end()-4, Rt(-3), Rt(7)); } write_timings(); } void roots() { CGAL_assertion(std::numeric_limits::has_infinity); Rt inf= std::numeric_limits::infinity(); Rt minf= -std::numeric_limits::infinity(); Rt big(100000); Rt small_rt(-1000000); Rt z(0); CGAL_assertion(big < inf); CGAL_assertion(big > minf); CGAL_assertion(small_rt < big); CGAL_assertion(z > small_rt); CGAL_assertion(-big < big); CGAL_assertion(small_rt < inf); CGAL_assertion(small_rt > minf); CGAL_assertion(z > minf); CGAL_assertion(z < inf); } void all() { square_free(); wilkinson(); mignotte(); small_intervals(); non_simple(); } void exact() { { Fn q= cf_(NT("1225969745589853940699882447880155625/664613997892457936451903530140172288"), NT("-149192919905533219658325090294590900625/2658455991569831745807614120560689152"), NT("-176473560706138356181046066127379288725/2658455991569831745807614120560689152"), NT("-59323957331081368745121550919931250845/10633823966279326983230456482242756608"), NT("213976196148401335217623674372070736157/10633823966279326983230456482242756608"), NT("10107182444809889626671506586504631263/5316911983139663491615228241121378304"), NT("-12967429119484147645038507190192518603/10633823966279326983230456482242756608"), NT("-894074013945673684338239220768251181/10633823966279326983230456482242756608"), NT("963347446801307512325971073199501/5316911983139663491615228241121378304")); DV a; a.push_back(-14.46710600); a.push_back(-3.440766418); a.push_back(0.031679482287); a.push_back(2.562471103); a.push_back(3.490003117); a.push_back(478.0766178); check_polynomial(q, a.begin(), a.end()); Root_container s= k_.root_container_object(q, Rt(-10000.0), Rt(10000.0)); std::vector roots; std::copy(s.begin(), s.end(), std::back_inserter(roots)); //typename Root_container::iterator it=s.begin(); for (unsigned int offset=0; offset < roots.size()-1; ++offset) { check_polynomial(q, a.begin()+offset, a.end(), roots[offset]); } } { Fn q= cf_(NT("2102889623460648672193194772242161145741209860309/2854495385411919762116571938898990272765493248"), NT("-27785292706190294695336118341445556791078034998297/5708990770823839524233143877797980545530986496"), NT("26399617884277473686036041581122386808181680932651/2854495385411919762116571938898990272765493248"), NT("-65515073263163417483134441553521565/5070602400912917605986812821504"), NT("6369956942652855102749740125692887/316912650057057350374175801344"), NT("-19558908001688696225/2251799813685248"), NT("5694238778856570877/562949953421312"), NT("-6468/1")); DV a; a.push_back(0.2307182653); a.push_back(0.4663233325); a.push_back(1.602781661); check_polynomial(q, a.begin(), a.end(), 0); Root_container s= k_.root_container_object(q, -Rt(10000.0), Rt(100000.0)); std::vector roots; std::copy(s.begin(), s.end(), std::back_inserter(roots)); //typename Root_container::iterator it=s.begin(); for (unsigned int offset=0; offset < roots.size()-1; ++offset) { check_polynomial(q, a.begin()+offset, a.end(), roots[offset]); } } } }; //typedef CGAL::Polynomial::Polynomial_kernel Kernel_gmpq; //typedef CGAL::Polynomial::Polynomial_kernel Kernel_double; /*typedef CGAL::Polynomial::Filtered_kernel, Polynomial_gmpq> Filtered_kernel_gmpq;*/ //typedef CGAL::Polynomial::Polynomial_kernel Kernel_core; //typedef Kernel_gmpq Exact_kernel; //typedef Filtered_kernel_gmpq Filtered_kernel; //typedef Kernel_double Numeric_kernel; #endif