mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
Updated hypot with simpler formula.
Added sinh and cosh to ntl.hpp. Fixed FreeBSD test failures (no real long long support). [SVN r3598]
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 283 B After Width: | Height: | Size: 426 B |
Binary file not shown.
|
Before Width: | Height: | Size: 415 B After Width: | Height: | Size: 532 B |
@@ -193,16 +193,11 @@ overflow or underflow, even though the result is in fact perfectly representable
|
||||
The function is even and symmetric in x and y, so first take assume
|
||||
['x,y > 0] and ['x > y] (we can permute the arguments if this is not the case).
|
||||
|
||||
Then if ['x > HIGH] return [$../equations/hypot2.png] for ['y > 1] or /x/ otherwise.
|
||||
Then if ['x * [epsilon][space] >= y] we can simply return /x/.
|
||||
|
||||
Otherwise if ['y < LOW] return x if ['x > 1 || y == 0] otherwise [$../equations/hypot2.png].
|
||||
Otherwise the result is given by:
|
||||
|
||||
All other cases are free from overflow or underflow problems and so can be dealt
|
||||
with via the usual formula [$../equations/hypot.png].
|
||||
|
||||
The constant HIGH is the square root of half the largest
|
||||
representable value. The constant LOW is the square root of the
|
||||
smallest representable value.
|
||||
[$../equations/hypot2.png]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -43,45 +43,12 @@ T hypot(T x, T y)
|
||||
|
||||
if(y > x)
|
||||
(std::swap)(x, y);
|
||||
//
|
||||
// Figure out overflow and underflow limits,
|
||||
// we could make these constants static to save
|
||||
// a few cycles, but the code would then not be
|
||||
// thread safe :-(
|
||||
//
|
||||
T safe_upper = sqrt(tools::max_value<T>()) / 2;
|
||||
T safe_lower = sqrt(tools::min_value<T>());
|
||||
static const T one = 1;
|
||||
//
|
||||
// Now handle special cases:
|
||||
//
|
||||
if(x >= safe_upper)
|
||||
{
|
||||
if(y <= one)
|
||||
{
|
||||
// y is negligible:
|
||||
return x;
|
||||
}
|
||||
T a = sqrt(x) * sqrt(y);
|
||||
T b = sqrt(x/y + y/x);
|
||||
// We may have overflow:
|
||||
if(tools::max_value<T>() /a < b)
|
||||
return tools::overflow_error<T>(BOOST_CURRENT_FUNCTION, 0);
|
||||
return a * b;
|
||||
}
|
||||
else if(y <= safe_lower)
|
||||
{
|
||||
if((x >= one) || (y == 0))
|
||||
{
|
||||
// y is negligible:
|
||||
return x;
|
||||
}
|
||||
return sqrt(x) * sqrt(y) * sqrt(x/y + y/x);
|
||||
}
|
||||
//
|
||||
// If we get here then x^2+y^2 will not overflow or underflow:
|
||||
//
|
||||
return sqrt(x*x + y*y);
|
||||
|
||||
if(x * tools::epsilon<T>() >= y)
|
||||
return x;
|
||||
|
||||
T rat = y / x;
|
||||
return x * sqrt(1 + rat*rat);
|
||||
} // template <class T> T hypot(T x, T y)
|
||||
|
||||
|
||||
|
||||
@@ -325,6 +325,16 @@ namespace NTL{
|
||||
boost::math::tools::digits<NTL::RR>());
|
||||
}
|
||||
|
||||
inline NTL::RR sinh(NTL::RR z)
|
||||
{
|
||||
return (expm1(z) - expm1(-z)) / 2;
|
||||
}
|
||||
|
||||
inline NTL::RR cosh(NTL::RR z)
|
||||
{
|
||||
return (exp(z) + exp(-z)) / 2;
|
||||
}
|
||||
|
||||
inline NTL::RR fmod(NTL::RR x, NTL::RR y)
|
||||
{
|
||||
// This is a really crummy version of fmod, we rely on lots
|
||||
|
||||
@@ -640,10 +640,17 @@ int test_main(int, char* [])
|
||||
// (Parameter value, arbitrarily zero, only communicates the floating point type).
|
||||
test_spots(0.0F); // Test float.
|
||||
test_spots(0.0); // Test double.
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
test_spots(0.0L); // Test long double.
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
|
||||
#endif
|
||||
#else
|
||||
std::cout << "<note>The long double tests have been disabled on this platform "
|
||||
"either because the long double overloads of the usual math functions are "
|
||||
"not available at all, or because they are too inaccurate for these tests "
|
||||
"to pass.</note>" << std::cout;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
} // int test_main(int, char* [])
|
||||
|
||||
@@ -321,8 +321,15 @@ int test_main(int, char* [])
|
||||
expected_results();
|
||||
test_spots(0.0F, "float");
|
||||
test_spots(0.0, "double");
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
test_spots(0.0L, "long double");
|
||||
test_spots(boost::math::concepts::real_concept(0), "real_concept");
|
||||
#else
|
||||
std::cout << "<note>The long double tests have been disabled on this platform "
|
||||
"either because the long double overloads of the usual math functions are "
|
||||
"not available at all, or because they are too inaccurate for these tests "
|
||||
"to pass.</note>" << std::cout;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -193,8 +193,15 @@ int test_main(int, char* [])
|
||||
|
||||
test_spots(0.0F, "float");
|
||||
test_spots(0.0, "double");
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
test_spots(0.0L, "long double");
|
||||
test_spots(boost::math::concepts::real_concept(0), "real_concept");
|
||||
#else
|
||||
std::cout << "<note>The long double tests have been disabled on this platform "
|
||||
"either because the long double overloads of the usual math functions are "
|
||||
"not available at all, or because they are too inaccurate for these tests "
|
||||
"to pass.</note>" << std::cout;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -182,8 +182,15 @@ int test_main(int, char* [])
|
||||
expected_results();
|
||||
test_spots(0.0F, "float");
|
||||
test_spots(0.0, "double");
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
test_spots(0.0L, "long double");
|
||||
test_spots(boost::math::concepts::real_concept(0), "real_concept");
|
||||
#else
|
||||
std::cout << "<note>The long double tests have been disabled on this platform "
|
||||
"either because the long double overloads of the usual math functions are "
|
||||
"not available at all, or because they are too inaccurate for these tests "
|
||||
"to pass.</note>" << std::cout;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -224,8 +224,15 @@ int test_main(int, char* [])
|
||||
expected_results();
|
||||
test_spots(0.0F, "float");
|
||||
test_spots(0.0, "double");
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
test_spots(0.0L, "long double");
|
||||
test_spots(boost::math::concepts::real_concept(0), "real_concept");
|
||||
#else
|
||||
std::cout << "<note>The long double tests have been disabled on this platform "
|
||||
"either because the long double overloads of the usual math functions are "
|
||||
"not available at all, or because they are too inaccurate for these tests "
|
||||
"to pass.</note>" << std::cout;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -122,16 +122,18 @@ void expected_results()
|
||||
largest_type, // test type(s)
|
||||
"(?i).*large.*", // test data group
|
||||
".*", 200000, 10000); // test function
|
||||
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
//
|
||||
// Cygwin:
|
||||
// No long doubles:
|
||||
//
|
||||
add_expected_result(
|
||||
"[^|]*", // compiler
|
||||
"[^|]*", // stdlib
|
||||
"cygwin", // platform
|
||||
BOOST_PLATFORM, // platform
|
||||
largest_type, // test type(s)
|
||||
"(?i).*large.*", // test data group
|
||||
".*", 10000, 500); // test function
|
||||
".*", 13000, 500); // test function
|
||||
#endif
|
||||
//
|
||||
// Catch all cases come last:
|
||||
//
|
||||
|
||||
@@ -66,6 +66,7 @@ void expected_results()
|
||||
if((std::numeric_limits<long double>::digits <= 64)
|
||||
&& (std::numeric_limits<long double>::digits != std::numeric_limits<double>::digits))
|
||||
{
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
add_expected_result(
|
||||
".*", // compiler
|
||||
".*", // stdlib
|
||||
@@ -73,6 +74,7 @@ void expected_results()
|
||||
"double", // test type(s)
|
||||
".*", // test data group
|
||||
".*", 10, 5); // test function
|
||||
#endif
|
||||
}
|
||||
add_expected_result(
|
||||
".*", // compiler
|
||||
|
||||
@@ -64,6 +64,7 @@ void expected_results()
|
||||
if((std::numeric_limits<long double>::digits <= 64)
|
||||
&& (std::numeric_limits<long double>::digits != std::numeric_limits<double>::digits))
|
||||
{
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
add_expected_result(
|
||||
".*", // compiler
|
||||
".*", // stdlib
|
||||
@@ -71,6 +72,7 @@ void expected_results()
|
||||
"double", // test type(s)
|
||||
".*", // test data group
|
||||
".*", 10, 5); // test function
|
||||
#endif
|
||||
}
|
||||
add_expected_result(
|
||||
".*", // compiler
|
||||
|
||||
@@ -758,10 +758,17 @@ int test_main(int, char* [])
|
||||
// (Parameter value, arbitrarily zero, only communicates the floating point type).
|
||||
test_spots(0.0F); // Test float.
|
||||
test_spots(0.0); // Test double.
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
test_spots(0.0L); // Test long double.
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
|
||||
#endif
|
||||
#else
|
||||
std::cout << "<note>The long double tests have been disabled on this platform "
|
||||
"either because the long double overloads of the usual math functions are "
|
||||
"not available at all, or because they are too inaccurate for these tests "
|
||||
"to pass.</note>" << std::cout;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
} // int test_main(int, char* [])
|
||||
|
||||
@@ -57,6 +57,7 @@ void expected_results()
|
||||
#else
|
||||
largest_type = "(long\\s+)?double";
|
||||
#endif
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
if((std::numeric_limits<long double>::digits <= 64) &&
|
||||
(std::numeric_limits<long double>::digits != std::numeric_limits<double>::digits))
|
||||
{
|
||||
@@ -68,6 +69,7 @@ void expected_results()
|
||||
".*", // test data group
|
||||
".*", 10, 5); // test function
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// Catch all cases come last:
|
||||
//
|
||||
|
||||
@@ -63,7 +63,7 @@ void expected_results()
|
||||
add_expected_result(
|
||||
"[^|]*", // compiler
|
||||
"[^|]*", // stdlib
|
||||
"HP-UX|linux", // platform
|
||||
"HP-UX|linux|.*(bsd|BSD).*", // platform
|
||||
"float", // test type(s)
|
||||
"[^|]*", // test data group
|
||||
"boost::math::tgamma_ratio[^|]*", 35, 8); // test function
|
||||
|
||||
Reference in New Issue
Block a user