2
0
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:
Jens Maurer
2001-09-26 21:29:40 +00:00
parent 2b7b441640
commit 3c8349e7ec
19 changed files with 1891 additions and 1764 deletions

View File

@@ -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 \
{ \

View File

@@ -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 \
{ \

View 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 */

View 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 */

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}