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
00030
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
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
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
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
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
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)
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
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)
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
00278 {
00279 if((-__n)&1)
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
00298 }
00299 else if(__i.inf() < 0)
00300 {
00301 __res = -pow(-__i,__exp)*__l;
00302 this->intersect(1./__res);
00303 }
00304 else
00305 {
00306 __res = pow(__i,__exp)*__l;
00307 this->intersect(1./__res);
00308 }
00309 }
00310 else
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
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
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_