Esempio n. 1
0
template<class T, class Policies> inline
interval<T, Policies> operator*(const interval<T, Policies>& x,
                                const interval<T, Policies>& y)
{
  BOOST_NUMERIC_INTERVAL_using_max(min);
  BOOST_NUMERIC_INTERVAL_using_max(max);
  typedef interval<T, Policies> I;
  if (interval_lib::detail::test_input(x, y))
    return I::empty();
  typename Policies::rounding rnd;
  const T& xl = x.lower();
  const T& xu = x.upper();
  const T& yl = y.lower();
  const T& yu = y.upper();

  if (interval_lib::detail::is_neg(xl))
    if (interval_lib::detail::is_pos(xu))
      if (interval_lib::detail::is_neg(yl))
        if (interval_lib::detail::is_pos(yu)) // M * M
          return I(min(rnd.mul_down(xl, yu), rnd.mul_down(xu, yl)),
                   max(rnd.mul_up  (xl, yl), rnd.mul_up  (xu, yu)), true);
        else                    // M * N
          return I(rnd.mul_down(xu, yl), rnd.mul_up(xl, yl), true);
      else
        if (interval_lib::detail::is_pos(yu)) // M * P
          return I(rnd.mul_down(xl, yu), rnd.mul_up(xu, yu), true);
        else                    // M * Z
          return I(0, 0, true);
    else
      if (interval_lib::detail::is_neg(yl))
        if (interval_lib::detail::is_pos(yu)) // N * M
          return I(rnd.mul_down(xl, yu), rnd.mul_up(xl, yl), true);
        else                    // N * N
          return I(rnd.mul_down(xu, yu), rnd.mul_up(xl, yl), true);
      else
        if (interval_lib::detail::is_pos(yu)) // N * P
          return I(rnd.mul_down(xl, yu), rnd.mul_up(xu, yl), true);
        else                    // N * Z
          return I(0, 0, true);
  else
    if (interval_lib::detail::is_pos(xu))
      if (interval_lib::detail::is_neg(yl))
        if (interval_lib::detail::is_pos(yu)) // P * M
          return I(rnd.mul_down(xu, yl), rnd.mul_up(xu, yu), true);
        else                    // P * N
          return I(rnd.mul_down(xu, yl), rnd.mul_up(xl, yu), true);
      else
        if (interval_lib::detail::is_pos(yu)) // P * P
          return I(rnd.mul_down(xl, yl), rnd.mul_up(xu, yu), true);
        else                    // P * Z
          return I(0, 0, true);
    else                        // Z * ?
      return I(0, 0, true);
}
Esempio n. 2
0
template<class T, class Policies> inline
interval<T, Policies> intersect(const interval<T, Policies>& x,
                                const interval<T, Policies>& y)
{
  BOOST_NUMERIC_INTERVAL_using_max(min);
  BOOST_NUMERIC_INTERVAL_using_max(max);
  if (interval_lib::detail::test_input(x, y))
    return interval<T, Policies>::empty();
  const T& l = max(x.lower(), y.lower());
  const T& u = min(x.upper(), y.upper());
  if (l <= u) return interval<T, Policies>(l, u, true);
  else        return interval<T, Policies>::empty();
}
Esempio n. 3
0
template<class T, class Policies> inline
interval<T, Policies> hull(const T& x, const interval<T, Policies>& y)
{
  BOOST_NUMERIC_INTERVAL_using_max(min);
  BOOST_NUMERIC_INTERVAL_using_max(max);
  bool bad_x = interval_lib::detail::test_input<T, Policies>(x);
  bool bad_y = interval_lib::detail::test_input(y);
  if (bad_x)
    if (bad_y) return interval<T, Policies>::empty();
    else       return y;
  else
    if (bad_y) return interval<T, Policies>(x, x, true);
  return interval<T, Policies>(min(x, y.lower()),
                               max(x, y.upper()), true);
}
Esempio n. 4
0
template<class T, class Policies> inline
interval<T, Policies> min(const T& x, const interval<T, Policies>& y)
{
  BOOST_NUMERIC_INTERVAL_using_max(min);
  typedef interval<T, Policies> I;
  if (interval_lib::detail::test_input(x, y))
    return I::empty();
  return I(min(x, y.lower()), min(x, y.upper()), true);
}
Esempio n. 5
0
template<class T, class Policies> inline
interval<T, Policies> abs(const interval<T, Policies>& x)
{
  BOOST_NUMERIC_INTERVAL_using_max(max);
  typedef interval<T, Policies> I;
  if (interval_lib::detail::test_input(x))
    return I::empty();
  if (!interval_lib::detail::is_neg(x.lower())) return x;
  if (interval_lib::detail::is_neg(x.upper())) return -x;
  return I(0, max(-x.lower(), x.upper()), true);
}