tanatan.hpp Gecode Gecode::Float Gecode::Float::Trigonometric I0__PI_2I FloatVal(0,pi_half_upper()) POS X ((I0__PI_2I.in(X))?0:1) ATANINF_DOWN r.atan_down(aTanIv.min()) ATANSUP_UP r.atan_up(aTanIv.max()) I0__PI_2I FloatVal(0,pi_half_upper()) I0__PI_2I FloatVal(0,pi_half_upper()) /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *VincentBarichard<Vincent.Barichard@univ-angers.fr> * *Copyright: *VincentBarichard,2012 * *Lastmodified: *$Date:2013-02-0421:28:39+0100(Mon,04Feb2013)$by$Author:schulte$ *$Revision:13262$ * *ThisfileispartofGecode,thegenericconstraint *developmentenvironment: *http://www.gecode.org * *Permissionisherebygranted,freeofcharge,toanypersonobtaining *acopyofthissoftwareandassociateddocumentationfiles(the *"Software"),todealintheSoftwarewithoutrestriction,including *withoutlimitationtherightstouse,copy,modify,merge,publish, *distribute,sublicense,and/orsellcopiesoftheSoftware,andto *permitpersonstowhomtheSoftwareisfurnishedtodoso,subjectto *thefollowingconditions: * *Theabovecopyrightnoticeandthispermissionnoticeshallbe *includedinallcopiesorsubstantialportionsoftheSoftware. * *THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND, *EXPRESSORIMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOF *MERCHANTABILITY,FITNESSFORAPARTICULARPURPOSEAND *NONINFRINGEMENT.INNOEVENTSHALLTHEAUTHORSORCOPYRIGHTHOLDERSBE *LIABLEFORANYCLAIM,DAMAGESOROTHERLIABILITY,WHETHERINANACTION *OFCONTRACT,TORTOROTHERWISE,ARISINGFROM,OUTOFORINCONNECTION *WITHTHESOFTWAREORTHEUSEOROTHERDEALINGSINTHESOFTWARE. * */ namespaceGecode{namespaceFloat{namespaceTrigonometric{ /* *ATanprojectionfunction * */ template<classV> void aTanProject(Rounding&r,constV&aTanIv,FloatNum&iv_min,FloatNum&iv_max,int&n_min,int&n_max){ #defineI0__PI_2IFloatVal(0,pi_half_upper()) #definePOS(X)((I0__PI_2I.in(X))?0:1) #defineATANINF_DOWNr.atan_down(aTanIv.min()) #defineATANSUP_UPr.atan_up(aTanIv.max()) //0<=>in[0;PI/2] //1<=>in[PI/2;PI] switch(POS(iv_min)) { case0: if(r.tan_down(iv_min)>aTanIv.max()){n_min++;iv_min=ATANINF_DOWN;} elseif(r.tan_up(iv_min)<aTanIv.min()){iv_min=ATANINF_DOWN;} break; case1: if(r.tan_down(iv_min)>aTanIv.max()){n_min+=2;iv_min=ATANINF_DOWN;} elseif(r.tan_up(iv_min)<aTanIv.min()){n_min++;iv_min=ATANINF_DOWN;} break; default: GECODE_NEVER; break; } //0<=>in[0;PI/2] //1<=>in[PI/2;PI] switch(POS(iv_max)) { case0: if(r.tan_down(iv_max)>aTanIv.max()){iv_max=ATANSUP_UP;} elseif(r.tan_up(iv_max)<aTanIv.min()){n_max--;iv_max=ATANSUP_UP;} break; case1: if(r.tan_down(iv_max)>aTanIv.max()){n_max++;iv_max=ATANSUP_UP;} elseif(r.tan_up(iv_max)<aTanIv.min()){iv_max=ATANSUP_UP;} break; default: GECODE_NEVER; break; } #undefATANINF_DOWN #undefATANSUP_UP #undefPOS #undefI0__PI_2I } /* *Boundsconsistenttangentoperator * */ template<classA,classB> forceinline Tan<A,B>::Tan(Homehome,Ax0,Bx1) :MixBinaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND>(home,x0,x1){} template<classA,classB> ExecStatus Tan<A,B>::post(Homehome,Ax0,Bx1){ if(same(x0,x1)){ #defineI0__PI_2IFloatVal(0,pi_half_upper()) if(I0__PI_2I.in(x0.max()))GECODE_ME_CHECK(x0.lq(home,0)); if(I0__PI_2I.in(-x0.min()))GECODE_ME_CHECK(x0.gq(home,0)); #undefI0__PI_2I } (void)new(home)Tan<A,B>(home,x0,x1); returnES_OK; } template<classA,classB> forceinline Tan<A,B>::Tan(Space&home,boolshare,Tan<A,B>&p) :MixBinaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND>(home,share,p){} template<classA,classB> Actor* Tan<A,B>::copy(Space&home,boolshare){ returnnew(home)Tan<A,B>(home,share,*this); } template<classA,classB> ExecStatus Tan<A,B>::propagate(Space&home,constModEventDelta&){ Roundingr; intn_min=static_cast<int>(r.div_up(x0.min()+pi_half_upper(),pi_upper())); intn_max=static_cast<int>(r.div_up(x0.max()+pi_half_upper(),pi_upper())); if(same(x0,x1)){ #defineI0__PI_2IFloatVal(0,pi_half_upper()) if(I0__PI_2I.in(x0.max()))GECODE_ME_CHECK(x0.lq(home,0)); if(I0__PI_2I.in(-x0.min()))GECODE_ME_CHECK(x0.gq(home,0)); #undefI0__PI_2I n_min=static_cast<int>(r.div_up(x0.min(),pi_upper())); n_max=static_cast<int>(r.div_up(x0.max(),pi_upper())); FloatNumx0_min; FloatNumx0_max; FloatNumt=x0.min(); do{ x0_min=t; if(r.tan_down(x0_min)>x0_min)n_min++; t=r.add_down(r.mul_up(n_min,pi_upper()),r.tan_down(x0_min)); }while(t>x0_min); t=r.sub_down(r.mul_up(2*n_max,pi_upper()),x0.max()); do{ x0_max=t; if(r.tan_down(x0_max)<x0_max)n_max--; t=r.add_up(r.mul_up(n_max,pi_upper()),r.tan_up(x0_max)); }while(t>x0_max); x0_max=r.sub_up(r.mul_up(2*n_max,pi_upper()),x0_max); if(x0_min>x0_max)returnES_FAILED; GECODE_ME_CHECK(x0.eq(home,FloatVal(x0_min,x0_max))); }else{ GECODE_ME_CHECK(x1.eq(home,tan(x0.val()))); n_min=static_cast<int>(r.div_up(x0.min(),pi_upper())); n_max=static_cast<int>(r.div_up(x0.max(),pi_upper())); if(x0.min()<0)n_min--; if(x0.max()<0)n_max--; FloatNumiv_min=r.sub_down(x0.min(),r.mul_down(n_min,pi_upper())); FloatNumiv_max=r.sub_up(x0.max(),r.mul_down(n_max,pi_upper())); aTanProject(r,x1,iv_min,iv_max,n_min,n_max); FloatNumn_iv_min=r.add_down(iv_min,r.mul_down(n_min,pi_upper())); FloatNumn_iv_max=r.add_up(iv_max,r.mul_down(n_max,pi_upper())); if(n_iv_min>n_iv_max)returnES_FAILED; GECODE_ME_CHECK(x0.eq(home,FloatVal(n_iv_min,n_iv_max))); GECODE_ME_CHECK(x1.eq(home,tan(x0.val())));//Redotanbecausewithx0reduction,sinmaybemoreaccurate } return(x0.assigned())?home.ES_SUBSUMED(*this):ES_FIX; } /* *Boundsconsistentarctangentoperator * */ template<classA,classB> forceinline ATan<A,B>::ATan(Homehome,Ax0,Bx1) :MixBinaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND>(home,x0,x1){} template<classA,classB> ExecStatus ATan<A,B>::post(Homehome,Ax0,Bx1){ if(same(x0,x1)){ GECODE_ME_CHECK(x0.eq(home,0.0)); }else{ (void)new(home)ATan<A,B>(home,x0,x1); } returnES_OK; } template<classA,classB> forceinline ATan<A,B>::ATan(Space&home,boolshare,ATan<A,B>&p) :MixBinaryPropagator<A,PC_FLOAT_BND,B,PC_FLOAT_BND>(home,share,p){} template<classA,classB> Actor* ATan<A,B>::copy(Space&home,boolshare){ returnnew(home)ATan<A,B>(home,share,*this); } template<classA,classB> ExecStatus ATan<A,B>::propagate(Space&home,constModEventDelta&){ GECODE_ME_CHECK(x1.eq(home,atan(x0.domain()))); GECODE_ME_CHECK(x0.eq(home,tan(x1.domain()))); return(x0.assigned()&&x1.assigned())?home.ES_SUBSUMED(*this):ES_FIX; } }}} //STATISTICS:float-prop