epoc32/include/stdapis/boost/math/complex/acosh.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100 (2010-03-31)
branchSymbian2
changeset 3 e1b950c65cb4
parent 2 epoc32/include/stdapis/boost/math/special_functions/acosh.hpp@2fe1408b6811
child 4 837f303aceeb
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     1 //    boost asinh.hpp header file
     2 
     3 //  (C) Copyright Eric Ford 2001 & Hubert Holin.
     4 //  Distributed under the Boost Software License, Version 1.0. (See
     5 //  accompanying file LICENSE_1_0.txt or copy at
     6 //  http://www.boost.org/LICENSE_1_0.txt)
     7 
     8 // See http://www.boost.org for updates, documentation, and revision history.
     9 
    10 #ifndef BOOST_ACOSH_HPP
    11 #define BOOST_ACOSH_HPP
    12 
    13 
    14 #include <cmath>
    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 {
    27     namespace math
    28     {
    29 #if defined(__GNUC__) && (__GNUC__ < 3)
    30         // gcc 2.x ignores function scope using declarations,
    31         // put them in the scope of the enclosing namespace instead:
    32         
    33         using    ::std::abs;
    34         using    ::std::sqrt;
    35         using    ::std::log;
    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 }
   195 
   196 #endif /* BOOST_ACOSH_HPP */
   197 
   198