shape_doc 0.1
|
00001 /***************************************************************************** 00002 * M a t h e m a g i x 00003 ***************************************************************************** 00004 * solver_implicit 00005 * 2008-11-09 00006 * Bernard Mourrain 00007 ***************************************************************************** 00008 * Copyright (C) 2008 INRIA Sophia-Antipolis 00009 ***************************************************************************** 00010 * Comments : 00011 ****************************************************************************/ 00012 #ifndef shape_implicit_solver_hpp 00013 #define shape_implicit_solver_hpp 00014 //=========================================================================== 00015 # include <realroot/Interval.hpp> 00016 # include <realroot/polynomial_bernstein.hpp> 00017 # include <realroot/GMP.hpp> 00018 # include <realroot/solver_uv_sleeve.hpp> 00019 # include <realroot/solver_mv_bernstein.hpp> 00020 # include <shape/point.hpp> 00021 # include <shape/bounding_box.hpp> 00022 # include <shape/box_face.hpp> 00023 # include <shape/topological_degree.hpp> 00024 00025 # define TMPL template<class C, class V> 00026 # define SELF solver_implicit<C,V> 00027 00028 //==================================================================== 00029 namespace mmx { namespace shape { 00030 //==================================================================== 00031 00032 inline double lower(double x){return x;} 00033 inline double upper(double x){return x;} 00034 00035 template<class S1, class S2> 00036 point<double>* point_on_edge(const bounding_box<double>& bx, double u, const S1& s1, const S2& s2) 00037 { 00038 typedef point<double> Point; 00039 double p[3]; 00040 p[S1::var] = S1::eval(bx); 00041 p[S2::var] = S2::eval(bx); 00042 int v= 3-S1::var-S2::var; 00043 p[v]= lower(bx,v)*(1-u) + upper(bx,v)*u; 00044 00045 return new Point(p[0],p[1],p[2]); 00046 // delete p; 00047 } 00048 //-------------------------------------------------------------------- 00049 TMPL struct solver_implicit { 00050 00051 typedef REF_OF(V) Ref; 00052 typedef vertex<C,V> Point; 00053 typedef bounding_box<C,Ref> BoundingBox; 00054 typedef box_face<C,Ref> BoxFace; 00055 00056 static BoxFace north_edge; 00057 static BoxFace south_edge; 00058 static BoxFace west_edge; 00059 static BoxFace east_edge; 00060 static BoxFace front_edge; 00061 static BoxFace back_edge; 00062 00063 static BoxFace north_back_edge; 00064 static BoxFace south_back_edge; 00065 static BoxFace west_back_edge; 00066 static BoxFace east_back_edge; 00067 00068 static BoxFace north_front_edge; 00069 static BoxFace south_front_edge; 00070 static BoxFace west_front_edge; 00071 static BoxFace east_front_edge; 00072 00073 static BoxFace north_west_edge; 00074 static BoxFace south_west_edge; 00075 static BoxFace north_east_edge; 00076 static BoxFace south_east_edge; 00077 00078 static BoxFace north_face; 00079 static BoxFace south_face; 00080 static BoxFace west_face; 00081 static BoxFace east_face; 00082 static BoxFace front_face; 00083 static BoxFace back_face; 00084 00085 static inline Point* new_point(double a, double b, double c) { 00086 return new Point(a,b,c); 00087 } 00088 00089 //-------------------------------------------------------------------- 00090 template<class MultivariateDenseBernstein> static 00091 void edge_point(Seq<Point *>& lp, 00092 const MultivariateDenseBernstein & p, 00093 const BoxFace & E, 00094 const BoundingBox & bx) { 00095 MultivariateDenseBernstein f; 00096 00097 tensor::face(f,p,E.cvar(0),E.side(0)); 00098 00099 polynomial<double, with<Bernstein> > dw(1,f.size()-1), up(1,f.size()-1); 00100 for(unsigned i=0; i<f.size();i++) { 00101 up[i]= upper(f[i]); 00102 dw[i]= lower(f[i]); 00103 } 00104 00105 double 00106 U = E.lower(bx), 00107 V = E.upper(bx); 00108 00109 Seq<double> sol; 00110 solver< double, Sleeve<Approximate> >::solve(sol,dw,up,U,V); 00111 00112 // std::cout<<"****U= "<<U<<std::endl; 00113 // std::cout<<"****V= "<<V<<std::endl; 00114 // std::cout<<"***dw= "<<dw<<std::endl; 00115 // std::cout<<"***up= "<<up<<std::endl; 00116 // std::cout<<"******Sols : "<<sol.size()<<std::endl; 00117 00118 Approximate approx; 00119 std::vector<double> pt(3); 00120 for(unsigned i=0;i<sol.size(); i++) 00121 if(E.is_valid(bx, sol[i], approx.eps)) { 00122 lp<< E.new_point(bx,sol[i]); 00123 } 00124 } 00125 //-------------------------------------------------------------------- 00126 template<class MultivariateDenseBernstein> static 00127 int edge_sign_var(const MultivariateDenseBernstein & p, 00128 const BoxFace & E) { 00129 MultivariateDenseBernstein f; 00130 tensor::face(f,p,E.cvar(0),E.side(0)); 00131 return sign_variation(f.begin(), f.end()); 00132 00133 } 00134 //-------------------------------------------------------------------- 00135 template<class MultivariateDenseBernstein> static 00136 void face_point(Seq<Point *>& sol, 00137 const Seq<MultivariateDenseBernstein>& eqs, 00138 const BoxFace& F, 00139 const BoundingBox& bx) { 00140 00141 typedef polynomial< double, with<Bernstein> > Polynomial; 00142 00143 Polynomial f, p; 00144 Seq<Polynomial> sys; 00145 for(unsigned i=0;i< eqs.size(); i++) { 00146 let::assign(p.rep(), eqs[i].rep()); 00147 tensor::face(f.rep(), p.rep(), F.cvar(0), F.side(0)); 00148 sys<<f; 00149 } 00150 00151 solver<double, ProjRd<SBD_RDRDL> > slv; 00152 std::vector<double> res; 00153 slv.solve_bernstein(res,sys); 00154 Approximate approx; 00155 00156 for(int i=0;i<(int)res.size()-1;i+=2) { 00157 00158 // if (res[i]<approx.eps) res[i]=0; 00159 // else if (res[i]>1-approx.eps) res[i]=1; 00160 00161 // if (res[i+1]<approx.eps) res[i+1]=0; 00162 // else if (res[i+1]>1-approx.eps) res[i+1]=1; 00163 00164 Point * p = F.new_point(bx, res[i], res[i+1]); 00165 if (F.is_valid(*p, bx)) sol<< p; 00166 // else delete p; 00167 } 00168 } 00169 //-------------------------------------------------------------------- 00170 template<class Polynomial> 00171 static void intersection(Seq<Point* >& sol, 00172 const Polynomial& f1, 00173 const Polynomial& f2, const BoundingBox & bx) { 00174 00175 typedef polynomial< double, with<Bernstein> > MultivariateDenseBernstein; 00176 MultivariateDenseBernstein p1, p2; 00177 00178 00179 let::assign(p1.rep(), f1.rep() ); 00180 let::assign(p2.rep(), f2.rep() ); 00181 00182 Seq<MultivariateDenseBernstein> sys; 00183 sys<<p1<<p2; 00184 00185 solver<double, ProjRd<SBD_RDRDL> > slv; 00186 std::vector<double> res; 00187 slv.solve_bernstein(res,sys); 00188 00189 double x_sc= (bx.xmax()-bx.xmin()), y_sc= (bx.ymax()-bx.ymin()); 00190 for(unsigned i=0;i<res.size();i+=2) 00191 { 00192 sol << new_point(bx.xmin()+res[i]*x_sc, bx.ymin()+res[i+1]*y_sc, 0.0); 00193 } 00194 } 00195 //-------------------------------------------------------------------- 00196 template<class Polynomial> 00197 static void extremal(Seq<Point* >& sol, 00198 const Polynomial& pol, const BoundingBox& b) { 00199 00200 typedef polynomial< double, with<Bernstein> > MultivariateDenseBernstein; 00201 00202 // typedef Polynomial MultivariateDenseBernstein; 00203 00204 00205 typedef polynomial< GMP::rational, with<Bernstein> > MultivariateDenseBernsteinQ; 00206 00207 Seq<mmx::GMP::rational> bx; 00208 bx<<as<mmx::GMP::rational>(b.xmin()); 00209 bx<<as<mmx::GMP::rational>(b.xmax()); 00210 bx<<as<mmx::GMP::rational>(b.ymin()); 00211 bx<<as<mmx::GMP::rational>(b.ymax()); 00212 00213 00214 //tensor::bernstein<mmx::GMP::rational> P(pol.rep(),bx); 00215 //typename Polynomial::Scalar mx = as<typename Polynomial::Scalar>(array::max_abs(P)); 00216 //Polynomial Pol=pol/mx, dxpol = diff(Pol,0), dypol = diff(Pol,1); 00217 00218 Polynomial dxpol = diff(pol,0), dypol = diff(pol,1); 00219 tensor::bernstein<mmx::GMP::rational> 00220 dxP(dxpol.rep(),bx),dyP(dypol.rep(),bx); 00221 00222 MultivariateDenseBernstein dxp,dyp; 00223 let::assign(dxp.rep(), dxP); 00224 let::assign(dyp.rep(), dyP); 00225 00226 Seq<MultivariateDenseBernstein> sys; 00227 // Seq<MultivariateDenseBernsteinQ> sys; 00228 sys<<dxp<<dyp; 00229 00230 solver<double, ProjRd<SBD_RDRDL> > slv; 00231 00232 std::vector<double> res; 00233 slv.solve_bernstein(res,sys); 00234 00235 double x_sc= (b.xmax()-b.xmin()), y_sc= (b.ymax()-b.ymin()); 00236 for(unsigned i=0;i<res.size();i+=2) { 00237 sol << new_point(b.xmin()+res[i]*x_sc, b.ymin()+res[i+1]*y_sc, 0.0); 00238 } 00239 } 00240 //-------------------------------------------------------------------- 00241 template<class Polynomial> 00242 static void singular(Seq<Point* >& sol, 00243 const Polynomial& pol, const BoundingBox& b) { 00244 00245 typedef polynomial< double, with<Bernstein> > MultivariateDenseBernstein; 00246 typedef polynomial< GMP::rational, with<Bernstein> > MultivariateDenseBernsteinQ; 00247 00248 Seq<mmx::GMP::rational> bx; 00249 bx<<as<mmx::GMP::rational>(b.xmin()); 00250 bx<<as<mmx::GMP::rational>(b.xmax()); 00251 bx<<as<mmx::GMP::rational>(b.ymin()); 00252 bx<<as<mmx::GMP::rational>(b.ymax()); 00253 00254 Polynomial dxpol = diff(pol,0), dypol = diff(pol,1); 00255 tensor::bernstein<mmx::GMP::rational> 00256 P(pol.rep(),bx), dxP(dxpol.rep(),bx),dyP(dypol.rep(),bx); 00257 00258 MultivariateDenseBernstein p,dxp,dyp; 00259 let::assign(p.rep() , P); 00260 let::assign(dxp.rep(), dxP); 00261 let::assign(dyp.rep(), dyP); 00262 00263 Seq<MultivariateDenseBernstein> sys; 00264 sys<<p<<dxp<<dyp; 00265 00266 solver<double, ProjRd<SBD_RDRDL> > slv; 00267 // solver<ring<double,Bernstein>, ProjRd<SBD_RDRDL> >::eps=1e-10; 00268 00269 std::vector<double> res; 00270 slv.solve_bernstein(res,sys); 00271 00272 double x_sc= (b.xmax()-b.xmin()), y_sc= (b.ymax()-b.ymin()); 00273 for(unsigned i=0;i<res.size();i+=2) { 00274 sol << new_point(b.xmin()+res[i]*x_sc, b.ymin()+res[i+1]*y_sc, 0.0); 00275 } 00276 } 00277 00278 //-------------------------------------------------------------------- 00279 template<class MultivariateDenseBernstein> static 00280 void common_edge_point(Seq<Point *>& lp, 00281 const MultivariateDenseBernstein & p, 00282 const BoxFace & E, 00283 const BoundingBox & bx1, 00284 const BoundingBox & bx2 ) { 00285 MultivariateDenseBernstein f; 00286 00287 tensor::face(f,p,E.cvar(0),E.side(0)); 00288 00289 polynomial<double, with<Bernstein> > dw(1,f.size()-1), up(1,f.size()-1); 00290 for(unsigned i=0; i<f.size();i++) { 00291 up[i]= upper(f[i]); 00292 dw[i]= lower(f[i]); 00293 //up[i]=dw[i]=f[i]; 00294 } 00295 00296 double 00297 U = std::max( E.lower(bx1), E.lower(bx2) ) , 00298 V = std::min( E.upper(bx1), E.upper(bx2) ) ; 00299 00300 Seq<double> sol; 00301 00302 solver< double, Sleeve<Approximate> >::solve(sol,dw,up,U,V); 00303 00304 sol.sort();// sort from smaller to bigger 00305 00306 Approximate approx; 00307 for(unsigned i=0;i<sol.size(); i++) 00308 { 00309 lp<< E.new_point(bx1,sol[i]); 00310 } 00311 } 00312 }; 00313 //==================================================================== 00314 # define REF REF_OF(V) 00315 TMPL box_face<C,REF> SELF::north_face(1,1); 00316 TMPL box_face<C,REF> SELF::south_face(1,0); 00317 TMPL box_face<C,REF> SELF::west_face (0,0); 00318 TMPL box_face<C,REF> SELF::east_face (0,1); 00319 TMPL box_face<C,REF> SELF::front_face(2,1); 00320 TMPL box_face<C,REF> SELF::back_face(2,0); 00321 00322 // 2D box edges; 00323 TMPL box_face<C,REF> SELF::north_edge(1,1,2,0); 00324 TMPL box_face<C,REF> SELF::south_edge(1,0,2,0); 00325 TMPL box_face<C,REF> SELF::west_edge(0,0,2,0); 00326 TMPL box_face<C,REF> SELF::east_edge(0,1,2,0); 00327 00328 TMPL box_face<C,REF> SELF::front_edge(2,1,0,0); 00329 TMPL box_face<C,REF> SELF::back_edge (2,0,0,0); 00330 00331 // 3D box edges; 00332 TMPL box_face<C,REF> SELF::north_back_edge (1,1,2,0); 00333 TMPL box_face<C,REF> SELF::south_back_edge (1,0,2,0); 00334 TMPL box_face<C,REF> SELF::west_back_edge (0,0,2,0); 00335 TMPL box_face<C,REF> SELF::east_back_edge (0,1,2,0); 00336 00337 TMPL box_face<C,REF> SELF::north_front_edge(1,1,2,1); 00338 TMPL box_face<C,REF> SELF::south_front_edge(1,0,2,1); 00339 TMPL box_face<C,REF> SELF::west_front_edge (0,0,2,1); 00340 TMPL box_face<C,REF> SELF::east_front_edge (0,1,2,1); 00341 00342 TMPL box_face<C,REF> SELF::north_west_edge (0,0,1,1); 00343 TMPL box_face<C,REF> SELF::south_west_edge (0,0,1,0); 00344 TMPL box_face<C,REF> SELF::north_east_edge (0,1,1,1); 00345 TMPL box_face<C,REF> SELF::south_east_edge (0,1,1,0); 00346 00347 //=========================================================================== 00348 } //namespace shape 00349 } //namespace mmx 00350 00351 # undef TMPL 00352 # undef SELF 00353 # undef REF 00354 # undef BoxFace 00355 # endif //shape_implicit_solver