annotate DEPENDENCIES/generic/include/boost/numeric/interval/arith.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /* Boost interval/arith.hpp template implementation file
Chris@16 2 *
Chris@16 3 * Copyright 2000 Jens Maurer
Chris@16 4 * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
Chris@16 5 *
Chris@16 6 * Distributed under the Boost Software License, Version 1.0.
Chris@16 7 * (See accompanying file LICENSE_1_0.txt or
Chris@16 8 * copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 */
Chris@16 10
Chris@16 11 #ifndef BOOST_NUMERIC_INTERVAL_ARITH_HPP
Chris@16 12 #define BOOST_NUMERIC_INTERVAL_ARITH_HPP
Chris@16 13
Chris@16 14 #include <boost/config.hpp>
Chris@16 15 #include <boost/numeric/interval/interval.hpp>
Chris@16 16 #include <boost/numeric/interval/detail/bugs.hpp>
Chris@16 17 #include <boost/numeric/interval/detail/test_input.hpp>
Chris@16 18 #include <boost/numeric/interval/detail/division.hpp>
Chris@16 19 #include <algorithm>
Chris@16 20
Chris@16 21 namespace boost {
Chris@16 22 namespace numeric {
Chris@16 23
Chris@16 24 /*
Chris@16 25 * Basic arithmetic operators
Chris@16 26 */
Chris@16 27
Chris@16 28 template<class T, class Policies> inline
Chris@16 29 const interval<T, Policies>& operator+(const interval<T, Policies>& x)
Chris@16 30 {
Chris@16 31 return x;
Chris@16 32 }
Chris@16 33
Chris@16 34 template<class T, class Policies> inline
Chris@16 35 interval<T, Policies> operator-(const interval<T, Policies>& x)
Chris@16 36 {
Chris@16 37 if (interval_lib::detail::test_input(x))
Chris@16 38 return interval<T, Policies>::empty();
Chris@16 39 return interval<T, Policies>(-x.upper(), -x.lower(), true);
Chris@16 40 }
Chris@16 41
Chris@16 42 template<class T, class Policies> inline
Chris@16 43 interval<T, Policies>& interval<T, Policies>::operator+=(const interval<T, Policies>& r)
Chris@16 44 {
Chris@16 45 if (interval_lib::detail::test_input(*this, r))
Chris@16 46 set_empty();
Chris@16 47 else {
Chris@16 48 typename Policies::rounding rnd;
Chris@16 49 set(rnd.add_down(low, r.low), rnd.add_up(up, r.up));
Chris@16 50 }
Chris@16 51 return *this;
Chris@16 52 }
Chris@16 53
Chris@16 54 template<class T, class Policies> inline
Chris@16 55 interval<T, Policies>& interval<T, Policies>::operator+=(const T& r)
Chris@16 56 {
Chris@16 57 if (interval_lib::detail::test_input(*this, r))
Chris@16 58 set_empty();
Chris@16 59 else {
Chris@16 60 typename Policies::rounding rnd;
Chris@16 61 set(rnd.add_down(low, r), rnd.add_up(up, r));
Chris@16 62 }
Chris@16 63 return *this;
Chris@16 64 }
Chris@16 65
Chris@16 66 template<class T, class Policies> inline
Chris@16 67 interval<T, Policies>& interval<T, Policies>::operator-=(const interval<T, Policies>& r)
Chris@16 68 {
Chris@16 69 if (interval_lib::detail::test_input(*this, r))
Chris@16 70 set_empty();
Chris@16 71 else {
Chris@16 72 typename Policies::rounding rnd;
Chris@16 73 set(rnd.sub_down(low, r.up), rnd.sub_up(up, r.low));
Chris@16 74 }
Chris@16 75 return *this;
Chris@16 76 }
Chris@16 77
Chris@16 78 template<class T, class Policies> inline
Chris@16 79 interval<T, Policies>& interval<T, Policies>::operator-=(const T& r)
Chris@16 80 {
Chris@16 81 if (interval_lib::detail::test_input(*this, r))
Chris@16 82 set_empty();
Chris@16 83 else {
Chris@16 84 typename Policies::rounding rnd;
Chris@16 85 set(rnd.sub_down(low, r), rnd.sub_up(up, r));
Chris@16 86 }
Chris@16 87 return *this;
Chris@16 88 }
Chris@16 89
Chris@16 90 template<class T, class Policies> inline
Chris@16 91 interval<T, Policies>& interval<T, Policies>::operator*=(const interval<T, Policies>& r)
Chris@16 92 {
Chris@16 93 return *this = *this * r;
Chris@16 94 }
Chris@16 95
Chris@16 96 template<class T, class Policies> inline
Chris@16 97 interval<T, Policies>& interval<T, Policies>::operator*=(const T& r)
Chris@16 98 {
Chris@16 99 return *this = r * *this;
Chris@16 100 }
Chris@16 101
Chris@16 102 template<class T, class Policies> inline
Chris@16 103 interval<T, Policies>& interval<T, Policies>::operator/=(const interval<T, Policies>& r)
Chris@16 104 {
Chris@16 105 return *this = *this / r;
Chris@16 106 }
Chris@16 107
Chris@16 108 template<class T, class Policies> inline
Chris@16 109 interval<T, Policies>& interval<T, Policies>::operator/=(const T& r)
Chris@16 110 {
Chris@16 111 return *this = *this / r;
Chris@16 112 }
Chris@16 113
Chris@16 114 template<class T, class Policies> inline
Chris@16 115 interval<T, Policies> operator+(const interval<T, Policies>& x,
Chris@16 116 const interval<T, Policies>& y)
Chris@16 117 {
Chris@16 118 if (interval_lib::detail::test_input(x, y))
Chris@16 119 return interval<T, Policies>::empty();
Chris@16 120 typename Policies::rounding rnd;
Chris@16 121 return interval<T,Policies>(rnd.add_down(x.lower(), y.lower()),
Chris@16 122 rnd.add_up (x.upper(), y.upper()), true);
Chris@16 123 }
Chris@16 124
Chris@16 125 template<class T, class Policies> inline
Chris@16 126 interval<T, Policies> operator+(const T& x, const interval<T, Policies>& y)
Chris@16 127 {
Chris@16 128 if (interval_lib::detail::test_input(x, y))
Chris@16 129 return interval<T, Policies>::empty();
Chris@16 130 typename Policies::rounding rnd;
Chris@16 131 return interval<T,Policies>(rnd.add_down(x, y.lower()),
Chris@16 132 rnd.add_up (x, y.upper()), true);
Chris@16 133 }
Chris@16 134
Chris@16 135 template<class T, class Policies> inline
Chris@16 136 interval<T, Policies> operator+(const interval<T, Policies>& x, const T& y)
Chris@16 137 { return y + x; }
Chris@16 138
Chris@16 139 template<class T, class Policies> inline
Chris@16 140 interval<T, Policies> operator-(const interval<T, Policies>& x,
Chris@16 141 const interval<T, Policies>& y)
Chris@16 142 {
Chris@16 143 if (interval_lib::detail::test_input(x, y))
Chris@16 144 return interval<T, Policies>::empty();
Chris@16 145 typename Policies::rounding rnd;
Chris@16 146 return interval<T,Policies>(rnd.sub_down(x.lower(), y.upper()),
Chris@16 147 rnd.sub_up (x.upper(), y.lower()), true);
Chris@16 148 }
Chris@16 149
Chris@16 150 template<class T, class Policies> inline
Chris@16 151 interval<T, Policies> operator-(const T& x, const interval<T, Policies>& y)
Chris@16 152 {
Chris@16 153 if (interval_lib::detail::test_input(x, y))
Chris@16 154 return interval<T, Policies>::empty();
Chris@16 155 typename Policies::rounding rnd;
Chris@16 156 return interval<T,Policies>(rnd.sub_down(x, y.upper()),
Chris@16 157 rnd.sub_up (x, y.lower()), true);
Chris@16 158 }
Chris@16 159
Chris@16 160 template<class T, class Policies> inline
Chris@16 161 interval<T, Policies> operator-(const interval<T, Policies>& x, const T& y)
Chris@16 162 {
Chris@16 163 if (interval_lib::detail::test_input(x, y))
Chris@16 164 return interval<T, Policies>::empty();
Chris@16 165 typename Policies::rounding rnd;
Chris@16 166 return interval<T,Policies>(rnd.sub_down(x.lower(), y),
Chris@16 167 rnd.sub_up (x.upper(), y), true);
Chris@16 168 }
Chris@16 169
Chris@16 170 template<class T, class Policies> inline
Chris@16 171 interval<T, Policies> operator*(const interval<T, Policies>& x,
Chris@16 172 const interval<T, Policies>& y)
Chris@16 173 {
Chris@16 174 BOOST_USING_STD_MIN();
Chris@16 175 BOOST_USING_STD_MAX();
Chris@16 176 typedef interval<T, Policies> I;
Chris@16 177 if (interval_lib::detail::test_input(x, y))
Chris@16 178 return I::empty();
Chris@16 179 typename Policies::rounding rnd;
Chris@16 180 const T& xl = x.lower();
Chris@16 181 const T& xu = x.upper();
Chris@16 182 const T& yl = y.lower();
Chris@16 183 const T& yu = y.upper();
Chris@16 184
Chris@16 185 if (interval_lib::user::is_neg(xl))
Chris@16 186 if (interval_lib::user::is_pos(xu))
Chris@16 187 if (interval_lib::user::is_neg(yl))
Chris@16 188 if (interval_lib::user::is_pos(yu)) // M * M
Chris@16 189 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(rnd.mul_down(xl, yu), rnd.mul_down(xu, yl)),
Chris@16 190 max BOOST_PREVENT_MACRO_SUBSTITUTION(rnd.mul_up (xl, yl), rnd.mul_up (xu, yu)), true);
Chris@16 191 else // M * N
Chris@16 192 return I(rnd.mul_down(xu, yl), rnd.mul_up(xl, yl), true);
Chris@16 193 else
Chris@16 194 if (interval_lib::user::is_pos(yu)) // M * P
Chris@16 195 return I(rnd.mul_down(xl, yu), rnd.mul_up(xu, yu), true);
Chris@16 196 else // M * Z
Chris@16 197 return I(static_cast<T>(0), static_cast<T>(0), true);
Chris@16 198 else
Chris@16 199 if (interval_lib::user::is_neg(yl))
Chris@16 200 if (interval_lib::user::is_pos(yu)) // N * M
Chris@16 201 return I(rnd.mul_down(xl, yu), rnd.mul_up(xl, yl), true);
Chris@16 202 else // N * N
Chris@16 203 return I(rnd.mul_down(xu, yu), rnd.mul_up(xl, yl), true);
Chris@16 204 else
Chris@16 205 if (interval_lib::user::is_pos(yu)) // N * P
Chris@16 206 return I(rnd.mul_down(xl, yu), rnd.mul_up(xu, yl), true);
Chris@16 207 else // N * Z
Chris@16 208 return I(static_cast<T>(0), static_cast<T>(0), true);
Chris@16 209 else
Chris@16 210 if (interval_lib::user::is_pos(xu))
Chris@16 211 if (interval_lib::user::is_neg(yl))
Chris@16 212 if (interval_lib::user::is_pos(yu)) // P * M
Chris@16 213 return I(rnd.mul_down(xu, yl), rnd.mul_up(xu, yu), true);
Chris@16 214 else // P * N
Chris@16 215 return I(rnd.mul_down(xu, yl), rnd.mul_up(xl, yu), true);
Chris@16 216 else
Chris@16 217 if (interval_lib::user::is_pos(yu)) // P * P
Chris@16 218 return I(rnd.mul_down(xl, yl), rnd.mul_up(xu, yu), true);
Chris@16 219 else // P * Z
Chris@16 220 return I(static_cast<T>(0), static_cast<T>(0), true);
Chris@16 221 else // Z * ?
Chris@16 222 return I(static_cast<T>(0), static_cast<T>(0), true);
Chris@16 223 }
Chris@16 224
Chris@16 225 template<class T, class Policies> inline
Chris@16 226 interval<T, Policies> operator*(const T& x, const interval<T, Policies>& y)
Chris@16 227 {
Chris@16 228 typedef interval<T, Policies> I;
Chris@16 229 if (interval_lib::detail::test_input(x, y))
Chris@16 230 return I::empty();
Chris@16 231 typename Policies::rounding rnd;
Chris@16 232 const T& yl = y.lower();
Chris@16 233 const T& yu = y.upper();
Chris@16 234 // x is supposed not to be infinite
Chris@16 235 if (interval_lib::user::is_neg(x))
Chris@16 236 return I(rnd.mul_down(x, yu), rnd.mul_up(x, yl), true);
Chris@16 237 else if (interval_lib::user::is_zero(x))
Chris@16 238 return I(static_cast<T>(0), static_cast<T>(0), true);
Chris@16 239 else
Chris@16 240 return I(rnd.mul_down(x, yl), rnd.mul_up(x, yu), true);
Chris@16 241 }
Chris@16 242
Chris@16 243 template<class T, class Policies> inline
Chris@16 244 interval<T, Policies> operator*(const interval<T, Policies>& x, const T& y)
Chris@16 245 { return y * x; }
Chris@16 246
Chris@16 247 template<class T, class Policies> inline
Chris@16 248 interval<T, Policies> operator/(const interval<T, Policies>& x,
Chris@16 249 const interval<T, Policies>& y)
Chris@16 250 {
Chris@16 251 if (interval_lib::detail::test_input(x, y))
Chris@16 252 return interval<T, Policies>::empty();
Chris@16 253 if (zero_in(y))
Chris@16 254 if (!interval_lib::user::is_zero(y.lower()))
Chris@16 255 if (!interval_lib::user::is_zero(y.upper()))
Chris@16 256 return interval_lib::detail::div_zero(x);
Chris@16 257 else
Chris@16 258 return interval_lib::detail::div_negative(x, y.lower());
Chris@16 259 else
Chris@16 260 if (!interval_lib::user::is_zero(y.upper()))
Chris@16 261 return interval_lib::detail::div_positive(x, y.upper());
Chris@16 262 else
Chris@16 263 return interval<T, Policies>::empty();
Chris@16 264 else
Chris@16 265 return interval_lib::detail::div_non_zero(x, y);
Chris@16 266 }
Chris@16 267
Chris@16 268 template<class T, class Policies> inline
Chris@16 269 interval<T, Policies> operator/(const T& x, const interval<T, Policies>& y)
Chris@16 270 {
Chris@16 271 if (interval_lib::detail::test_input(x, y))
Chris@16 272 return interval<T, Policies>::empty();
Chris@16 273 if (zero_in(y))
Chris@16 274 if (!interval_lib::user::is_zero(y.lower()))
Chris@16 275 if (!interval_lib::user::is_zero(y.upper()))
Chris@16 276 return interval_lib::detail::div_zero<T, Policies>(x);
Chris@16 277 else
Chris@16 278 return interval_lib::detail::div_negative<T, Policies>(x, y.lower());
Chris@16 279 else
Chris@16 280 if (!interval_lib::user::is_zero(y.upper()))
Chris@16 281 return interval_lib::detail::div_positive<T, Policies>(x, y.upper());
Chris@16 282 else
Chris@16 283 return interval<T, Policies>::empty();
Chris@16 284 else
Chris@16 285 return interval_lib::detail::div_non_zero(x, y);
Chris@16 286 }
Chris@16 287
Chris@16 288 template<class T, class Policies> inline
Chris@16 289 interval<T, Policies> operator/(const interval<T, Policies>& x, const T& y)
Chris@16 290 {
Chris@16 291 if (interval_lib::detail::test_input(x, y) || interval_lib::user::is_zero(y))
Chris@16 292 return interval<T, Policies>::empty();
Chris@16 293 typename Policies::rounding rnd;
Chris@16 294 const T& xl = x.lower();
Chris@16 295 const T& xu = x.upper();
Chris@16 296 if (interval_lib::user::is_neg(y))
Chris@16 297 return interval<T, Policies>(rnd.div_down(xu, y), rnd.div_up(xl, y), true);
Chris@16 298 else
Chris@16 299 return interval<T, Policies>(rnd.div_down(xl, y), rnd.div_up(xu, y), true);
Chris@16 300 }
Chris@16 301
Chris@16 302 } // namespace numeric
Chris@16 303 } // namespace boost
Chris@16 304
Chris@16 305 #endif // BOOST_NUMERIC_INTERVAL_ARITH_HPP