1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-06-07 00:51:32 +00:00

re-implementation complex transcendental functions

This commit is contained in:
bolero-MURAKAMI 2014-07-19 20:03:13 +09:00
parent c830cab086
commit 22c3f6e132
32 changed files with 1460 additions and 486 deletions

27
sprout/complex/abs.hpp Normal file
View file

@ -0,0 +1,27 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_ABS_HPP
#define SPROUT_COMPLEX_ABS_HPP
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/norm.hpp>
#include <sprout/math/sqrt.hpp>
namespace sprout {
//
// abs
//
template<typename T>
inline SPROUT_CONSTEXPR T
abs(sprout::complex<T> const& x) {
return sprout::math::sqrt(sprout::norm(x));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_ABS_HPP

71
sprout/complex/acos.hpp Normal file
View file

@ -0,0 +1,71 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_ACOS_HPP
#define SPROUT_COMPLEX_ACOS_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/asin.hpp>
namespace sprout {
//
// acos
//
// G.6.1.1 The cacos functions
// cacos(conj(z)) = conj(cacos(z)).
// cacos(<28>}0 + i0) returns p /2 - i0.
// cacos(<28>}0 + iNaN) returns p /2 + iNaN.
// cacos(x + i<>‡) returns p /2 - i<>‡, for finite x.
// cacos(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for nonzero finite x.
// cacos(-<2D>‡+ iy) returns p - i<>‡, for positive-signed finite y.
// cacos(+<2B>‡+ iy) returns +0 - i<>‡, for positive-signed finite y.
// cacos(-<2D>‡+ i<>‡) returns 3p /4 - i<>‡.
// cacos(+<2B>‡+ i<>‡) returns p /4 - i<>‡.
// cacos(<28>}<7D>‡+ iNaN) returns NaN <20>} i<>‡ (where the sign of the imaginary part of the result is unspecified).
// cacos(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite y.
// cacos(NaN + i<>‡) returns NaN - i<>‡.
// cacos(NaN + iNaN) returns NaN + iNaN.
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
acos_impl(sprout::complex<T> const& t) {
return sprout::complex<T>(sprout::math::half_pi<T>() - t.real(), -t.imag());
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
acos(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? x
: sprout::math::isinf(x.imag()) ? type(x.real(), -x.imag())
: type(x.real(), sprout::numeric_limits<T>::quiet_NaN())
: sprout::math::isnan(x.imag())
? sprout::math::isinf(x.real()) ? type(sprout::numeric_limits<T>::quiet_NaN(), x.real())
: x.real() == 0 ? type(sprout::math::half_pi<T>(), x.imag())
: type(sprout::numeric_limits<T>::quiet_NaN(), sprout::numeric_limits<T>::quiet_NaN())
: x.real() == sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(sprout::math::quarter_pi<T>(), -x.imag())
: type(T(0), sprout::math::copysign(sprout::numeric_limits<T>::infinity(), -x.imag()))
: x.real() == -sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(sprout::math::three_quarters_pi<T>(), -x.imag())
: type(sprout::math::pi<T>(), sprout::math::copysign(sprout::numeric_limits<T>::infinity(), -x.imag()))
: sprout::math::isinf(x.imag()) ? type(sprout::math::half_pi<T>(), sprout::math::copysign(sprout::numeric_limits<T>::infinity(), -x.imag()))
: x.real() == 0 && x.imag() == 0 ? type(sprout::math::half_pi<T>(), -x.imag())
: sprout::detail::acos_impl(sprout::asin(x))
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_ACOS_HPP

63
sprout/complex/acosh.hpp Normal file
View file

@ -0,0 +1,63 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_ACOSH_HPP
#define SPROUT_COMPLEX_ACOSH_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/log.hpp>
#include <sprout/complex/sqrt.hpp>
namespace sprout {
//
// acosh
//
// G.6.2.1 The cacosh functions
// cacosh(conj(z)) = conj(cacosh(z)).
// cacosh(<28>}0 + i0) returns +0 + ip /2.
// cacosh(x + i<>‡) returns +<2B>‡+ ip /2, for finite x.
// cacosh(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite x.
// cacosh(-<2D>‡+ iy) returns +<2B>‡+ ip , for positive-signed finite y.
// cacosh(+<2B>‡+ iy) returns +<2B>‡+ i0, for positive-signed finite y.
// cacosh(-<2D>‡+ i<>‡) returns +<2B>‡+ i3p /4.
// cacosh(+<2B>‡+ i<>‡) returns +<2B>‡+ ip /4.
// cacosh(<28>}<7D>‡+ iNaN) returns +<2B>‡+ iNaN.
// cacosh(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite y.
// cacosh(NaN + i<>‡) returns +<2B>‡+ iNaN.
// cacosh(NaN + iNaN) returns NaN + iNaN.
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
acosh(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? x
: sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), x.real())
: type(x.real(), x.real())
: sprout::math::isnan(x.imag())
? sprout::math::isinf(x.real()) ? type(sprout::numeric_limits<T>::infinity(), x.imag())
: type(sprout::numeric_limits<T>::quiet_NaN(), x.imag())
: x.real() == sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), sprout::math::copysign(sprout::math::quarter_pi<T>(), x.imag()))
: type(sprout::numeric_limits<T>::infinity(), (x.imag() == 0 ? x.imag() : sprout::math::copysign(T(0), x.imag())))
: x.real() == -sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), sprout::math::copysign(sprout::math::three_quarters_pi<T>(), x.imag()))
: type(sprout::numeric_limits<T>::infinity(), sprout::math::copysign(sprout::math::pi<T>(), x.imag()))
: sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), sprout::math::copysign(sprout::math::half_pi<T>(), x.imag()))
: x.real() == 0 && x.imag() == 0 ? type(T(0), sprout::math::copysign(sprout::math::half_pi<T>(), x.imag()))
: T(2) * sprout::log(sprout::sqrt(sprout::math::half<T>() * (x + T(1))) + sprout::sqrt(sprout::math::half<T>() * (x - T(1))))
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_ACOSH_HPP

37
sprout/complex/arg.hpp Normal file
View file

@ -0,0 +1,37 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_ARG_HPP
#define SPROUT_COMPLEX_ARG_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/math/atan2.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
//
// arg
//
template<typename T>
inline SPROUT_CONSTEXPR T
arg(sprout::complex<T> const& x) {
return sprout::math::atan2(x.imag(), x.real());
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
arg(ArithmeticType x) {
return sprout::math::atan2(ArithmeticType(0), x);
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_ARG_HPP

30
sprout/complex/asin.hpp Normal file
View file

@ -0,0 +1,30 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_ASIN_HPP
#define SPROUT_COMPLEX_ASIN_HPP
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/perp.hpp>
#include <sprout/complex/asinh.hpp>
namespace sprout {
//
// asin
//
// casin(z) = -i casinh(iz)
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
asin(sprout::complex<T> const& x) {
return -sprout::perp(sprout::asinh(sprout::perp(x)));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_ASIN_HPP

65
sprout/complex/asinh.hpp Normal file
View file

@ -0,0 +1,65 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_ASINH_HPP
#define SPROUT_COMPLEX_ASINH_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/log.hpp>
#include <sprout/complex/sqrt.hpp>
namespace sprout {
//
// asinh
//
// G.6.2.2 The casinh functions
// casinh(conj(z)) = conj(casinh(z)) and casinh is odd.
// casinh(+0 + i0) returns 0 + i0.
// casinh(x + i<>‡) returns +<2B>‡+ ip /2 for positive-signed finite x.
// casinh(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite x.
// casinh(+<2B>‡+ iy) returns +<2B>‡+ i0 for positive-signed finite y.
// casinh(+<2B>‡+ i<>‡) returns +<2B>‡+ ip /4.
// casinh(+<2B>‡+ iNaN) returns +<2B>‡+ iNaN.
// casinh(NaN + i0) returns NaN + i0.
// casinh(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite nonzero y.
// casinh(NaN + i<>‡) returns <20>}<7D>‡+ iNaN (where the sign of the real part of the result is unspecified).
// casinh(NaN + iNaN) returns NaN + iNaN.
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
asinh(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? x
: sprout::math::isinf(x.imag()) ? type(x.imag(), x.real())
: x.imag() == 0 ? x
: type(x.real(), x.real())
: sprout::math::isnan(x.imag())
? sprout::math::isinf(x.real()) ? x
: type(sprout::math::copysign(sprout::numeric_limits<T>::quiet_NaN(), x.real()), x.imag())
: sprout::math::isinf(x.real())
? x.imag() == sprout::numeric_limits<T>::infinity() ? type(x.real(), sprout::math::quarter_pi<T>())
: x.imag() == -sprout::numeric_limits<T>::infinity() ? type(x.real(), -sprout::math::quarter_pi<T>())
: x.imag() == 0 ? x
: type(x.real(), (x.imag() == 0 ? x.imag() : sprout::math::copysign(T(0), x.imag())))
: sprout::math::isinf(x.imag()) ? type(
sprout::math::copysign(sprout::numeric_limits<T>::infinity(), x.real()),
sprout::math::copysign(sprout::math::half_pi<T>(), x.imag())
)
: x.real() == 0 && x.imag() == 0 ? x
: sprout::log(sprout::sqrt(type((x.real() - x.imag()) * (x.real() + x.imag()) + T(1), T(2) * x.real() * x.imag())) + x)
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_ASINH_HPP

30
sprout/complex/atan.hpp Normal file
View file

@ -0,0 +1,30 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_ATAN_HPP
#define SPROUT_COMPLEX_ATAN_HPP
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/perp.hpp>
#include <sprout/complex/atanh.hpp>
namespace sprout {
//
// atan
//
// catan(z) = -i catanh(iz)
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atan(sprout::complex<T> const& x) {
return -sprout::perp(sprout::atanh(sprout::perp(x)));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_ATAN_HPP

84
sprout/complex/atanh.hpp Normal file
View file

@ -0,0 +1,84 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_ATANH_HPP
#define SPROUT_COMPLEX_ATANH_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/math/log.hpp>
#include <sprout/math/atan2.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/log.hpp>
#include <sprout/complex/sqrt.hpp>
#include <sprout/complex/operators.hpp>
namespace sprout {
//
// atanh
//
// G.6.2.3 The catanh functions
// catanh(conj(z)) = conj(catanh(z)) and catanh is odd.
// catanh(+0 + i0) returns +0 + i0.
// catanh(+0 + iNaN) returns +0 + iNaN.
// catanh(+1 + i0) returns +<2B>‡+ i0 and raises the <20>e<EFBFBD>edivide-by-zero<72>f<EFBFBD>f floating-point exception.
// catanh(x + i<>‡) returns +0 + ip /2, for finite positive-signed x.
// catanh(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for nonzero finite x.
// catanh(+<2B>‡+ iy) returns +0 + ip /2, for finite positive-signed y.
// catanh(+<2B>‡+ i<>‡) returns +0 + ip /2.
// catanh(+<2B>‡+ iNaN) returns +0 + iNaN.
// catanh(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite y.
// catanh(NaN + i<>‡) returns <20>}0 + ip /2 (where the sign of the real part of the result is unspecified).
// catanh(NaN + iNaN) returns NaN + iNaN.
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atanh_impl_1(sprout::complex<T> const& x, T const& i2, T const& z, T const& num, T const& den) {
return sprout::complex<T>(
sprout::math::quarter<T>() * (sprout::math::log(i2 + num * num) - sprout::math::log(i2 + den * den)),
sprout::math::half<T>() * sprout::math::atan2(T(2) * x.imag(), z)
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atanh_impl(sprout::complex<T> const& x, T const& i2) {
return sprout::detail::atanh_impl_1(
x, i2,
T(1) - i2 - x.real() * x.real(),
T(1) + x.imag(), T(1) - x.imag()
);
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atanh(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? type(x.imag(), x.imag())
: sprout::math::isinf(x.imag()) ? type(sprout::math::copysign(T(0), x.real()), sprout::math::copysign(sprout::math::half_pi<T>(), x.imag()))
: type(x.real(), x.real())
: sprout::math::isnan(x.imag())
? sprout::math::isinf(x.real()) ? type(sprout::math::copysign(T(0), x.real()), x.imag())
: x.real() == 0 ? x
: type(x.imag(), x.imag())
: sprout::math::isinf(x.real()) || sprout::math::isinf(x.imag())
? type(sprout::math::copysign(T(0), x.real()), sprout::math::copysign(sprout::math::half_pi<T>(), x.imag()))
: x.real() == 0 && x.imag() == 0 ? x
: (x.real() == 1 || x.real() == -1) && x.imag() == 0 ? type(sprout::math::copysign(sprout::numeric_limits<T>::infinity(), x.real()), x.imag())
// : sprout::detail::atanh_impl(x, x.imag() * x.imag())
: (sprout::log(T(1) + x) - sprout::log(T(1) - x)) / T(2)
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_ATANH_HPP

37
sprout/complex/conj.hpp Normal file
View file

@ -0,0 +1,37 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_CONJ_HPP
#define SPROUT_COMPLEX_CONJ_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/type_traits/complex_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
//
// conj
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
conj(sprout::complex<T> const& x) {
return sprout::complex<T>(x.real(), -x.imag());
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::complex_promote<ArithmeticType>::type
conj(ArithmeticType x) {
typedef typename sprout::complex_promote<ArithmeticType>::type type;
return type(x);
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_CONJ_HPP

29
sprout/complex/cos.hpp Normal file
View file

@ -0,0 +1,29 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_COS_HPP
#define SPROUT_COMPLEX_COS_HPP
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/perp.hpp>
#include <sprout/complex/cosh.hpp>
namespace sprout {
//
// cos
//
// ccos(z) = ccosh(iz)
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
cos(sprout::complex<T> const& x) {
return sprout::cosh(sprout::perp(x));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_COS_HPP

73
sprout/complex/cosh.hpp Normal file
View file

@ -0,0 +1,73 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_COSH_HPP
#define SPROUT_COMPLEX_COSH_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/abs.hpp>
#include <sprout/math/cos.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/math/cosh.hpp>
#include <sprout/math/sinh.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/euler.hpp>
#include <sprout/complex/detail/copysign_mul.hpp>
namespace sprout {
//
// cosh
//
// G.6.2.4 The ccosh functions
// ccosh(conj(z)) = conj(ccosh(z)) and ccosh is even.
// ccosh(+0 + i0) returns 1 + i0.
// ccosh(+0 + i<>‡) returns NaN <20>} i0 (where the sign of the imaginary part of the result is unspecified) and raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception.
// ccosh(+0 + iNaN) returns NaN <20>} i0 (where the sign of the imaginary part of the result is unspecified).
// ccosh(x + i<>‡) returns NaN + iNaN and raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite nonzero x.
// ccosh(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite nonzero x.
// ccosh(+<2B>‡+ i0) returns +<2B>‡+ i0.
// ccosh(+<2B>‡+ iy) returns +<2B>‡ cis(y), for finite nonzero y.
// ccosh(+<2B>‡+ i<>‡) returns <20>}<7D>‡+ iNaN (where the sign of the real part of the result is unspecified) and raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception.
// ccosh(+<2B>‡+ iNaN) returns +<2B>‡+ iNaN.
// ccosh(NaN + i0) returns NaN <20>} i0 (where the sign of the imaginary part of the result is unspecified).
// ccosh(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for all nonzero numbers y.
// ccosh(NaN + iNaN) returns NaN + iNaN.
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
cosh(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? type(x.real(), x.real())
: x.imag() == 0 ? type(sprout::numeric_limits<T>::quiet_NaN(), x.imag())
: type(x.real(), x.real())
: sprout::math::isnan(x.imag())
? sprout::math::isinf(x.real()) ? type(sprout::numeric_limits<T>::infinity(), sprout::numeric_limits<T>::quiet_NaN())
: x.real() == 0 ? type(sprout::numeric_limits<T>::quiet_NaN(), x.real())
: type(x.imag(), x.imag())
: x.real() == sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), sprout::numeric_limits<T>::quiet_NaN())
: x.imag() == 0 ? type(sprout::numeric_limits<T>::infinity(), x.imag())
: sprout::detail::copysign_mul(sprout::numeric_limits<T>::infinity(), sprout::euler(x.imag()))
: x.real() == -sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), sprout::numeric_limits<T>::quiet_NaN())
: x.imag() == 0 ? type(sprout::numeric_limits<T>::infinity(), x.imag()) // ???? GCC or Clang
: sprout::detail::copysign_mul(sprout::numeric_limits<T>::infinity(), sprout::euler(-x.imag()))
: sprout::math::isinf(x.imag())
? x.real() == 0 ? type(sprout::numeric_limits<T>::quiet_NaN(), x.real())
: type(-sprout::numeric_limits<T>::quiet_NaN(), -sprout::numeric_limits<T>::quiet_NaN())
: x.real() == 0 && x.imag() == 0 ? type(T(1), x.imag())
: type(sprout::math::cosh(x.real()) * sprout::math::cos(x.imag()), sprout::math::sinh(x.real()) * sprout::math::sin(x.imag()))
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_COSH_HPP

View file

@ -0,0 +1,27 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_DETAIL_COPYSIGN_MUL_HPP
#define SPROUT_COMPLEX_DETAIL_COPYSIGN_MUL_HPP
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
namespace sprout {
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
copysign_mul(T const& t, sprout::complex<T> const& z) {
return sprout::complex<T>(
sprout::math::copysign(t, z.real()),
sprout::math::copysign(t, z.imag())
);
}
} // namespace detail
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_DETAIL_COPYSIGN_MUL_HPP

27
sprout/complex/euler.hpp Normal file
View file

@ -0,0 +1,27 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_EULER_HPP
#define SPROUT_COMPLEX_EULER_HPP
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/math/cos.hpp>
namespace sprout {
//
// euler
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
euler(T const& theta) {
return sprout::complex<T>(sprout::math::cos(theta), sprout::math::sin(theta));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_EULER_HPP

70
sprout/complex/exp.hpp Normal file
View file

@ -0,0 +1,70 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_EXP_HPP
#define SPROUT_COMPLEX_EXP_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/polar.hpp>
#include <sprout/complex/euler.hpp>
#include <sprout/complex/detail/copysign_mul.hpp>
namespace sprout {
//
// exp
//
// G.6.3.1 The cexp functions
// cexp(conj(z)) = conj(cexp(z)).
// cexp(<28>}0 + i0) returns 1 + i0.
// cexp(x + i<>‡) returns NaN + iNaN and raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite x.
// cexp(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite x.
// cexp(+<2B>‡+ i0) returns +<2B>‡+ i0.
// cexp(-<2D>‡+ iy) returns +0 cis(y), for finite y.
// cexp(+<2B>‡+ iy) returns +<2B>‡ cis(y), for finite nonzero y.
// cexp(-<2D>‡+ i<>‡) returns <20>}0 <20>} i0 (where the signs of the real and imaginary parts of the result are unspecified).
// cexp(+<2B>‡+ i<>‡) returns <20>}<7D>‡+ iNaN and raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception (where the sign of the real part of the result is unspecified).
// cexp(-<2D>‡+ iNaN) returns <20>}0 <20>} i0 (where the signs of the real and imaginary parts of the result are unspecified).
// cexp(+<2B>‡+ iNaN) returns <20>}<7D>‡+ iNaN (where the sign of the real part of the result is unspecified).
// cexp(NaN + i0) returns NaN + i0.
// cexp(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for all non-zero numbers y.
// cexp(NaN + iNaN) returns NaN + iNaN.
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
exp(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? type(x.real(), x.real())
: x.imag() == 0 ? type(x.real(), x.imag())
: type(x.real(), x.real())
: sprout::math::isnan(x.imag())
? x.real() == sprout::numeric_limits<T>::infinity() ? type(x.real(), x.imag())
: x.real() == -sprout::numeric_limits<T>::infinity() ? type(T(0), T(0))
: sprout::math::isinf(x.real()) ? type(sprout::numeric_limits<T>::infinity(), sprout::numeric_limits<T>::quiet_NaN())
: type(x.imag(), x.imag())
: x.real() == sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), sprout::numeric_limits<T>::quiet_NaN())
: x.imag() == 0 ? type(sprout::numeric_limits<T>::infinity(), x.imag())
: sprout::detail::copysign_mul(sprout::numeric_limits<T>::infinity(), sprout::euler(x.imag()))
: x.real() == -sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(T(0), T(0))
: T(0) * sprout::euler(x.imag())
: sprout::math::isinf(x.imag())
? type(-sprout::numeric_limits<T>::quiet_NaN(), -sprout::numeric_limits<T>::quiet_NaN())
: x.real() == 0 && x.imag() == 0 ? type(T(1), x.imag())
: sprout::polar(sprout::math::exp(x.real()), x.imag())
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_EXP_HPP

41
sprout/complex/imag.hpp Normal file
View file

@ -0,0 +1,41 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_IMAG_HPP
#define SPROUT_COMPLEX_IMAG_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
//
// imag
//
template<typename T>
inline SPROUT_CONSTEXPR T const&
imag(sprout::complex<T> const& x) {
return x.imag();
}
template<typename T>
inline SPROUT_CONSTEXPR T&
imag(sprout::complex<T>& x) {
return x.imag();
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
imag(ArithmeticType) {
return 0;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_IMAG_HPP

70
sprout/complex/log.hpp Normal file
View file

@ -0,0 +1,70 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_LOG_HPP
#define SPROUT_COMPLEX_LOG_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/math/signbit.hpp>
#include <sprout/math/log.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/abs.hpp>
#include <sprout/complex/arg.hpp>
namespace sprout {
//
// log
//
// G.6.3.2 The clog functions
// clog(conj(z)) = conj(clog(z)).
// clog(-0 + i0) returns -<2D>‡+ ip and raises the <20>e<EFBFBD>edivide-by-zero<72>f<EFBFBD>f floating-point exception.
// clog(+0 + i0) returns -<2D>‡+ i0 and raises the <20>e<EFBFBD>edivide-by-zero<72>f<EFBFBD>f floating-point exception.
// clog(x + i<>‡) returns +<2B>‡+ ip /2, for finite x.
// clog(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite x.
// clog(-<2D>‡+ iy) returns +<2B>‡+ ip , for finite positive-signed y.
// clog(+<2B>‡+ iy) returns +<2B>‡+ i0, for finite positive-signed y.
// clog(-<2D>‡+ i<>‡) returns +<2B>‡+ i3p /4.
// clog(+<2B>‡+ i<>‡) returns +<2B>‡+ ip /4.
// clog(<28>}<7D>‡+ iNaN) returns +<2B>‡+ iNaN.
// clog(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite y.
// clog(NaN + i<>‡) returns +<2B>‡+ iNaN.
// clog(NaN + iNaN) returns NaN + iNaN.
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
log(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? type(sprout::numeric_limits<T>::quiet_NaN(), x.real())
: sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), x.real())
: type(sprout::numeric_limits<T>::quiet_NaN(), x.real())
: sprout::math::isnan(x.imag())
? sprout::math::isinf(x.real()) ? type(sprout::numeric_limits<T>::infinity(), x.imag())
: type(sprout::numeric_limits<T>::quiet_NaN(), x.imag())
: x.real() == sprout::numeric_limits<T>::infinity()
? x.imag() == sprout::numeric_limits<T>::infinity() ? type(sprout::numeric_limits<T>::infinity(), sprout::math::quarter_pi<T>())
: x.imag() == -sprout::numeric_limits<T>::infinity() ? type(sprout::numeric_limits<T>::infinity(), -sprout::math::quarter_pi<T>())
: type(sprout::numeric_limits<T>::infinity(), (x.imag() == 0 ? x.imag() : sprout::math::copysign(T(0), x.imag())))
: x.real() == -sprout::numeric_limits<T>::infinity()
? x.imag() == sprout::numeric_limits<T>::infinity() ? type(sprout::numeric_limits<T>::infinity(), sprout::math::three_quarters_pi<T>())
: x.imag() == -sprout::numeric_limits<T>::infinity() ? type(sprout::numeric_limits<T>::infinity(), -sprout::math::three_quarters_pi<T>())
: type(sprout::numeric_limits<T>::infinity(), sprout::math::copysign(sprout::math::pi<T>(), x.imag()))
: sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), sprout::math::copysign(sprout::math::half_pi<T>(), x.imag()))
: x.real() == 0 && x.imag() == 0
? sprout::math::signbit(x.real()) ? type(-sprout::numeric_limits<T>::infinity(), sprout::math::copysign(sprout::math::pi<T>(), x.imag()))
: type(-sprout::numeric_limits<T>::infinity(), x.imag())
: type(sprout::math::log(sprout::abs(x)), sprout::arg(x))
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_LOG_HPP

38
sprout/complex/log10.hpp Normal file
View file

@ -0,0 +1,38 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_LOG10_HPP
#define SPROUT_COMPLEX_LOG10_HPP
#include <sprout/config.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/log.hpp>
namespace sprout {
//
// log10
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
log10_impl(sprout::complex<T> const& z) {
return sprout::math::isnan(z.real()) || sprout::math::isnan(z.imag()) ? z
: z / sprout::math::ln_ten<T>()
;
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
log10(sprout::complex<T> const& x) {
return sprout::detail::log10_impl(sprout::log(x));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_LOG10_HPP

38
sprout/complex/log2.hpp Normal file
View file

@ -0,0 +1,38 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_LOG2_HPP
#define SPROUT_COMPLEX_LOG2_HPP
#include <sprout/config.hpp>
#include <sprout/math/constants.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/log.hpp>
namespace sprout {
//
// log2
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
log2_impl(sprout::complex<T> const& z) {
return sprout::math::isnan(z.real()) || sprout::math::isnan(z.imag()) ? z
: z / sprout::math::ln_two<T>()
;
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
log2(sprout::complex<T> const& x) {
return sprout::detail::log2_impl(sprout::log(x));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_LOG2_HPP

View file

@ -16,21 +16,33 @@
#include <sprout/math/round.hpp> #include <sprout/math/round.hpp>
namespace sprout { namespace sprout {
//
// ceil
//
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> inline SPROUT_CONSTEXPR sprout::complex<T>
ceil(sprout::complex<T> const& x) { ceil(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::math::ceil(x.real()), sprout::math::ceil(x.imag())); return sprout::complex<T>(sprout::math::ceil(x.real()), sprout::math::ceil(x.imag()));
} }
//
// floor
//
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> inline SPROUT_CONSTEXPR sprout::complex<T>
floor(sprout::complex<T> const& x) { floor(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::math::floor(x.real()), sprout::math::floor(x.imag())); return sprout::complex<T>(sprout::math::floor(x.real()), sprout::math::floor(x.imag()));
} }
//
// trunc
//
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> inline SPROUT_CONSTEXPR sprout::complex<T>
trunc(sprout::complex<T> const& x) { trunc(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::math::trunc(x.real()), sprout::math::trunc(x.imag())); return sprout::complex<T>(sprout::math::trunc(x.real()), sprout::math::trunc(x.imag()));
} }
//
// round
//
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> inline SPROUT_CONSTEXPR sprout::complex<T>
round(sprout::complex<T> const& x) { round(sprout::complex<T> const& x) {

37
sprout/complex/norm.hpp Normal file
View file

@ -0,0 +1,37 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_NORM_HPP
#define SPROUT_COMPLEX_NORM_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
//
// norm
//
template<typename T>
inline SPROUT_CONSTEXPR T
norm(sprout::complex<T> const& x) {
return x.real() * x.real() + x.imag() * x.imag();
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
norm(ArithmeticType x) {
typedef typename sprout::float_promote<ArithmeticType>::type type;
return type(x) * type(x);
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_NORM_HPP

38
sprout/complex/perp.hpp Normal file
View file

@ -0,0 +1,38 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_PERP_HPP
#define SPROUT_COMPLEX_PERP_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
//
// perp
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
perp(sprout::complex<T> const& x) {
return sprout::complex<T>(-x.imag(), x.real());
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::complex_promote<ArithmeticType>::type
perp(ArithmeticType x) {
typedef typename sprout::complex_promote<ArithmeticType>::type type;
typedef typename type::value_type value_type;
return type(-value_type(0), value_type(x));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_PERP_HPP

63
sprout/complex/polar.hpp Normal file
View file

@ -0,0 +1,63 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_POLER_HPP
#define SPROUT_COMPLEX_POLER_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/signbit.hpp>
#include <sprout/math/cos.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/type_traits/complex_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
//
// polar
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
polar_impl(T const& x, T const& y) {
return sprout::complex<T>(
sprout::math::isnan(x) ? T() : x,
sprout::math::isnan(y) ? T() : y
);
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
polar(T const& rho, T const& theta = T()) {
typedef sprout::complex<T> type;
return sprout::math::isnan(rho) || sprout::math::signbit(rho)
? type(sprout::numeric_limits<T>::quiet_NaN(), sprout::numeric_limits<T>::quiet_NaN())
: sprout::math::isnan(theta)
? sprout::math::isinf(rho) ? type(rho, theta)
: type(theta, theta)
: sprout::math::isinf(theta)
? sprout::math::isinf(rho) ? type(rho, sprout::numeric_limits<T>::quiet_NaN())
: type(sprout::numeric_limits<T>::quiet_NaN(), sprout::numeric_limits<T>::quiet_NaN())
: sprout::detail::polar_impl(rho * sprout::math::cos(theta), rho * sprout::math::sin(theta))
;
}
template<
typename ArithmeticType1, typename ArithmeticType2,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::complex_promote<ArithmeticType1, ArithmeticType2>::type
polar(ArithmeticType1 const& rho, ArithmeticType2 const& theta) {
typedef typename sprout::complex_promote<ArithmeticType1, ArithmeticType2>::type::value_type value_type;
return sprout::polar(static_cast<value_type>(rho), static_cast<value_type>(theta));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_POLER_HPP

59
sprout/complex/pow.hpp Normal file
View file

@ -0,0 +1,59 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_POW_HPP
#define SPROUT_COMPLEX_POW_HPP
#include <sprout/config.hpp>
#include <sprout/math/pow.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/exp.hpp>
#include <sprout/complex/log.hpp>
namespace sprout {
//
// pow
//
// G.6.4.1 The cpow functions
// 1 The cpow functions raise floating-point exceptions if appropriate for the calculation of
// the parts of the result, and may raise spurious exceptions.317)
//
// 317) This allows cpow(z, c) to be implemented as cexp(c clog(z)) without precluding
// implementations that treat special cases more carefully.
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
pow(sprout::complex<T> const& x, sprout::complex<T> const& y) {
return x == T() ? T()
: sprout::exp(y * sprout::log(x))
;
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> pow_impl(sprout::complex<T> const& t, T const& y) {
return sprout::polar(sprout::exp(y * t.real()), y * t.imag());
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
pow(sprout::complex<T> const& x, T const& y) {
return x == T() ? T()
: x.imag() == T() && x.real() > T() ? sprout::math::pow(x.real(), y)
: sprout::detail::pow_impl(sprout::log(x), y)
;
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
pow(T const& x, sprout::complex<T> const& y) {
return x > T() ? sprout::polar(sprout::pow(x, y.real()), y.imag() * sprout::log(x))
: sprout::pow(sprout::complex<T>(x), y)
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_POW_HPP

47
sprout/complex/proj.hpp Normal file
View file

@ -0,0 +1,47 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_PROJ_HPP
#define SPROUT_COMPLEX_PROJ_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/type_traits/complex_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
//
// proj
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
proj(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isinf(x.real()) || sprout::math::isinf(x.imag())
? type(sprout::numeric_limits<T>::infinity(), sprout::math::copysign(T(), x.imag()))
: x
;
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::complex_promote<ArithmeticType>::type
proj(ArithmeticType x) {
typedef typename sprout::complex_promote<ArithmeticType>::type type;
return sprout::math::isinf(x)
? type(sprout::numeric_limits<ArithmeticType>::infinity())
: type(x)
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_PROJ_HPP

41
sprout/complex/real.hpp Normal file
View file

@ -0,0 +1,41 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_REAL_HPP
#define SPROUT_COMPLEX_REAL_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
//
// real
//
template<typename T>
inline SPROUT_CONSTEXPR T const&
real(sprout::complex<T> const& x) {
return x.real();
}
template<typename T>
inline SPROUT_CONSTEXPR T&
real(sprout::complex<T>& x) {
return x.real();
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
real(ArithmeticType x) {
return x;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_REAL_HPP

30
sprout/complex/sin.hpp Normal file
View file

@ -0,0 +1,30 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_SIN_HPP
#define SPROUT_COMPLEX_SIN_HPP
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/perp.hpp>
#include <sprout/complex/sinh.hpp>
namespace sprout {
//
// sin
//
// csin(z) = -i csinh(iz)
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sin(sprout::complex<T> const& x) {
return -sprout::perp(sprout::sinh(sprout::perp(x)));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_SIN_HPP

73
sprout/complex/sinh.hpp Normal file
View file

@ -0,0 +1,73 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_SINH_HPP
#define SPROUT_COMPLEX_SINH_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/cos.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/math/cosh.hpp>
#include <sprout/math/sinh.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/euler.hpp>
#include <sprout/complex/detail/copysign_mul.hpp>
namespace sprout {
//
// sinh
//
// G.6.2.5 The csinh functions
// csinh(conj(z)) = conj(csinh(z)) and csinh is odd.
// csinh(+0 + i0) returns +0 + i0.
// csinh(+0 + i<>‡) returns <20>}0 + iNaN (where the sign of the real part of the result is unspecified) and raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception.
// csinh(+0 + iNaN) returns <20>}0 + iNaN (where the sign of the real part of the result is unspecified).
// csinh(x + i<>‡) returns NaN + iNaN and raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for positive finite x.
// csinh(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite nonzero x.
// csinh(+<2B>‡+ i0) returns +<2B>‡+ i0.
// csinh(+<2B>‡+ iy) returns +<2B>‡ cis(y), for positive finite y.
// csinh(+<2B>‡+ i<>‡) returns <20>}<7D>‡+ iNaN (where the sign of the real part of the result is unspecified) and raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception.
// csinh(+<2B>‡+ iNaN) returns <20>}<7D>‡+ iNaN (where the sign of the real part of the result is unspecified).
// csinh(NaN + i0) returns NaN + i0.
// csinh(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for all nonzero numbers y.
// csinh(NaN + iNaN) returns NaN + iNaN.
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sinh(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? type(x.real(), x.real())
: sprout::math::isinf(x.imag()) ? type(x.real(), x.real())
: x.imag() == 0 ? x
: type(x.real(), x.real())
: sprout::math::isnan(x.imag())
? sprout::math::isinf(x.real()) ? type(x.real(), sprout::numeric_limits<T>::quiet_NaN())
: x.real() == 0 ? type(x.real(), sprout::numeric_limits<T>::quiet_NaN())
: type(x.imag(), x.imag())
: x.real() == sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(x.real(), sprout::numeric_limits<T>::quiet_NaN())
: x.imag() == 0 ? x
: sprout::detail::copysign_mul(sprout::numeric_limits<T>::infinity(), sprout::euler(x.imag()))
: x.real() == -sprout::numeric_limits<T>::infinity()
? sprout::math::isinf(x.imag()) ? type(x.real(), sprout::numeric_limits<T>::quiet_NaN())
: x.imag() == 0 ? x
: -sprout::detail::copysign_mul(sprout::numeric_limits<T>::infinity(), sprout::euler(-x.imag()))
: sprout::math::isinf(x.imag())
? x.real() == 0 ? type(x.real(), sprout::numeric_limits<T>::quiet_NaN())
: type(-sprout::numeric_limits<T>::quiet_NaN(), -sprout::numeric_limits<T>::quiet_NaN())
: x.real() == 0 && x.imag() == 0 ? x
: type(sprout::math::sinh(x.real()) * sprout::math::cos(x.imag()), sprout::math::cosh(x.real()) * sprout::math::sin(x.imag()))
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_SINH_HPP

85
sprout/complex/sqrt.hpp Normal file
View file

@ -0,0 +1,85 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_SQRT_HPP
#define SPROUT_COMPLEX_SQRT_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/math/signbit.hpp>
#include <sprout/math/abs.hpp>
#include <sprout/math/sqrt.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/abs.hpp>
namespace sprout {
//
// sqrt
//
// G.6.4.2 The csqrt functions
// csqrt(conj(z)) = conj(csqrt(z)).
// csqrt(<28>}0 + i0) returns +0 + i0.
// csqrt(x + i<>‡) returns +<2B>‡+ i<>‡, for all x (including NaN).
// csqrt(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite x.
// csqrt(-<2D>‡+ iy) returns +0 + i<>‡, for finite positive-signed y.
// csqrt(+<2B>‡+ iy) returns +<2B>‡+ i0, for finite positive-signed y.
// csqrt(-<2D>‡+ iNaN) returns NaN <20>} i<>‡ (where the sign of the imaginary part of the result is unspecified).
// csqrt(+<2B>‡+ iNaN) returns +<2B>‡+ iNaN.
// csqrt(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite y.
// csqrt(NaN + iNaN) returns NaN + iNaN.
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sqrt_impl_1(sprout::complex<T> const& x, T const& t) {
return sprout::complex<T>(t, sprout::math::signbit(x.imag()) ? -t : t);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sqrt_impl_2_1(sprout::complex<T> const& x, T const& t, T const& u) {
return x.real() > T(0) ? sprout::complex<T>(u, x.imag() / t)
: sprout::complex<T>(sprout::math::abs(x.imag()) / t, sprout::math::signbit(x.imag()) ? -u : u)
;
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sqrt_impl_2(sprout::complex<T> const& x, T const& t) {
return sprout::detail::sqrt_impl_2_1(x, t, t / T(2));
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sqrt(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits<T>::infinity(), x.imag())
: sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? type(sprout::numeric_limits<T>::quiet_NaN(), sprout::numeric_limits<T>::quiet_NaN())
: type(sprout::numeric_limits<T>::quiet_NaN(), sprout::numeric_limits<T>::quiet_NaN())
: sprout::math::isnan(x.imag())
? x.real() == sprout::numeric_limits<T>::infinity()
? type(sprout::numeric_limits<T>::infinity(), sprout::math::copysign(sprout::numeric_limits<T>::quiet_NaN(), x.imag()))
: x.real() == -sprout::numeric_limits<T>::infinity()
? type(
sprout::math::copysign(sprout::numeric_limits<T>::quiet_NaN(), x.imag()),
sprout::math::copysign(sprout::numeric_limits<T>::infinity(), x.imag())
)
: type(sprout::numeric_limits<T>::quiet_NaN(), sprout::numeric_limits<T>::quiet_NaN())
: x.real() == sprout::numeric_limits<T>::infinity()
? type(sprout::numeric_limits<T>::infinity(), (x.imag() == 0 ? x.imag() : sprout::math::copysign(T(0), x.imag())))
: x.real() == -sprout::numeric_limits<T>::infinity()
? type(T(0), sprout::math::copysign(T(0), x.imag()))
: x.real() == 0 && x.imag() == 0 ? type(T(0), x.imag())
: x.real() == 0 ? sprout::detail::sqrt_impl_1(x, sprout::math::sqrt(sprout::math::abs(x.imag()) / T(2)))
: sprout::detail::sqrt_impl_2(x, sprout::math::sqrt(T(2) * (sprout::abs(x) + sprout::math::abs(x.real()))))
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_SQRT_HPP

30
sprout/complex/tan.hpp Normal file
View file

@ -0,0 +1,30 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_TAN_HPP
#define SPROUT_COMPLEX_TAN_HPP
#include <sprout/config.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/perp.hpp>
#include <sprout/complex/tanh.hpp>
namespace sprout {
//
// tan
//
// ctan(z) = -i ctanh(iz)
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
tan(sprout::complex<T> const& x) {
return -sprout::perp(sprout::tanh(sprout::perp(x)));
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_TAN_HPP

60
sprout/complex/tanh.hpp Normal file
View file

@ -0,0 +1,60 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_COMPLEX_TANH_HPP
#define SPROUT_COMPLEX_TANH_HPP
#include <sprout/config.hpp>
#include <sprout/limits.hpp>
#include <sprout/math/isnan.hpp>
#include <sprout/math/isinf.hpp>
#include <sprout/math/sin.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/complex/complex.hpp>
#include <sprout/complex/operators.hpp>
#include <sprout/complex/cosh.hpp>
#include <sprout/complex/sinh.hpp>
namespace sprout {
//
// tanh
//
// G.6.2.6 The ctanh functions
// ctanh(conj(z)) = conj(ctanh(z))and ctanh is odd.
// ctanh(+0 + i0) returns +0 + i0.
// ctanh(x + i<>‡) returns NaN + iNaN and raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite x.
// ctanh(x + iNaN) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for finite x.
// ctanh(+<2B>‡+ iy) returns 1 + i0 sin(2y), for positive-signed finite y.
// ctanh(+<2B>‡+ i<>‡) returns 1 <20>} i0 (where the sign of the imaginary part of the result is unspecified).
// ctanh(+<2B>‡+ iNaN) returns 1 <20>} i0 (where the sign of the imaginary part of the result is unspecified).
// ctanh(NaN + i0) returns NaN + i0.
// ctanh(NaN + iy) returns NaN + iNaN and optionally raises the <20>e<EFBFBD>einvalid<69>f<EFBFBD>f floating-point exception, for all nonzero numbers y.
// ctanh(NaN + iNaN) returns NaN + iNaN.
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
tanh(sprout::complex<T> const& x) {
typedef sprout::complex<T> type;
return sprout::math::isnan(x.real())
? sprout::math::isnan(x.imag()) ? x
: x.imag() == 0 ? x
: type(x.real(), x.real())
: sprout::math::isnan(x.imag())
? sprout::math::isinf(x.real()) ? type(T(1), T(0))
: type(x.imag(), x.imag())
: sprout::math::isinf(x.real())
? sprout::math::isinf(x.imag()) ? type(T(1), T(0))
: type(T(1), T(0) * sprout::math::sin(T(2) * x.imag()))
: sprout::math::isinf(x.imag())
? type(-sprout::numeric_limits<T>::quiet_NaN(), -sprout::numeric_limits<T>::quiet_NaN())
: x.real() == 0 && x.imag() == 0 ? x
: sprout::sinh(x) / sprout::cosh(x)
;
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_TANH_HPP

View file

@ -9,321 +9,23 @@
#define SPROUT_COMPLEX_TRANSCENDENTALS_HPP #define SPROUT_COMPLEX_TRANSCENDENTALS_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/complex/complex.hpp> #include <sprout/complex/acos.hpp>
#include <sprout/complex/operators.hpp> #include <sprout/complex/asin.hpp>
#include <sprout/complex/values.hpp> #include <sprout/complex/atan.hpp>
#include <sprout/math/constants.hpp> #include <sprout/complex/acosh.hpp>
#include <sprout/math/abs.hpp> #include <sprout/complex/asinh.hpp>
#include <sprout/math/sin.hpp> #include <sprout/complex/atanh.hpp>
#include <sprout/math/cos.hpp> #include <sprout/complex/cos.hpp>
#include <sprout/math/atan2.hpp> #include <sprout/complex/cosh.hpp>
#include <sprout/math/sinh.hpp> #include <sprout/complex/exp.hpp>
#include <sprout/math/cosh.hpp> #include <sprout/complex/log.hpp>
#include <sprout/math/exp.hpp> #include <sprout/complex/log10.hpp>
#include <sprout/math/log.hpp> #include <sprout/complex/log2.hpp>
#include <sprout/math/pow.hpp> #include <sprout/complex/pow.hpp>
#include <sprout/math/sqrt.hpp> #include <sprout/complex/sin.hpp>
#include <sprout/complex/sinh.hpp>
namespace sprout { #include <sprout/complex/sqrt.hpp>
// 26.4.8, transcendentals: #include <sprout/complex/tan.hpp>
template<typename T> #include <sprout/complex/tanh.hpp>
SPROUT_CONSTEXPR sprout::complex<T>
acos(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
asin(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
atan(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
acosh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
asinh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
atanh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
cos(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
cosh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
exp(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
log(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
log10(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
pow(sprout::complex<T> const& x, T const& y);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
pow(sprout::complex<T> const& x, sprout::complex<T> const& y);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
pow(T const& x, sprout::complex<T> const& y);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
sin(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
sinh(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
sqrt(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
tan(sprout::complex<T> const& x);
template<typename T>
SPROUT_CONSTEXPR sprout::complex<T>
tanh(sprout::complex<T> const& x);
//
// acos
// asin
// atan
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
acos_impl(sprout::complex<T> const& t) {
return sprout::complex<T>(sprout::math::half_pi<T>() - t.real(), -t.imag());
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
acos(sprout::complex<T> const& x) {
return sprout::detail::acos_impl(sprout::asin(x));
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
asin_impl(sprout::complex<T> const& t) {
return sprout::complex<T>(t.imag(), -t.real());
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
asin(sprout::complex<T> const& x) {
return sprout::detail::asin_impl(sprout::asinh(sprout::complex<T>(-x.imag(), x.real())));
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atan_impl_1(sprout::complex<T> const& x, T const& r2, T const& z, T const& num, T const& den) {
return sprout::complex<T>(
T(0.5) * sprout::atan2(T(2) * x.real(), z),
T(0.25) * sprout::log((r2 + num * num) / (r2 + den * den))
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atan_impl(sprout::complex<T> const& x, T const& r2) {
return sprout::detail::atan_impl_1(
x, r2,
T(1) - r2 - x.imag() * x.imag(),
x.imag() + T(1), x.imag() - T(1)
);
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atan(sprout::complex<T> const& x) {
return sprout::detail::atan_impl(x, x.real() * x.real());
}
//
// acosh
// asinh
// atanh
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
acosh(sprout::complex<T> const& x) {
return T(2) * sprout::log(sprout::sqrt(T(0.5) * (x + T(1))) + sprout::sqrt(T(0.5) * (x - T(1))));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
asinh(sprout::complex<T> const& x) {
return sprout::log(
sprout::sqrt(
sprout::complex<T>(
(x.real() - x.imag()) * (x.real() + x.imag()) + T(1),
T(2) * x.real() * x.imag()
)
)
+ x
);
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atanh_impl_1(sprout::complex<T> const& x, T const& i2, T const& z, T const& num, T const& den) {
return sprout::complex<T>(
T(0.25) * (sprout::log(i2 + num * num) - sprout::log(i2 + den * den)),
T(0.5) * sprout::atan2(T(2) * x.imag(), z)
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atanh_impl(sprout::complex<T> const& x, T const& i2) {
return sprout::detail::atanh_impl_1(
x, i2,
T(1) - i2 - x.real() * x.real(),
T(1) + x.imag(), T(1) - x.imag()
);
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
atanh(sprout::complex<T> const& x) {
return sprout::detail::atanh_impl(x, x.imag() * x.imag());
}
//
// cos
// cosh
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
cos(sprout::complex<T> const& x) {
return sprout::complex<T>(
sprout::cos(x.real()) * sprout::cosh(x.imag()),
-(sprout::sin(x.real()) * sprout::sinh(x.imag()))
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
cosh(sprout::complex<T> const& x) {
return sprout::complex<T>(
sprout::cosh(x.real()) * sprout::cos(x.imag()),
sprout::sinh(x.real()) * sprout::sin(x.imag())
);
}
//
// exp
// log
// log10
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
exp(sprout::complex<T> const& x) {
return sprout::polar(sprout::exp(x.real()), x.imag());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
log(sprout::complex<T> const& x) {
return sprout::complex<T>(sprout::log(sprout::abs(x)), sprout::arg(x));
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> log10(sprout::complex<T> const& x) {
return sprout::log(x) / sprout::log(T(10));
}
//
// pow
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T> pow_impl(sprout::complex<T> const& t, T const& y) {
return sprout::polar(sprout::exp(y * t.real()), y * t.imag());
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
pow(sprout::complex<T> const& x, T const& y) {
return x == T() ? T()
: x.imag() == T() && x.real() > T() ? sprout::pow(x.real(), y)
: sprout::detail::pow_impl(sprout::log(x), y)
;
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
pow(sprout::complex<T> const& x, sprout::complex<T> const& y) {
return x == T() ? T()
: sprout::exp(y * sprout::log(x))
;
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
pow(T const& x, sprout::complex<T> const& y) {
return x > T() ? sprout::polar(sprout::pow(x, y.real()), y.imag() * sprout::log(x))
: sprout::pow(sprout::complex<T>(x), y)
;
}
//
// sin
// sinh
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sin(sprout::complex<T> const& x) {
return sprout::complex<T>(
sprout::sin(x.real()) * sprout::cosh(x.imag()),
sprout::cos(x.real()) * sprout::sinh(x.imag())
);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sinh(sprout::complex<T> const& x) {
return sprout::complex<T>(
sprout::sinh(x.real()) * sprout::cos(x.imag()),
sprout::cosh(x.real()) * sprout::sin(x.imag())
);
}
//
// sqrt
//
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sqrt_impl_1(sprout::complex<T> const& x, T const& t) {
return sprout::complex<T>(t, x.imag() < T() ? -t : t);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sqrt_impl_2_1(sprout::complex<T> const& x, T const& t, T const& u) {
return x.real() > T() ? sprout::complex<T>(u, x.imag() / t)
: sprout::complex<T>(sprout::abs(x.imag()) / t, x.imag() < T() ? -u : u)
;
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sqrt_impl_2(sprout::complex<T> const& x, T const& t) {
return sprout::detail::sqrt_impl_2_1(x, t, t / 2);
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
sqrt(sprout::complex<T> const& x) {
return x.real() == T() ? sprout::detail::sqrt_impl_1(x, sprout::sqrt(abs(x.imag()) / 2))
: sprout::detail::sqrt_impl_2(x, sprout::sqrt(2 * (sprout::abs(x) + sprout::abs(x.real()))))
;
}
//
// tan
// tanh
//
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
tan(sprout::complex<T> const& x) {
return sprout::sin(x) / sprout::cos(x);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
tanh(sprout::complex<T> const& x) {
return sprout::sinh(x) / sprout::cosh(x);
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_TRANSCENDENTALS_HPP #endif // #ifndef SPROUT_COMPLEX_TRANSCENDENTALS_HPP

View file

@ -8,176 +8,16 @@
#ifndef SPROUT_COMPLEX_VALUES_HPP #ifndef SPROUT_COMPLEX_VALUES_HPP
#define SPROUT_COMPLEX_VALUES_HPP #define SPROUT_COMPLEX_VALUES_HPP
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/limits.hpp> #include <sprout/complex/real.hpp>
#include <sprout/complex/complex.hpp> #include <sprout/complex/imag.hpp>
#include <sprout/complex/operators.hpp> #include <sprout/complex/abs.hpp>
#include <sprout/math/sin.hpp> #include <sprout/complex/arg.hpp>
#include <sprout/math/cos.hpp> #include <sprout/complex/norm.hpp>
#include <sprout/math/atan2.hpp> #include <sprout/complex/conj.hpp>
#include <sprout/math/sqrt.hpp> #include <sprout/complex/proj.hpp>
#include <sprout/math/isinf.hpp> #include <sprout/complex/polar.hpp>
#include <sprout/math/isnan.hpp> #include <sprout/complex/perp.hpp>
#include <sprout/math/signbit.hpp> #include <sprout/complex/euler.hpp>
#include <sprout/math/copysign.hpp>
#include <sprout/type_traits/float_promote.hpp>
#include <sprout/type_traits/complex_promote.hpp>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout {
template<typename T>
SPROUT_CONSTEXPR T
norm(sprout::complex<T> const& x);
//
// 26.4.7, values:
//
template<typename T>
inline SPROUT_CONSTEXPR T const&
real(sprout::complex<T> const& x) {
return x.real();
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
real(ArithmeticType x) {
return x;
}
template<typename T>
inline SPROUT_CONSTEXPR T const&
imag(sprout::complex<T> const& x) {
return x.imag();
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
imag(ArithmeticType) {
return 0;
}
template<typename T>
inline SPROUT_CONSTEXPR T&
real(sprout::complex<T>& x) {
return x.real();
}
template<typename T>
inline SPROUT_CONSTEXPR T&
imag(sprout::complex<T>& x) {
return x.imag();
}
template<typename T>
inline SPROUT_CONSTEXPR T
abs(sprout::complex<T> const& x) {
return sprout::sqrt(sprout::norm(x));
}
template<typename T>
inline SPROUT_CONSTEXPR T
arg(sprout::complex<T> const& x) {
return sprout::atan2(x.imag(), x.real());
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
arg(ArithmeticType x) {
return sprout::atan2(ArithmeticType(0), x);
}
template<typename T>
inline SPROUT_CONSTEXPR T
norm(sprout::complex<T> const& x) {
return x.real() * x.real() + x.imag() * x.imag();
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::float_promote<ArithmeticType>::type
norm(ArithmeticType x) {
typedef typename sprout::complex_promote<ArithmeticType>::type type;
return type(x) * type(x);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
conj(sprout::complex<T> const& x) {
return sprout::complex<T>(x.real(), -x.imag());
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::complex_promote<ArithmeticType>::type
conj(ArithmeticType x) {
typedef typename sprout::complex_promote<ArithmeticType>::type type;
return type(x);
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
proj(sprout::complex<T> const& x) {
return sprout::math::isinf(x.real()) || sprout::math::isinf(x.imag())
? sprout::complex<T>(sprout::numeric_limits<T>::infinity(), sprout::math::copysign(T(), x.imag()))
: x
;
}
template<
typename ArithmeticType,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::complex_promote<ArithmeticType>::type
proj(ArithmeticType x) {
typedef typename sprout::complex_promote<ArithmeticType>::type type;
return sprout::math::isinf(x)
? type(sprout::numeric_limits<ArithmeticType>::infinity())
: type(x)
;
}
namespace detail {
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
polar_impl(T const& x, T const& y) {
typedef sprout::complex<T> type;
return type(
sprout::math::isnan(x) ? T() : x,
sprout::math::isnan(y) ? T() : y
);
}
} // namespace detail
template<typename T>
inline SPROUT_CONSTEXPR sprout::complex<T>
polar(T const& rho, T const& theta = T()) {
typedef sprout::complex<T> type;
return sprout::math::isnan(rho) || sprout::math::signbit(rho)
? type(sprout::numeric_limits<T>::quiet_NaN(), sprout::numeric_limits<T>::quiet_NaN())
: sprout::math::isnan(theta)
? sprout::math::isinf(rho) ? type(rho, theta)
: type(theta, theta)
: sprout::math::isinf(theta)
? sprout::math::isinf(rho) ? type(rho, sprout::numeric_limits<T>::quiet_NaN())
: type(sprout::numeric_limits<T>::quiet_NaN(), sprout::numeric_limits<T>::quiet_NaN())
: sprout::detail::polar_impl(rho * sprout::cos(theta), rho * sprout::sin(theta))
;
}
template<
typename ArithmeticType1, typename ArithmeticType2,
typename sprout::enabler_if<std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR typename sprout::complex_promote<ArithmeticType1, ArithmeticType2>::type
polar(ArithmeticType1 const& rho, ArithmeticType2 const& theta) {
typedef typename sprout::complex_promote<ArithmeticType1, ArithmeticType2>::type::value_type value_type;
return sprout::polar<value_type>(rho, theta);
}
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_VALUES_HPP #endif // #ifndef SPROUT_COMPLEX_VALUES_HPP