00001
00002 #include <basix/vector.hpp>
00003 #include <basix/vector_sort.hpp>
00004 #include <numerix/kernel.hpp>
00005 #include <realroot/Seq.hpp>
00006 #include <realroot/Interval_glue.hpp>
00007 #include <realroot/ring_monomial_tensor.hpp>
00008 #include <realroot/solver_uv_sleeve.hpp>
00009 #include <realroot/solver_uv_continued_fraction.hpp>
00010 #include <realroot/solver_uv_interval_newton.hpp>
00011
00012
00013 #define TMPL template<class C>
00014 #define RING ring<C,MonomialTensor>
00015 #define POLYNOMIAL polynomial< C, with<MonomialTensor> >
00016
00017 namespace mmx {
00018
00019 template<typename FT, typename RT, typename Poly>
00020 struct as_helper<interval<FT>,IntervalData<RT,Poly> > {
00021 static inline interval<FT>
00022 cv (const IntervalData<RT,Poly>& I) {
00023 FT left, right;
00024 if ( I.c == RT(0))
00025 left = sign(I.a) * bound_root( I.p, Cauchy<FT>());
00026 else
00027 left = FT(I.a)/I.c;
00028
00029 if ( I.d == RT(0))
00030 right = sign(I.b) * bound_root( I.p, Cauchy<FT>());
00031 else
00032 right = FT(I.b)/I.d;
00033
00034 return interval<FT>(left, right);
00035 }
00036 };
00037
00038 TMPL vector<generic>
00039 solver_univariate_contfrac_prec(const POLYNOMIAL & p, const int& prec) {
00040 typedef Numerix kernel;
00041 typedef typename kernel::integer Integer;
00042 typedef typename kernel::rational Rational;
00043 typedef typename kernel::interval_rational interval_rational;
00044 typedef solver< Integer, ContFrac<Approximate> > Solver;
00045
00046 vector<interval_rational> sol;
00047 Solver::set_precision(prec);
00048 Solver::solve(sol,p);
00049 sort(sol);
00050
00051 vector<generic> r;
00052 for(unsigned i=0;i<sol.size();i++)
00053 r <<as<generic>(interval< Rational > (lower(sol[i]),upper(sol[i])));
00054
00055 return r;
00056 }
00057
00058
00059 TMPL vector<generic> solver_univariate_contfrac(const POLYNOMIAL & p) {
00060 return solver_univariate_contfrac_prec(p,mmx_bit_precision);
00061 }
00062
00063
00064 TMPL vector<generic>
00065 solver_univariate_contfrac(const POLYNOMIAL & p, const interval<rational>& D) {
00066 typedef Numerix kernel;
00067 typedef typename kernel::integer Integer;
00068 typedef typename kernel::rational Rational;
00069 typedef typename kernel::interval_rational interval_rational;
00070 typedef solver<Integer, ContFrac<Approximate> > Solver;
00071
00072 vector<interval_rational> sol;
00073 Solver::set_precision(mmx_bit_precision);
00074 Solver::solve(sol,p,lower(D),upper(D));
00075 sort(sol);
00076 vector<generic> r;
00077 for(unsigned i=0;i<N(sol);i++)
00078 r <<as<generic>(interval< rational > (lower(sol[i]),upper(sol[i])));
00079 return r;
00080 }
00081
00082
00083
00084 TMPL vector<generic>
00085 solver_univariate_contfrac_approx_prec(const POLYNOMIAL & p, const int& prec) {
00086 typedef Numerix kernel;
00087 typedef typename kernel::integer Integer;
00088 typedef typename kernel::rational rational;
00089 typedef typename kernel::interval_rational interval_rational;
00090 typedef solver<Integer,ContFrac<Approximate> > Solver;
00091
00092
00093 Solver::set_precision(prec);
00094
00095 vector<interval_rational> sol;
00096 Solver::solve(sol,p);
00097 sort(sol);
00098 long int old_prec = mmx_bit_precision;
00099 vector<generic> r;
00100 mmx_bit_precision = prec;
00101 for(unsigned i=0;i<sol.size();i++) {
00102 r << as<generic>(as<floating<> >((lower(sol[i])+upper(sol[i]))/2));
00103 }
00104 mmx_bit_precision = old_prec;
00105 return r;
00106 }
00107
00108 TMPL vector<generic>
00109 solver_univariate_contfrac_approx(const POLYNOMIAL & p) {
00110 return solver_univariate_contfrac_approx_prec(p,mmx_bit_precision);
00111 }
00112
00113 TMPL vector<generic>
00114 solver_univariate_sleeve(const POLYNOMIAL & p) {
00115 typedef Numerix kernel;
00116 typedef typename kernel::integer Integer;
00117 typedef typename kernel::rational rational;
00118 typedef typename kernel::interval_rational interval_rational;
00119 typedef kernel::interval_rational interval_rational;
00120 Seq<interval_rational> sol;
00121 solver<RING,Sleeve<Isolate> >::solve(sol,p);
00122 vector<generic> r;
00123 for(unsigned i=0;i<sol.size();i++) r << as<generic>(sol[i]);
00124 return r;
00125 }
00126
00127 TMPL interval<floating<> >
00128 solver_univariate_newton(const POLYNOMIAL & p, const interval<floating<> >& I) {
00129 typedef interval<floating<> > interval_t;
00130 IntervalNewton<interval_t,C> Nwt(I);
00131 Seq<interval_t> sol =solve(p,Nwt);
00132
00133 return sol[0];
00134 }
00135
00136 }
00137
00138 #undef TMPL
00139 #undef RING
00140 #undef POLYNOMIAL
00141
00142