|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r75933 - in trunk: boost/math/complex libs/math/test
From: john_at_[hidden]
Date: 2011-12-13 13:11:48
Author: johnmaddock
Date: 2011-12-13 13:11:46 EST (Tue, 13 Dec 2011)
New Revision: 75933
URL: http://svn.boost.org/trac/boost/changeset/75933
Log:
Fix complex number routines to work with signed zeros, changes involve:
* Use boost::math::signbit rather than comparison to zero.
* Use boost::math::changesign rather than unary negation (unary negation fails for Intel on Linux when the argument is a zero).
* Update to use boost::math::isnan/isinf rather than the old code.
* Update to use boost::math constants.
Fixes #6171.
Text files modified:
trunk/boost/math/complex/acos.hpp | 39 ++++---
trunk/boost/math/complex/acosh.hpp | 2
trunk/boost/math/complex/asin.hpp | 44 +++++----
trunk/boost/math/complex/atanh.hpp | 46 +++++----
trunk/boost/math/complex/details.hpp | 18 +--
trunk/libs/math/test/complex_test.cpp | 186 ++++++++++++++++++++++++++-------------
6 files changed, 201 insertions(+), 134 deletions(-)
Modified: trunk/boost/math/complex/acos.hpp
==============================================================================
--- trunk/boost/math/complex/acos.hpp (original)
+++ trunk/boost/math/complex/acos.hpp 2011-12-13 13:11:46 EST (Tue, 13 Dec 2011)
@@ -38,11 +38,15 @@
static const T half = static_cast<T>(0.5L);
static const T a_crossover = static_cast<T>(1.5L);
static const T b_crossover = static_cast<T>(0.6417L);
- static const T s_pi = static_cast<T>(3.141592653589793238462643383279502884197L);
- static const T half_pi = static_cast<T>(1.57079632679489661923132169163975144L);
- static const T log_two = static_cast<T>(0.69314718055994530941723212145817657L);
- static const T quarter_pi = static_cast<T>(0.78539816339744830961566084581987572L);
+ static const T s_pi = boost::math::constants::pi<T>();
+ static const T half_pi = s_pi / 2;
+ static const T log_two = boost::math::constants::ln_two<T>();
+ static const T quarter_pi = s_pi / 4;
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
//
// Get real and imaginary parts, discard the signs as we can
// figure out the sign of the result later:
@@ -58,14 +62,14 @@
// but doing it this way prevents overflow/underflow arithmetic
// in the main body of the logic, which may trip up some machines:
//
- if(std::numeric_limits<T>::has_infinity && (x == std::numeric_limits<T>::infinity()))
+ if((boost::math::isinf)(x))
{
- if(y == std::numeric_limits<T>::infinity())
+ if((boost::math::isinf)(y))
{
real = quarter_pi;
imag = std::numeric_limits<T>::infinity();
}
- else if(detail::test_is_nan(y))
+ else if((boost::math::isnan)(y))
{
return std::complex<T>(y, -std::numeric_limits<T>::infinity());
}
@@ -76,18 +80,18 @@
imag = std::numeric_limits<T>::infinity();
}
}
- else if(detail::test_is_nan(x))
+ else if((boost::math::isnan)(x))
{
- if(y == std::numeric_limits<T>::infinity())
- return std::complex<T>(x, (z.imag() < 0) ? std::numeric_limits<T>::infinity() : -std::numeric_limits<T>::infinity());
+ if((boost::math::isinf)(y))
+ return std::complex<T>(x, ((boost::math::signbit)(z.imag())) ? std::numeric_limits<T>::infinity() : -std::numeric_limits<T>::infinity());
return std::complex<T>(x, x);
}
- else if(std::numeric_limits<T>::has_infinity && (y == std::numeric_limits<T>::infinity()))
+ else if((boost::math::isinf)(y))
{
real = half_pi;
imag = std::numeric_limits<T>::infinity();
}
- else if(detail::test_is_nan(y))
+ else if((boost::math::isnan)(y))
{
return std::complex<T>((x == 0) ? half_pi : y, y);
}
@@ -98,7 +102,7 @@
// begin with the special case for real numbers:
//
if((y == 0) && (x <= one))
- return std::complex<T>((x == 0) ? half_pi : std::acos(z.real()));
+ return std::complex<T>((x == 0) ? half_pi : std::acos(z.real()), (boost::math::changesign)(z.imag()));
//
// Figure out if our input is within the "safe area" identified by Hull et al.
// This would be more efficient with portable floating point exception handling;
@@ -222,12 +226,15 @@
//
// Finish off by working out the sign of the result:
//
- if(z.real() < 0)
+ if((boost::math::signbit)(z.real()))
real = s_pi - real;
- if(z.imag() > 0)
- imag = -imag;
+ if(!(boost::math::signbit)(z.imag()))
+ imag = (boost::math::changesign)(imag);
return std::complex<T>(real, imag);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
}
} } // namespaces
Modified: trunk/boost/math/complex/acosh.hpp
==============================================================================
--- trunk/boost/math/complex/acosh.hpp (original)
+++ trunk/boost/math/complex/acosh.hpp 2011-12-13 13:11:46 EST (Tue, 13 Dec 2011)
@@ -24,7 +24,7 @@
// as well as compatibility with C99.
//
std::complex<T> result = boost::math::acos(z);
- if(!detail::test_is_nan(result.imag()) && result.imag() <= 0)
+ if(!(boost::math::isnan)(result.imag()) && signbit(result.imag()))
return detail::mult_i(result);
return detail::mult_minus_i(result);
}
Modified: trunk/boost/math/complex/asin.hpp
==============================================================================
--- trunk/boost/math/complex/asin.hpp (original)
+++ trunk/boost/math/complex/asin.hpp 2011-12-13 13:11:46 EST (Tue, 13 Dec 2011)
@@ -38,11 +38,14 @@
static const T half = static_cast<T>(0.5L);
static const T a_crossover = static_cast<T>(1.5L);
static const T b_crossover = static_cast<T>(0.6417L);
- //static const T pi = static_cast<T>(3.141592653589793238462643383279502884197L);
- static const T half_pi = static_cast<T>(1.57079632679489661923132169163975144L);
- static const T log_two = static_cast<T>(0.69314718055994530941723212145817657L);
- static const T quarter_pi = static_cast<T>(0.78539816339744830961566084581987572L);
-
+ static const T s_pi = boost::math::constants::pi<T>();
+ static const T half_pi = s_pi / 2;
+ static const T log_two = boost::math::constants::ln_two<T>();
+ static const T quarter_pi = s_pi / 4;
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
//
// Get real and imaginary parts, discard the signs as we can
// figure out the sign of the result later:
@@ -57,11 +60,11 @@
// below, but handling it as a special case prevents overflow/underflow
// arithmetic which may trip up some machines:
//
- if(detail::test_is_nan(x))
+ if((boost::math::isnan)(x))
{
- if(detail::test_is_nan(y))
+ if((boost::math::isnan)(y))
return std::complex<T>(x, x);
- if(std::numeric_limits<T>::has_infinity && (y == std::numeric_limits<T>::infinity()))
+ if((boost::math::isinf)(y))
{
real = x;
imag = std::numeric_limits<T>::infinity();
@@ -69,14 +72,14 @@
else
return std::complex<T>(x, x);
}
- else if(detail::test_is_nan(y))
+ else if((boost::math::isnan)(y))
{
if(x == 0)
{
real = 0;
imag = y;
}
- else if(std::numeric_limits<T>::has_infinity && (x == std::numeric_limits<T>::infinity()))
+ else if((boost::math::isinf)(x))
{
real = y;
imag = std::numeric_limits<T>::infinity();
@@ -84,9 +87,9 @@
else
return std::complex<T>(y, y);
}
- else if(std::numeric_limits<T>::has_infinity && (x == std::numeric_limits<T>::infinity()))
+ else if((boost::math::isinf)(x))
{
- if(y == std::numeric_limits<T>::infinity())
+ if((boost::math::isinf)(y))
{
real = quarter_pi;
imag = std::numeric_limits<T>::infinity();
@@ -97,7 +100,7 @@
imag = std::numeric_limits<T>::infinity();
}
}
- else if(std::numeric_limits<T>::has_infinity && (y == std::numeric_limits<T>::infinity()))
+ else if((boost::math::isinf)(y))
{
real = 0;
imag = std::numeric_limits<T>::infinity();
@@ -108,7 +111,7 @@
// special case for real numbers:
//
if((y == 0) && (x <= one))
- return std::complex<T>(std::asin(z.real()));
+ return std::complex<T>(std::asin(z.real()), z.imag());
//
// Figure out if our input is within the "safe area" identified by Hull et al.
// This would be more efficient with portable floating point exception handling;
@@ -174,7 +177,7 @@
if(x < one)
{
real = std::asin(x);
- imag = y / std::sqrt(xp1*xm1);
+ imag = y / std::sqrt(-xp1*xm1);
}
else
{
@@ -232,12 +235,15 @@
//
// Finish off by working out the sign of the result:
//
- if(z.real() < 0)
- real = -real;
- if(z.imag() < 0)
- imag = -imag;
+ if((boost::math::signbit)(z.real()))
+ real = (boost::math::changesign)(real);
+ if((boost::math::signbit)(z.imag()))
+ imag = (boost::math::changesign)(imag);
return std::complex<T>(real, imag);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
}
} } // namespaces
Modified: trunk/boost/math/complex/atanh.hpp
==============================================================================
--- trunk/boost/math/complex/atanh.hpp (original)
+++ trunk/boost/math/complex/atanh.hpp 2011-12-13 13:11:46 EST (Tue, 13 Dec 2011)
@@ -37,14 +37,19 @@
// at : http://jove.prohosting.com/~skripty/toc.htm
//
- static const T half_pi = static_cast<T>(1.57079632679489661923132169163975144L);
- static const T pi = static_cast<T>(3.141592653589793238462643383279502884197L);
+ static const T pi = boost::math::constants::pi<T>();
+ static const T half_pi = pi / 2;
static const T one = static_cast<T>(1.0L);
static const T two = static_cast<T>(2.0L);
static const T four = static_cast<T>(4.0L);
static const T zero = static_cast<T>(0);
static const T a_crossover = static_cast<T>(0.3L);
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+
T x = std::fabs(z.real());
T y = std::fabs(z.imag());
@@ -56,20 +61,20 @@
//
// Begin by handling the special cases specified in C99:
//
- if(detail::test_is_nan(x))
+ if((boost::math::isnan)(x))
{
- if(detail::test_is_nan(y))
+ if((boost::math::isnan)(y))
return std::complex<T>(x, x);
- else if(std::numeric_limits<T>::has_infinity && (y == std::numeric_limits<T>::infinity()))
- return std::complex<T>(0, ((z.imag() < 0) ? -half_pi : half_pi));
+ else if((boost::math::isinf)(y))
+ return std::complex<T>(0, ((boost::math::signbit)(z.imag()) ? -half_pi : half_pi));
else
return std::complex<T>(x, x);
}
- else if(detail::test_is_nan(y))
+ else if((boost::math::isnan)(y))
{
if(x == 0)
return std::complex<T>(x, y);
- if(std::numeric_limits<T>::has_infinity && (x == std::numeric_limits<T>::infinity()))
+ if((boost::math::isinf)(x))
return std::complex<T>(0, y);
else
return std::complex<T>(y, y);
@@ -104,7 +109,7 @@
T alpha = two*x / (one + xx + yy);
if(alpha < a_crossover)
{
- real = boost::math::log1p(alpha) - boost::math::log1p(-alpha);
+ real = boost::math::log1p(alpha) - boost::math::log1p((boost::math::changesign)(alpha));
}
else
{
@@ -112,13 +117,13 @@
real = boost::math::log1p(x2 + xx + yy) - std::log(xm1*xm1 + yy);
}
real /= four;
- if(z.real() < 0)
- real = -real;
+ if((boost::math::signbit)(z.real()))
+ real = (boost::math::changesign)(real);
imag = std::atan2((y * two), (one - xx - yy));
imag /= two;
if(z.imag() < 0)
- imag = -imag;
+ imag = (boost::math::changesign)(imag);
}
else
{
@@ -133,9 +138,7 @@
T alpha = 0;
if(x >= safe_upper)
{
- // this is really a test for infinity,
- // but we may not have the necessary numeric_limits support:
- if((x > (std::numeric_limits<T>::max)()) || (y > (std::numeric_limits<T>::max)()))
+ if((boost::math::isinf)(x) || (boost::math::isinf)(y))
{
alpha = 0;
}
@@ -180,7 +183,7 @@
}
if(alpha < a_crossover)
{
- real = boost::math::log1p(alpha) - boost::math::log1p(-alpha);
+ real = boost::math::log1p(alpha) - boost::math::log1p((boost::math::changesign)(alpha));
}
else
{
@@ -194,8 +197,8 @@
}
real /= four;
- if(z.real() < 0)
- real = -real;
+ if((boost::math::signbit)(z.real()))
+ real = (boost::math::changesign)(real);
//
// Now handle imaginary part, this is much easier,
@@ -234,10 +237,13 @@
imag = std::atan2(two*y, 1 - x*x);
}
imag /= two;
- if(z.imag() < 0)
- imag = -imag;
+ if((boost::math::signbit)(z.imag()))
+ imag = (boost::math::changesign)(imag);
}
return std::complex<T>(real, imag);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
}
} } // namespaces
Modified: trunk/boost/math/complex/details.hpp
==============================================================================
--- trunk/boost/math/complex/details.hpp (original)
+++ trunk/boost/math/complex/details.hpp 2011-12-13 13:11:46 EST (Tue, 13 Dec 2011)
@@ -16,6 +16,10 @@
#include <boost/limits.hpp>
#include <math.h> // isnan where available
#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/math/special_functions/sign.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/math/special_functions/sign.hpp>
+#include <boost/math/constants/constants.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ using ::sqrt; }
@@ -24,21 +28,9 @@
namespace boost{ namespace math{ namespace detail{
template <class T>
-inline bool test_is_nan(T t)
-{
- // Comparisons with Nan's always fail:
- return std::numeric_limits<T>::has_infinity && (!(t <= std::numeric_limits<T>::infinity()) || !(t >= -std::numeric_limits<T>::infinity()));
-}
-#ifdef isnan
-template<> inline bool test_is_nan<float>(float t) { return isnan(t); }
-template<> inline bool test_is_nan<double>(double t) { return isnan(t); }
-template<> inline bool test_is_nan<long double>(long double t) { return isnan(t); }
-#endif
-
-template <class T>
inline T mult_minus_one(const T& t)
{
- return test_is_nan(t) ? t : -t;
+ return (boost::math::isnan)(t) ? t : (boost::math::changesign)(t);
}
template <class T>
Modified: trunk/libs/math/test/complex_test.cpp
==============================================================================
--- trunk/libs/math/test/complex_test.cpp (original)
+++ trunk/libs/math/test/complex_test.cpp 2011-12-13 13:11:46 EST (Tue, 13 Dec 2011)
@@ -77,6 +77,15 @@
}
}
+ if((boost::math::isnan)(a.real()))
+ {
+ BOOST_ERROR("Found non-finite value for real part: " << a);
+ }
+ if((boost::math::isnan)(a.imag()))
+ {
+ BOOST_ERROR("Found non-finite value for inaginary part: " << a);
+ }
+
T rel = boost::math::fabs((b-a)/b) / eps;
if( rel > max_error)
{
@@ -276,7 +285,7 @@
// but an attempt to access it will terminate the program!!!!
if(std::numeric_limits<T>::has_quiet_NaN)
nan = std::numeric_limits<T>::quiet_NaN();
- if(boost::math::detail::test_is_nan(nan))
+ if((boost::math::isnan)(nan))
test_nan = true;
#endif
#if defined(__DECCXX) && !defined(_IEEE_FP)
@@ -303,11 +312,11 @@
{
result = boost::math::acos(ct(zero,nan));
BOOST_CHECK_CLOSE(result.real(), half_pi, eps*200);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acos(ct(mzero,nan));
BOOST_CHECK_CLOSE(result.real(), half_pi, eps*200);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
}
if(test_infinity)
{
@@ -323,8 +332,8 @@
if(test_nan)
{
result = boost::math::acos(ct(one, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
}
if(test_infinity)
{
@@ -363,41 +372,70 @@
if(test_nan)
{
result = boost::math::acos(ct(infinity, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
BOOST_CHECK(std::fabs(result.imag()) == infinity);
result = boost::math::acos(ct(-infinity, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
BOOST_CHECK(std::fabs(result.imag()) == infinity);
result = boost::math::acos(ct(nan, zero));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acos(ct(nan, -zero));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acos(ct(nan, one));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acos(ct(nan, -one));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acos(ct(nan, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acos(ct(nan, infinity));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
BOOST_CHECK(result.imag() == -infinity);
result = boost::math::acos(ct(nan, -infinity));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
BOOST_CHECK(result.imag() == infinity);
}
+ if(boost::math::signbit(mzero))
+ {
+ result = boost::math::acos(ct(-1.25f, zero));
+ BOOST_CHECK(result.real() > 0);
+ BOOST_CHECK(result.imag() < 0);
+ result = boost::math::asin(ct(-1.75f, mzero));
+ BOOST_CHECK(result.real() < 0);
+ BOOST_CHECK(result.imag() < 0);
+ result = boost::math::atan(ct(mzero, -1.75f));
+ BOOST_CHECK(result.real() < 0);
+ BOOST_CHECK(result.imag() < 0);
+
+ result = boost::math::acos(ct(zero, zero));
+ BOOST_CHECK(result.real() > 0);
+ BOOST_CHECK(result.imag() == 0);
+ BOOST_CHECK((boost::math::signbit)(result.imag()));
+ result = boost::math::acos(ct(zero, mzero));
+ BOOST_CHECK(result.real() > 0);
+ BOOST_CHECK(result.imag() == 0);
+ BOOST_CHECK(0 == (boost::math::signbit)(result.imag()));
+ result = boost::math::acos(ct(mzero, zero));
+ BOOST_CHECK(result.real() > 0);
+ BOOST_CHECK(result.imag() == 0);
+ BOOST_CHECK((boost::math::signbit)(result.imag()));
+ result = boost::math::acos(ct(mzero, mzero));
+ BOOST_CHECK(result.real() > 0);
+ BOOST_CHECK(result.imag() == 0);
+ BOOST_CHECK(0 == (boost::math::signbit)(result.imag()));
+ }
//
// C99 spot tests for acosh:
@@ -408,7 +446,7 @@
result = boost::math::acosh(ct(zero, mzero));
BOOST_CHECK(result.real() == 0);
- BOOST_CHECK_CLOSE(result.imag(), half_pi, eps*200);
+ BOOST_CHECK_CLOSE(result.imag(), -half_pi, eps*200);
result = boost::math::acosh(ct(mzero, zero));
BOOST_CHECK(result.real() == 0);
@@ -416,7 +454,7 @@
result = boost::math::acosh(ct(mzero, mzero));
BOOST_CHECK(result.real() == 0);
- BOOST_CHECK_CLOSE(result.imag(), half_pi, eps*200);
+ BOOST_CHECK_CLOSE(result.imag(), -half_pi, eps*200);
if(test_infinity)
{
@@ -432,8 +470,8 @@
if(test_nan)
{
result = boost::math::acosh(ct(one, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
}
if(test_infinity)
{
@@ -474,31 +512,37 @@
{
result = boost::math::acosh(ct(infinity, nan));
BOOST_CHECK(result.real() == infinity);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acosh(ct(-infinity, nan));
BOOST_CHECK(result.real() == infinity);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acosh(ct(nan, one));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acosh(ct(nan, infinity));
BOOST_CHECK(result.real() == infinity);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acosh(ct(nan, -one));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acosh(ct(nan, -infinity));
BOOST_CHECK(result.real() == infinity);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::acosh(ct(nan, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
+ }
+ if(boost::math::signbit(mzero))
+ {
+ result = boost::math::acosh(ct(-2.5f, zero));
+ BOOST_CHECK(result.real() > 0);
+ BOOST_CHECK(result.imag() > 0);
}
//
// C99 spot checks for asinh:
@@ -541,16 +585,16 @@
if(test_nan)
{
result = boost::math::asinh(ct(one, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::asinh(ct(-one, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::asinh(ct(zero, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
}
if(test_infinity)
@@ -592,39 +636,45 @@
{
result = boost::math::asinh(ct(infinity, nan));
BOOST_CHECK(result.real() == infinity);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::asinh(ct(-infinity, nan));
BOOST_CHECK(result.real() == -infinity);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::asinh(ct(nan, zero));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
BOOST_CHECK(result.imag() == 0);
result = boost::math::asinh(ct(nan, mzero));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
BOOST_CHECK(result.imag() == 0);
result = boost::math::asinh(ct(nan, one));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::asinh(ct(nan, -one));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::asinh(ct(nan, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::asinh(ct(nan, infinity));
BOOST_CHECK(std::fabs(result.real()) == infinity);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::asinh(ct(nan, -infinity));
BOOST_CHECK(std::fabs(result.real()) == infinity);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
+ }
+ if(boost::math::signbit(mzero))
+ {
+ result = boost::math::asinh(ct(zero, 1.5f));
+ BOOST_CHECK(result.real() > 0);
+ BOOST_CHECK(result.imag() > 0);
}
//
@@ -650,11 +700,11 @@
{
result = boost::math::atanh(ct(zero, nan));
BOOST_CHECK(result.real() == zero);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::atanh(ct(-zero, nan));
BOOST_CHECK(result.real() == zero);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
}
if(test_infinity)
@@ -694,12 +744,12 @@
if(test_nan)
{
result = boost::math::atanh(ct(pi, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::atanh(ct(-pi, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
}
if(test_infinity)
@@ -741,19 +791,19 @@
{
result = boost::math::atanh(ct(infinity, nan));
BOOST_CHECK(result.real() == 0);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::atanh(ct(-infinity, nan));
BOOST_CHECK(result.real() == 0);
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::atanh(ct(nan, pi));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::atanh(ct(nan, -pi));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
result = boost::math::atanh(ct(nan, infinity));
BOOST_CHECK(result.real() == 0);
@@ -764,10 +814,16 @@
BOOST_CHECK_CLOSE(result.imag(), -half_pi, eps*200);
result = boost::math::atanh(ct(nan, nan));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.real()));
- BOOST_CHECK(boost::math::detail::test_is_nan(result.imag()));
+ BOOST_CHECK((boost::math::isnan)(result.real()));
+ BOOST_CHECK((boost::math::isnan)(result.imag()));
}
+ if(boost::math::signbit(mzero))
+ {
+ result = boost::math::atanh(ct(-2.0f, mzero));
+ BOOST_CHECK(result.real() < 0);
+ BOOST_CHECK(result.imag() < 0);
+ }
}
//
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk