Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

interval.h

Go to the documentation of this file.
00001 #ifndef _INTERVAL_H_
00002 #define _INTERVAL_H_
00003 
00004 #define FILIB_USE_MACROS 0
00005 #define FILIB_EXTENDED 1
00006 
00007 #include <iostream>
00008 #if FILIB_USE_MACROS
00009 #include <Interval.h>
00010 #else
00011 #include <interval/interval.hpp>
00012 #endif
00013 
00014 #if defined(INFINITY)
00015 #undef INFINITY
00016 #endif
00017 #define INFINITY filib::fp_traits_base<double>::infinity()
00018 
00019 #if defined(L_PI)
00020 #undef L_PI
00021 #endif
00022 #define L_PI filib::fp_traits_base<double>::l_pi()
00023 
00024 #if defined(U_PI)
00025 #undef U_PI
00026 #endif
00027 #define U_PI filib::fp_traits_base<double>::u_pi()
00028 
00029 //#define min(a,b) ((a)<(b)?(a):(b))
00030 //#define max(a,b) ((a)>(b)?(a):(b))
00031 #define sgn(x)   ((x)>0?1.:(x)<0?-1.:0.)
00032 #define is_integer(x) (rint((x))==(x)&&rint((x))<MAXINT&&rint((x))>-MAXINT)
00033 #define get_integer(x) ((int)rint((x)))
00034 
00035 //data type
00036 class interval;
00037 
00038 struct interval_st
00039 {
00040   double l,u;
00041 
00042   interval_st& operator=(const interval& __i);
00043 };
00044 
00045 #if FILIB_USE_MACROS
00046 class interval : public Interval
00047 #else
00048 class interval : public filib::interval<>
00049 #endif
00050 {
00051 private:
00052 #if FILIB_USE_MACROS
00053   typedef Interval __Base;
00054 #else
00055   typedef filib::interval<> __Base;
00056 #endif
00057 
00058 public:
00059   interval(const double& lo, const double& up) : __Base(lo,up) {}
00060 
00061   interval(const double& __d = 0) : __Base(__d) {}
00062   
00063   interval(const int& __d) : __Base(__d+0.) {}
00064   interval(const unsigned int& __d) : __Base(__d+0.) {}
00065   interval(const long int& __d) : __Base(__d+0.) {}
00066   interval(const unsigned long int& __d) : __Base(__d+0.) {}
00067 
00068   interval(const __Base& __i) : __Base(__i) {}
00069 
00070   interval(const interval& __i) : __Base(__i) {}
00071 
00072   interval(const interval_st& __i) : __Base(__i.l, __i.u) {}
00073   
00074   //i.set(a,b) sets i to [a,b]
00075   void set(double lo, double up)
00076   {
00077     *this = interval(lo,up);
00078   }
00079 
00080   bool empty() const { return __Base::isEmpty(); }
00081   bool is_thin() const { return __Base::isPoint(); }
00082   bool is_unbounded_below() const { return inf() == -INFINITY; }
00083   bool is_unbounded_above() const { return sup() == INFINITY; }
00084   bool is_entire() const { return inf() == -INFINITY && sup() == INFINITY; }
00085   bool is_bounded() const
00086         { return !is_unbounded_below() && !is_unbounded_above(); }
00087 
00088   double rel_width() const { return __Base::relDiam(); }
00089 
00090   // i.intersect(j) intersects i with j
00091   interval& intersect(const interval& __i)
00092   {
00093     interval help(__Base::intersect(__i));
00094     return *this = help;
00095   }
00096 
00097   interval& hulldiff(const interval& __i)
00098   {
00099     if(subset(__i))
00100       *this = EMPTY();
00101     else if(!superset(__i))
00102     {
00103       if(__i.contains(inf()))
00104         *this = interval(__i.sup(), sup());
00105       else
00106         *this = interval(inf(), __i.inf());
00107     }
00108     return *this;
00109   }
00110 
00111   bool contains(const interval& __i) const
00112   {
00113     if(inf() <= __i.inf() && sup() >= __i.sup())
00114       return true;
00115     else
00116       return false;
00117   }
00118 
00119   void setpair(double& __l, double& __u) const { __l = inf(); __u = sup(); }
00120 
00121   interval& operator=(const double& __d) { return *this = interval(__d); }
00122   interval& operator=(const int& __d) { return *this = interval(__d); }
00123   interval& operator=(const unsigned int& __d) { return *this = interval(__d); }
00124   interval& operator=(const long int& __d) { return *this = interval(__d); }
00125   interval& operator=(const unsigned long int& __d)
00126         { return *this = interval(__d); }
00127 
00128   interval& ipow(int n) { *this = power(*this, n); return *this; }
00129 
00130   interval& intersect_div(const interval& __i, const interval& __j);
00131   interval& intersect_power(const interval& __i, const int& __n);
00132   interval& intersect_invsqr_wc(const interval& __i, const double& __l,
00133                                 const double& __d);
00134   interval& intersect_invpower_wc(const interval& __i, const double& __l,
00135                                const int& __n);
00136   interval& intersect_invsin_wc(const interval& __i, const double& __l,
00137                                 const double& __d);
00138   interval& intersect_invcos_wc(const interval& __i, const double& __l,
00139                                 const double& __d);
00140   interval& intersect_invgauss_wc(const interval& __i, const double& __l,
00141                                   const double& __m, const double& __s);
00142 
00143   double project(const double& __d);
00144 };
00145 // end of interval class
00146 
00147 inline interval_st& interval_st::operator=(const interval& __i)
00148 { 
00149   l=__i.inf();
00150   u=__i.sup();
00151   return *this;
00152 }
00153 
00154 // special 'splitting' methods
00155 inline interval& interval::intersect_div(const interval& __i,
00156                                          const interval& __j)
00157 {
00158   interval help;
00159   
00160   if(__j.inf() < 0 && __j.sup() > 0 && !__i.contains(0))
00161   {
00162     interval up, lo;
00163     
00164     up = __i/interval(0,__j.sup());
00165     lo = __i/interval(__j.inf(),0);
00166     up.intersect(*this);
00167     lo.intersect(*this);
00168     if(up.empty()) *this = lo;
00169     else if(lo.empty()) *this = up;
00170   }
00171   else
00172   {
00173     help = __i/__j;
00174     this->intersect(help);
00175   }
00176   return *this;
00177 }
00178 
00179 inline interval& interval::intersect_power(const interval& __i,
00180                                            const int& __n)
00181 {
00182   if(__n < 0 && __i.inf() < 0 && __i.sup() > 0)
00183   {
00184     if((-__n)&1) // __n odd
00185     {
00186       interval up, lo;
00187       
00188       up = power(interval(0,__i.sup()),__n);
00189       lo = power(interval(__i.inf(),0),__n);
00190       up.intersect(*this);
00191       lo.intersect(*this);
00192       if(up.empty()) *this = lo;
00193       else if(lo.empty()) *this = up;
00194     }
00195     else // __n even
00196     {
00197       interval res;
00198 
00199       res = 1./power(__i, -__n);
00200       this->intersect(res);
00201     }
00202   }
00203   else
00204     this->intersect(power(__i,__n));
00205   return *this;
00206 }
00207 
00208 inline interval& interval::intersect_invsqr_wc(const interval& __i,
00209                         const double& __l, const double& __d)
00210 {
00211   interval up, lo;
00212 
00213   up = (sqrt(__i) - __d)/__l;
00214   lo = (-sqrt(__i) - __d)/__l;
00215   up.intersect(*this);
00216   lo.intersect(*this);
00217   if(up.empty())
00218     *this = lo;
00219   else if(lo.empty())
00220     *this = up;
00221   else
00222     this->intersect(interval(lo.inf(), up.sup()));
00223   return *this;
00224 }
00225 
00226 inline interval& interval::intersect_invpower_wc(const interval& __i,
00227                         const double& __l, const int& __n)
00228 {
00229   if(__n == 0)
00230   {
00231     if(!__i.contains(1.))
00232       *this = EMPTY();
00233   }
00234   else if(__n > 0)
00235   {
00236     if(__n & 1) // n is odd, hence power bijective R^*<->R^*
00237     {
00238       interval __exp = interval(1.)/(1.*__n);
00239       interval __res;
00240 
00241       if(__i.inf() < 0 && __i.sup() > 0)
00242       {
00243         __res = -pow(interval(0,-__i.inf()),__exp);
00244         __res.hull(pow(interval(0,__i.sup()),__exp));
00245       }
00246       else if(__i.inf() < 0)
00247         __res = -pow(-__i,__exp);
00248       else
00249         __res = pow(__i,__exp);
00250       this->intersect(__res/__l);
00251     }
00252     else
00253     {
00254       interval __exp = interval(1.)/(1.*__n);
00255       interval __hi, __lo;
00256 
00257       if(__i.sup() < 0)
00258       {
00259         *this = EMPTY();
00260         return *this;
00261       }
00262       else if(__i.inf() < 0)
00263         __hi = pow(interval(0,__i.sup()),__exp)/__l;
00264       else
00265         __hi = pow(__i,__exp)/__l;
00266       __lo = -__hi;
00267       __hi.intersect(*this);
00268       __lo.intersect(*this);
00269       if(__lo.empty())
00270         *this = __hi;
00271       else if(__hi.empty())
00272         *this = __lo;
00273       else
00274         *this = interval(__lo.inf(), __hi.sup());
00275     }
00276   }
00277   else // __n < 0
00278   {
00279     if((-__n)&1) // __n odd
00280     {
00281       interval __exp = interval(1.)/(-1.*__n);
00282       interval __res;
00283 
00284       if(__i.inf() < 0 && __i.sup() > 0)
00285       {
00286         interval __up;
00287         
00288         __res = -pow(interval(0,-__i.inf()),__exp);
00289         __res.hull(pow(interval(0,__i.sup()),__exp));
00290         __res *= __l;
00291         __up = 1./interval(0,__res.sup());
00292         __res = 1./interval(__res.inf(),0);
00293         __up.intersect(*this);
00294         __res.intersect(*this);
00295         if(__up.empty()) *this = __res;
00296         else if(__res.empty()) *this = __up;
00297         // else *this is unchanged, because hull(__res,__up) == ENTIRE()
00298       }
00299       else if(__i.inf() < 0)
00300       { // the argument interval is cle 0
00301         __res = -pow(-__i,__exp)*__l;
00302         this->intersect(1./__res);
00303       }
00304       else
00305       { // the argument interval is cge 0
00306         __res = pow(__i,__exp)*__l;
00307         this->intersect(1./__res);
00308       }
00309     }
00310     else // __n is even and < 0
00311     {
00312       interval __exp = interval(1.)/(1.*__n);
00313       interval __up, __lo;
00314 
00315       if(__i.sup() < 0)
00316         *this = EMPTY();
00317       else if(__i.inf() < 0)
00318         __lo = interval(0,__i.sup());
00319       else
00320         __lo = __i;
00321 
00322       __up = pow(__lo,__exp)/__l;
00323       __lo = -__up;
00324       __lo.intersect(*this);
00325       __up.intersect(*this);
00326       if(__lo.empty())
00327         *this = __up;
00328       else if(__up.empty())
00329         *this = __lo;
00330       else
00331         *this = interval(__lo.inf(), __up.sup());
00332     }
00333   }
00334   return *this;
00335 }
00336 
00337 inline interval& interval::intersect_invsin_wc(const interval& __i,
00338                         const double& __l, const double& __d)
00339 {
00340   std::cerr << "interval intersect_invsin_wc is not yet implemented!" <<
00341     std::endl;
00342   exit(-1);
00343   return *this;
00344 }
00345 
00346 inline interval& interval::intersect_invcos_wc(const interval& __i,
00347                         const double& __l, const double& __d)
00348 {
00349   std::cerr << "interval intersect_invcos_wc is not yet implemented!" <<
00350     std::endl;
00351   exit(-1);
00352   return *this;
00353 }
00354 
00355 inline interval& interval::intersect_invgauss_wc(const interval& __i,
00356                 const double& __l, const double& __m, const double& __s)
00357 {
00358   std::cerr << "interval intersect_invgauss_wc is not yet implemented!" <<
00359     std::endl;
00360   exit(-1);
00361   return *this;
00362 }
00363 
00364 // elementary functions for intervals
00365 inline interval ipow(const interval& __i, int __n)
00366 {
00367   return power(__i,__n);
00368 }
00369 
00370 inline interval gauss(const interval& __i)
00371 {
00372   return exp(-sqr(__i));
00373 }
00374 
00375 inline interval atan2(const interval& __i, const interval& __j)
00376 {
00377   std::cerr << "interval atan2 is not yet implemented!" << std::endl;
00378   exit(-1);
00379 }
00380 
00381 inline double safeguarded_mid(const interval& __i)
00382 {
00383   if(__i.inf() < 0 && __i.sup() > 0)
00384     return 0.;
00385   else if(__i.inf() == -INFINITY)
00386     return 2.*__i.sup();
00387   else if(__i.sup() == INFINITY)
00388     return 2.*__i.inf();
00389   else if(__i.inf() == 0 || __i.sup() == 0)
00390     return mid(__i);
00391   else
00392   {
00393     double r = sgn(__i.inf())*sqrt(fabs(__i.sup()))*sqrt(fabs(__i.inf()));
00394     if(__i.contains(r))
00395       return r;
00396     else
00397       return mid(__i);
00398   }
00399 }
00400 
00401 inline double absmin(const interval& __i)
00402 {
00403   if(__i.contains(0.))
00404     return 0.;
00405   else if(__i.inf() > 0)
00406     return __i.inf();
00407   else
00408     return __i.sup();
00409 }
00410 
00411 template <class _C>
00412 inline bool operator==(const interval& __i, const _C& __d)
00413 {
00414   return filib::operator==(__i, interval(__d));
00415 }
00416 
00417 template <class _C>
00418 inline bool operator!=(const interval& __i, const _C& __d)
00419 {
00420   return filib::operator!=(__i, interval(__d));
00421 }
00422 
00423 inline double gainfactor(const interval& _old, const interval& _new)
00424 {
00425   if(_old.is_thin())
00426     return 1.;
00427   if(_old.is_bounded() && _new.is_bounded())
00428     return _new.width()/_old.width();
00429   if((_new.sup() != INFINITY && _old.sup() == INFINITY) ||
00430      (_new.inf() != -INFINITY && _old.inf() == -INFINITY))
00431     return 0.;
00432   return 1.;
00433 }
00434 
00435 #if 0
00436 inline interval operator+(int n, const interval& i) { return interval(n)+i; }
00437 inline interval operator+(const interval& i, int n) { return interval(n)+i; }
00438 inline interval operator-(int n, const interval& i) { return interval(n)-i; }
00439 inline interval operator-(const interval& i, int n) { return interval(n)-i; }
00440 inline interval operator*(int n, const interval& i) { return interval(n)*i; }
00441 inline interval operator*(const interval& i, int n) { return interval(n)*i; }
00442 inline interval operator/(int n, const interval& i) { return interval(n)/i; }
00443 inline interval operator/(const interval& i, int n) { return interval(n)/i; }
00444 #endif
00445 
00446 // special additional functions
00447 #if 0
00448 double project(const double& __d) const
00449 {
00450   if(__d < inf())
00451     return inf();
00452   else if(__d > sup())
00453     return sup();
00454   else
00455     return __d;
00456 }
00457 #endif
00458 #endif // _INTERVAL_H_

Generated on Tue Nov 4 01:57:58 2003 for COCONUT API by doxygen1.2.18