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:
parent
c830cab086
commit
22c3f6e132
32 changed files with 1460 additions and 486 deletions
27
sprout/complex/abs.hpp
Normal file
27
sprout/complex/abs.hpp
Normal 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
71
sprout/complex/acos.hpp
Normal 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
63
sprout/complex/acosh.hpp
Normal 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
37
sprout/complex/arg.hpp
Normal 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
30
sprout/complex/asin.hpp
Normal 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
65
sprout/complex/asinh.hpp
Normal 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
30
sprout/complex/atan.hpp
Normal 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
84
sprout/complex/atanh.hpp
Normal 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
37
sprout/complex/conj.hpp
Normal 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
29
sprout/complex/cos.hpp
Normal 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
73
sprout/complex/cosh.hpp
Normal 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
|
27
sprout/complex/detail/copysign_mul.hpp
Normal file
27
sprout/complex/detail/copysign_mul.hpp
Normal 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
27
sprout/complex/euler.hpp
Normal 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
70
sprout/complex/exp.hpp
Normal 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
41
sprout/complex/imag.hpp
Normal 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
70
sprout/complex/log.hpp
Normal 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
38
sprout/complex/log10.hpp
Normal 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
38
sprout/complex/log2.hpp
Normal 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
|
|
@ -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
37
sprout/complex/norm.hpp
Normal 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
38
sprout/complex/perp.hpp
Normal 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
63
sprout/complex/polar.hpp
Normal 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
59
sprout/complex/pow.hpp
Normal 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
47
sprout/complex/proj.hpp
Normal 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
41
sprout/complex/real.hpp
Normal 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
30
sprout/complex/sin.hpp
Normal 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
73
sprout/complex/sinh.hpp
Normal 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
85
sprout/complex/sqrt.hpp
Normal 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
30
sprout/complex/tan.hpp
Normal 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
60
sprout/complex/tanh.hpp
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue