00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00028
00029
00030
00031
00032 #ifndef _INTERVAL_BOOST_H_
00033 #define _INTERVAL_BOOST_H_
00034
00035 #include <iostream>
00036 #include <values.h>
00037 #include <boost/numeric/interval.hpp>
00038 #include <boost/numeric/interval/checking.hpp>
00039 #include <boost/numeric/interval/compare.hpp>
00040 #include <boost/numeric/interval/policies.hpp>
00041
00042 namespace coco
00043 {
00044
00045 #define coconut_init_interval()
00046
00047
00048 template<class T>
00049 struct checking_my
00050 {
00051 static T pos_inf(){return COCO_INF;}
00052 static T neg_inf(){return -COCO_INF;}
00053 static T inf()
00054 {
00055
00056
00057 return COCO_INF;
00058 }
00059 static T nan()
00060 {
00061 assert(std::numeric_limits<T>::has_quiet_NaN);
00062 return std::numeric_limits<T>::quiet_NaN();
00063 }
00064 static bool is_nan(const T& x)
00065 {
00066 return std::numeric_limits<T>::has_quiet_NaN && (x != x);
00067 }
00068 static T empty_inf()
00069 {
00070 return (std::numeric_limits<T>::has_quiet_NaN ?
00071 std::numeric_limits<T>::quiet_NaN() : static_cast<T>(1));
00072 }
00073 static T empty_upper()
00074 {
00075 return (std::numeric_limits<T>::has_quiet_NaN ?
00076 std::numeric_limits<T>::quiet_NaN() : static_cast<T>(0));
00077 }
00078 static T empty_lower()
00079 {
00080 return (std::numeric_limits<T>::has_quiet_NaN ?
00081 std::numeric_limits<T>::quiet_NaN() : static_cast<T>(0));
00082 }
00083 static bool is_empty(const T& l, const T& u)
00084 {
00085 return !(l <= u);
00086 }
00087 };
00088
00089 template<class T>
00090 struct my_rounded_math:
00091 boost::numeric::interval_lib::save_state_nothing<
00092 boost::numeric::interval_lib::rounded_transc_opp<T>
00093 >
00094 {};
00095
00096
00097 typedef boost::numeric::interval_lib::policies<
00098 my_rounded_math<double>,
00099 checking_my<double>
00100 >my_policies;
00101
00102
00103 class interval;
00104
00105 struct interval_st
00106 {
00107 double l, u;
00108 interval_st& operator=(const interval& __i);
00109 };
00110
00111
00112 class interval
00113 {
00114 private:
00115
00116 typedef boost::numeric::interval<double, my_policies> __Base;
00117
00118 private:
00119 __Base I;
00120
00121
00122
00123
00124
00125
00126
00127 static int precision_val;
00128
00129 private:
00130 static interval __construct(const __Base& x)
00131 { interval __x; __x.I = x; return __x; }
00132
00133 public:
00134 interval(double lo, double up) : I(lo, up) {}
00135 interval(double d = 0) : I(d) {}
00136 interval(int d) : I((double) d) {}
00137 interval(unsigned d) : I((double) d) {}
00138 interval(long d) : I((double) d) {}
00139 interval(unsigned long d) : I((double) d) {}
00140 interval(const interval& x) : I(x.base()) {}
00141 interval(const interval_st& x) : I(x.l, x.u) {}
00142
00143
00144 void set(double lo, double up)
00145 {
00146 *this = interval(lo, up);
00147 }
00148
00149
00150 double inf() const {return I.lower();}
00151 double sup() const {return I.upper();}
00152 __Base base() const {return I;}
00153 static interval EMPTY() {return __construct(__Base::empty());}
00154
00155
00156 bool empty() const {return boost::numeric::empty(I);}
00157 bool is_empty() const {return boost::numeric::empty(I);}
00158 bool is_thin() const {return singleton(I);}
00159 bool is_unbounded_below() const {return inf() == -COCO_INF;}
00160 bool is_unbounded_above() const {return sup() == COCO_INF;}
00161 bool is_entire() const {return inf() == -COCO_INF && sup() == COCO_INF;}
00162 bool is_bounded() const
00163 {return !is_unbounded_below() && !is_unbounded_above();}
00164
00165 bool subset (const interval& x) const
00166 {return boost::numeric::subset(I, x.base());}
00167 bool superset (const interval& x) const
00168 {return boost::numeric::subset(x.base(),I);}
00169 bool proper_subset (const interval& x) const
00170 {return boost::numeric::proper_subset(I, x.base());}
00171 bool proper_superset (const interval& x) const
00172 {return boost::numeric::proper_subset(x.base(),I);}
00173 bool disjoint (const interval& x) const
00174 {return !boost::numeric::overlap(I, x.base());}
00175
00176 double rel_width() const;
00177
00178
00179 interval& intersect(const interval& x)
00180 {
00181 I=boost::numeric::intersect(I,x.base());
00182 return *this;
00183 }
00184
00185
00186 interval& hull(const interval& x)
00187 {
00188 I=boost::numeric::hull(I,x.base());
00189 return *this;
00190 }
00191
00192 interval& hulldiff(const interval& x)
00193 {
00194 if(subset(x)){
00195 return *this=EMPTY();
00196 }
00197 else if(!superset(x))
00198 {
00199 if(x.contains(inf()))
00200 *this = interval(x.sup(), sup());
00201 else
00202 *this = interval(inf(), x.inf());
00203 }
00204 return *this;
00205 }
00206
00207 bool contains(const interval& x) const
00208 {
00209 if(inf() <= x.inf() && sup() >= x.sup())
00210 return true;
00211 else
00212 return false;
00213 }
00214
00215 void setpair(double& lo, double& up) const {lo = inf(); up = sup();}
00216 void get_bounds(double& a, double& b) const {a = inf(); b = sup();}
00217 void set_bounds(double a, double b) {I.assign(a, b);}
00218 void set_lb(double d) {I.assign(d, I.upper());}
00219 void set_ub(double d) {I.assign(I.lower(), d);}
00220
00221 interval& operator=(const interval& x){I=__Base(x.base()); return *this;}
00222 interval& operator=(double d) {I.assign(d,d); return *this;}
00223 interval& operator=(int d) {I.assign(d,d); return *this;}
00224 interval& operator=(unsigned d) {I.assign(d,d); return *this;}
00225 interval& operator=(long d) {I.assign(d,d); return *this;}
00226 interval& operator=(unsigned long d) {I.assign(d,d); return *this;}
00227
00228
00229
00230 interval operator-() const {return __construct(-I);}
00231
00233 interval& ipow(int n);
00235 interval& imin(const interval& x);
00237 interval& imax(const interval& x);
00238
00240 interval& round_to_integer();
00241
00242 interval& intersect_div(const interval& __i, const interval& __j);
00243 interval& intersect_power(const interval& __i, int __n);
00244 interval& intersect_invsqr_wc(const interval& __i, double __l, double __d);
00245 interval& intersect_invpower_wc(const interval& __i, double __l, int __n);
00246 interval& intersect_invsin_wc(const interval& __i, double __l, double __d);
00247 interval& intersect_invcos_wc(const interval& __i, double __l, double __d);
00248 interval& intersect_invgauss_wc(const interval& __i, double __l, double __m, double __s);
00249
00250 double project(double __d) const;
00251
00252
00253
00254
00255
00256
00257
00258
00259 interval& operator+=(const interval& a);
00260
00261
00262
00263
00264 interval& operator+=(double a);
00265
00266
00267
00268
00269 interval& operator-=(const interval& a);
00270
00271
00272
00273 interval& operator-=(double a);
00274
00275
00276
00277 interval& operator*=(const interval& a);
00278
00279
00280
00281 interval& operator*=(double a);
00282
00283
00284
00285 interval& operator/=(const interval& a);
00286
00287
00288
00289 interval& operator/=(double a);
00290
00304 double mid() const;
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 double diam() const;
00318 double width() const;
00319
00335 double relDiam() const;
00336
00348 double rad() const;
00349
00360 double mig() const;
00361
00373 double mag() const;
00374
00386 double dist(const interval& x) const;
00387
00399 double safeguarded_mid() const;
00400
00403 static int const & precision();
00405 static int precision(int const & p);
00406
00407 friend std::ostream &operator << (std::ostream &s, const interval &a);
00408 friend interval operator+(const interval& a, const interval& b);
00409 friend interval operator+(const interval& a, double b);
00410 friend interval operator+(double b, const interval& a);
00411 friend interval operator-(const interval& a, const interval& b);
00412 friend interval operator-(const interval& a, double b);
00413 friend interval operator-(double b, const interval& a);
00414 friend interval cancel(const interval& a, const interval& b);
00415 friend interval operator*(const interval& a, const interval& b);
00416 friend interval operator*(const interval& a, double b);
00417 friend interval operator*(double b, const interval& a);
00418 friend interval operator/(const interval& a, const interval& b);
00419 friend interval operator/(const interval& a, double b);
00420 friend interval operator/(double b, const interval& a);
00421 friend interval acos(const interval& x);
00422 friend interval abs(const interval& x);
00423 friend interval acosh(const interval& x);
00424 friend interval acot(const interval& x);
00425 friend interval acoth(const interval& x);
00426 friend interval asin(const interval& x);
00427 friend interval asinh(const interval& x);
00428 friend interval atan(const interval& x);
00429 friend interval atanh(const interval& x);
00430 friend interval cos(const interval& x);
00431 friend interval cosh(const interval& x);
00432 friend interval cot(const interval& x);
00433 friend interval coth(const interval& x);
00434 friend interval exp(const interval& x);
00435 friend interval exp10(const interval& x);
00436 friend interval exp2(const interval& x);
00437 friend interval expm1(const interval& x);
00438 friend interval log(const interval& x);
00439 friend interval log10(const interval& x);
00440 friend interval log1p(const interval& x);
00441 friend interval log2(const interval& x);
00442 friend interval power(const interval& x, int n);
00443 friend interval pow(const interval& x, const interval& y);
00444 friend interval sin(const interval& x);
00445 friend interval sinh(const interval& x);
00446 friend interval sqr(const interval& x);
00447 friend interval sqrt(const interval& x);
00448 friend interval tan(const interval& x);
00449 friend interval tanh(const interval& x);
00450 friend interval imax(const interval& x, const interval& y);
00451 friend interval imin(const interval& x, const interval& y);
00452 friend interval division_part1(const interval& x, const interval& y,
00453 bool& b);
00454 friend interval division_part2(const interval& x, const interval& y,
00455 bool b);
00456 };
00457
00458
00459
00460
00461
00462
00463
00464 inline double safeguarded_mid(const interval& __i)
00465 {return __i.safeguarded_mid();}
00466 interval ipow(const interval& x, int n);
00467
00468 interval gauss(const interval& x);
00469 interval atan2(const interval& y, const interval& x);
00470 double absmin(const interval& __i);
00471 double gainfactor(const interval& _old, const interval& _new);
00472
00473 template <class _TC>
00474 bool operator==(const interval& __i, const _TC& __d);
00475
00476 template <class _TC>
00477 bool operator!=(const interval& __i, const _TC& __d);
00478
00479
00480
00481
00482
00483
00484
00485
00486 inline bool operator==(const interval& a, const interval& b)
00487 {return a.sup()==b.sup() && a.inf()==b.inf();}
00488 inline bool operator==(const interval& a, double b)
00489 {return a.sup()==b && a.inf()==b;}
00490 inline bool operator!=(const interval& a, const interval& b)
00491 {return a.sup()!=b.sup() || a.inf()!=b.inf();}
00492 inline bool operator!=(const interval& a, double b)
00493 {return a.sup()!=b || a.inf() != b;}
00494 inline bool operator<(const interval& a, const interval& b){return a.sup() < b.inf();}
00495 inline bool operator<(const interval& a, double b){return a.sup() < b;}
00496 inline bool operator<(double a, const interval& b){return a < b.inf();}
00497
00498 interval operator+(const interval& a, const interval& b);
00499 interval operator+(const interval& a, double b);
00500 interval operator+(double b, const interval& a);
00501 interval operator-(const interval& a, const interval& b);
00502 interval operator-(const interval& a, double b);
00503 interval operator-(double b, const interval& a);
00504 interval cancel(const interval& a, const interval& b);
00505 interval operator*(const interval& a, const interval& b);
00506 interval operator*(const interval& a, double b);
00507 interval operator*(double b, const interval& a);
00508 interval operator/(const interval& a, const interval& b);
00509 interval operator/(const interval& a, double b);
00510 interval operator/(double b, const interval& a);
00511
00512
00513 std::ostream &operator << (std::ostream &s, const interval &a);
00514
00518 double mid(const interval&);
00522 double diam(const interval&);
00523 double width(const interval&);
00527 double relDiam(const interval&);
00531 double rad(const interval&);
00535 double mig(const interval&);
00539 double mag(const interval&);
00543 double dist(const interval& x, const interval& y);
00544
00548 interval round_to_integer(const interval& x);
00549
00553 interval acos(const interval& x);
00554
00558 interval abs(const interval& x);
00559
00564 interval acosh(const interval& x);
00565
00570 interval acot(const interval& x);
00571
00576 interval acoth(const interval& x);
00577
00581 interval asin(const interval& x);
00582
00587 interval asinh(const interval& x);
00588
00592 interval atan(const interval& x);
00593
00598 interval atanh(const interval& x);
00599
00603 interval cos(const interval& x);
00604
00608 interval cosh(const interval& x);
00609
00613 interval cot(const interval& x);
00614
00619 interval coth(const interval& x);
00620
00624 interval exp(const interval& x);
00625
00630 interval exp10(const interval& x);
00631
00636 interval exp2(const interval& x);
00637
00641 interval expm1(const interval& x);
00642
00647 interval log(const interval& x);
00648
00653 interval log10(const interval& x);
00654
00658 interval log1p(const interval& x);
00659
00664 interval log2(const interval& x);
00665
00669 interval power(const interval& x, int n);
00670
00674 interval pow(const interval& x, const interval& y);
00675
00679 interval sin(const interval& x);
00680
00684 interval sinh(const interval& x);
00685
00689 interval sqr(const interval& x);
00690
00694 interval sqrt(const interval& x);
00695
00699 interval tan(const interval& x);
00700
00705 interval tanh(const interval& x);
00706
00711 interval imax(const interval& x, const interval& y);
00712
00717 interval imin(const interval& x, const interval& y);
00718
00719
00720
00721
00722
00723
00724 inline
00725 interval_st& interval_st::operator=(const interval& x)
00726 {
00727 l = x.inf();
00728 u = x.sup();
00729 return *this;
00730 }
00731
00732
00733
00734 inline
00735 interval ipow(const interval& x, int n)
00736 {
00737 return power(x, n);
00738 }
00739
00740
00741 inline
00742 interval gauss(const interval& x)
00743 {
00744 return exp(-sqr(x));
00745 }
00746
00747
00748 inline
00749 interval atan2(const interval& y, const interval& x)
00750 {
00751 return atan(y/x);
00752 }
00753
00754
00755 inline
00756 double absmin(const interval& __i)
00757 {
00758 if(__i.contains(0.))
00759 return 0.;
00760 else if(__i.inf() > 0)
00761 return __i.inf();
00762 else
00763 return __i.sup();
00764 }
00765
00766 interval division_part1(const interval& x, const interval& y, bool& b);
00767
00768 interval division_part2(const interval& x, const interval& y, bool b = true);
00769
00770 inline
00771 double gainfactor(const interval& _old, const interval& _new)
00772 {
00773 if(_old.is_thin())
00774 return 1.;
00775 if(_old.is_bounded() && _new.is_bounded())
00776 return _new.width()/_old.width();
00777 if((_new.sup() != COCO_INF && _old.sup() == COCO_INF) ||
00778 (_new.inf() != -COCO_INF && _old.inf() == -COCO_INF))
00779 return 0.;
00780 return 1.;
00781 }
00782
00783
00784 template <class _TC>
00785 inline
00786 bool operator==(const interval& __i, const _TC& __d)
00787 {
00788 return boost::numeric::interval_lib::compare::set::operator==(__i.base(), interval(__d).base());
00789 }
00790
00791
00792 template <class _TC>
00793 inline
00794 bool operator!=(const interval& __i, const _TC& __d)
00795 {
00796 return boost::numeric::interval_lib::compare::set::operator!=(__i.base(), interval(__d).base());
00797 }
00798
00799
00800
00801 inline
00802 double interval::project(double __d) const
00803 {
00804 if(__d < inf())
00805 return inf();
00806 else if(__d > sup())
00807 return sup();
00808 else
00809 return __d;
00810 }
00811
00812
00813 }
00814
00815
00816 #endif // _INTERVAL_BOOST_H_