synaps/usolve/sturmsmdeg.h

00001 // Copyright (c) 2003  INRIA Sophia-Antipolis (France) and
00002 //                     Department of Informatics and Telecommunications
00003 //                     University of Athens (Greece).
00004 // All rights reserved.
00005 //
00006 // Authors : Elias P. TSIGARIDAS <et@di.uoa.gr>
00007 
00008 // Partially supported by INRIA's project "CALAMATA", a
00009 // bilateral collaboration with National Kapodistrian University of
00010 // Athens.
00011 // Partially supported by the IST Programme of the EU as a Shared-cost
00012 // RTD (FET Open) Project under Contract No  IST-2000-26473
00013 // (ECG - Effective Computational Geometry for Curves and Surfaces)
00014 //
00015 
00016 #ifndef SYNAPS_ARITHM_ALGEBRAIC_ASOLVER_H
00017 #define SYNAPS_ARITHM_ALGEBRAIC_ASOLVER_H
00018 
00019 #include <synaps/usolve/Algebraic_config.h>
00020 #include <synaps/usolve.h>
00021 #include <synaps/usolve/Method_name.h>
00022 #include <synaps/usolve/Construct_rootof.h>
00023 #include <synaps/upol/SturmSeq.h>
00024 #include <synaps/upol/SquareFree.h>
00025 #include <synaps/usolve/Util.h>
00026 #include <synaps/upol/Bound.h>
00027 #include <synaps/usolve/method_name.h>
00028 #include <stack>
00029 
00030 
00031 __ALGEBRAIC_BEGIN_NAMESPACE
00032 
00033 #if 0
00034 
00035 //--------------------------------------------------------------------------------
00036 
00037 template < typename RT, typename POLY >
00038 void
00039 compute_intermediate_points(const Seq< root_of<RT, POLY> >& V,
00040                             Seq< typename NumberTraits<RT>::FT >& Points)
00041 {
00042     typedef root_of<RT, POLY>    RO_t;
00043     typedef NumberTraits<RT>    NTR;
00044     typedef typename NTR::FT     FT;
00045     typedef typename NTR::FIT    FIT;
00046 
00047     typedef typename Seq<RO_t>::const_iterator  IT1;
00048 
00049     IT1 it = V.begin();
00050     Points.push_back( FT(it->left() - 1) );
00051 
00052     ++it;
00053     for (; it != V.end(); ++it) {
00054         while ( ((it-1)->right() >= it->left())  ) {
00055             (it-1)->refine_interval();
00056             it->refine_interval();
00057         }
00058         Points.push_back( FT(((it - 1)->right() + it->left())/2) );
00059     }
00060     Points.push_back(FT((it-1)->right() + 1));
00061     return;
00062 }
00063 
00064 //--------------------------------------------------------------------------------
00065 
00066 
00067 //--------------------------------------------------------------------------------
00068 //--------------------------------------------------------------------------------
00069 //--------------------------------------------------------------------------------
00070 
00071 
00072 template < typename RT,
00073            typename OutputIterator >
00074 OutputIterator
00075 solve( const typename Sturm<RT>::Poly& F,
00076        OutputIterator  sol,
00077        unsigned mult,
00078        const Sturm<RT>& mth)
00079 {
00080     typedef typename Sturm<RT>::FT    FT;
00081     typedef typename Sturm<RT>::FIT   FIT;
00082     typedef typename Sturm<RT>::RO_t  RO_t;
00083     typedef typename Sturm<RT>::Poly  POLY;
00084 
00085     typedef Quadtuple<FT>   Quad;
00086 
00087     std::stack<Quad>   Work;
00088     std::vector<FIT>   result;
00089 
00090     SturmSeq<RT> sth(F, UPOLDAR::diff(F), SUBRES());
00091 
00092     FT b = max_bound(sth[0], Cauchy());
00093     FT a = -b;
00094     POLY h = sth[0];
00095 
00096     int Va = Var(sth, a);
00097     int Vb = Var(sth, b);
00098     int V = Va - Vb;
00099 
00100     if (V == 0) return sol;
00101     if (V == 1) {
00102         *sol++ = RO_t(sth[0], a, b, mult);
00103         return sol;
00104     }
00105     Work.push( Quad(a, b, Va, Vb) );
00106 
00107     POLY x(2, AsSize()); x[1] = RT(1);
00108 
00109     while (!Work.empty()) {
00110         Quad q = Work.top();
00111         Work.pop();
00112     
00113         FT c = (q.a() + q.b())/2;
00114         if (sign(UPOLDAR::eval_horner(sth[0], c)) == ZERO) {
00115             result.push_back( FIT(c, c) );
00116 
00117             POLY t(2, AsSize());
00118             t[1] = denominator(c);
00119             t[0] = -numerator(c);
00120             h = EUCLIDIAN::pquo(h, t);
00121 
00122             POLY f = translate(sth[0], c)/x;
00123             FT M = min_bound(f, Cauchy());
00124             //int Vc_plus = Count(sth, FT(c + M));
00125             int Vc_plus = Var(sth, FT(c + M));
00126             //int Vc_minus = Var(sth, FT(c - M));
00127             int Vc_minus = Vc_plus + 1;
00128 
00129             if (q.Va() == Vc_minus + 1) {
00130                 result.push_back( FIT(q.a(), FT(c - M)) );
00131                 //continue;
00132             }
00133             if (q.Va() > Vc_minus + 1) {
00134                 Work.push( Quad(q.a(), FT(c - M), q.Va(), Vc_minus) );
00135                 //continue;
00136             }
00137             if (q.Vb() == Vc_plus - 1) {
00138                 FIT I(FT(c + M), q.b());
00139                 result.push_back( FIT(FT(c + M), q.b()) );
00140                 //continue;
00141             }
00142             if (q.Vb() < Vc_plus - 1) {
00143                 Work.push( Quad(c + M, q.b(), Vc_plus, q.Vb()) );
00144                 //continue;
00145             }
00146         } else {
00147             int Vc = Var(sth, c);
00148             if (q.Va() == Vc + 1) {
00149                 result.push_back( FIT(q.a(), c) );
00150                 //continue;
00151             }
00152             if (q.Vb() == Vc - 1) {
00153                 result.push_back( FIT(c, q.b()) );
00154                 //continue;
00155             }
00156 
00157             if (q.Vb() < Vc - 1) {
00158                 Work.push( Quad(c, q.b(), Vc, q.Vb()) );
00159                 //continue;
00160             }
00161             if (q.Va() > Vc + 1) {
00162                 Work.push( Quad(q.a(), c, q.Va(), Vc) );
00163                 //continue;
00164             }
00165         }
00166 
00167     }
00168     std::sort(result.begin(), result.end());
00169     typename std::vector<FIT>::const_iterator it;
00170     for (it = result.begin(); it != result.end(); ++it) {
00171         if (singleton(*it) ) {
00172             RO_t r = make_root_of_1(RT(-numerator(it->lower())), denominator(it->lower()), mth);
00173             r.set_multiplicity(mult);
00174             *sol++ = r;
00175         } else {
00176             *sol++ = RO_t(h, it->lower(), it->upper(), mult);
00177         }
00178     }
00179 
00180     return sol;
00181 }
00182 
00183 
00184 
00185 
00186 //----------------------------------------------------------------------------
00187 
00188 
00189 template < typename RT,
00190            typename OutputIterator >
00191 OutputIterator
00192 sturm_in_interval( const SturmSeq<RT>                  StHa,
00193                    const typename Sturm<RT>::FIT       I,
00194                    OutputIterator                      sol,
00195                    unsigned                            mult,
00196                    const Sturm<RT>&                    MTH)
00197 {
00198     typedef typename Sturm<RT>::FT    FT;
00199     typedef typename Sturm<RT>::FIT   FIT;
00200     typedef typename Sturm<RT>::Poly  Poly;
00201     typedef typename Sturm<RT>::RO_t  RO_t;
00202 
00203     typedef Quadtuple<FT>   Quad;
00204 
00205     std::stack<Quad>   Work;
00206     std::vector<FIT>   result;
00207 
00208     FT a = lower(I);
00209     FT b = upper(I);
00210 
00211     Poly h = StHa[0];
00212 
00213     int Va = Var(StHa, a);
00214     int Vb = Var(StHa, b);
00215     int V = Va - Vb;
00216 
00217     if (V == 0) return sol;
00218     if (V == 1) {
00219         *sol++ = RO_t(StHa[0], a, b, mult);
00220         return sol;
00221     }
00222     Work.push( Quad(a, b, Va, Vb) );
00223 
00224     Poly x(2, AsSize()); x[1] = RT(1);
00225 
00226     while (!Work.empty()) {
00227         Quad q = Work.top();
00228         Work.pop();
00229    
00230         FT c = (q.a() + q.b())/2;
00231         if (sign(UPOLDAR::eval_horner(StHa[0], c)) == ZERO) {
00232             result.push_back( FIT(c, c) );
00233 
00234             Poly t(2, AsSize());
00235             t[1] = denominator(c);
00236             t[0] = -numerator(c);
00237             h = EUCLIDIAN::pquo(h, t);
00238 
00239             Poly f = translate(StHa[0], c)/x;
00240             FT M = min_bound(f, Cauchy());
00241             int Vc_plus = Var(StHa, FT(c + M));
00242             //int Vc_minus = Var(StHa, FT(c - M));
00243             int Vc_minus = Vc_plus + 1;
00244 
00245             if (q.Va() == Vc_minus + 1) { result.push_back( FIT(q.a(), FT(c - M)) ); }
00246             if (q.Va() > Vc_minus + 1) { Work.push( Quad(q.a(), FT(c - M), q.Va(), Vc_minus) ); }
00247 
00248             if (q.Vb() == Vc_plus - 1) { result.push_back( FIT(FT(c + M), q.b()) ); }
00249             if (q.Vb() < Vc_plus - 1) { Work.push( Quad(c + M, q.b(), Vc_plus, q.Vb()) ); }
00250         } else {
00251             int Vc = Var(StHa, c);
00252             if (q.Va() == Vc + 1) { result.push_back( FIT(q.a(), c) ); }
00253             if (q.Vb() == Vc - 1) { result.push_back( FIT(c, q.b()) ); }
00254 
00255             if (q.Vb() < Vc - 1) { Work.push( Quad(c, q.b(), Vc, q.Vb()) ); }
00256             if (q.Va() > Vc + 1) { Work.push( Quad(q.a(), c, q.Va(), Vc) ); }
00257         }
00258     }
00259     std::sort(result.begin(), result.end());
00260     typename std::vector<FIT>::const_iterator it;
00261     for (it = result.begin(); it != result.end(); ++it) {
00262         if (singleton(*it) ) {
00263             RO_t r = make_root_of_1(it->lower(), MTH);
00264             r.set_multiplicity(mult);
00265             *sol++ = r;
00266         } else {
00267             *sol++ = RO_t(h, it->lower(), it->upper(), mult);
00268         }
00269     }
00270     return sol;
00271 }
00272 
00273 
00274 
00275 
00276 
00277 template < typename NT,
00278            typename OutputIterator >
00279 OutputIterator
00280 solve( const typename Sturm<NT>::Poly& f,
00281        OutputIterator  sol,
00282        const Sturm<NT>& mth)
00283 {
00284     //std::cout << "solve<Sturm>" << std::endl;
00285     typedef typename Sturm<NT>::RT    RT;
00286     typedef typename Sturm<NT>::FT    FT;
00287     typedef typename Sturm<NT>::FIT   FIT;
00288     typedef typename Sturm<NT>::RO_t  RO_t;
00289     typedef typename Sturm<NT>::Poly  Poly;
00290 
00291     if (UPOLDAR::degree(f) < 5) {
00292         return solve(f, sol, Small_degree<RT>());
00293     }
00294   
00295     Seq<Poly> PL = SquareFreeFactorization(f);
00296 
00297     for (int i = 0; i < PL.size(); ++i) {
00298         if (UPOLDAR::degree(PL[i]) < 5) {
00299             //std::cout << "small\n";
00300             solve(PL[i], sol, i+1, Small_degree<NT>());
00301         } else {
00302             //std::cout << "big\n";
00303             solve(PL[i], sol, i+1, Sturm<NT>());
00304         }
00305     }   
00306     return sol; 
00307 }
00308 
00309 #endif
00310 
00312 
00313 __ALGEBRAIC_END_NAMESPACE
00314 
00315 
00316 #endif // SYNAPS_ARITHM_ALGEBRAIC_ASOLVER_H
00317 

SYNAPS DOCUMENTATION
logo