mirror of
https://github.com/boostorg/math.git
synced 2026-02-13 00:22:23 +00:00
update from Hubert Holin
now works with significantly more compilers [SVN r11284]
This commit is contained in:
@@ -18,6 +18,17 @@ namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
// gcc 2.x ignores function scope using declarations,
|
||||
// put them in the scope of the enclosing namespace instead:
|
||||
using ::std::valarray;
|
||||
using ::std::sqrt;
|
||||
using ::std::cos;
|
||||
using ::std::sin;
|
||||
using ::std::exp;
|
||||
using ::std::cosh;
|
||||
#endif
|
||||
|
||||
#define BOOST_OCTONION_ACCESSOR_GENERATOR(type) \
|
||||
type real() const \
|
||||
{ \
|
||||
|
||||
@@ -23,6 +23,17 @@ namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
// gcc 2.x ignores function scope using declarations,
|
||||
// put them in the scope of the enclosing namespace instead:
|
||||
using ::std::valarray;
|
||||
using ::std::sqrt;
|
||||
using ::std::cos;
|
||||
using ::std::sin;
|
||||
using ::std::exp;
|
||||
using ::std::cosh;
|
||||
#endif
|
||||
|
||||
#define BOOST_QUATERNION_ACCESSOR_GENERATOR(type) \
|
||||
type real() const \
|
||||
{ \
|
||||
|
||||
129
include/boost/math/special_functions/acosh.hpp
Normal file
129
include/boost/math/special_functions/acosh.hpp
Normal file
@@ -0,0 +1,129 @@
|
||||
// boost asinh.hpp header file
|
||||
|
||||
// (C) Copyright Eric Ford 2001 & Hubert Holin. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_ACOSH_HPP
|
||||
#define BOOST_ACOSH_HPP
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/limits.hpp>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
// This is the inverse of the hyperbolic cosine function.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
// gcc 2.x ignores function scope using declarations,
|
||||
// put them in the scope of the enclosing namespace instead:
|
||||
|
||||
using ::std::abs;
|
||||
using ::std::sqrt;
|
||||
using ::std::log;
|
||||
|
||||
using ::std::numeric_limits;
|
||||
#endif
|
||||
|
||||
// These are implementation details (for main fare see below)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <
|
||||
typename T,
|
||||
bool QuietNanSupported
|
||||
>
|
||||
struct acosh_helper2_t
|
||||
{
|
||||
static T get_NaN()
|
||||
{
|
||||
return(::std::numeric_limits<T>::quiet_NaN());
|
||||
}
|
||||
}; // boost::detail::acosh_helper2_t
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct acosh_helper2_t<T, false>
|
||||
{
|
||||
static T get_NaN()
|
||||
{
|
||||
::std::string error_reporting("Argument to acosh is greater than or equal to +1!");
|
||||
::std::domain_error bad_argument(error_reporting);
|
||||
|
||||
throw(bad_argument);
|
||||
}
|
||||
}; // boost::detail::acosh_helper2_t
|
||||
|
||||
} // boost::detail
|
||||
|
||||
|
||||
// This is the main fare
|
||||
|
||||
template<typename T>
|
||||
inline T acosh(const T x)
|
||||
{
|
||||
using ::std::abs;
|
||||
using ::std::sqrt;
|
||||
using ::std::log;
|
||||
|
||||
using ::std::numeric_limits;
|
||||
|
||||
typedef detail::acosh_helper2_t<T, std::numeric_limits<T>::has_quiet_NaN> helper2_type;
|
||||
|
||||
|
||||
T const one = static_cast<T>(1);
|
||||
T const two = static_cast<T>(2);
|
||||
|
||||
static T const taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
|
||||
static T const taylor_n_bound = sqrt(taylor_2_bound);
|
||||
static T const upper_taylor_2_bound = one/taylor_2_bound;
|
||||
|
||||
if (x < one)
|
||||
{
|
||||
return(helper2_type::get_NaN());
|
||||
}
|
||||
else if (x >= taylor_n_bound)
|
||||
{
|
||||
if (x > upper_taylor_2_bound)
|
||||
{
|
||||
// approximation by laurent series in 1/x at 0+ order from -1 to 0
|
||||
return( log( x*two) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return( log( x + sqrt(x*x-one) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
T y = sqrt(x-one);
|
||||
|
||||
// approximation by taylor series in y at 0 up to order 2
|
||||
T result = y;
|
||||
|
||||
if (y >= taylor_2_bound)
|
||||
{
|
||||
T y3 = y*y*y;
|
||||
|
||||
// approximation by taylor series in y at 0 up to order 4
|
||||
result -= y3/static_cast<T>(12);
|
||||
}
|
||||
|
||||
return(sqrt(static_cast<T>(2))*result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BOOST_ACOSH_HPP */
|
||||
|
||||
|
||||
98
include/boost/math/special_functions/asinh.hpp
Normal file
98
include/boost/math/special_functions/asinh.hpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// boost asinh.hpp header file
|
||||
|
||||
// (C) Copyright Eric Ford & Hubert Holin 2001. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_ASINH_HPP
|
||||
#define BOOST_ASINH_HPP
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/limits.hpp>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
// This is the inverse of the hyperbolic sine function.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
// gcc 2.x ignores function scope using declarations,
|
||||
// put them in the scope of the enclosing namespace instead:
|
||||
|
||||
using ::std::abs;
|
||||
using ::std::sqrt;
|
||||
using ::std::log;
|
||||
|
||||
using ::std::numeric_limits;
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline T asinh(const T x)
|
||||
{
|
||||
using ::std::abs;
|
||||
using ::std::sqrt;
|
||||
using ::std::log;
|
||||
|
||||
using ::std::numeric_limits;
|
||||
|
||||
|
||||
T const one = static_cast<T>(1);
|
||||
T const two = static_cast<T>(2);
|
||||
|
||||
static T const taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
|
||||
static T const taylor_n_bound = sqrt(taylor_2_bound);
|
||||
static T const upper_taylor_2_bound = one/taylor_2_bound;
|
||||
static T const upper_taylor_n_bound = one/taylor_n_bound;
|
||||
|
||||
if (x >= +taylor_n_bound)
|
||||
{
|
||||
if (x > upper_taylor_n_bound)
|
||||
{
|
||||
if (x > upper_taylor_2_bound)
|
||||
{
|
||||
// approximation by laurent series in 1/x at 0+ order from -1 to 0
|
||||
return( log( x * two) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// approximation by laurent series in 1/x at 0+ order from -1 to 1
|
||||
return( log( x*two + (one/(x*two)) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return( log( x + sqrt(x*x+one) ) );
|
||||
}
|
||||
}
|
||||
else if (x <= -taylor_n_bound)
|
||||
{
|
||||
return(-asinh(-x));
|
||||
}
|
||||
else
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 2
|
||||
T result = x;
|
||||
|
||||
if (abs(x) >= taylor_2_bound)
|
||||
{
|
||||
T x3 = x*x*x;
|
||||
|
||||
// approximation by taylor series in x at 0 up to order 4
|
||||
result -= x3/static_cast<T>(6);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BOOST_ASINH_HPP */
|
||||
@@ -23,6 +23,17 @@ namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
// gcc 2.x ignores function scope using declarations,
|
||||
// put them in the scope of the enclosing namespace instead:
|
||||
|
||||
using ::std::abs;
|
||||
using ::std::sqrt;
|
||||
using ::std::log;
|
||||
|
||||
using ::std::numeric_limits;
|
||||
#endif
|
||||
|
||||
// These are implementation details (for main fare see below)
|
||||
|
||||
namespace detail
|
||||
@@ -35,12 +46,12 @@ namespace boost
|
||||
{
|
||||
static T get_pos_infinity()
|
||||
{
|
||||
return(+std::numeric_limits<T>::infinity());
|
||||
return(+::std::numeric_limits<T>::infinity());
|
||||
}
|
||||
|
||||
static T get_neg_infinity()
|
||||
{
|
||||
return(-std::numeric_limits<T>::infinity());
|
||||
return(-::std::numeric_limits<T>::infinity());
|
||||
}
|
||||
}; // boost::math::detail::atanh_helper1_t
|
||||
|
||||
@@ -51,7 +62,7 @@ namespace boost
|
||||
static T get_pos_infinity()
|
||||
{
|
||||
::std::string error_reporting("Argument to atanh is +1 (result: +Infinity)!");
|
||||
::std::out_of_range bad_argument(error_reporting);
|
||||
::std::out_of_range bad_argument(error_reporting);
|
||||
|
||||
throw(bad_argument);
|
||||
}
|
||||
@@ -59,7 +70,7 @@ namespace boost
|
||||
static T get_neg_infinity()
|
||||
{
|
||||
::std::string error_reporting("Argument to atanh is -1 (result: -Infinity)!");
|
||||
::std::out_of_range bad_argument(error_reporting);
|
||||
::std::out_of_range bad_argument(error_reporting);
|
||||
|
||||
throw(bad_argument);
|
||||
}
|
||||
@@ -72,14 +83,9 @@ namespace boost
|
||||
>
|
||||
struct atanh_helper2_t
|
||||
{
|
||||
static T get_pos_NaN()
|
||||
static T get_NaN()
|
||||
{
|
||||
return(+std::numeric_limits<T>::quiet_NaN());
|
||||
}
|
||||
|
||||
static T get_neg_NaN()
|
||||
{
|
||||
return(-std::numeric_limits<T>::quiet_NaN());
|
||||
return(::std::numeric_limits<T>::quiet_NaN());
|
||||
}
|
||||
}; // boost::detail::atanh_helper2_t
|
||||
|
||||
@@ -87,18 +93,10 @@ namespace boost
|
||||
template<typename T>
|
||||
struct atanh_helper2_t<T, false>
|
||||
{
|
||||
static T get_pos_NaN()
|
||||
static T get_NaN()
|
||||
{
|
||||
::std::string error_reporting("Argument to atanh is strictly greater than +1!");
|
||||
::std::domain_error bad_argument(error_reporting);
|
||||
|
||||
throw(bad_argument);
|
||||
}
|
||||
|
||||
static T get_neg_NaN()
|
||||
{
|
||||
::std::string error_reporting("Argument to atanh is strictly smaller than -1!");
|
||||
::std::domain_error bad_argument(error_reporting);
|
||||
::std::string error_reporting("Argument to atanh is strictly greater than +1 or strictly smaller than -1!");
|
||||
::std::domain_error bad_argument(error_reporting);
|
||||
|
||||
throw(bad_argument);
|
||||
}
|
||||
@@ -113,44 +111,55 @@ namespace boost
|
||||
{
|
||||
using ::std::abs;
|
||||
using ::std::sqrt;
|
||||
using ::std::log;
|
||||
|
||||
using ::std::numeric_limits;
|
||||
|
||||
typedef detail::atanh_helper1_t<T, std::numeric_limits<T>::has_infinity> helper1_type;
|
||||
typedef detail::atanh_helper2_t<T, std::numeric_limits<T>::has_quiet_NaN> helper2_type;
|
||||
typedef detail::atanh_helper1_t<T, ::std::numeric_limits<T>::has_infinity> helper1_type;
|
||||
typedef detail::atanh_helper2_t<T, ::std::numeric_limits<T>::has_quiet_NaN> helper2_type;
|
||||
|
||||
|
||||
static T const e0 = sqrt(numeric_limits<T>::epsilon());
|
||||
T const one = static_cast<T>(1);
|
||||
T const two = static_cast<T>(2);
|
||||
|
||||
T const one = static_cast<T>(1);
|
||||
T const two = static_cast<T>(2);
|
||||
static T const taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
|
||||
static T const taylor_n_bound = sqrt(taylor_2_bound);
|
||||
|
||||
if (x < -one)
|
||||
if (x < -one)
|
||||
{
|
||||
return(helper2_type::get_neg_NaN());
|
||||
return(helper2_type::get_NaN());
|
||||
}
|
||||
else if (x == -one)
|
||||
else if (x < -one+numeric_limits<T>::epsilon())
|
||||
{
|
||||
return(helper1_type::get_neg_infinity());
|
||||
}
|
||||
else if (x == +one)
|
||||
else if (x > +one-numeric_limits<T>::epsilon())
|
||||
{
|
||||
return(helper1_type::get_pos_infinity());
|
||||
}
|
||||
else if (x > +one)
|
||||
else if (x > +one)
|
||||
{
|
||||
return(helper2_type::get_pos_NaN());
|
||||
return(helper2_type::get_NaN());
|
||||
}
|
||||
else if (abs(x) < e0)
|
||||
else if (abs(x) >= taylor_n_bound)
|
||||
{
|
||||
return(x);
|
||||
}
|
||||
else // -one < x <= -e0 or +e0 <= x < +one
|
||||
{
|
||||
using ::std::log;
|
||||
|
||||
return(log( (one + x) / (one - x) ) / two);
|
||||
}
|
||||
else
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 2
|
||||
T result = x;
|
||||
|
||||
if (abs(x) >= taylor_2_bound)
|
||||
{
|
||||
T x3 = x*x*x;
|
||||
|
||||
// approximation by taylor series in x at 0 up to order 4
|
||||
result += x3/static_cast<T>(3);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,17 @@ namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
// gcc 2.x ignores function scope using declarations,
|
||||
// put them in the scope of the enclosing namespace instead:
|
||||
|
||||
using ::std::abs;
|
||||
using ::std::sqrt;
|
||||
using ::std::sin;
|
||||
|
||||
using ::std::numeric_limits;
|
||||
#endif
|
||||
|
||||
// This is the "Sinus Cardinal" of index Pi.
|
||||
|
||||
template<typename T>
|
||||
@@ -34,26 +45,29 @@ namespace boost
|
||||
|
||||
using ::std::numeric_limits;
|
||||
|
||||
static T const e1 = numeric_limits<T>::epsilon();
|
||||
static T const e2 = sqrt(e1);
|
||||
static T const e3 = sqrt(e2);
|
||||
static T const taylor_0_bound = numeric_limits<T>::epsilon();
|
||||
static T const taylor_2_bound = sqrt(taylor_0_bound);
|
||||
static T const taylor_n_bound = sqrt(taylor_2_bound);
|
||||
|
||||
if (abs(x) > e3)
|
||||
if (abs(x) >= taylor_n_bound)
|
||||
{
|
||||
return(sin(x)/x);
|
||||
}
|
||||
else
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 0
|
||||
T result = static_cast<T>(1);
|
||||
|
||||
if (abs(x) > e1)
|
||||
if (abs(x) >= taylor_0_bound)
|
||||
{
|
||||
T x2 = x*x;
|
||||
|
||||
// approximation by taylor series in x at 0 up to order 2
|
||||
result -= x2/static_cast<T>(6);
|
||||
|
||||
if (abs(x) > e2)
|
||||
if (abs(x) >= taylor_2_bound)
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 4
|
||||
result += (x2*x2)/static_cast<T>(120);
|
||||
}
|
||||
}
|
||||
@@ -72,26 +86,29 @@ namespace boost
|
||||
|
||||
using ::std::numeric_limits;
|
||||
|
||||
static T const e1 = numeric_limits<T>::epsilon();
|
||||
static T const e2 = sqrt(e1);
|
||||
static T const e3 = sqrt(e2);
|
||||
static T const taylor_0_bound = numeric_limits<T>::epsilon();
|
||||
static T const taylor_2_bound = sqrt(taylor_0_bound);
|
||||
static T const taylor_n_bound = sqrt(taylor_2_bound);
|
||||
|
||||
if (abs(x) > e3)
|
||||
if (abs(x) >= taylor_n_bound)
|
||||
{
|
||||
return(sin(x)/x);
|
||||
}
|
||||
else
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 0
|
||||
U<T> result = static_cast< U<T> >(1);
|
||||
|
||||
if (abs(x) > e1)
|
||||
if (abs(x) >= taylor_0_bound)
|
||||
{
|
||||
U<T> x2 = x*x;
|
||||
|
||||
// approximation by taylor series in x at 0 up to order 2
|
||||
result -= x2/static_cast<T>(6);
|
||||
|
||||
if (abs(x) > e2)
|
||||
if (abs(x) >= taylor_2_bound)
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 4
|
||||
result += (x2*x2)/static_cast<T>(120);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,17 @@ namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
// gcc 2.x ignores function scope using declarations,
|
||||
// put them in the scope of the enclosing namespace instead:
|
||||
|
||||
using ::std::abs;
|
||||
using ::std::sqrt;
|
||||
using ::std::sinh;
|
||||
|
||||
using ::std::numeric_limits;
|
||||
#endif
|
||||
|
||||
// This is the "Hyperbolic Sinus Cardinal" of index Pi.
|
||||
|
||||
template<typename T>
|
||||
@@ -34,26 +45,29 @@ namespace boost
|
||||
|
||||
using ::std::numeric_limits;
|
||||
|
||||
static T const e1 = numeric_limits<T>::epsilon();
|
||||
static T const e2 = sqrt(e1);
|
||||
static T const e3 = sqrt(e2);
|
||||
static T const taylor_0_bound = numeric_limits<T>::epsilon();
|
||||
static T const taylor_2_bound = sqrt(taylor_0_bound);
|
||||
static T const taylor_n_bound = sqrt(taylor_2_bound);
|
||||
|
||||
if (abs(x) > e3)
|
||||
if (abs(x) >= taylor_n_bound)
|
||||
{
|
||||
return(sinh(x)/x);
|
||||
}
|
||||
else
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 0
|
||||
T result = static_cast<T>(1);
|
||||
|
||||
if (abs(x) > e1)
|
||||
if (abs(x) >= taylor_0_bound)
|
||||
{
|
||||
T x2 = x*x;
|
||||
|
||||
// approximation by taylor series in x at 0 up to order 2
|
||||
result += x2/static_cast<T>(6);
|
||||
|
||||
if (abs(x) > e2)
|
||||
if (abs(x) >= taylor_2_bound)
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 4
|
||||
result += (x2*x2)/static_cast<T>(120);
|
||||
}
|
||||
}
|
||||
@@ -72,26 +86,29 @@ namespace boost
|
||||
|
||||
using ::std::numeric_limits;
|
||||
|
||||
static T const e1 = numeric_limits<T>::epsilon();
|
||||
static T const e2 = sqrt(e1);
|
||||
static T const e3 = sqrt(e2);
|
||||
static T const taylor_0_bound = numeric_limits<T>::epsilon();
|
||||
static T const taylor_2_bound = sqrt(taylor_0_bound);
|
||||
static T const taylor_n_bound = sqrt(taylor_2_bound);
|
||||
|
||||
if (abs(x) > e3)
|
||||
if (abs(x) >= taylor_n_bound)
|
||||
{
|
||||
return(sinh(x)/x);
|
||||
}
|
||||
else
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 0
|
||||
U<T> result = static_cast< U<T> >(1);
|
||||
|
||||
if (abs(x) > e1)
|
||||
if (abs(x) >= taylor_0_bound)
|
||||
{
|
||||
U<T> x2 = x*x;
|
||||
|
||||
// approximation by taylor series in x at 0 up to order 2
|
||||
result += x2/static_cast<T>(6);
|
||||
|
||||
if (abs(x) > e2)
|
||||
if (abs(x) >= taylor_2_bound)
|
||||
{
|
||||
// approximation by taylor series in x at 0 up to order 4
|
||||
result += (x2*x2)/static_cast<T>(120);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user