epoc32/include/stdapis/boost/math/complex/acosh.hpp
branchSymbian3
changeset 4 837f303aceeb
parent 3 e1b950c65cb4
equal deleted inserted replaced
3:e1b950c65cb4 4:837f303aceeb
     1 //    boost asinh.hpp header file
     1 //  (C) Copyright John Maddock 2005.
       
     2 //  Use, modification and distribution are subject to the
       
     3 //  Boost Software License, Version 1.0. (See accompanying file
       
     4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     2 
     5 
     3 //  (C) Copyright Eric Ford 2001 & Hubert Holin.
     6 #ifndef BOOST_MATH_COMPLEX_ACOSH_INCLUDED
     4 //  Distributed under the Boost Software License, Version 1.0. (See
     7 #define BOOST_MATH_COMPLEX_ACOSH_INCLUDED
     5 //  accompanying file LICENSE_1_0.txt or copy at
       
     6 //  http://www.boost.org/LICENSE_1_0.txt)
       
     7 
     8 
     8 // See http://www.boost.org for updates, documentation, and revision history.
     9 #ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED
       
    10 #  include <boost/math/complex/details.hpp>
       
    11 #endif
       
    12 #ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED
       
    13 #  include <boost/math/complex/acos.hpp>
       
    14 #endif
     9 
    15 
    10 #ifndef BOOST_ACOSH_HPP
    16 namespace boost{ namespace math{
    11 #define BOOST_ACOSH_HPP
       
    12 
    17 
    13 
    18 template<class T> 
    14 #include <cmath>
    19 inline std::complex<T> acosh(const std::complex<T>& z)
    15 #include <limits>
       
    16 #include <string>
       
    17 #include <stdexcept>
       
    18 
       
    19 
       
    20 #include <boost/config.hpp>
       
    21 
       
    22 
       
    23 // This is the inverse of the hyperbolic cosine function.
       
    24 
       
    25 namespace boost
       
    26 {
    20 {
    27     namespace math
    21    //
    28     {
    22    // We use the relation acosh(z) = +-i acos(z)
    29 #if defined(__GNUC__) && (__GNUC__ < 3)
    23    // Choosing the sign of multiplier to give real(acosh(z)) >= 0
    30         // gcc 2.x ignores function scope using declarations,
    24    // as well as compatibility with C99.
    31         // put them in the scope of the enclosing namespace instead:
    25    //
    32         
    26    std::complex<T> result = boost::math::acos(z);
    33         using    ::std::abs;
    27    if(!detail::test_is_nan(result.imag()) && result.imag() <= 0)
    34         using    ::std::sqrt;
    28       return detail::mult_i(result);
    35         using    ::std::log;
    29    return detail::mult_minus_i(result);
    36         
       
    37         using    ::std::numeric_limits;
       
    38 #endif
       
    39         
       
    40 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
       
    41         // This is the main fare
       
    42         
       
    43         template<typename T>
       
    44         inline T    acosh(const T x)
       
    45         {
       
    46             using    ::std::abs;
       
    47             using    ::std::sqrt;
       
    48             using    ::std::log;
       
    49             
       
    50             using    ::std::numeric_limits;
       
    51             
       
    52             
       
    53             T const    one = static_cast<T>(1);
       
    54             T const    two = static_cast<T>(2);
       
    55             
       
    56             static T const    taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
       
    57             static T const    taylor_n_bound = sqrt(taylor_2_bound);
       
    58             static T const    upper_taylor_2_bound = one/taylor_2_bound;
       
    59             
       
    60             if        (x < one)
       
    61             {
       
    62                 if    (numeric_limits<T>::has_quiet_NaN)
       
    63                 {
       
    64                     return(numeric_limits<T>::quiet_NaN());
       
    65                 }
       
    66                 else
       
    67                 {
       
    68                     ::std::string        error_reporting("Argument to atanh is strictly greater than +1 or strictly smaller than -1!");
       
    69                     ::std::domain_error  bad_argument(error_reporting);
       
    70                     
       
    71                     throw(bad_argument);
       
    72                 }
       
    73             }
       
    74             else if    (x >= taylor_n_bound)
       
    75             {
       
    76                 if    (x > upper_taylor_2_bound)
       
    77                 {
       
    78                     // approximation by laurent series in 1/x at 0+ order from -1 to 0
       
    79                     return( log( x*two) );
       
    80                 }
       
    81                 else
       
    82                 {
       
    83                     return( log( x + sqrt(x*x-one) ) );
       
    84                 }
       
    85             }
       
    86             else
       
    87             {
       
    88                 T    y = sqrt(x-one);
       
    89                 
       
    90                 // approximation by taylor series in y at 0 up to order 2
       
    91                 T    result = y;
       
    92                 
       
    93                 if    (y >= taylor_2_bound)
       
    94                 {
       
    95                     T    y3 = y*y*y;
       
    96                     
       
    97                     // approximation by taylor series in y at 0 up to order 4
       
    98                     result -= y3/static_cast<T>(12);
       
    99                 }
       
   100                 
       
   101                 return(sqrt(static_cast<T>(2))*result);
       
   102             }
       
   103         }
       
   104 #else
       
   105         // These are implementation details (for main fare see below)
       
   106         
       
   107         namespace detail
       
   108         {
       
   109             template    <
       
   110                             typename T,
       
   111                             bool QuietNanSupported
       
   112                         >
       
   113             struct    acosh_helper2_t
       
   114             {
       
   115                 static T    get_NaN()
       
   116                 {
       
   117                     return(::std::numeric_limits<T>::quiet_NaN());
       
   118                 }
       
   119             };  // boost::detail::acosh_helper2_t
       
   120             
       
   121             
       
   122             template<typename T>
       
   123             struct    acosh_helper2_t<T, false>
       
   124             {
       
   125                 static T    get_NaN()
       
   126                 {
       
   127                     ::std::string        error_reporting("Argument to acosh is greater than or equal to +1!");
       
   128                     ::std::domain_error  bad_argument(error_reporting);
       
   129                     
       
   130                     throw(bad_argument);
       
   131                 }
       
   132             };  // boost::detail::acosh_helper2_t
       
   133         
       
   134         }  // boost::detail
       
   135         
       
   136         
       
   137         // This is the main fare
       
   138         
       
   139         template<typename T>
       
   140         inline T    acosh(const T x)
       
   141         {
       
   142             using    ::std::abs;
       
   143             using    ::std::sqrt;
       
   144             using    ::std::log;
       
   145             
       
   146             using    ::std::numeric_limits;
       
   147             
       
   148             typedef    detail::acosh_helper2_t<T, std::numeric_limits<T>::has_quiet_NaN>    helper2_type;
       
   149             
       
   150             
       
   151             T const    one = static_cast<T>(1);
       
   152             T const    two = static_cast<T>(2);
       
   153             
       
   154             static T const    taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
       
   155             static T const    taylor_n_bound = sqrt(taylor_2_bound);
       
   156             static T const    upper_taylor_2_bound = one/taylor_2_bound;
       
   157             
       
   158             if        (x < one)
       
   159             {
       
   160                 return(helper2_type::get_NaN());
       
   161             }
       
   162             else if    (x >= taylor_n_bound)
       
   163             {
       
   164                 if    (x > upper_taylor_2_bound)
       
   165                 {
       
   166                     // approximation by laurent series in 1/x at 0+ order from -1 to 0
       
   167                     return( log( x*two) );
       
   168                 }
       
   169                 else
       
   170                 {
       
   171                     return( log( x + sqrt(x*x-one) ) );
       
   172                 }
       
   173             }
       
   174             else
       
   175             {
       
   176                 T    y = sqrt(x-one);
       
   177                 
       
   178                 // approximation by taylor series in y at 0 up to order 2
       
   179                 T    result = y;
       
   180                 
       
   181                 if    (y >= taylor_2_bound)
       
   182                 {
       
   183                     T    y3 = y*y*y;
       
   184                     
       
   185                     // approximation by taylor series in y at 0 up to order 4
       
   186                     result -= y3/static_cast<T>(12);
       
   187                 }
       
   188                 
       
   189                 return(sqrt(static_cast<T>(2))*result);
       
   190             }
       
   191         }
       
   192 #endif /* defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) */
       
   193     }
       
   194 }
    30 }
   195 
    31 
   196 #endif /* BOOST_ACOSH_HPP */
    32 } } // namespaces
   197 
    33 
   198 
    34 #endif // BOOST_MATH_COMPLEX_ACOSH_INCLUDED