realroot_doc 0.1.1
|
00001 #include <stack> 00002 #include <fstream> 00003 #include <string> 00004 #include <vector> 00005 00006 #include <realroot/Interval.hpp> 00007 #include <realroot/polynomial_bernstein.hpp> 00008 #include <realroot/polynomial_tensor.hpp> 00009 #include <realroot/tensor_convert.hpp> 00010 00011 #pragma once 00012 00013 #define REP poly.rep() 00014 #define SIZE poly.size() 00015 #define TODOUBLE as<double> 00016 00017 using namespace mmx; 00018 00019 00021 //BOX structure 00022 template<class C> 00023 struct domain 00024 { 00025 typedef Interval<C> int_t; 00026 typedef Seq< Interval<C> > seqint_t; 00027 typedef std::vector<C> vec_t; 00028 00029 //CONSTRUCTORS 00030 00031 seqint_t I; 00032 00033 00034 domain( ){ }; 00035 domain( int n ){ int_t unit( C(0),C(1) ); for(int i = 0; i < n; i++){I<<unit;}; }; 00036 domain( int_t intxy ){ I<<intxy<<intxy; }; 00037 domain( int_t intx , int_t inty ){ I<<intx<<inty; }; 00038 00039 //FCTS 00040 C dim(){ 00041 int d=0; 00042 for(unsigned i = 0; i < I.size(); i++){d++;} 00043 return(d); 00044 } 00045 00046 00047 C diam(){ 00048 C d=C(0); 00049 for(unsigned i = 0; i < I.size(); i++){ 00050 d +=I[i].size()*I[i].size();} 00051 return(sqrt(d)); 00052 } 00053 00054 vec_t llc( ) 00055 {vec_t v(I.size()); 00056 for(unsigned i = 0; i < I.size(); i++){ 00057 v[i]= I[i].m;}; 00058 return v; 00059 }; 00060 00061 vec_t urc( ) 00062 { vec_t v(I.size()); 00063 for(unsigned i = 0; i < I.size(); i++){ 00064 v[i]= I[i].M;}; 00065 return v; 00066 }; 00067 00068 vec_t center( ) 00069 { vec_t v(I.size()); 00070 for(unsigned i = 0; i < I.size(); i++){ 00071 v[i]= I[i].center();}; 00072 return v; 00073 }; 00074 00075 00076 Seq<C> delta( ) 00077 {Seq<C> d; 00078 for(unsigned i = 0; i < I.size(); i++){ 00079 d<<I[i].size();} 00080 return(d); 00081 }; 00082 00083 void print(int digits) 00084 { std::cout.precision(digits); 00085 std::cout<<"["<< TODOUBLE(I[0].m)<<", "<< TODOUBLE(I[0].M)<<"]x["<< TODOUBLE(I[1].m)<<", "<< TODOUBLE(I[1].M)<<"],"<<std::endl; 00086 // std::cout << "box midpt: (" <<(llc()[0]+urc()[0])/C(2)<<","<<(llc()[1]+urc()[1])/C(2)<<")"<<std::endl; 00087 std::cout << "diam: " <<diam()<<std::endl; 00088 }; 00089 00090 00091 void split(domain<C> * ch) 00092 { 00093 00094 C cx=I[0].center() ; 00095 C cy=I[1].center() ; 00096 00097 Interval<C> Ixl(I[0].m , cx), Ixr(cx , I[0].M), Iyl(I[1].m , cy), Iyr(cy, I[1].M); 00098 00099 00100 ch[0]=domain(Ixl,Iyl); 00101 ch[1]=domain(Ixr,Iyl); 00102 ch[2]=domain(Ixl,Iyr); 00103 ch[3]=domain(Ixr,Iyr); 00104 };/*subdivison of a box*/ 00105 /* 00106 Seq< vec_t > cornerpts( ) 00107 { Seq< vec_t > cp; 00108 cp<<vec(I[0].m,I[1].m)<<vec(I[0].M,I[1].m)<<vec(I[0].m,I[1].M)<<vec(I[0].M,I[1].M); 00109 return cp; 00110 };*/ 00111 00112 };//end of boxes 00113 00114 00116 //arc_rep structure 00117 00118 template<class C> 00119 struct arc_rep 00120 { 00121 00122 typedef C coeff_t; 00123 typedef std::vector<coeff_t> vec_t; 00124 typedef Seq<coeff_t> seq_t; 00125 typedef domain<coeff_t> box_t; 00126 typedef polynomial< coeff_t ,with<Bernstein> > bernstein_t; 00127 typedef polynomial< coeff_t ,with<MonomialTensor> > monom_t; 00128 00129 00130 00131 vec_t pts[3]; 00132 00133 //CONSTRUCTORS 00134 00135 arc_rep(){pts[0]=vec_t(); pts[1]=vec_t(); pts[2]=vec_t();}; 00136 00137 arc_rep( vec_t p0, vec_t p1, vec_t p2){ 00138 if(p0.size()!=0 && p1.size()!=0 && p2.size()!=0 ) 00139 {if(matrat(v_minus(p1,p0),v_minus(p2,p0))[1]> coeff_t(0)){pts[0]=p2; pts[1]=p1; pts[2]=p0;} 00140 else{pts[0]=p0; pts[1]=p1; pts[2]=p2;}; }else{pts[0]=p0; pts[1]=p1; pts[2]=p2;} 00141 }; 00142 00143 arc_rep( vec_t p[3]){ 00144 if(p[0].size()!=0 && p[1].size()!=0 && p[2].size()!=0 ){ 00145 if(matrat( v_minus(p[1],p[0]),v_minus(p[2],p[0]) )[1]> coeff_t(0)){pts[0]=p[2]; pts[1]=p[1]; pts[2]=p[0];} 00146 else{pts[0]=p[0]; pts[1]=p[1]; pts[2]=p[2];}; }else{pts[0]=p[0]; pts[1]=p[1]; pts[2]=p[2];} 00147 }; 00148 00149 //FCTS 00150 00151 00152 coeff_t weight() 00153 {return(dot(v_minus(pts[0],pts[1]),v_minus(pts[1],pts[2]))/ 00154 (v_length(v_minus(pts[1],pts[2]))*v_length(v_minus(pts[1],pts[0]))));}; 00155 00156 00157 vec_t midc(){ 00158 vec_t pp=v_minus(pts[0],pts[2]); pp=rotl(pp); 00159 vec_t m=v_mul(coeff_t( sign(dot(pp, v_minus(pts[1],pts[2]) ))),pp); 00160 coeff_t w=weight(); 00161 00162 vec_t d; 00163 if( (coeff_t(1)-w*w) > coeff_t(0) && w!=coeff_t(0) ){ 00164 d=v_plus(v_div(v_plus(pts[0],pts[2]),coeff_t(2)),v_div(v_mul(coeff_t(sqrt( coeff_t(1)-w*w )),m),(coeff_t(2)*w))); } 00165 else { 00166 d=v_div(v_plus(pts[0],pts[2]),coeff_t(2)); }; 00167 return(d); 00168 00169 };/*middle control point in bb rep.*/ 00170 00171 00172 00173 seq_t arc_eq(){ 00174 00175 00176 vec_t cvec=matrat(v_minus(pts[0],pts[1]),v_minus(pts[2],pts[1])); 00177 00178 coeff_t eh2=cvec[1]; 00179 coeff_t ehx=dot(cvec, vec(pts[2][1]-pts[0][1],(coeff_t)(-1)*pts[0][0]-pts[2][0])); 00180 coeff_t ehy=dot(cvec, vec(pts[0][0]-pts[2][0],(coeff_t)(-1)*pts[0][1]-pts[2][1])); 00181 coeff_t ehc=dot(cvec, vec(pts[0][1]*pts[2][0]-pts[0][0]*pts[2][1], 00182 pts[0][0]*pts[2][0]+pts[0][1]*pts[2][1])); 00183 00184 seq_t eh; eh<<eh2<<ehx<<ehy<<ehc; 00185 00186 return(eh); 00187 }; /*coeff vector of monom rep: eh2*(x^2+y^2)+ehx*x+ehy*y+ehc=0*/ 00188 00189 00190 00191 vec_t critpt(int var){ 00192 00193 vec_t pt; 00194 Seq<coeff_t> coeffx,coeffy,wvec; 00195 pt=vec(coeff_t(-1),coeff_t(-1)); 00196 coeffx<<pts[0][0]<< midc()[0]*weight()<< pts[2][0]; 00197 coeffy<<pts[0][1]<< midc()[1]*weight()<<pts[2][1]; 00198 wvec<<coeff_t(1)<< weight()<<coeff_t(1); 00199 coeff_t t, cx,cy,w; 00200 00201 if (var==0 && (coeffx[2]-coeffx[0])!=0) 00202 { 00203 t=(coeffx[0]-coeffx[1])/(coeffx[2]-coeffx[0]); 00204 } 00205 else if (var==1 && (coeffy[2]-coeffy[0])!=0) 00206 { 00207 t=(coeffy[0]-coeffy[1])/(coeffy[2]-coeffy[0]); 00208 }; 00209 00210 if(is_unit1(t)){ 00211 tensor::eval(cx,seq2b(coeffx).rep(),t); 00212 tensor::eval(cy,seq2b(coeffy).rep(),t); 00213 tensor::eval(w,seq2b(wvec).rep(),t); 00214 pt=vec( cx/w , cy/w ); 00215 } 00216 // std::cout <<pt<<std::endl; 00217 return(pt); 00218 }; /*tang. pt in var*/ 00219 00220 00221 arc_rep<coeff_t> offset(coeff_t r){ 00222 vec_t newp[3]; 00223 Seq<coeff_t> mo, ehrat; 00224 int i;unsigned j; 00225 vec_t pp=rotl(v_minus(pts[0],pts[2])); 00226 00227 coeff_t l=v_length(pp); 00228 coeff_t w=weight(); 00229 00230 for( i=0; i<3; i++){newp[i]=vec_t(); }; 00231 arc_rep<coeff_t> ncirc(newp); 00232 if( l!=coeff_t(0) ){ 00233 if( w==coeff_t(1)){ for( i=0; i<3; i++){ newp[i]=v_plus(pts[i],v_mul(r/l,pp)); } }//case of a quarter of a circle 00234 else if ( 00235 //( coeff_t(1)-w*w )>coeff_t(0) && 00236 ( r + l/(coeff_t(2)*sqrt( coeff_t(1)-w*w ) )) > coeff_t(0) 00237 && v_length( v_minus(pts[1],v_plus(pts[0],pts[2])) )!=coeff_t(0) ) 00238 { 00239 00240 newp[0]=v_plus(pts[0],v_mul(coeff_t(2)*r/l, 00241 rotl( v_minus(v_minus(v_mul((coeff_t(1)+w),pts[1]),v_mul((w+ coeff_t(0.5)),pts[0])), 00242 v_div(pts[2],coeff_t(2)) 00243 ) 00244 ) 00245 ) 00246 ); 00247 00248 newp[1]=v_plus(pts[1], 00249 v_mul(r/v_length(v_minus(pts[1],v_div(v_plus(pts[0],pts[2]),coeff_t(2)))), 00250 v_minus(v_minus(pts[1],v_div(pts[0],coeff_t(2))),v_div(pts[2],coeff_t(2))) 00251 ) 00252 ); 00253 00254 newp[2]=v_minus(pts[2], 00255 v_mul(coeff_t(2)*r/l, 00256 rotl(v_minus(v_minus(v_mul((coeff_t(1)+w),pts[1]),v_mul((w+(coeff_t)(0.5)),pts[2])), 00257 v_div(pts[0],coeff_t(2)) 00258 ) 00259 ) 00260 ) 00261 ); 00262 }; 00263 00264 //std::cout <<"newp0: "<<newp[0]<<" "<<newp[1]<<" "<<newp[2]<<std::endl; 00265 ncirc=arc_rep<coeff_t>(newp); 00266 if(is_arc(ncirc)){ 00267 Seq<vec_t> isp; 00268 ehrat=ncirc.arc_eq(); 00269 mo=solve2(ehrat[0],ehrat[2],ehrat[3]); 00270 for( j=0; j<2; j++){if(is_unit1(mo[j])){isp<<vec(coeff_t(0),mo[j]);};}; 00271 mo=solve2(ehrat[0],ehrat[2],ehrat[0]+ehrat[1]+ehrat[3]); 00272 for( j=0; j<2; j++){if(is_unit1(mo[j])){isp<<vec(coeff_t(1),mo[j]);};}; 00273 mo=solve2(ehrat[0],ehrat[1],ehrat[3]); 00274 for( j=0; j<2; j++){if(is_unit1(mo[j])){isp<<vec(mo[j],coeff_t(0));};}; 00275 mo=solve2(ehrat[0],ehrat[1],ehrat[0]+ehrat[2]+ehrat[3]); 00276 for( j=0; j<2; j++){if(is_unit1(mo[j])){isp<<vec(mo[j],coeff_t(1));};}; 00277 00278 if (isp.size()==0){newp[0]=vec_t(); }else{ 00279 newp[0]=isp[0]; 00280 for( j=1; j<isp.size(); j++) 00281 {if(v_length(v_minus(isp[j],pts[0]))<v_length(v_minus(newp[0],pts[0]))){newp[0]=isp[j];};}; 00282 }; 00283 00284 if (isp.size()==0){newp[2]=vec_t(); }else{ 00285 newp[2]=isp[0]; 00286 for( j=1; j<isp.size(); j++) 00287 {if(v_length(v_minus(isp[j],pts[2]))<v_length(v_minus(newp[2],pts[2]))){newp[2]=isp[j];};}; 00288 }; 00289 ncirc=arc_rep<coeff_t>(newp); 00290 // std::cout <<"newp1: "<<newp[0]<<" "<<newp[1]<<" "<<newp[2]<<std::endl; 00291 /*if (is_arc(ncirc)){ 00292 if( matrat(v_minus(newp[1],newp[0]),v_minus(newp[2],newp[0]))[1]>coeff_t(0) ) 00293 { vec_t u=newp[0]; newp[0]=newp[2]; newp[2]=u;}};*/ 00294 }; 00295 }; 00296 return( ncirc ); 00297 } /*offset arc computation(with precise endpoints) - OR OUTSIDE!!!*/ 00298 00299 };//end of struct arc_rep 00300 00301 00303 //box_rep structure 00304 00305 00306 template<class C> 00307 struct box_rep 00308 { 00309 00310 typedef C coeff_t; 00311 typedef std::vector<coeff_t> vec_t; 00312 typedef domain<coeff_t> box_t; 00313 typedef polynomial< coeff_t ,with<Bernstein> > bernstein_t; 00314 typedef polynomial< coeff_t ,with<MonomialTensor> > monom_t; 00315 typedef arc_rep<coeff_t> arc_rep_t; 00316 00317 00318 box_t box; 00319 bernstein_t poly; 00320 00321 //CONSTRUCTORS 00322 00323 box_rep(bernstein_t p){box_t bb; poly=p; box=bb; }; 00324 box_rep(bernstein_t p, box_t bb) 00325 { 00326 bernstein_t pa=p; 00327 00328 tensor::restrict(pa.rep(), 0 , bb.I[0].m , bb.I[0].M ); 00329 tensor::restrict(pa.rep(), 1 , bb.I[1].m , bb.I[1].M ); 00330 00331 poly=pa; 00332 box=bb; 00333 }; 00334 00335 00336 //FCTS 00337 00338 bool not_empty(){ 00339 00340 if( sign(min_coeff(poly))*sign(max_coeff(poly)) > 0 ){ 00341 return false; 00342 } 00343 else{ 00344 return true; 00345 } 00346 }/*detect empty boxes*/ 00347 00348 00349 bool edge_event(int var , int n){ 00350 00351 bernstein_t face_p; 00352 int event = 0; 00353 00354 tensor::face(face_p, poly, var, n); 00355 00356 int stc = 0; 00357 00358 for(unsigned i = 0 ; i < face_p.size() ; i++){ 00359 if( stc*sign(face_p.rep()[i]) == -1 ){ 00360 stc = sign(face_p.rep()[i]); event++; 00361 } 00362 else if ( stc == 0 && sign(face_p.rep()[i])!=0 ){ 00363 stc = sign(face_p.rep()[i]); 00364 }; 00365 } 00366 if(event==1){return true;}else{return false;}; 00367 }/*edge event along ONE edge*/ 00368 00369 00370 int first_nonzero(bernstein_t list, int e){ 00371 00372 int elem =0; 00373 int n = list.size(); 00374 int j; 00375 00376 for(int i = 0; i < n ; i++){ 00377 if( e==0 ){ j=i; }else{j=n-i-1;} 00378 if( coeff_t(0)!=(list[j]) ){ 00379 elem=sign(list[j]); 00380 break; 00381 } 00382 } 00383 return elem; 00384 00385 } 00386 00387 00388 bool corner_event(int c1, int c2){ 00389 vec_t evc=vec(coeff_t(c1),coeff_t(c2)); 00390 coeff_t v; 00391 eval(v, poly.rep(), evc ); 00392 bernstein_t face_p, face_q; 00393 00394 if ( is_small(v) ){ 00395 tensor::face(face_p, poly, 0, c2); 00396 tensor::face(face_q, poly, 1, c1); 00397 00398 if (first_nonzero(face_p, c1)*first_nonzero(face_q, c2) < 0){return true; }else{ return false; }; 00399 00400 }else{ return false;}; 00401 } 00402 00403 00404 Seq<vec_t>event_list(){ 00405 Seq<vec_t> elist; 00406 if(edge_event( 0, 0)){elist<<vec(coeff_t(0),coeff_t(0))<<vec(coeff_t(1),coeff_t(0));} 00407 if(edge_event( 0, 1)){elist<<vec(coeff_t(0),coeff_t(1))<<vec(coeff_t(1),coeff_t(1));} 00408 if(edge_event( 1, 0)){elist<<vec(coeff_t(0),coeff_t(0))<<vec(coeff_t(0),coeff_t(1));} 00409 if(edge_event( 1, 1)){elist<<vec(coeff_t(1),coeff_t(0))<<vec(coeff_t(1),coeff_t(1));} 00410 00411 if(corner_event( 0, 0)){elist<<vec(coeff_t(0),coeff_t(0))<<vec_t();} 00412 if(corner_event( 0, 1)){elist<<vec(coeff_t(0),coeff_t(1))<<vec_t();} 00413 if(corner_event( 1, 0)){elist<<vec(coeff_t(1),coeff_t(0))<<vec_t();} 00414 if(corner_event( 1, 1)){elist<<vec(coeff_t(1),coeff_t(1))<<vec_t();} 00415 return elist; 00416 00417 } //boxes with single implicitly defined curve segment*/ 00418 00419 00420 coeff_t min_grad(){ 00421 00422 bernstein_t p0 = diff(poly,0); 00423 bernstein_t p1 = diff(poly,1); 00424 bernstein_t grad; 00425 bernstein_t gradx0 = p0; 00426 bernstein_t gradx1 = p1; 00427 00428 00429 mul(gradx0.rep(),p0.rep()); 00430 mul(gradx1.rep(),p1.rep()); 00431 add(grad.rep(),gradx0.rep(),gradx1.rep()); 00432 00433 return(min_coeff(grad)); 00434 } 00435 00436 00437 coeff_t max_eval(arc_rep_t circ){ 00438 bernstein_t neww, bxt, byt, bwt, num, polyco; 00439 monom_t monomp, newnom, xt, yt, wt; 00440 Seq<coeff_t> v; 00441 00442 v<<coeff_t(1)<<circ.weight()<<coeff_t(1); 00443 neww=seq2b( v ); 00444 v.clear(); 00445 00446 pow(neww,degree(poly,0)+degree(poly,1)); 00447 00448 v<<circ.pts[0][0]<<circ.midc()[0]*circ.weight()<<circ.pts[2][0]; 00449 bxt=seq2b(v); v.clear(); 00450 tensor::assign(xt.rep(),bxt.rep()); 00451 v<<circ.pts[0][1]<<circ.midc()[1]*circ.weight()<<circ.pts[2][1]; 00452 byt=seq2b(v); v.clear(); 00453 tensor::assign(yt.rep(),byt.rep()); 00454 v<<coeff_t(1)<<circ.weight()<<coeff_t(1); 00455 bwt=seq2b(v); v.clear(); 00456 tensor::assign(wt.rep(),bwt.rep()); 00457 00458 Seq<monom_t> paramv; paramv<<wt<<xt<<yt; 00459 00460 polyco=poly; 00461 tensor::assign(monomp.rep(),polyco.rep()); 00462 tensor::heval(newnom, monomp.rep(), paramv ); 00463 00464 let::assign(num.rep(),newnom.rep()); 00465 00466 return(abs_max_coeff(num)/min_coeff(neww)); 00467 00468 }; 00469 00470 00471 };//end of structure box_rep 00472 00473 00474 #include <realroot/fatarcs_fcts.hpp> 00475 00476 00477