00001
00002
00003
00004
00005
00006
00007
00009 #ifndef SYNAPS_SOLVE_EXCLUSION_H
00010 #define SYNAPS_SOLVE_EXCLUSION_H
00011
00012 #include <synaps/init.h>
00013 #include <synaps/base/type.h>
00014 #include <synaps/base/Seq.h>
00015 #include <synaps/upol/UPOLDAR.m>
00016
00017 #include <cmath>
00018
00019
00020 __BEGIN_NAMESPACE_SYNAPS
00021
00022 using std::abs;
00023
00035 struct Exclusion
00036 {
00037 double eps;
00038
00039 Exclusion(): eps(1.e-6) {}
00040 Exclusion(double e): eps(e) {}
00041 Exclusion(const Exclusion & E): eps(E.eps) {}
00042 template<class R>
00043 typename R::value_type operator()(const R & p,
00044 const typename R::value_type & x0,
00045 const typename R::value_type & r) const;
00046 };
00047
00048
00053 template<class R>
00054 typename R::value_type Exclusion::operator()(const R & p,
00055 const typename R::value_type & x0,
00056 const typename R::value_type & r) const
00057 {
00058 R tmp=p;
00059 using UPOLDAR::shift; shift(tmp,x0);
00060 tmp[0]= abs(tmp[0]);
00061 for(int i=1; i <=tmp.get_degree(); i++) tmp[i]= -abs(tmp[i]);
00062 return tmp(r);
00063 }
00064
00065
00066 template<class C> struct box
00067 {
00068 C center, radius;
00069 box(): center(0), radius(0){}
00070 box(C c, C r): center(c), radius(r){}
00071 box(const box<C> & b): center(b.center), radius(b.radius){}
00072 box<C>& operator=(const box<C> & b)
00073 {center =b.center; radius=b.radius; return *this;}
00074 };
00075
00076
00077 template<class POL, class C>
00078 Seq<C> solve(const POL& p,const Exclusion & EX, const C& a,const C& b)
00079 {
00080 std::vector<box<C> > lst;
00081 Seq<C> sol;
00082 lst.push_back(box<C>((a+b)/2, abs(b-a)/2));
00083 typename std::vector<box<C> >::iterator ib=lst.begin();
00084 while(lst.size()!=0)
00085 {
00086
00087 if(EX(p,ib->center,ib->radius)<0)
00088 {
00089 if(ib->radius<EX.eps)
00090 {
00091 sol.push_back(ib->center);
00092 lst.erase(ib);ib=lst.end();ib--;
00093 } else {
00094 C nr=(ib->radius/2);
00095 box<C> nb(ib->center+nr,nr);
00096 ib->center-=nr;
00097 ib->radius/=2;
00098 ib=lst.insert(ib,nb);
00099 ib++;
00100 }
00101 }
00102 else
00103 {
00104 lst.erase(ib);
00105 ib=lst.end();ib--;
00106 }
00107 }
00108
00109
00110 Seq<C> liste;
00111 for(typename std::vector<C>::iterator iter=sol.begin();iter!=sol.end();iter++){
00112 C ab=*iter;
00113 C ac=*iter;
00114 while ((abs(*iter-*(iter+1))<EX.eps*3) && ((iter+1)!=sol.end()))
00115 {iter++;ac=*iter;}
00116 liste.push_back((ab+ac)/2);
00117 }
00118 return (liste);
00119 }
00120
00121 template<class POL, class C> inline
00122 Seq<C> solve(const POL& p, const box<C> & b, const Exclusion & mth)
00123 {
00124 return solve(p,b.center-b.radius,b.center+b.radius,mth);
00125 }
00126
00127
00128
00129 __END_NAMESPACE_SYNAPS
00130
00131
00132
00133 #endif // SYNAPS_SOLVE_EXCLUSION_H
00134