Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:49:07

0001 /* Boost interval/interval.hpp header file
0002  *
0003  * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
0004  *
0005  * Distributed under the Boost Software License, Version 1.0.
0006  * (See accompanying file LICENSE_1_0.txt or
0007  * copy at http://www.boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_NUMERIC_INTERVAL_INTERVAL_HPP
0011 #define BOOST_NUMERIC_INTERVAL_INTERVAL_HPP
0012 
0013 #include <stdexcept>
0014 #include <string>
0015 #include <boost/numeric/interval/detail/interval_prototype.hpp>
0016 
0017 namespace boost {
0018 namespace numeric {
0019 
0020 namespace interval_lib {
0021     
0022 class comparison_error
0023   : public std::runtime_error 
0024 {
0025 public:
0026   comparison_error()
0027     : std::runtime_error("boost::interval: uncertain comparison")
0028   { }
0029 };
0030 
0031 } // namespace interval_lib
0032 
0033 /*
0034  * interval class
0035  */
0036 
0037 template<class T, class Policies>
0038 class interval
0039 {
0040 private:
0041   struct interval_holder;
0042   struct number_holder;
0043 public:
0044   typedef T base_type;
0045   typedef Policies traits_type;
0046 
0047   T const &lower() const;
0048   T const &upper() const;
0049 
0050   interval();
0051   interval(T const &v);
0052   template<class T1> interval(T1 const &v);
0053   interval(T const &l, T const &u);
0054   template<class T1, class T2> interval(T1 const &l, T2 const &u);
0055   interval(interval<T, Policies> const &r);
0056   template<class Policies1> interval(interval<T, Policies1> const &r);
0057   template<class T1, class Policies1> interval(interval<T1, Policies1> const &r);
0058 
0059   interval &operator=(T const &v);
0060   template<class T1> interval &operator=(T1 const &v);
0061   interval &operator=(interval<T, Policies> const &r);
0062   template<class Policies1> interval &operator=(interval<T, Policies1> const &r);
0063   template<class T1, class Policies1> interval &operator=(interval<T1, Policies1> const &r);
0064  
0065   void assign(const T& l, const T& u);
0066 
0067   static interval empty();
0068   static interval whole();
0069   static interval hull(const T& x, const T& y);
0070 
0071   interval& operator+= (const T& r);
0072   interval& operator+= (const interval& r);
0073   interval& operator-= (const T& r);
0074   interval& operator-= (const interval& r);
0075   interval& operator*= (const T& r);
0076   interval& operator*= (const interval& r);
0077   interval& operator/= (const T& r);
0078   interval& operator/= (const interval& r);
0079 
0080   bool operator< (const interval_holder& r) const;
0081   bool operator> (const interval_holder& r) const;
0082   bool operator<= (const interval_holder& r) const;
0083   bool operator>= (const interval_holder& r) const;
0084   bool operator== (const interval_holder& r) const;
0085   bool operator!= (const interval_holder& r) const;
0086 
0087   bool operator< (const number_holder& r) const;
0088   bool operator> (const number_holder& r) const;
0089   bool operator<= (const number_holder& r) const;
0090   bool operator>= (const number_holder& r) const;
0091   bool operator== (const number_holder& r) const;
0092   bool operator!= (const number_holder& r) const;
0093 
0094   // the following is for internal use only, it is not a published interface
0095   // nevertheless, it's public because friends don't always work correctly.
0096   interval(const T& l, const T& u, bool): low(l), up(u) {}
0097   void set_empty();
0098   void set_whole();
0099   void set(const T& l, const T& u);
0100 
0101 private:
0102   struct interval_holder {
0103     template<class Policies2>
0104     interval_holder(const interval<T, Policies2>& r)
0105       : low(r.lower()), up(r.upper())
0106     {
0107       typedef typename Policies2::checking checking2;
0108       if (checking2::is_empty(low, up))
0109         throw interval_lib::comparison_error();
0110     }
0111 
0112     const T& low;
0113     const T& up;
0114   };
0115 
0116   struct number_holder {
0117     number_holder(const T& r) : val(r)
0118     {
0119       typedef typename Policies::checking checking;
0120       if (checking::is_nan(r))
0121         throw interval_lib::comparison_error();
0122     }
0123     
0124     const T& val;
0125   };
0126 
0127   typedef typename Policies::checking checking;
0128   typedef typename Policies::rounding rounding;
0129 
0130   T low;
0131   T up;
0132 };
0133 
0134 template<class T, class Policies> inline
0135 interval<T, Policies>::interval():
0136   low(static_cast<T>(0)), up(static_cast<T>(0))
0137 {}
0138 
0139 template<class T, class Policies> inline
0140 interval<T, Policies>::interval(T const &v): low(v), up(v)
0141 {
0142   if (checking::is_nan(v)) set_empty();
0143 }
0144 
0145 template<class T, class Policies> template<class T1> inline
0146 interval<T, Policies>::interval(T1 const &v)
0147 {
0148   if (checking::is_nan(v)) set_empty();
0149   else {
0150     rounding rnd;
0151     low = rnd.conv_down(v);
0152     up  = rnd.conv_up  (v);
0153   }
0154 }
0155 
0156 template<class T, class Policies> template<class T1, class T2> inline
0157 interval<T, Policies>::interval(T1 const &l, T2 const &u)
0158 {
0159   if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u)) set_empty();
0160   else {
0161     rounding rnd;
0162     low = rnd.conv_down(l);
0163     up  = rnd.conv_up  (u);
0164   }
0165 }
0166 
0167 template<class T, class Policies> inline
0168 interval<T, Policies>::interval(T const &l, T const &u): low(l), up(u)
0169 {
0170   if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u))
0171     set_empty();
0172 }
0173 
0174 
0175 template<class T, class Policies> inline
0176 interval<T, Policies>::interval(interval<T, Policies> const &r): low(r.lower()), up(r.upper())
0177 {}
0178 
0179 template<class T, class Policies> template<class Policies1> inline
0180 interval<T, Policies>::interval(interval<T, Policies1> const &r): low(r.lower()), up(r.upper())
0181 {
0182   typedef typename Policies1::checking checking1;
0183   if (checking1::is_empty(r.lower(), r.upper())) set_empty();
0184 }
0185 
0186 template<class T, class Policies> template<class T1, class Policies1> inline
0187 interval<T, Policies>::interval(interval<T1, Policies1> const &r)
0188 {
0189   typedef typename Policies1::checking checking1;
0190   if (checking1::is_empty(r.lower(), r.upper())) set_empty();
0191   else {
0192     rounding rnd;
0193     low = rnd.conv_down(r.lower());
0194     up  = rnd.conv_up  (r.upper());
0195   }
0196 }
0197 
0198 template<class T, class Policies> inline
0199 interval<T, Policies> &interval<T, Policies>::operator=(T const &v)
0200 {
0201   if (checking::is_nan(v)) set_empty();
0202   else low = up = v;
0203   return *this;
0204 }
0205 
0206 template<class T, class Policies> template<class T1> inline
0207 interval<T, Policies> &interval<T, Policies>::operator=(T1 const &v)
0208 {
0209   if (checking::is_nan(v)) set_empty();
0210   else {
0211     rounding rnd;
0212     low = rnd.conv_down(v);
0213     up  = rnd.conv_up  (v);
0214   }
0215   return *this;
0216 }
0217 
0218 template<class T, class Policies> inline
0219 interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies> const &r)
0220 {
0221   low = r.lower();
0222   up  = r.upper();
0223   return *this;
0224 }
0225 
0226 template<class T, class Policies> template<class Policies1> inline
0227 interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies1> const &r)
0228 {
0229   typedef typename Policies1::checking checking1;
0230   if (checking1::is_empty(r.lower(), r.upper())) set_empty();
0231   else {
0232     low = r.lower();
0233     up  = r.upper();
0234   }
0235   return *this;
0236 }
0237 
0238 template<class T, class Policies> template<class T1, class Policies1> inline
0239 interval<T, Policies> &interval<T, Policies>::operator=(interval<T1, Policies1> const &r)
0240 {
0241   typedef typename Policies1::checking checking1;
0242   if (checking1::is_empty(r.lower(), r.upper())) set_empty();
0243   else {
0244     rounding rnd;
0245     low = rnd.conv_down(r.lower());
0246     up  = rnd.conv_up  (r.upper());
0247   }
0248   return *this;
0249 }
0250 
0251 template<class T, class Policies> inline
0252 void interval<T, Policies>::assign(const T& l, const T& u)
0253 {
0254   if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u))
0255     set_empty();
0256   else set(l, u);
0257 }
0258 
0259 template<class T, class Policies> inline
0260 void interval<T, Policies>::set(const T& l, const T& u)
0261 {
0262   low = l;
0263   up  = u;
0264 }
0265 
0266 template<class T, class Policies> inline
0267 void interval<T, Policies>::set_empty()
0268 {
0269   low = checking::empty_lower();
0270   up  = checking::empty_upper();
0271 }
0272 
0273 template<class T, class Policies> inline
0274 void interval<T, Policies>::set_whole()
0275 {
0276   low = checking::neg_inf();
0277   up  = checking::pos_inf();
0278 }
0279 
0280 template<class T, class Policies> inline
0281 interval<T, Policies> interval<T, Policies>::hull(const T& x, const T& y)
0282 {
0283   bool bad_x = checking::is_nan(x);
0284   bool bad_y = checking::is_nan(y);
0285   if (bad_x)
0286     if (bad_y) return interval::empty();
0287     else       return interval(y, y, true);
0288   else
0289     if (bad_y) return interval(x, x, true);
0290   if (x <= y) return interval(x, y, true);
0291   else        return interval(y, x, true);
0292 }
0293 
0294 template<class T, class Policies> inline
0295 interval<T, Policies> interval<T, Policies>::empty()
0296 {
0297   return interval<T, Policies>(checking::empty_lower(),
0298                                checking::empty_upper(), true);
0299 }
0300 
0301 template<class T, class Policies> inline
0302 interval<T, Policies> interval<T, Policies>::whole()
0303 {
0304   return interval<T, Policies>(checking::neg_inf(), checking::pos_inf(), true);
0305 }
0306 
0307 template<class T, class Policies> inline
0308 const T& interval<T, Policies>::lower() const
0309 {
0310   return low;
0311 }
0312 
0313 template<class T, class Policies> inline
0314 const T& interval<T, Policies>::upper() const
0315 {
0316   return up;
0317 }
0318 
0319 /*
0320  * interval/interval comparisons
0321  */
0322 
0323 template<class T, class Policies> inline
0324 bool interval<T, Policies>::operator< (const interval_holder& r) const
0325 {
0326   if (!checking::is_empty(low, up)) {
0327     if (up < r.low) return true;
0328     else if (low >= r.up) return false;
0329   }
0330   throw interval_lib::comparison_error();
0331 }
0332 
0333 template<class T, class Policies> inline
0334 bool interval<T, Policies>::operator> (const interval_holder& r) const
0335 {
0336   if (!checking::is_empty(low, up)) {
0337     if (low > r.up) return true;
0338     else if (up <= r.low) return false;
0339   }
0340   throw interval_lib::comparison_error();
0341 }
0342 
0343 template<class T, class Policies> inline
0344 bool interval<T, Policies>::operator<= (const interval_holder& r) const
0345 {
0346   if (!checking::is_empty(low, up)) {
0347     if (up <= r.low) return true;
0348     else if (low > r.up) return false;
0349   }
0350   throw interval_lib::comparison_error();
0351 }
0352 
0353 template<class T, class Policies> inline
0354 bool interval<T, Policies>::operator>= (const interval_holder& r) const
0355 {
0356   if (!checking::is_empty(low, up)) {
0357     if (low >= r.up) return true;
0358     else if (up < r.low) return false;
0359   }
0360   throw interval_lib::comparison_error();
0361 }
0362 
0363 template<class T, class Policies> inline
0364 bool interval<T, Policies>::operator== (const interval_holder& r) const
0365 {
0366   if (!checking::is_empty(low, up)) {
0367     if (up == r.low && low == r.up) return true;
0368     else if (up < r.low || low > r.up) return false;
0369   }
0370   throw interval_lib::comparison_error();
0371 }
0372 
0373 template<class T, class Policies> inline
0374 bool interval<T, Policies>::operator!= (const interval_holder& r) const
0375 {
0376   if (!checking::is_empty(low, up)) {
0377     if (up < r.low || low > r.up) return true;
0378     else if (up == r.low && low == r.up) return false;
0379   }
0380   throw interval_lib::comparison_error();
0381 }
0382 
0383 /*
0384  * interval/number comparisons
0385  */
0386 
0387 template<class T, class Policies> inline
0388 bool interval<T, Policies>::operator< (const number_holder& r) const
0389 {
0390   if (!checking::is_empty(low, up)) {
0391     if (up < r.val) return true;
0392     else if (low >= r.val) return false;
0393   }
0394   throw interval_lib::comparison_error();
0395 }
0396 
0397 template<class T, class Policies> inline
0398 bool interval<T, Policies>::operator> (const number_holder& r) const
0399 {
0400   if (!checking::is_empty(low, up)) {
0401     if (low > r.val) return true;
0402     else if (up <= r.val) return false;
0403   }
0404   throw interval_lib::comparison_error();
0405 }
0406 
0407 template<class T, class Policies> inline
0408 bool interval<T, Policies>::operator<= (const number_holder& r) const
0409 {
0410   if (!checking::is_empty(low, up)) {
0411     if (up <= r.val) return true;
0412     else if (low > r.val) return false;
0413   }
0414   throw interval_lib::comparison_error();
0415 }
0416 
0417 template<class T, class Policies> inline
0418 bool interval<T, Policies>::operator>= (const number_holder& r) const
0419 {
0420   if (!checking::is_empty(low, up)) {
0421     if (low >= r.val) return true;
0422     else if (up < r.val) return false;
0423   }
0424   throw interval_lib::comparison_error();
0425 }
0426 
0427 template<class T, class Policies> inline
0428 bool interval<T, Policies>::operator== (const number_holder& r) const
0429 {
0430   if (!checking::is_empty(low, up)) {
0431     if (up == r.val && low == r.val) return true;
0432     else if (up < r.val || low > r.val) return false;
0433   }
0434   throw interval_lib::comparison_error();
0435 }
0436 
0437 template<class T, class Policies> inline
0438 bool interval<T, Policies>::operator!= (const number_holder& r) const
0439 {
0440   if (!checking::is_empty(low, up)) {
0441     if (up < r.val || low > r.val) return true;
0442     else if (up == r.val && low == r.val) return false;
0443   }
0444   throw interval_lib::comparison_error();
0445 }
0446 
0447 } // namespace numeric
0448 } // namespace boost
0449 
0450 #endif // BOOST_NUMERIC_INTERVAL_INTERVAL_HPP