shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/topological_degree.hpp
Go to the documentation of this file.
00001 #ifndef shape_topological_degree_hpp
00002 #define shape_topological_degree_hpp
00003 
00004 #include <realroot/sign_variation.hpp>
00005 #include <realroot/Interval.hpp>
00006 #include <realroot/Seq.hpp>
00007 #include <realroot/polynomial_bernstein.hpp>
00008 
00009 #define Polynomial polynomial<C, with<Bernstein> >
00010 
00011 namespace mmx {
00012 
00013 template<class C>
00014 bool not_const_sign(const Polynomial& f)
00015 // si les coefficients de f sont de signes constants not_const_sign = false, 
00016 // sinon not_const_sign = true
00017 {
00018   bool b = false;
00019   int d  = f.size();
00020   int i,j;
00021   for (i = 0; (i < d) && (f[i] == 0); i++) ;
00022   
00023   if (i < d)
00024   {
00025     for (j = i+1; (j < d+1)&&(!b); j++)
00026     {
00027       b = (sign(f[i]) * sign(f[j]) < 0);
00028     }
00029   }
00030   return b;
00031 }
00032 //----------------------------------------------------------------------
00033 template<class C>
00034 C eval(const Polynomial& f, const C& x)
00035 // evaluation de f en x
00036 {
00037   return f[0];
00038 }
00039 
00040 //----------------------------------------------------------------------
00041 template<class B, class C>
00042 void separate_roots(Seq<Interval<B> >& L, 
00043                     const Polynomial& bf, const Polynomial& bg, 
00044                     double eps)
00045 // isolation de racines reelles de l'equation bf*bg = 0 sur [a,b]
00046 {
00047   typedef Interval<B> interval_t;
00048   Seq< interval_t > L0; 
00049   Seq< Polynomial > Lf, Lg; 
00050   Polynomial f1,f2,g1,g2;
00051   interval_t I0;
00052 
00053   std::cout<< bf<< std::endl;
00054   std::cout<< bg<< std::endl;
00055   if (not_const_sign(bf) || not_const_sign(bg))
00056   {
00057     Lf.push_back(bf);
00058     Lg.push_back(bg);
00059     L0 << interval_t(0,1);
00060   }
00061   B middle = 0.5;
00062   while (L0.size())
00063   {
00064     int i = L0.size()-1;
00065     I0 = L0[i];
00066     L0.resize(i);
00067     f1 = Lf[i]; f2=f1;
00068     Lf.resize(i);
00069     g1 = Lg[i]; g2=g1;
00070     Lg.resize(i);
00071     
00072     if (I0.size() < eps)
00073     {
00074       L << I0;
00075     }
00076     else
00077     {
00078       tensor::split(f1,f2,0,0.5);
00079       tensor::split(g1,g2,0,0.5);
00080 
00081       if (not_const_sign(f2) || not_const_sign(g2))
00082       {
00083         Lf.push_back(f2);
00084         Lg.push_back(g2);
00085         L0 << interval_t(middle * I0.lower() + (1-middle) * I0.upper(),
00086                          I0.upper());
00087       }
00088         
00089       if ((f2[0]==0) || (g2[0]==0))
00090       {
00091         Lf.push_back(f2);
00092         Lg.push_back(g2);
00093         L0 << interval_t(middle * I0.lower() + (1-middle) * I0.upper(),
00094                          middle * I0.lower() + (1-middle) * I0.upper());
00095       }
00096         
00097       if (not_const_sign(f1) || not_const_sign(g1))
00098       {
00099         Lf.push_back(f1);
00100         Lg.push_back(g1);
00101         L0<< interval_t(I0.lower(),
00102                         middle * I0.lower() + (1-middle) * I0.upper());
00103       }
00104     }
00105   }
00106 }
00107 
00111 template<class C>
00112 int topological_degree(const Polynomial& f, const Polynomial& g) 
00113 // calcul le degree topologique deg((f,g),(0,0),box)
00114 {
00115   typedef Interval<double> interval_t;
00116   //  double a=0, b=1, c=0, d=1;
00117   
00118   std::cout<< "B topo"<< std::endl;
00119   //  print(std::cout,f); 
00120   //  std::cout<<"f "<<f;std::cout<< std::endl;
00121   //  print(std::cout,g); std::cout<< std::endl;
00122   //  std::cout<<"g "<<g;std::cout<< std::endl;
00123 
00124   Seq< interval_t > sa, sb, sc, sd;
00125 
00126   Polynomial ff;
00127   tensor::face(ff, f, 0, 0);
00128   //  std::cout<<"ff "<<ff; std::cout<< std::endl;
00129 
00130   Polynomial fg;   //Polynomial h1(face(g.env,0));
00131   tensor::face(fg, g, 0, 0);
00132   //  std::cout<<"fg "<<fg; std::cout<< std::endl;
00133 
00134  //  tensor::face(fb, f, 0, 1);
00135 //   std::cout<<"fb "<<fb; std::cout<< std::endl;
00136  
00137 //   tensor::face(fc, f, 1, 0);
00138 //   std::cout<<"fc "<<fc; std::cout<< std::endl;
00139 
00140 //   tensor::face(fd, f, 1, 1);
00141 //   std::cout<<"fd "<<fd; std::cout<< std::endl;
00142 
00143 //   std::cout<< "C topo"<<std::endl;
00144 
00145 
00146 //   tensor::face(gb, g, 0, 1);
00147 //   std::cout<<gb; std::cout<< std::endl;
00148 
00149 //   tensor::face(gc, g, 1, 0);
00150 //   std::cout<<gc; std::cout<< std::endl;
00151 
00152 //   tensor::face(gd, g, 1, 1);
00153 //   std::cout<<gd;
00154   return 0;
00155 
00156   // fa(t) = f(a,t), fb(t) = f(b,t), fc(t) = f(t,c), fd(t) = f(t,d)
00157   // ga(t) = g(a,t), gb(t) = g(b,t), gc(t) = g(t,c), fd(t) = f(t,d)
00158   
00159   // sa la liste d'intervalles qui isolent les racines reelles de fa*ga=0
00160   // sb la liste d'intervalles qui isolent les racines reelles de fb*gb=0
00161   // sc la liste d'intervalles qui isolent les racines reelles de fc*gc=0
00162   // sd la liste d'intervalles qui isolent les racines reelles de fd*gd=0
00163   
00164 //   double eps = 1e-8; 
00165 //   separate_roots(sa, fa, ga, eps);
00166 //   std::cout << "A "<< sa.size()<< std::endl;
00167 //   separate_roots(sb, fb, gb, eps);
00168 //   std::cout << "B "<< sb.size()<< std::endl;
00169 //   separate_roots(sc, fc, gc, eps);
00170 //   std::cout << "C "<< sc.size()<< std::endl;
00171 //   separate_roots(sd, fd, gd, eps);
00172 //   std::cout << "D "<< sd.size()<< std::endl;
00173   
00174 //  int ja = sa.size();
00175 //   if (ja < 2)
00176 //   {
00177 //     if (ja == 0) sa.resize(1);
00178 //     sa[0].assign(c, d);
00179 //   }
00180 //   else
00181 //   {
00182 //     sa[0].assign(c, 0.5*(sa[0].upper() + sa[1].lower()));
00183 //     for (int i = 1; i < ja-1; i++)
00184 //     {
00185 //       sa[i].assign(sa[i-1].upper(), 0.5*(sa[i].upper() + sa[i+1].lower()));
00186 //     }
00187 //     sa[ja-1].assign(sa[ja-2].upper(), d);
00188 //   }
00189 
00190 //   int jb = sb.size();
00191 //   if (jb < 2)
00192 //   {
00193 //     if (jb == 0) sb.resize(1);
00194 //     sb[0].assign(c, d);
00195 //   }
00196 //   else
00197 //   {
00198 //     sb[0].assign(c, 0.5*(sb[0].upper() + sb[1].lower()));
00199 //     for (int i = 1; i < jb-1; i++)
00200 //     {
00201 //       sb[i].assign(sb[i-1].upper(), 0.5*(sb[i].upper()+sb[i+1].lower()));
00202 //     }
00203 //     sb[jb-1].assign(sb[jb-2].upper(), d);
00204 //   }
00205   
00206 //   int jc = sc.size();
00207 //   if (jc < 2)
00208 //   {
00209 //     if (jc == 0) sc.resize(1);
00210 //     sc[0].assign(a, b);
00211 //   }
00212 //   else
00213 //   {
00214 //     sc[0].assign(a, 0.5*(sc[0].upper() + sc[1].lower()));
00215 //     for (int i = 1; i < jc-1; i++)
00216 //     {
00217 //       sc[i].assign(sc[i-1].upper(), 0.5*(sc[i].upper() + sc[i+1].lower()));
00218 //     }
00219 //     sc[jc-1].assign(sc[jc-2].upper(), b);
00220 //   }
00221 
00222 //   int jd = sd.size();
00223 //   if (jd < 2)
00224 //   {
00225 //     if (jd == 0) sd.resize(1);
00226 //     sd[0].assign(a, b);
00227 //   }
00228 //   else
00229 //   {
00230 //     sd[0].assign(a, 0.5*(sd[0].upper() + sd[1].lower()));
00231 //     for (int i = 1; i < jd-1; i++)
00232 //     {
00233 //       sd[i].assign(sd[i-1].upper(), 0.5*(sd[i].upper()+sd[i+1].lower()));
00234 //     }
00235 //     sd[jd-1].assign(sd[jd-2].upper(), b);
00236 //   }
00237 
00238 //   int deg = 0;
00239   
00240 //   for (int i = 0; i < ja; i++)
00241 //   {
00242 //     C u = sa[i].lower(), v = sa[i].upper();
00243 //     int sfu = sign(eval<C>(fa,(u-c)/(d-c))), 
00244 //       sfv = sign(eval<C>(fa,(v-c)/(d-c))), 
00245 //       sgu = sign(eval<C>(ga,(u-c)/(d-c))), 
00246 //       sgv = sign(eval<C>(ga,(v-c)/(d-c)));
00247 //     if (sfu == sfv)
00248 //       deg += sfu * (sgu - sgv);
00249 //     else
00250 //       deg += sgu * (sfv - sfu);
00251 //   }
00252   
00253 //   for (int i = 0; i < jb; i++)
00254 //   {
00255 //     C u = sb[i].lower(), v = sb[i].upper();
00256 //     int sfu = sign(eval<C>(fb,(u-c)/(d-c))), 
00257 //       sfv = sign(eval<C>(fb,(v-c)/(d-c))), 
00258 //       sgu = sign(eval<C>(gb,(u-c)/(d-c))), 
00259 //       sgv = sign(eval<C>(gb,(v-c)/(d-c)));
00260 //     if (sfu == sfv)
00261 //       deg += sfu * (sgv - sgu);
00262 //     else
00263 //       deg += sgu * (sfu - sfv);
00264 //   }
00265   
00266 //   for (int i = 0; i < jc; i++)
00267 //   {
00268 //     C u = sc[i].lower(), v = sc[i].upper();
00269 //     int sfu = sign(eval<C>(fc,(u-a)/(b-a))), 
00270 //       sfv = sign(eval<C>(fc,(v-a)/(b-a))), 
00271 //       sgu = sign(eval<C>(gc,(u-a)/(b-a))), 
00272 //       sgv = sign(eval<C>(gc,(v-a)/(b-a)));
00273 //     if (sfu == sfv)
00274 //       deg += sfu * (sgv - sgu);
00275 //     else
00276 //       deg += sgu * (sfu - sfv);
00277 //   }
00278   
00279 //   for (int i = 0; i < jd; i++)
00280 //   {
00281 //     C u = sd[i].lower(), v = sd[i].upper();
00282 //     int sfu = sign(eval<C>(fd,(u-a)/(b-a))), 
00283 //       sfv = sign(eval<C>(fd,(v-a)/(b-a))), 
00284 //       sgu = sign(eval<C>(gd,(u-a)/(b-a))), 
00285 //       sgv = sign(eval<C>(gd,(v-a)/(b-a)));
00286 //     if (sfu == sfv)
00287 //       deg += sfu * (sgu - sgv);
00288 //     else
00289 //       deg += sgu * (sfv - sfu);
00290 //   }
00291 
00292 //   return (int)(deg/8);
00293 }
00294 //======================================================================
00295 #undef Polynomial
00296 //======================================================================
00297 } // namespace mmx
00298 #endif //shape_topological_degree_hpp
00299