os/ossrv/ossrv_pub/boost_apis/boost/numeric/interval/transc.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* Boost interval/transc.hpp template implementation file
sl@0
     2
 *
sl@0
     3
 * Copyright 2000 Jens Maurer
sl@0
     4
 * Copyright 2002 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
sl@0
     5
 *
sl@0
     6
 * Distributed under the Boost Software License, Version 1.0.
sl@0
     7
 * (See accompanying file LICENSE_1_0.txt or
sl@0
     8
 * copy at http://www.boost.org/LICENSE_1_0.txt)
sl@0
     9
 */
sl@0
    10
sl@0
    11
#ifndef BOOST_NUMERIC_INTERVAL_TRANSC_HPP
sl@0
    12
#define BOOST_NUMERIC_INTERVAL_TRANSC_HPP
sl@0
    13
sl@0
    14
#include <boost/config.hpp>
sl@0
    15
#include <boost/numeric/interval/detail/interval_prototype.hpp>
sl@0
    16
#include <boost/numeric/interval/detail/bugs.hpp>
sl@0
    17
#include <boost/numeric/interval/detail/test_input.hpp>
sl@0
    18
#include <boost/numeric/interval/rounding.hpp>
sl@0
    19
#include <boost/numeric/interval/constants.hpp>
sl@0
    20
#include <boost/numeric/interval/arith.hpp>
sl@0
    21
#include <boost/numeric/interval/arith2.hpp>
sl@0
    22
#include <algorithm>
sl@0
    23
sl@0
    24
namespace boost {
sl@0
    25
namespace numeric {
sl@0
    26
sl@0
    27
template<class T, class Policies> inline
sl@0
    28
interval<T, Policies> exp(const interval<T, Policies>& x)
sl@0
    29
{
sl@0
    30
  typedef interval<T, Policies> I;
sl@0
    31
  if (interval_lib::detail::test_input(x))
sl@0
    32
    return I::empty();
sl@0
    33
  typename Policies::rounding rnd;
sl@0
    34
  return I(rnd.exp_down(x.lower()), rnd.exp_up(x.upper()), true);
sl@0
    35
}
sl@0
    36
sl@0
    37
template<class T, class Policies> inline
sl@0
    38
interval<T, Policies> log(const interval<T, Policies>& x)
sl@0
    39
{
sl@0
    40
  typedef interval<T, Policies> I;
sl@0
    41
  if (interval_lib::detail::test_input(x) ||
sl@0
    42
      !interval_lib::user::is_pos(x.upper()))
sl@0
    43
    return I::empty();
sl@0
    44
  typename Policies::rounding rnd;
sl@0
    45
  typedef typename Policies::checking checking;
sl@0
    46
  T l = !interval_lib::user::is_pos(x.lower())
sl@0
    47
             ? checking::neg_inf() : rnd.log_down(x.lower());
sl@0
    48
  return I(l, rnd.log_up(x.upper()), true);
sl@0
    49
}
sl@0
    50
sl@0
    51
template<class T, class Policies> inline
sl@0
    52
interval<T, Policies> cos(const interval<T, Policies>& x)
sl@0
    53
{
sl@0
    54
  if (interval_lib::detail::test_input(x))
sl@0
    55
    return interval<T, Policies>::empty();
sl@0
    56
  typename Policies::rounding rnd;
sl@0
    57
  typedef interval<T, Policies> I;
sl@0
    58
  typedef typename interval_lib::unprotect<I>::type R;
sl@0
    59
sl@0
    60
  // get lower bound within [0, pi]
sl@0
    61
  const R pi2 = interval_lib::pi_twice<R>();
sl@0
    62
  R tmp = fmod((const R&)x, pi2);
sl@0
    63
  if (width(tmp) >= pi2.lower())
sl@0
    64
    return I(static_cast<T>(-1), static_cast<T>(1), true); // we are covering a full period
sl@0
    65
  if (tmp.lower() >= interval_lib::constants::pi_upper<T>())
sl@0
    66
    return -cos(tmp - interval_lib::pi<R>());
sl@0
    67
  T l = tmp.lower();
sl@0
    68
  T u = tmp.upper();
sl@0
    69
sl@0
    70
  BOOST_USING_STD_MIN();
sl@0
    71
  // separate into monotone subintervals
sl@0
    72
  if (u <= interval_lib::constants::pi_lower<T>())
sl@0
    73
    return I(rnd.cos_down(u), rnd.cos_up(l), true);
sl@0
    74
  else if (u <= pi2.lower())
sl@0
    75
    return I(static_cast<T>(-1), rnd.cos_up(min BOOST_PREVENT_MACRO_SUBSTITUTION(rnd.sub_down(pi2.lower(), u), l)), true);
sl@0
    76
  else
sl@0
    77
    return I(static_cast<T>(-1), static_cast<T>(1), true);
sl@0
    78
}
sl@0
    79
sl@0
    80
template<class T, class Policies> inline
sl@0
    81
interval<T, Policies> sin(const interval<T, Policies>& x)
sl@0
    82
{
sl@0
    83
  typedef interval<T, Policies> I;
sl@0
    84
  if (interval_lib::detail::test_input(x))
sl@0
    85
    return I::empty();
sl@0
    86
  typename Policies::rounding rnd;
sl@0
    87
  typedef typename interval_lib::unprotect<I>::type R;
sl@0
    88
  I r = cos((const R&)x - interval_lib::pi_half<R>());
sl@0
    89
  (void)&rnd;
sl@0
    90
  return r;
sl@0
    91
}
sl@0
    92
sl@0
    93
template<class T, class Policies> inline
sl@0
    94
interval<T, Policies> tan(const interval<T, Policies>& x)
sl@0
    95
{
sl@0
    96
  typedef interval<T, Policies> I;
sl@0
    97
  if (interval_lib::detail::test_input(x))
sl@0
    98
    return I::empty();
sl@0
    99
  typename Policies::rounding rnd;
sl@0
   100
  typedef typename interval_lib::unprotect<I>::type R;
sl@0
   101
sl@0
   102
  // get lower bound within [-pi/2, pi/2]
sl@0
   103
  const R pi = interval_lib::pi<R>();
sl@0
   104
  R tmp = fmod((const R&)x, pi);
sl@0
   105
  const T pi_half_d = interval_lib::constants::pi_half_lower<T>();
sl@0
   106
  if (tmp.lower() >= pi_half_d)
sl@0
   107
    tmp -= pi;
sl@0
   108
  if (tmp.lower() <= -pi_half_d || tmp.upper() >= pi_half_d)
sl@0
   109
    return I::whole();
sl@0
   110
  return I(rnd.tan_down(tmp.lower()), rnd.tan_up(tmp.upper()), true);
sl@0
   111
}
sl@0
   112
sl@0
   113
template<class T, class Policies> inline
sl@0
   114
interval<T, Policies> asin(const interval<T, Policies>& x)
sl@0
   115
{
sl@0
   116
  typedef interval<T, Policies> I;
sl@0
   117
  if (interval_lib::detail::test_input(x)
sl@0
   118
     || x.upper() < static_cast<T>(-1) || x.lower() > static_cast<T>(1))
sl@0
   119
    return I::empty();
sl@0
   120
  typename Policies::rounding rnd;
sl@0
   121
  T l = (x.lower() <= static_cast<T>(-1))
sl@0
   122
             ? -interval_lib::constants::pi_half_upper<T>()
sl@0
   123
             : rnd.asin_down(x.lower());
sl@0
   124
  T u = (x.upper() >= static_cast<T>(1) )
sl@0
   125
             ?  interval_lib::constants::pi_half_upper<T>()
sl@0
   126
             : rnd.asin_up  (x.upper());
sl@0
   127
  return I(l, u, true);
sl@0
   128
}
sl@0
   129
sl@0
   130
template<class T, class Policies> inline
sl@0
   131
interval<T, Policies> acos(const interval<T, Policies>& x)
sl@0
   132
{
sl@0
   133
  typedef interval<T, Policies> I;
sl@0
   134
  if (interval_lib::detail::test_input(x)
sl@0
   135
     || x.upper() < static_cast<T>(-1) || x.lower() > static_cast<T>(1))
sl@0
   136
    return I::empty();
sl@0
   137
  typename Policies::rounding rnd;
sl@0
   138
  T l = (x.upper() >= static_cast<T>(1) )
sl@0
   139
          ? static_cast<T>(0)
sl@0
   140
          : rnd.acos_down(x.upper());
sl@0
   141
  T u = (x.lower() <= static_cast<T>(-1))
sl@0
   142
          ? interval_lib::constants::pi_upper<T>()
sl@0
   143
          : rnd.acos_up  (x.lower());
sl@0
   144
  return I(l, u, true);
sl@0
   145
}
sl@0
   146
sl@0
   147
template<class T, class Policies> inline
sl@0
   148
interval<T, Policies> atan(const interval<T, Policies>& x)
sl@0
   149
{
sl@0
   150
  typedef interval<T, Policies> I;
sl@0
   151
  if (interval_lib::detail::test_input(x))
sl@0
   152
    return I::empty();
sl@0
   153
  typename Policies::rounding rnd;
sl@0
   154
  return I(rnd.atan_down(x.lower()), rnd.atan_up(x.upper()), true);
sl@0
   155
}
sl@0
   156
sl@0
   157
template<class T, class Policies> inline
sl@0
   158
interval<T, Policies> sinh(const interval<T, Policies>& x)
sl@0
   159
{
sl@0
   160
  typedef interval<T, Policies> I;
sl@0
   161
  if (interval_lib::detail::test_input(x))
sl@0
   162
    return I::empty();
sl@0
   163
  typename Policies::rounding rnd;
sl@0
   164
  return I(rnd.sinh_down(x.lower()), rnd.sinh_up(x.upper()), true);
sl@0
   165
}
sl@0
   166
sl@0
   167
template<class T, class Policies> inline
sl@0
   168
interval<T, Policies> cosh(const interval<T, Policies>& x)
sl@0
   169
{
sl@0
   170
  typedef interval<T, Policies> I;
sl@0
   171
  if (interval_lib::detail::test_input(x))
sl@0
   172
    return I::empty();
sl@0
   173
  typename Policies::rounding rnd;
sl@0
   174
  if (interval_lib::user::is_neg(x.upper()))
sl@0
   175
    return I(rnd.cosh_down(x.upper()), rnd.cosh_up(x.lower()), true);
sl@0
   176
  else if (!interval_lib::user::is_neg(x.lower()))
sl@0
   177
    return I(rnd.cosh_down(x.lower()), rnd.cosh_up(x.upper()), true);
sl@0
   178
  else
sl@0
   179
    return I(static_cast<T>(0), rnd.cosh_up(-x.lower() > x.upper() ? x.lower() : x.upper()), true);
sl@0
   180
}
sl@0
   181
sl@0
   182
template<class T, class Policies> inline
sl@0
   183
interval<T, Policies> tanh(const interval<T, Policies>& x)
sl@0
   184
{
sl@0
   185
  typedef interval<T, Policies> I;
sl@0
   186
  if (interval_lib::detail::test_input(x))
sl@0
   187
    return I::empty();
sl@0
   188
  typename Policies::rounding rnd;
sl@0
   189
  return I(rnd.tanh_down(x.lower()), rnd.tanh_up(x.upper()), true);
sl@0
   190
}
sl@0
   191
sl@0
   192
template<class T, class Policies> inline
sl@0
   193
interval<T, Policies> asinh(const interval<T, Policies>& x)
sl@0
   194
{
sl@0
   195
  typedef interval<T, Policies> I;
sl@0
   196
  if (interval_lib::detail::test_input(x))
sl@0
   197
    return I::empty();
sl@0
   198
  typename Policies::rounding rnd;
sl@0
   199
  return I(rnd.asinh_down(x.lower()), rnd.asinh_up(x.upper()), true);
sl@0
   200
}
sl@0
   201
sl@0
   202
template<class T, class Policies> inline
sl@0
   203
interval<T, Policies> acosh(const interval<T, Policies>& x)
sl@0
   204
{
sl@0
   205
  typedef interval<T, Policies> I;
sl@0
   206
  if (interval_lib::detail::test_input(x) || x.upper() < static_cast<T>(1))
sl@0
   207
    return I::empty();
sl@0
   208
  typename Policies::rounding rnd;
sl@0
   209
  T l = x.lower() <= static_cast<T>(1) ? static_cast<T>(0) : rnd.acosh_down(x.lower());
sl@0
   210
  return I(l, rnd.acosh_up(x.upper()), true);
sl@0
   211
}
sl@0
   212
sl@0
   213
template<class T, class Policies> inline
sl@0
   214
interval<T, Policies> atanh(const interval<T, Policies>& x)
sl@0
   215
{
sl@0
   216
  typedef interval<T, Policies> I;
sl@0
   217
  if (interval_lib::detail::test_input(x)
sl@0
   218
      || x.upper() < static_cast<T>(-1) || x.lower() > static_cast<T>(1))
sl@0
   219
    return I::empty();
sl@0
   220
  typename Policies::rounding rnd;
sl@0
   221
  typedef typename Policies::checking checking;
sl@0
   222
  T l = (x.lower() <= static_cast<T>(-1))
sl@0
   223
             ? checking::neg_inf() : rnd.atanh_down(x.lower());
sl@0
   224
  T u = (x.upper() >= static_cast<T>(1) )
sl@0
   225
             ? checking::pos_inf() : rnd.atanh_up  (x.upper());
sl@0
   226
  return I(l, u, true);
sl@0
   227
}
sl@0
   228
sl@0
   229
} // namespace numeric
sl@0
   230
} // namespace boost
sl@0
   231
sl@0
   232
#endif // BOOST_NUMERIC_INTERVAL_TRANSC_HPP