arith2.hpp gecode/third-party/boost/config.hpp gecode/third-party/boost/numeric/interval/detail/interval_prototype.hpp gecode/third-party/boost/numeric/interval/detail/test_input.hpp gecode/third-party/boost/numeric/interval/detail/bugs.hpp gecode/third-party/boost/numeric/interval/detail/division.hpp gecode/third-party/boost/numeric/interval/arith.hpp gecode/third-party/boost/numeric/interval/policies.hpp algorithm cassert gecode/third-party/boost/config/no_tr1/cmath.hpp /usr/include/gecode/third-party/boost/numeric/interval/transc.hpp /usr/include/gecode/third-party/boost/numeric/interval.hpp boost boost::numeric boost::numeric::interval_lib boost::numeric::interval_lib::detail /*Boostinterval/arith2.hpptemplateimplementationfile * *Thisheaderprovidessomeauxiliaryarithmetic *functions:fmod,sqrt,square,pov,inverseand *amulti-intervaldivision. * *Copyright2002-2003HervéBrönnimann,GuillaumeMelquiond,SylvainPion * *DistributedundertheBoostSoftwareLicense,Version1.0. *(SeeaccompanyingfileLICENSE_1_0.txtor *copyathttp://www.boost.org/LICENSE_1_0.txt) */ #ifndefBOOST_NUMERIC_INTERVAL_ARITH2_HPP #defineBOOST_NUMERIC_INTERVAL_ARITH2_HPP #include<gecode/third-party/boost/config.hpp> #include<gecode/third-party/boost/numeric/interval/detail/interval_prototype.hpp> #include<gecode/third-party/boost/numeric/interval/detail/test_input.hpp> #include<gecode/third-party/boost/numeric/interval/detail/bugs.hpp> #include<gecode/third-party/boost/numeric/interval/detail/division.hpp> #include<gecode/third-party/boost/numeric/interval/arith.hpp> #include<gecode/third-party/boost/numeric/interval/policies.hpp> #include<algorithm> #include<cassert> #include<gecode/third-party/boost/config/no_tr1/cmath.hpp> namespaceboost{ namespacenumeric{ template<classT,classPolicies>inline interval<T,Policies>fmod(constinterval<T,Policies>&x, constinterval<T,Policies>&y) { if(interval_lib::detail::test_input(x,y)) returninterval<T,Policies>::empty(); typenamePolicies::roundingrnd; typedeftypenameinterval_lib::unprotect<interval<T,Policies>>::typeI; Tconst&yb=interval_lib::user::is_neg(x.lower())?y.lower():y.upper(); Tn=rnd.int_down(rnd.div_down(x.lower(),yb)); return(constI&)x-n*(constI&)y; } template<classT,classPolicies>inline interval<T,Policies>fmod(constinterval<T,Policies>&x,constT&y) { if(interval_lib::detail::test_input(x,y)) returninterval<T,Policies>::empty(); typenamePolicies::roundingrnd; typedeftypenameinterval_lib::unprotect<interval<T,Policies>>::typeI; Tn=rnd.int_down(rnd.div_down(x.lower(),y)); return(constI&)x-n*I(y); } template<classT,classPolicies>inline interval<T,Policies>fmod(constT&x,constinterval<T,Policies>&y) { if(interval_lib::detail::test_input(x,y)) returninterval<T,Policies>::empty(); typenamePolicies::roundingrnd; typedeftypenameinterval_lib::unprotect<interval<T,Policies>>::typeI; Tconst&yb=interval_lib::user::is_neg(x)?y.lower():y.upper(); Tn=rnd.int_down(rnd.div_down(x,yb)); returnx-n*(constI&)y; } namespaceinterval_lib{ template<classT,classPolicies>inline interval<T,Policies>division_part1(constinterval<T,Policies>&x, constinterval<T,Policies>&y,bool&b) { typedefinterval<T,Policies>I; b=false; if(detail::test_input(x,y)) returnI::empty(); if(zero_in(y)) if(!user::is_zero(y.lower())) if(!user::is_zero(y.upper())) returndetail::div_zero_part1(x,y,b); else returndetail::div_negative(x,y.lower()); else if(!user::is_zero(y.upper())) returndetail::div_positive(x,y.upper()); else returnI::empty(); else returndetail::div_non_zero(x,y); } template<classT,classPolicies>inline interval<T,Policies>division_part2(constinterval<T,Policies>&x, constinterval<T,Policies>&y,boolb=true) { if(!b)returninterval<T,Policies>::empty(); returndetail::div_zero_part2(x,y); } template<classT,classPolicies>inline interval<T,Policies>multiplicative_inverse(constinterval<T,Policies>&x) { typedefinterval<T,Policies>I; if(detail::test_input(x)) returnI::empty(); Tone=static_cast<T>(1); typenamePolicies::roundingrnd; if(zero_in(x)){ typedeftypenamePolicies::checkingchecking; if(!user::is_zero(x.lower())) if(!user::is_zero(x.upper())) returnI::whole(); else returnI(checking::neg_inf(),rnd.div_up(one,x.lower()),true); else if(!user::is_zero(x.upper())) returnI(rnd.div_down(one,x.upper()),checking::pos_inf(),true); else returnI::empty(); }else returnI(rnd.div_down(one,x.upper()),rnd.div_up(one,x.lower()),true); } namespacedetail{ template<classT,classRounding>inline Tpow_dn(constT&x_,intpwr,Rounding&rnd)//xandpwrarepositive { Tx=x_; Ty=(pwr&1)?x_:static_cast<T>(1); pwr>>=1; while(pwr>0){ x=rnd.mul_down(x,x); if(pwr&1)y=rnd.mul_down(x,y); pwr>>=1; } returny; } template<classT,classRounding>inline Tpow_up(constT&x_,intpwr,Rounding&rnd)//xandpwrarepositive { Tx=x_; Ty=(pwr&1)?x_:static_cast<T>(1); pwr>>=1; while(pwr>0){ x=rnd.mul_up(x,x); if(pwr&1)y=rnd.mul_up(x,y); pwr>>=1; } returny; } }//namespacedetail }//namespaceinterval_lib template<classT,classPolicies>inline interval<T,Policies>pow(constinterval<T,Policies>&x,intpwr) { BOOST_USING_STD_MAX(); usinginterval_lib::detail::pow_dn; usinginterval_lib::detail::pow_up; typedefinterval<T,Policies>I; if(interval_lib::detail::test_input(x)) returnI::empty(); if(pwr==0) if(interval_lib::user::is_zero(x.lower()) &&interval_lib::user::is_zero(x.upper())) returnI::empty(); else returnI(static_cast<T>(1)); elseif(pwr<0) returninterval_lib::multiplicative_inverse(pow(x,-pwr)); typenamePolicies::roundingrnd; if(interval_lib::user::is_neg(x.upper())){//[-2,-1] Tyl=pow_dn(static_cast<T>(-x.upper()),pwr,rnd); Tyu=pow_up(static_cast<T>(-x.lower()),pwr,rnd); if(pwr&1)//[-2,-1]^1 returnI(-yu,-yl,true); else//[-2,-1]^2 returnI(yl,yu,true); }elseif(interval_lib::user::is_neg(x.lower())){//[-1,1] if(pwr&1){//[-1,1]^1 returnI(-pow_up(static_cast<T>(-x.lower()),pwr,rnd),pow_up(x.upper(),pwr,rnd),true); }else{//[-1,1]^2 returnI(static_cast<T>(0),pow_up(maxBOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()),x.upper()),pwr,rnd),true); } }else{//[1,2] returnI(pow_dn(x.lower(),pwr,rnd),pow_up(x.upper(),pwr,rnd),true); } } template<classT,classPolicies>inline interval<T,Policies>sqrt(constinterval<T,Policies>&x) { typedefinterval<T,Policies>I; if(interval_lib::detail::test_input(x)||interval_lib::user::is_neg(x.upper())) returnI::empty(); typenamePolicies::roundingrnd; Tl=!interval_lib::user::is_pos(x.lower())?static_cast<T>(0):rnd.sqrt_down(x.lower()); returnI(l,rnd.sqrt_up(x.upper()),true); } template<classT,classPolicies>inline interval<T,Policies>square(constinterval<T,Policies>&x) { typedefinterval<T,Policies>I; if(interval_lib::detail::test_input(x)) returnI::empty(); typenamePolicies::roundingrnd; constT&xl=x.lower(); constT&xu=x.upper(); if(interval_lib::user::is_neg(xu)) returnI(rnd.mul_down(xu,xu),rnd.mul_up(xl,xl),true); elseif(interval_lib::user::is_pos(x.lower())) returnI(rnd.mul_down(xl,xl),rnd.mul_up(xu,xu),true); else returnI(static_cast<T>(0),(-xl>xu?rnd.mul_up(xl,xl):rnd.mul_up(xu,xu)),true); } namespaceinterval_lib{ namespacedetail{ template<classI>inline Iroot_aux(typenameI::base_typeconst&x,intk)//xandkarebiggerthanone { typedeftypenameI::base_typeT; Ttk(k); Iy(static_cast<T>(1),x,true); for(;;){ Ty0=median(y); Iyy=intersect(y,y0-(pow(I(y0,y0,true),k)-x)/(tk*pow(y,k-1))); if(equal(y,yy))returny; y=yy; } } template<classI>inline//xispositiveandkbiggerthanone typenameI::base_typeroot_aux_dn(typenameI::base_typeconst&x,intk) { typedeftypenameI::base_typeT; typedeftypenameI::traits_typePolicies; typenamePolicies::roundingrnd; Tone(1); if(x>one)returnroot_aux<I>(x,k).lower(); if(x==one)returnone; returnrnd.div_down(one,root_aux<I>(rnd.div_up(one,x),k).upper()); } template<classI>inline//xispositiveandkbiggerthanone typenameI::base_typeroot_aux_up(typenameI::base_typeconst&x,intk) { typedeftypenameI::base_typeT; typedeftypenameI::traits_typePolicies; typenamePolicies::roundingrnd; Tone(1); if(x>one)returnroot_aux<I>(x,k).upper(); if(x==one)returnone; returnrnd.div_up(one,root_aux<I>(rnd.div_down(one,x),k).lower()); } }//namespacedetail }//namespaceinterval_lib template<classT,classPolicies>inline interval<T,Policies>nth_root(interval<T,Policies>const&x,intk) { typedefinterval<T,Policies>I; if(interval_lib::detail::test_input(x))returnI::empty(); assert(k>0); if(k==1)returnx; typenamePolicies::roundingrnd; typedeftypenameinterval_lib::unprotect<I>::typeR; if(!interval_lib::user::is_pos(x.upper())){ if(interval_lib::user::is_zero(x.upper())){ Tzero(0); if(!(k&1)||interval_lib::user::is_zero(x.lower()))//[-1,0]^/2or[0,0] returnI(zero,zero,true); else//[-1,0]^/3 returnI(-interval_lib::detail::root_aux_up<R>(-x.lower(),k),zero,true); }elseif(!(k&1))//[-2,-1]^/2 returnI::empty(); else{//[-2,-1]^/3 returnI(-interval_lib::detail::root_aux_up<R>(-x.lower(),k), -interval_lib::detail::root_aux_dn<R>(-x.upper(),k),true); } } Tu=interval_lib::detail::root_aux_up<R>(x.upper(),k); if(!interval_lib::user::is_pos(x.lower())) if(!(k&1)||interval_lib::user::is_zero(x.lower()))//[-1,1]^/2or[0,1] returnI(static_cast<T>(0),u,true); else//[-1,1]^/3 returnI(-interval_lib::detail::root_aux_up<R>(-x.lower(),k),u,true); else//[1,2] returnI(interval_lib::detail::root_aux_dn<R>(x.lower(),k),u,true); } }//namespacenumeric }//namespaceboost #endif//BOOST_NUMERIC_INTERVAL_ARITH2_HPP