00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 # ifndef realroot_cell_mv_bernstein_hpp
00012 # define realroot_cell_mv_bernstein_hpp
00013
00014 # include <realroot/Seq.hpp>
00015 # include <realroot/sign_variation.hpp>
00016 # include <realroot/Interval.hpp>
00017 # include <realroot/ring_bernstein_tensor.hpp>
00018 # include <realroot/ring_sparse.hpp>
00019
00020 # undef C
00021 # define TMPL template<typename C>
00022 # define SELF cell_mv_bernstein<C>
00023
00024
00025 namespace mmx {
00026
00027
00028 TMPL
00029 class cell_mv_bernstein {
00030
00031 public:
00032
00033 typedef C Scalar;
00034 typedef polynomial<C, with<Bernstein> > Polynomial;
00035
00036 cell_mv_bernstein(void) ;
00037 cell_mv_bernstein(const Polynomial& p) {
00038 m_doms<<Interval<double>(0,1);
00039 m_equs<<p;
00040 }
00041 cell_mv_bernstein(const Seq<Polynomial>& E) {
00042 for(unsigned i=0;i<E.size();i++) m_doms<<Interval<double>(0,1);
00043 for(unsigned i=0;i<E.size();i++) m_equs<<E[i];
00044 }
00045
00046 cell_mv_bernstein(const Seq<Polynomial>& E, const Seq<Interval<double> >& D) {
00047 for(unsigned i=0;i<D.size();i++) m_doms<<D[i];
00048 for(unsigned i=0;i<E.size();i++) m_equs<<E[i];
00049 }
00050
00051 template<class POL>
00052 cell_mv_bernstein(const Seq<POL>& E, const Seq<Interval<double> >& D) {
00053 Seq<double> dmn;
00054 for(unsigned i=0;i<D.size();i++) {
00055 m_doms<<D[i];
00056 dmn <<D[i].lower() <<D[i].upper();
00057 }
00058
00059 for(unsigned i=0;i<E.size();i++) {
00060 Polynomial p;
00061 let::assign(p,E[i],dmn);
00062 m_equs<<p;
00063 }
00064 }
00065
00066 ~cell_mv_bernstein(void) ;
00067
00068 unsigned nbeq() const {return m_equs.size();}
00069 unsigned nbeq() {return m_equs.size();}
00070
00071 Polynomial equation(unsigned i) const {return m_equs[i];}
00072 Polynomial& equation(unsigned i) {return m_equs[i];}
00073
00074 unsigned nbvar() const {return m_doms.size();}
00075 unsigned nbvar() {return m_doms.size();}
00076
00077 Seq<Interval<double> > domain() const {return m_doms;}
00078 Seq<Interval<double> >& domain() {return m_doms;}
00079
00080 Interval<double> domain(unsigned i) const {return m_doms[i];}
00081 Interval<double>& domain(unsigned i) {return m_doms[i];}
00082
00083 C size(void) const {
00084 C s=0;
00085 for(unsigned i=0;i<m_doms.size();i++)
00086 s=std::max(s,m_doms[i].upper()-m_doms[i].lower());
00087 return s;
00088 }
00089
00090
00091 private:
00092 Seq<Polynomial> m_equs;
00093 Seq<Interval<double> > m_doms;
00094 };
00095
00096
00097 TMPL
00098 SELF::cell_mv_bernstein(void) {}
00099
00100 TMPL
00101 SELF::~cell_mv_bernstein(void) {}
00102
00103
00104 struct binary_approx {
00105
00106 static double m_eps;
00107
00108 template<class Cell, class Stack>
00109 static void subdivide(Cell* cl, Stack* stack);
00110
00111 template<class Cell>
00112 static bool reduce(Cell* cl);
00113
00114 template<class Cell>
00115 static bool regular(Cell* cl);
00116
00117 } ;
00118
00119 double binary_approx::m_eps=1e-6;
00120
00121 template<class Cell, class Stack> void
00122 binary_approx::subdivide(Cell* cl, Stack* st) {
00123
00124
00125 Cell* left = new Cell(*cl);
00126 Cell* right = new Cell(*cl);
00127
00128 unsigned v=0;
00129 typename Cell::Scalar s=cl->domain(0).upper()-cl->domain(0).lower(),s0;
00130 for (unsigned i=0;i<cl->nbvar();i++)
00131 if((s0=cl->domain(i).upper()-cl->domain(i).lower())>s) {
00132 s=s0;v=i;
00133 }
00134 typename Cell::Scalar m=(cl->domain(v).upper()+cl->domain(v).lower())/2;
00135
00136 for (unsigned i=0;i<cl->nbeq();i++)
00137 tensor::split(left->equation(i), right->equation(i), v);
00138 left->domain(v).upper()=m;
00139 right->domain(v).lower()=m;
00140
00141
00142
00143
00144
00145 st->push(left);
00146 st->push(right);
00147 };
00148
00149 template<class Cell> bool
00150 binary_approx::reduce(Cell* cl) {
00151 if(cl->size() < m_eps) return false;
00152 for(unsigned i=0;i<cl->nbeq();i++)
00153 if(!has_sign_variation(cl->equation(i))) return false;
00154 return true;
00155 }
00156
00157 template<class Cell> bool
00158 binary_approx::regular(Cell* cl) {
00159 for(unsigned i=0;i<cl->nbeq();i++)
00160 if(!has_sign_variation(cl->equation(i))) return false;
00161 return true;
00162 }
00163
00164
00165 struct binary_isolate: binary_approx {
00166
00167 template<class Cell>
00168 static bool reduce(Cell* cl);
00169
00170 } ;
00171
00172 template<class Cell> bool
00173 binary_isolate::reduce(Cell* cl) {
00174 if(cl->size() < m_eps) return false;
00175 std::cout<<"isolate"<<std::endl;
00176 for(unsigned i=0;i<cl->nbeq();i++)
00177 if(!has_sign_variation(cl->equation(i))) return false;
00178
00179
00180 return true;
00181 }
00182
00183
00184 }
00185
00186 # undef TMPL
00187 # undef SELF
00188 # endif