shape_doc 0.1
|
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