File indexing completed on 2025-01-30 09:49:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_NUMERIC_INTERVAL_UTILITY_HPP
0012 #define BOOST_NUMERIC_INTERVAL_UTILITY_HPP
0013
0014 #include <boost/numeric/interval/utility_fwd.hpp>
0015 #include <boost/numeric/interval/detail/test_input.hpp>
0016 #include <boost/numeric/interval/detail/bugs.hpp>
0017 #include <algorithm>
0018 #include <utility>
0019
0020
0021
0022
0023
0024 namespace boost {
0025 namespace numeric {
0026
0027
0028
0029
0030
0031 template<class T, class Policies> inline
0032 const T& lower(const interval<T, Policies>& x)
0033 {
0034 return x.lower();
0035 }
0036
0037 template<class T, class Policies> inline
0038 const T& upper(const interval<T, Policies>& x)
0039 {
0040 return x.upper();
0041 }
0042
0043 template<class T, class Policies> inline
0044 T checked_lower(const interval<T, Policies>& x)
0045 {
0046 if (empty(x)) {
0047 typedef typename Policies::checking checking;
0048 return checking::nan();
0049 }
0050 return x.lower();
0051 }
0052
0053 template<class T, class Policies> inline
0054 T checked_upper(const interval<T, Policies>& x)
0055 {
0056 if (empty(x)) {
0057 typedef typename Policies::checking checking;
0058 return checking::nan();
0059 }
0060 return x.upper();
0061 }
0062
0063 template<class T, class Policies> inline
0064 T width(const interval<T, Policies>& x)
0065 {
0066 if (interval_lib::detail::test_input(x)) return static_cast<T>(0);
0067 typename Policies::rounding rnd;
0068 return rnd.sub_up(x.upper(), x.lower());
0069 }
0070
0071 template<class T, class Policies> inline
0072 T median(const interval<T, Policies>& x)
0073 {
0074 if (interval_lib::detail::test_input(x)) {
0075 typedef typename Policies::checking checking;
0076 return checking::nan();
0077 }
0078 typename Policies::rounding rnd;
0079 return rnd.median(x.lower(), x.upper());
0080 }
0081
0082 template<class T, class Policies> inline
0083 interval<T, Policies> widen(const interval<T, Policies>& x, const T& v)
0084 {
0085 if (interval_lib::detail::test_input(x))
0086 return interval<T, Policies>::empty();
0087 typename Policies::rounding rnd;
0088 return interval<T, Policies>(rnd.sub_down(x.lower(), v),
0089 rnd.add_up (x.upper(), v), true);
0090 }
0091
0092
0093
0094
0095
0096 template<class T, class Policies> inline
0097 bool empty(const interval<T, Policies>& x)
0098 {
0099 return interval_lib::detail::test_input(x);
0100 }
0101
0102 template<class T, class Policies> inline
0103 bool zero_in(const interval<T, Policies>& x)
0104 {
0105 if (interval_lib::detail::test_input(x)) return false;
0106 return (!interval_lib::user::is_pos(x.lower())) &&
0107 (!interval_lib::user::is_neg(x.upper()));
0108 }
0109
0110 template<class T, class Policies> inline
0111 bool in_zero(const interval<T, Policies>& x)
0112 {
0113 return zero_in<T, Policies>(x);
0114 }
0115
0116 template<class T, class Policies> inline
0117 bool in(const T& x, const interval<T, Policies>& y)
0118 {
0119 if (interval_lib::detail::test_input(x, y)) return false;
0120 return y.lower() <= x && x <= y.upper();
0121 }
0122
0123 template<class T, class Policies> inline
0124 bool subset(const interval<T, Policies>& x,
0125 const interval<T, Policies>& y)
0126 {
0127 if (empty(x)) return true;
0128 return !empty(y) && y.lower() <= x.lower() && x.upper() <= y.upper();
0129 }
0130
0131 template<class T, class Policies1, class Policies2> inline
0132 bool proper_subset(const interval<T, Policies1>& x,
0133 const interval<T, Policies2>& y)
0134 {
0135 if (empty(y)) return false;
0136 if (empty(x)) return true;
0137 return y.lower() <= x.lower() && x.upper() <= y.upper() &&
0138 (y.lower() != x.lower() || x.upper() != y.upper());
0139 }
0140
0141 template<class T, class Policies1, class Policies2> inline
0142 bool overlap(const interval<T, Policies1>& x,
0143 const interval<T, Policies2>& y)
0144 {
0145 if (interval_lib::detail::test_input(x, y)) return false;
0146 return (x.lower() <= y.lower() && y.lower() <= x.upper()) ||
0147 (y.lower() <= x.lower() && x.lower() <= y.upper());
0148 }
0149
0150 template<class T, class Policies> inline
0151 bool singleton(const interval<T, Policies>& x)
0152 {
0153 return !empty(x) && x.lower() == x.upper();
0154 }
0155
0156 template<class T, class Policies1, class Policies2> inline
0157 bool equal(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
0158 {
0159 if (empty(x)) return empty(y);
0160 return !empty(y) && x.lower() == y.lower() && x.upper() == y.upper();
0161 }
0162
0163 template<class T, class Policies> inline
0164 interval<T, Policies> intersect(const interval<T, Policies>& x,
0165 const interval<T, Policies>& y)
0166 {
0167 BOOST_USING_STD_MIN();
0168 BOOST_USING_STD_MAX();
0169 if (interval_lib::detail::test_input(x, y))
0170 return interval<T, Policies>::empty();
0171 const T& l = max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower());
0172 const T& u = min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper());
0173 if (l <= u) return interval<T, Policies>(l, u, true);
0174 else return interval<T, Policies>::empty();
0175 }
0176
0177 template<class T, class Policies> inline
0178 interval<T, Policies> hull(const interval<T, Policies>& x,
0179 const interval<T, Policies>& y)
0180 {
0181 BOOST_USING_STD_MIN();
0182 BOOST_USING_STD_MAX();
0183 bool bad_x = interval_lib::detail::test_input(x);
0184 bool bad_y = interval_lib::detail::test_input(y);
0185 if (bad_x)
0186 if (bad_y) return interval<T, Policies>::empty();
0187 else return y;
0188 else
0189 if (bad_y) return x;
0190 return interval<T, Policies>(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()),
0191 max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
0192 }
0193
0194 template<class T, class Policies> inline
0195 interval<T, Policies> hull(const interval<T, Policies>& x, const T& y)
0196 {
0197 BOOST_USING_STD_MIN();
0198 BOOST_USING_STD_MAX();
0199 bool bad_x = interval_lib::detail::test_input(x);
0200 bool bad_y = interval_lib::detail::test_input<T, Policies>(y);
0201 if (bad_y)
0202 if (bad_x) return interval<T, Policies>::empty();
0203 else return x;
0204 else
0205 if (bad_x) return interval<T, Policies>(y, y, true);
0206 return interval<T, Policies>(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y),
0207 max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
0208 }
0209
0210 template<class T, class Policies> inline
0211 interval<T, Policies> hull(const T& x, const interval<T, Policies>& y)
0212 {
0213 BOOST_USING_STD_MIN();
0214 BOOST_USING_STD_MAX();
0215 bool bad_x = interval_lib::detail::test_input<T, Policies>(x);
0216 bool bad_y = interval_lib::detail::test_input(y);
0217 if (bad_x)
0218 if (bad_y) return interval<T, Policies>::empty();
0219 else return y;
0220 else
0221 if (bad_y) return interval<T, Policies>(x, x, true);
0222 return interval<T, Policies>(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()),
0223 max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
0224 }
0225
0226 template<class T> inline
0227 interval<T> hull(const T& x, const T& y)
0228 {
0229 return interval<T>::hull(x, y);
0230 }
0231
0232 template<class T, class Policies> inline
0233 std::pair<interval<T, Policies>, interval<T, Policies> >
0234 bisect(const interval<T, Policies>& x)
0235 {
0236 typedef interval<T, Policies> I;
0237 if (interval_lib::detail::test_input(x))
0238 return std::pair<I,I>(I::empty(), I::empty());
0239 const T m = median(x);
0240 return std::pair<I,I>(I(x.lower(), m, true), I(m, x.upper(), true));
0241 }
0242
0243
0244
0245
0246
0247 template<class T, class Policies> inline
0248 T norm(const interval<T, Policies>& x)
0249 {
0250 if (interval_lib::detail::test_input(x)) {
0251 typedef typename Policies::checking checking;
0252 return checking::nan();
0253 }
0254 BOOST_USING_STD_MAX();
0255 return max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper());
0256 }
0257
0258 template<class T, class Policies> inline
0259 interval<T, Policies> abs(const interval<T, Policies>& x)
0260 {
0261 typedef interval<T, Policies> I;
0262 if (interval_lib::detail::test_input(x))
0263 return I::empty();
0264 if (!interval_lib::user::is_neg(x.lower())) return x;
0265 if (!interval_lib::user::is_pos(x.upper())) return -x;
0266 BOOST_USING_STD_MAX();
0267 return I(static_cast<T>(0), max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper()), true);
0268 }
0269
0270 template<class T, class Policies> inline
0271 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
0272 const interval<T, Policies>& y)
0273 {
0274 typedef interval<T, Policies> I;
0275 if (interval_lib::detail::test_input(x, y))
0276 return I::empty();
0277 BOOST_USING_STD_MAX();
0278 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
0279 }
0280
0281 template<class T, class Policies> inline
0282 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
0283 {
0284 typedef interval<T, Policies> I;
0285 if (interval_lib::detail::test_input(x, y))
0286 return I::empty();
0287 BOOST_USING_STD_MAX();
0288 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
0289 }
0290
0291 template<class T, class Policies> inline
0292 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
0293 {
0294 typedef interval<T, Policies> I;
0295 if (interval_lib::detail::test_input(x, y))
0296 return I::empty();
0297 BOOST_USING_STD_MAX();
0298 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
0299 }
0300
0301 template<class T, class Policies> inline
0302 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
0303 const interval<T, Policies>& y)
0304 {
0305 typedef interval<T, Policies> I;
0306 if (interval_lib::detail::test_input(x, y))
0307 return I::empty();
0308 BOOST_USING_STD_MIN();
0309 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
0310 }
0311
0312 template<class T, class Policies> inline
0313 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
0314 {
0315 typedef interval<T, Policies> I;
0316 if (interval_lib::detail::test_input(x, y))
0317 return I::empty();
0318 BOOST_USING_STD_MIN();
0319 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
0320 }
0321
0322 template<class T, class Policies> inline
0323 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
0324 {
0325 typedef interval<T, Policies> I;
0326 if (interval_lib::detail::test_input(x, y))
0327 return I::empty();
0328 BOOST_USING_STD_MIN();
0329 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
0330 }
0331
0332 }
0333 }
0334
0335 #endif