diff --git a/sprout/complex/abs.hpp b/sprout/complex/abs.hpp new file mode 100644 index 00000000..674ebb07 --- /dev/null +++ b/sprout/complex/abs.hpp @@ -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 +#include +#include +#include + +namespace sprout { + // + // abs + // + template + inline SPROUT_CONSTEXPR T + abs(sprout::complex const& x) { + return sprout::math::sqrt(sprout::norm(x)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_ABS_HPP diff --git a/sprout/complex/acos.hpp b/sprout/complex/acos.hpp new file mode 100644 index 00000000..665bdccd --- /dev/null +++ b/sprout/complex/acos.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // acos + // + // G.6.1.1 The cacos functions + // cacos(conj(z)) = conj(cacos(z)). + // cacos(}0 + i0) returns p /2 - i0. + // cacos(}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 eeinvalidff floating-point exception, for nonzero finite x. + // cacos(-+ iy) returns p - i, for positive-signed finite y. + // cacos(++ iy) returns +0 - i, for positive-signed finite y. + // cacos(-+ i) returns 3p /4 - i. + // cacos(++ i) returns p /4 - i. + // cacos(}+ iNaN) returns NaN } i (where the sign of the imaginary part of the result is unspecified). + // cacos(NaN + iy) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite y. + // cacos(NaN + i) returns NaN - i. + // cacos(NaN + iNaN) returns NaN + iNaN. + // + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex + acos_impl(sprout::complex const& t) { + return sprout::complex(sprout::math::half_pi() - t.real(), -t.imag()); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex + acos(sprout::complex const& x) { + typedef sprout::complex 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::quiet_NaN()) + : sprout::math::isnan(x.imag()) + ? sprout::math::isinf(x.real()) ? type(sprout::numeric_limits::quiet_NaN(), x.real()) + : x.real() == 0 ? type(sprout::math::half_pi(), x.imag()) + : type(sprout::numeric_limits::quiet_NaN(), sprout::numeric_limits::quiet_NaN()) + : x.real() == sprout::numeric_limits::infinity() + ? sprout::math::isinf(x.imag()) ? type(sprout::math::quarter_pi(), -x.imag()) + : type(T(0), sprout::math::copysign(sprout::numeric_limits::infinity(), -x.imag())) + : x.real() == -sprout::numeric_limits::infinity() + ? sprout::math::isinf(x.imag()) ? type(sprout::math::three_quarters_pi(), -x.imag()) + : type(sprout::math::pi(), sprout::math::copysign(sprout::numeric_limits::infinity(), -x.imag())) + : sprout::math::isinf(x.imag()) ? type(sprout::math::half_pi(), sprout::math::copysign(sprout::numeric_limits::infinity(), -x.imag())) + : x.real() == 0 && x.imag() == 0 ? type(sprout::math::half_pi(), -x.imag()) + : sprout::detail::acos_impl(sprout::asin(x)) + ; + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_ACOS_HPP diff --git a/sprout/complex/acosh.hpp b/sprout/complex/acosh.hpp new file mode 100644 index 00000000..b9c3d21b --- /dev/null +++ b/sprout/complex/acosh.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // acosh + // + // G.6.2.1 The cacosh functions + // cacosh(conj(z)) = conj(cacosh(z)). + // cacosh(}0 + i0) returns +0 + ip /2. + // cacosh(x + i) returns ++ ip /2, for finite x. + // cacosh(x + iNaN) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite x. + // cacosh(-+ iy) returns ++ ip , for positive-signed finite y. + // cacosh(++ iy) returns ++ i0, for positive-signed finite y. + // cacosh(-+ i) returns ++ i3p /4. + // cacosh(++ i) returns ++ ip /4. + // cacosh(}+ iNaN) returns ++ iNaN. + // cacosh(NaN + iy) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite y. + // cacosh(NaN + i) returns ++ iNaN. + // cacosh(NaN + iNaN) returns NaN + iNaN. + // + template + inline SPROUT_CONSTEXPR sprout::complex + acosh(sprout::complex const& x) { + typedef sprout::complex type; + return sprout::math::isnan(x.real()) + ? sprout::math::isnan(x.imag()) ? x + : sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), x.real()) + : type(x.real(), x.real()) + : sprout::math::isnan(x.imag()) + ? sprout::math::isinf(x.real()) ? type(sprout::numeric_limits::infinity(), x.imag()) + : type(sprout::numeric_limits::quiet_NaN(), x.imag()) + : x.real() == sprout::numeric_limits::infinity() + ? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), sprout::math::copysign(sprout::math::quarter_pi(), x.imag())) + : type(sprout::numeric_limits::infinity(), (x.imag() == 0 ? x.imag() : sprout::math::copysign(T(0), x.imag()))) + : x.real() == -sprout::numeric_limits::infinity() + ? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), sprout::math::copysign(sprout::math::three_quarters_pi(), x.imag())) + : type(sprout::numeric_limits::infinity(), sprout::math::copysign(sprout::math::pi(), x.imag())) + : sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), sprout::math::copysign(sprout::math::half_pi(), x.imag())) + : x.real() == 0 && x.imag() == 0 ? type(T(0), sprout::math::copysign(sprout::math::half_pi(), x.imag())) + : T(2) * sprout::log(sprout::sqrt(sprout::math::half() * (x + T(1))) + sprout::sqrt(sprout::math::half() * (x - T(1)))) + ; + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_ACOSH_HPP diff --git a/sprout/complex/arg.hpp b/sprout/complex/arg.hpp new file mode 100644 index 00000000..cb5e1a5c --- /dev/null +++ b/sprout/complex/arg.hpp @@ -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 +#include +#include +#include +#include +#include + +namespace sprout { + // + // arg + // + template + inline SPROUT_CONSTEXPR T + arg(sprout::complex const& x) { + return sprout::math::atan2(x.imag(), x.real()); + } + template< + typename ArithmeticType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::float_promote::type + arg(ArithmeticType x) { + return sprout::math::atan2(ArithmeticType(0), x); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_ARG_HPP diff --git a/sprout/complex/asin.hpp b/sprout/complex/asin.hpp new file mode 100644 index 00000000..7805dc4c --- /dev/null +++ b/sprout/complex/asin.hpp @@ -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 +#include +#include +#include +#include + +namespace sprout { + // + // asin + // + // casin(z) = -i casinh(iz) + // + template + inline SPROUT_CONSTEXPR sprout::complex + asin(sprout::complex const& x) { + return -sprout::perp(sprout::asinh(sprout::perp(x))); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_ASIN_HPP diff --git a/sprout/complex/asinh.hpp b/sprout/complex/asinh.hpp new file mode 100644 index 00000000..b29ede68 --- /dev/null +++ b/sprout/complex/asinh.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +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 ++ ip /2 for positive-signed finite x. + // casinh(x + iNaN) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite x. + // casinh(++ iy) returns ++ i0 for positive-signed finite y. + // casinh(++ i) returns ++ ip /4. + // casinh(++ iNaN) returns ++ iNaN. + // casinh(NaN + i0) returns NaN + i0. + // casinh(NaN + iy) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite nonzero y. + // casinh(NaN + i) returns }+ iNaN (where the sign of the real part of the result is unspecified). + // casinh(NaN + iNaN) returns NaN + iNaN. + // + template + inline SPROUT_CONSTEXPR sprout::complex + asinh(sprout::complex const& x) { + typedef sprout::complex 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::quiet_NaN(), x.real()), x.imag()) + : sprout::math::isinf(x.real()) + ? x.imag() == sprout::numeric_limits::infinity() ? type(x.real(), sprout::math::quarter_pi()) + : x.imag() == -sprout::numeric_limits::infinity() ? type(x.real(), -sprout::math::quarter_pi()) + : 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::infinity(), x.real()), + sprout::math::copysign(sprout::math::half_pi(), 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 diff --git a/sprout/complex/atan.hpp b/sprout/complex/atan.hpp new file mode 100644 index 00000000..c8a3eeb6 --- /dev/null +++ b/sprout/complex/atan.hpp @@ -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 +#include +#include +#include +#include + +namespace sprout { + // + // atan + // + // catan(z) = -i catanh(iz) + // + template + inline SPROUT_CONSTEXPR sprout::complex + atan(sprout::complex const& x) { + return -sprout::perp(sprout::atanh(sprout::perp(x))); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_ATAN_HPP diff --git a/sprout/complex/atanh.hpp b/sprout/complex/atanh.hpp new file mode 100644 index 00000000..3dcbbc47 --- /dev/null +++ b/sprout/complex/atanh.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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 ++ i0 and raises the eedivide-by-zeroff 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 eeinvalidff floating-point exception, for nonzero finite x. + // catanh(++ iy) returns +0 + ip /2, for finite positive-signed y. + // catanh(++ i) returns +0 + ip /2. + // catanh(++ iNaN) returns +0 + iNaN. + // catanh(NaN + iy) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite y. + // catanh(NaN + i) returns }0 + ip /2 (where the sign of the real part of the result is unspecified). + // catanh(NaN + iNaN) returns NaN + iNaN. + // + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex + atanh_impl_1(sprout::complex const& x, T const& i2, T const& z, T const& num, T const& den) { + return sprout::complex( + sprout::math::quarter() * (sprout::math::log(i2 + num * num) - sprout::math::log(i2 + den * den)), + sprout::math::half() * sprout::math::atan2(T(2) * x.imag(), z) + ); + } + template + inline SPROUT_CONSTEXPR sprout::complex + atanh_impl(sprout::complex 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 + inline SPROUT_CONSTEXPR sprout::complex + atanh(sprout::complex const& x) { + typedef sprout::complex 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(), 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(), 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::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 diff --git a/sprout/complex/conj.hpp b/sprout/complex/conj.hpp new file mode 100644 index 00000000..811189d2 --- /dev/null +++ b/sprout/complex/conj.hpp @@ -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 +#include +#include +#include +#include + +namespace sprout { + // + // conj + // + template + inline SPROUT_CONSTEXPR sprout::complex + conj(sprout::complex const& x) { + return sprout::complex(x.real(), -x.imag()); + } + template< + typename ArithmeticType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::complex_promote::type + conj(ArithmeticType x) { + typedef typename sprout::complex_promote::type type; + return type(x); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_CONJ_HPP diff --git a/sprout/complex/cos.hpp b/sprout/complex/cos.hpp new file mode 100644 index 00000000..95b54bce --- /dev/null +++ b/sprout/complex/cos.hpp @@ -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 +#include +#include +#include + +namespace sprout { + // + // cos + // + // ccos(z) = ccosh(iz) + // + template + inline SPROUT_CONSTEXPR sprout::complex + cos(sprout::complex const& x) { + return sprout::cosh(sprout::perp(x)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_COS_HPP diff --git a/sprout/complex/cosh.hpp b/sprout/complex/cosh.hpp new file mode 100644 index 00000000..3f48559a --- /dev/null +++ b/sprout/complex/cosh.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 } i0 (where the sign of the imaginary part of the result is unspecified) and raises the eeinvalidff floating-point exception. + // ccosh(+0 + iNaN) returns NaN } i0 (where the sign of the imaginary part of the result is unspecified). + // ccosh(x + i) returns NaN + iNaN and raises the eeinvalidff floating-point exception, for finite nonzero x. + // ccosh(x + iNaN) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite nonzero x. + // ccosh(++ i0) returns ++ i0. + // ccosh(++ iy) returns + cis(y), for finite nonzero y. + // ccosh(++ i) returns }+ iNaN (where the sign of the real part of the result is unspecified) and raises the eeinvalidff floating-point exception. + // ccosh(++ iNaN) returns ++ iNaN. + // ccosh(NaN + i0) returns NaN } i0 (where the sign of the imaginary part of the result is unspecified). + // ccosh(NaN + iy) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for all nonzero numbers y. + // ccosh(NaN + iNaN) returns NaN + iNaN. + // + template + inline SPROUT_CONSTEXPR sprout::complex + cosh(sprout::complex const& x) { + typedef sprout::complex type; + return sprout::math::isnan(x.real()) + ? sprout::math::isnan(x.imag()) ? type(x.real(), x.real()) + : x.imag() == 0 ? type(sprout::numeric_limits::quiet_NaN(), x.imag()) + : type(x.real(), x.real()) + : sprout::math::isnan(x.imag()) + ? sprout::math::isinf(x.real()) ? type(sprout::numeric_limits::infinity(), sprout::numeric_limits::quiet_NaN()) + : x.real() == 0 ? type(sprout::numeric_limits::quiet_NaN(), x.real()) + : type(x.imag(), x.imag()) + : x.real() == sprout::numeric_limits::infinity() + ? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), sprout::numeric_limits::quiet_NaN()) + : x.imag() == 0 ? type(sprout::numeric_limits::infinity(), x.imag()) + : sprout::detail::copysign_mul(sprout::numeric_limits::infinity(), sprout::euler(x.imag())) + : x.real() == -sprout::numeric_limits::infinity() + ? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), sprout::numeric_limits::quiet_NaN()) + : x.imag() == 0 ? type(sprout::numeric_limits::infinity(), x.imag()) // ???? GCC or Clang + : sprout::detail::copysign_mul(sprout::numeric_limits::infinity(), sprout::euler(-x.imag())) + : sprout::math::isinf(x.imag()) + ? x.real() == 0 ? type(sprout::numeric_limits::quiet_NaN(), x.real()) + : type(-sprout::numeric_limits::quiet_NaN(), -sprout::numeric_limits::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 diff --git a/sprout/complex/detail/copysign_mul.hpp b/sprout/complex/detail/copysign_mul.hpp new file mode 100644 index 00000000..7c91d585 --- /dev/null +++ b/sprout/complex/detail/copysign_mul.hpp @@ -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 +#include + +namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex + copysign_mul(T const& t, sprout::complex const& z) { + return sprout::complex( + sprout::math::copysign(t, z.real()), + sprout::math::copysign(t, z.imag()) + ); + } + } // namespace detail +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_DETAIL_COPYSIGN_MUL_HPP diff --git a/sprout/complex/euler.hpp b/sprout/complex/euler.hpp new file mode 100644 index 00000000..56ca18d1 --- /dev/null +++ b/sprout/complex/euler.hpp @@ -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 +#include +#include +#include + +namespace sprout { + // + // euler + // + template + inline SPROUT_CONSTEXPR sprout::complex + euler(T const& theta) { + return sprout::complex(sprout::math::cos(theta), sprout::math::sin(theta)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_EULER_HPP diff --git a/sprout/complex/exp.hpp b/sprout/complex/exp.hpp new file mode 100644 index 00000000..0efa86cd --- /dev/null +++ b/sprout/complex/exp.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // exp + // + // G.6.3.1 The cexp functions + // cexp(conj(z)) = conj(cexp(z)). + // cexp(}0 + i0) returns 1 + i0. + // cexp(x + i) returns NaN + iNaN and raises the eeinvalidff floating-point exception, for finite x. + // cexp(x + iNaN) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite x. + // cexp(++ i0) returns ++ i0. + // cexp(-+ iy) returns +0 cis(y), for finite y. + // cexp(++ iy) returns + cis(y), for finite nonzero y. + // cexp(-+ i) returns }0 } i0 (where the signs of the real and imaginary parts of the result are unspecified). + // cexp(++ i) returns }+ iNaN and raises the eeinvalidff floating-point exception (where the sign of the real part of the result is unspecified). + // cexp(-+ iNaN) returns }0 } i0 (where the signs of the real and imaginary parts of the result are unspecified). + // cexp(++ iNaN) returns }+ 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 eeinvalidff floating-point exception, for all non-zero numbers y. + // cexp(NaN + iNaN) returns NaN + iNaN. + // + template + inline SPROUT_CONSTEXPR sprout::complex + exp(sprout::complex const& x) { + typedef sprout::complex 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::infinity() ? type(x.real(), x.imag()) + : x.real() == -sprout::numeric_limits::infinity() ? type(T(0), T(0)) + : sprout::math::isinf(x.real()) ? type(sprout::numeric_limits::infinity(), sprout::numeric_limits::quiet_NaN()) + : type(x.imag(), x.imag()) + : x.real() == sprout::numeric_limits::infinity() + ? sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), sprout::numeric_limits::quiet_NaN()) + : x.imag() == 0 ? type(sprout::numeric_limits::infinity(), x.imag()) + : sprout::detail::copysign_mul(sprout::numeric_limits::infinity(), sprout::euler(x.imag())) + : x.real() == -sprout::numeric_limits::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::quiet_NaN(), -sprout::numeric_limits::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 diff --git a/sprout/complex/imag.hpp b/sprout/complex/imag.hpp new file mode 100644 index 00000000..b91a1bd1 --- /dev/null +++ b/sprout/complex/imag.hpp @@ -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 +#include +#include +#include +#include + +namespace sprout { + // + // imag + // + template + inline SPROUT_CONSTEXPR T const& + imag(sprout::complex const& x) { + return x.imag(); + } + template + inline SPROUT_CONSTEXPR T& + imag(sprout::complex& x) { + return x.imag(); + } + template< + typename ArithmeticType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::float_promote::type + imag(ArithmeticType) { + return 0; + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_IMAG_HPP diff --git a/sprout/complex/log.hpp b/sprout/complex/log.hpp new file mode 100644 index 00000000..598d47c6 --- /dev/null +++ b/sprout/complex/log.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // log + // + // G.6.3.2 The clog functions + // clog(conj(z)) = conj(clog(z)). + // clog(-0 + i0) returns -+ ip and raises the eedivide-by-zeroff floating-point exception. + // clog(+0 + i0) returns -+ i0 and raises the eedivide-by-zeroff floating-point exception. + // clog(x + i) returns ++ ip /2, for finite x. + // clog(x + iNaN) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite x. + // clog(-+ iy) returns ++ ip , for finite positive-signed y. + // clog(++ iy) returns ++ i0, for finite positive-signed y. + // clog(-+ i) returns ++ i3p /4. + // clog(++ i) returns ++ ip /4. + // clog(}+ iNaN) returns ++ iNaN. + // clog(NaN + iy) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite y. + // clog(NaN + i) returns ++ iNaN. + // clog(NaN + iNaN) returns NaN + iNaN. + // + template + inline SPROUT_CONSTEXPR sprout::complex + log(sprout::complex const& x) { + typedef sprout::complex type; + return sprout::math::isnan(x.real()) + ? sprout::math::isnan(x.imag()) ? type(sprout::numeric_limits::quiet_NaN(), x.real()) + : sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), x.real()) + : type(sprout::numeric_limits::quiet_NaN(), x.real()) + : sprout::math::isnan(x.imag()) + ? sprout::math::isinf(x.real()) ? type(sprout::numeric_limits::infinity(), x.imag()) + : type(sprout::numeric_limits::quiet_NaN(), x.imag()) + : x.real() == sprout::numeric_limits::infinity() + ? x.imag() == sprout::numeric_limits::infinity() ? type(sprout::numeric_limits::infinity(), sprout::math::quarter_pi()) + : x.imag() == -sprout::numeric_limits::infinity() ? type(sprout::numeric_limits::infinity(), -sprout::math::quarter_pi()) + : type(sprout::numeric_limits::infinity(), (x.imag() == 0 ? x.imag() : sprout::math::copysign(T(0), x.imag()))) + : x.real() == -sprout::numeric_limits::infinity() + ? x.imag() == sprout::numeric_limits::infinity() ? type(sprout::numeric_limits::infinity(), sprout::math::three_quarters_pi()) + : x.imag() == -sprout::numeric_limits::infinity() ? type(sprout::numeric_limits::infinity(), -sprout::math::three_quarters_pi()) + : type(sprout::numeric_limits::infinity(), sprout::math::copysign(sprout::math::pi(), x.imag())) + : sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), sprout::math::copysign(sprout::math::half_pi(), x.imag())) + : x.real() == 0 && x.imag() == 0 + ? sprout::math::signbit(x.real()) ? type(-sprout::numeric_limits::infinity(), sprout::math::copysign(sprout::math::pi(), x.imag())) + : type(-sprout::numeric_limits::infinity(), x.imag()) + : type(sprout::math::log(sprout::abs(x)), sprout::arg(x)) + ; + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_LOG_HPP diff --git a/sprout/complex/log10.hpp b/sprout/complex/log10.hpp new file mode 100644 index 00000000..e1a1f771 --- /dev/null +++ b/sprout/complex/log10.hpp @@ -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 +#include +#include +#include +#include +#include + +namespace sprout { + // + // log10 + // + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex + log10_impl(sprout::complex const& z) { + return sprout::math::isnan(z.real()) || sprout::math::isnan(z.imag()) ? z + : z / sprout::math::ln_ten() + ; + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex + log10(sprout::complex const& x) { + return sprout::detail::log10_impl(sprout::log(x)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_LOG10_HPP diff --git a/sprout/complex/log2.hpp b/sprout/complex/log2.hpp new file mode 100644 index 00000000..953dcd58 --- /dev/null +++ b/sprout/complex/log2.hpp @@ -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 +#include +#include +#include +#include +#include + +namespace sprout { + // + // log2 + // + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex + log2_impl(sprout::complex const& z) { + return sprout::math::isnan(z.real()) || sprout::math::isnan(z.imag()) ? z + : z / sprout::math::ln_two() + ; + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex + log2(sprout::complex const& x) { + return sprout::detail::log2_impl(sprout::log(x)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_LOG2_HPP diff --git a/sprout/complex/nearest.hpp b/sprout/complex/nearest.hpp index 4379cdd2..cb859b79 100644 --- a/sprout/complex/nearest.hpp +++ b/sprout/complex/nearest.hpp @@ -16,21 +16,33 @@ #include namespace sprout { + // + // ceil + // template inline SPROUT_CONSTEXPR sprout::complex ceil(sprout::complex const& x) { return sprout::complex(sprout::math::ceil(x.real()), sprout::math::ceil(x.imag())); } + // + // floor + // template inline SPROUT_CONSTEXPR sprout::complex floor(sprout::complex const& x) { return sprout::complex(sprout::math::floor(x.real()), sprout::math::floor(x.imag())); } + // + // trunc + // template inline SPROUT_CONSTEXPR sprout::complex trunc(sprout::complex const& x) { return sprout::complex(sprout::math::trunc(x.real()), sprout::math::trunc(x.imag())); } + // + // round + // template inline SPROUT_CONSTEXPR sprout::complex round(sprout::complex const& x) { diff --git a/sprout/complex/norm.hpp b/sprout/complex/norm.hpp new file mode 100644 index 00000000..f9801f40 --- /dev/null +++ b/sprout/complex/norm.hpp @@ -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 +#include +#include +#include +#include + +namespace sprout { + // + // norm + // + template + inline SPROUT_CONSTEXPR T + norm(sprout::complex const& x) { + return x.real() * x.real() + x.imag() * x.imag(); + } + template< + typename ArithmeticType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::float_promote::type + norm(ArithmeticType x) { + typedef typename sprout::float_promote::type type; + return type(x) * type(x); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_NORM_HPP diff --git a/sprout/complex/perp.hpp b/sprout/complex/perp.hpp new file mode 100644 index 00000000..b2290350 --- /dev/null +++ b/sprout/complex/perp.hpp @@ -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 +#include +#include +#include +#include + +namespace sprout { + // + // perp + // + template + inline SPROUT_CONSTEXPR sprout::complex + perp(sprout::complex const& x) { + return sprout::complex(-x.imag(), x.real()); + } + template< + typename ArithmeticType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::complex_promote::type + perp(ArithmeticType x) { + typedef typename sprout::complex_promote::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 diff --git a/sprout/complex/polar.hpp b/sprout/complex/polar.hpp new file mode 100644 index 00000000..bc77ffd4 --- /dev/null +++ b/sprout/complex/polar.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // polar + // + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex + polar_impl(T const& x, T const& y) { + return sprout::complex( + sprout::math::isnan(x) ? T() : x, + sprout::math::isnan(y) ? T() : y + ); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex + polar(T const& rho, T const& theta = T()) { + typedef sprout::complex type; + return sprout::math::isnan(rho) || sprout::math::signbit(rho) + ? type(sprout::numeric_limits::quiet_NaN(), sprout::numeric_limits::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::quiet_NaN()) + : type(sprout::numeric_limits::quiet_NaN(), sprout::numeric_limits::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::value && std::is_arithmetic::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::complex_promote::type + polar(ArithmeticType1 const& rho, ArithmeticType2 const& theta) { + typedef typename sprout::complex_promote::type::value_type value_type; + return sprout::polar(static_cast(rho), static_cast(theta)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_POLER_HPP diff --git a/sprout/complex/pow.hpp b/sprout/complex/pow.hpp new file mode 100644 index 00000000..908226f2 --- /dev/null +++ b/sprout/complex/pow.hpp @@ -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 +#include +#include +#include +#include +#include + +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 + inline SPROUT_CONSTEXPR sprout::complex + pow(sprout::complex const& x, sprout::complex const& y) { + return x == T() ? T() + : sprout::exp(y * sprout::log(x)) + ; + } + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex pow_impl(sprout::complex const& t, T const& y) { + return sprout::polar(sprout::exp(y * t.real()), y * t.imag()); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex + pow(sprout::complex 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 + inline SPROUT_CONSTEXPR sprout::complex + pow(T const& x, sprout::complex const& y) { + return x > T() ? sprout::polar(sprout::pow(x, y.real()), y.imag() * sprout::log(x)) + : sprout::pow(sprout::complex(x), y) + ; + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_POW_HPP diff --git a/sprout/complex/proj.hpp b/sprout/complex/proj.hpp new file mode 100644 index 00000000..88e0d9eb --- /dev/null +++ b/sprout/complex/proj.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // proj + // + template + inline SPROUT_CONSTEXPR sprout::complex + proj(sprout::complex const& x) { + typedef sprout::complex type; + return sprout::math::isinf(x.real()) || sprout::math::isinf(x.imag()) + ? type(sprout::numeric_limits::infinity(), sprout::math::copysign(T(), x.imag())) + : x + ; + } + template< + typename ArithmeticType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::complex_promote::type + proj(ArithmeticType x) { + typedef typename sprout::complex_promote::type type; + return sprout::math::isinf(x) + ? type(sprout::numeric_limits::infinity()) + : type(x) + ; + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_PROJ_HPP diff --git a/sprout/complex/real.hpp b/sprout/complex/real.hpp new file mode 100644 index 00000000..50c9cb56 --- /dev/null +++ b/sprout/complex/real.hpp @@ -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 +#include +#include +#include +#include + +namespace sprout { + // + // real + // + template + inline SPROUT_CONSTEXPR T const& + real(sprout::complex const& x) { + return x.real(); + } + template + inline SPROUT_CONSTEXPR T& + real(sprout::complex& x) { + return x.real(); + } + template< + typename ArithmeticType, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR typename sprout::float_promote::type + real(ArithmeticType x) { + return x; + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_REAL_HPP diff --git a/sprout/complex/sin.hpp b/sprout/complex/sin.hpp new file mode 100644 index 00000000..c870946d --- /dev/null +++ b/sprout/complex/sin.hpp @@ -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 +#include +#include +#include +#include + +namespace sprout { + // + // sin + // + // csin(z) = -i csinh(iz) + // + template + inline SPROUT_CONSTEXPR sprout::complex + sin(sprout::complex const& x) { + return -sprout::perp(sprout::sinh(sprout::perp(x))); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_SIN_HPP diff --git a/sprout/complex/sinh.hpp b/sprout/complex/sinh.hpp new file mode 100644 index 00000000..1fcd1030 --- /dev/null +++ b/sprout/complex/sinh.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 }0 + iNaN (where the sign of the real part of the result is unspecified) and raises the eeinvalidff floating-point exception. + // csinh(+0 + iNaN) returns }0 + iNaN (where the sign of the real part of the result is unspecified). + // csinh(x + i) returns NaN + iNaN and raises the eeinvalidff floating-point exception, for positive finite x. + // csinh(x + iNaN) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite nonzero x. + // csinh(++ i0) returns ++ i0. + // csinh(++ iy) returns + cis(y), for positive finite y. + // csinh(++ i) returns }+ iNaN (where the sign of the real part of the result is unspecified) and raises the eeinvalidff floating-point exception. + // csinh(++ iNaN) returns }+ 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 eeinvalidff floating-point exception, for all nonzero numbers y. + // csinh(NaN + iNaN) returns NaN + iNaN. + // + template + inline SPROUT_CONSTEXPR sprout::complex + sinh(sprout::complex const& x) { + typedef sprout::complex 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::quiet_NaN()) + : x.real() == 0 ? type(x.real(), sprout::numeric_limits::quiet_NaN()) + : type(x.imag(), x.imag()) + : x.real() == sprout::numeric_limits::infinity() + ? sprout::math::isinf(x.imag()) ? type(x.real(), sprout::numeric_limits::quiet_NaN()) + : x.imag() == 0 ? x + : sprout::detail::copysign_mul(sprout::numeric_limits::infinity(), sprout::euler(x.imag())) + : x.real() == -sprout::numeric_limits::infinity() + ? sprout::math::isinf(x.imag()) ? type(x.real(), sprout::numeric_limits::quiet_NaN()) + : x.imag() == 0 ? x + : -sprout::detail::copysign_mul(sprout::numeric_limits::infinity(), sprout::euler(-x.imag())) + : sprout::math::isinf(x.imag()) + ? x.real() == 0 ? type(x.real(), sprout::numeric_limits::quiet_NaN()) + : type(-sprout::numeric_limits::quiet_NaN(), -sprout::numeric_limits::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 diff --git a/sprout/complex/sqrt.hpp b/sprout/complex/sqrt.hpp new file mode 100644 index 00000000..1e96a856 --- /dev/null +++ b/sprout/complex/sqrt.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // sqrt + // + // G.6.4.2 The csqrt functions + // csqrt(conj(z)) = conj(csqrt(z)). + // csqrt(}0 + i0) returns +0 + i0. + // csqrt(x + i) returns ++ i, for all x (including NaN). + // csqrt(x + iNaN) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite x. + // csqrt(-+ iy) returns +0 + i, for finite positive-signed y. + // csqrt(++ iy) returns ++ i0, for finite positive-signed y. + // csqrt(-+ iNaN) returns NaN } i (where the sign of the imaginary part of the result is unspecified). + // csqrt(++ iNaN) returns ++ iNaN. + // csqrt(NaN + iy) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite y. + // csqrt(NaN + iNaN) returns NaN + iNaN. + // + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::complex + sqrt_impl_1(sprout::complex const& x, T const& t) { + return sprout::complex(t, sprout::math::signbit(x.imag()) ? -t : t); + } + template + inline SPROUT_CONSTEXPR sprout::complex + sqrt_impl_2_1(sprout::complex const& x, T const& t, T const& u) { + return x.real() > T(0) ? sprout::complex(u, x.imag() / t) + : sprout::complex(sprout::math::abs(x.imag()) / t, sprout::math::signbit(x.imag()) ? -u : u) + ; + } + template + inline SPROUT_CONSTEXPR sprout::complex + sqrt_impl_2(sprout::complex const& x, T const& t) { + return sprout::detail::sqrt_impl_2_1(x, t, t / T(2)); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR sprout::complex + sqrt(sprout::complex const& x) { + typedef sprout::complex type; + return sprout::math::isinf(x.imag()) ? type(sprout::numeric_limits::infinity(), x.imag()) + : sprout::math::isnan(x.real()) + ? sprout::math::isnan(x.imag()) ? type(sprout::numeric_limits::quiet_NaN(), sprout::numeric_limits::quiet_NaN()) + : type(sprout::numeric_limits::quiet_NaN(), sprout::numeric_limits::quiet_NaN()) + : sprout::math::isnan(x.imag()) + ? x.real() == sprout::numeric_limits::infinity() + ? type(sprout::numeric_limits::infinity(), sprout::math::copysign(sprout::numeric_limits::quiet_NaN(), x.imag())) + : x.real() == -sprout::numeric_limits::infinity() + ? type( + sprout::math::copysign(sprout::numeric_limits::quiet_NaN(), x.imag()), + sprout::math::copysign(sprout::numeric_limits::infinity(), x.imag()) + ) + : type(sprout::numeric_limits::quiet_NaN(), sprout::numeric_limits::quiet_NaN()) + : x.real() == sprout::numeric_limits::infinity() + ? type(sprout::numeric_limits::infinity(), (x.imag() == 0 ? x.imag() : sprout::math::copysign(T(0), x.imag()))) + : x.real() == -sprout::numeric_limits::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 diff --git a/sprout/complex/tan.hpp b/sprout/complex/tan.hpp new file mode 100644 index 00000000..b7ed033d --- /dev/null +++ b/sprout/complex/tan.hpp @@ -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 +#include +#include +#include +#include + +namespace sprout { + // + // tan + // + // ctan(z) = -i ctanh(iz) + // + template + inline SPROUT_CONSTEXPR sprout::complex + tan(sprout::complex const& x) { + return -sprout::perp(sprout::tanh(sprout::perp(x))); + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_TAN_HPP diff --git a/sprout/complex/tanh.hpp b/sprout/complex/tanh.hpp new file mode 100644 index 00000000..8bcd6b3f --- /dev/null +++ b/sprout/complex/tanh.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 eeinvalidff floating-point exception, for finite x. + // ctanh(x + iNaN) returns NaN + iNaN and optionally raises the eeinvalidff floating-point exception, for finite x. + // ctanh(++ iy) returns 1 + i0 sin(2y), for positive-signed finite y. + // ctanh(++ i) returns 1 } i0 (where the sign of the imaginary part of the result is unspecified). + // ctanh(++ iNaN) returns 1 } 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 eeinvalidff floating-point exception, for all nonzero numbers y. + // ctanh(NaN + iNaN) returns NaN + iNaN. + // + template + inline SPROUT_CONSTEXPR sprout::complex + tanh(sprout::complex const& x) { + typedef sprout::complex 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::quiet_NaN(), -sprout::numeric_limits::quiet_NaN()) + : x.real() == 0 && x.imag() == 0 ? x + : sprout::sinh(x) / sprout::cosh(x) + ; + } +} // namespace sprout + +#endif // #ifndef SPROUT_COMPLEX_TANH_HPP diff --git a/sprout/complex/transcendentals.hpp b/sprout/complex/transcendentals.hpp index bbced750..3660eba6 100644 --- a/sprout/complex/transcendentals.hpp +++ b/sprout/complex/transcendentals.hpp @@ -9,321 +9,23 @@ #define SPROUT_COMPLEX_TRANSCENDENTALS_HPP #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sprout { - // 26.4.8, transcendentals: - template - SPROUT_CONSTEXPR sprout::complex - acos(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - asin(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - atan(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - acosh(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - asinh(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - atanh(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - cos(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - cosh(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - exp(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - log(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - log10(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - pow(sprout::complex const& x, T const& y); - template - SPROUT_CONSTEXPR sprout::complex - pow(sprout::complex const& x, sprout::complex const& y); - template - SPROUT_CONSTEXPR sprout::complex - pow(T const& x, sprout::complex const& y); - template - SPROUT_CONSTEXPR sprout::complex - sin(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - sinh(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - sqrt(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - tan(sprout::complex const& x); - template - SPROUT_CONSTEXPR sprout::complex - tanh(sprout::complex const& x); - - // - // acos - // asin - // atan - // - namespace detail { - template - inline SPROUT_CONSTEXPR sprout::complex - acos_impl(sprout::complex const& t) { - return sprout::complex(sprout::math::half_pi() - t.real(), -t.imag()); - } - } // namespace detail - template - inline SPROUT_CONSTEXPR sprout::complex - acos(sprout::complex const& x) { - return sprout::detail::acos_impl(sprout::asin(x)); - } - namespace detail { - template - inline SPROUT_CONSTEXPR sprout::complex - asin_impl(sprout::complex const& t) { - return sprout::complex(t.imag(), -t.real()); - } - } // namespace detail - template - inline SPROUT_CONSTEXPR sprout::complex - asin(sprout::complex const& x) { - return sprout::detail::asin_impl(sprout::asinh(sprout::complex(-x.imag(), x.real()))); - } - namespace detail { - template - inline SPROUT_CONSTEXPR sprout::complex - atan_impl_1(sprout::complex const& x, T const& r2, T const& z, T const& num, T const& den) { - return sprout::complex( - T(0.5) * sprout::atan2(T(2) * x.real(), z), - T(0.25) * sprout::log((r2 + num * num) / (r2 + den * den)) - ); - } - template - inline SPROUT_CONSTEXPR sprout::complex - atan_impl(sprout::complex 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 - inline SPROUT_CONSTEXPR sprout::complex - atan(sprout::complex const& x) { - return sprout::detail::atan_impl(x, x.real() * x.real()); - } - - // - // acosh - // asinh - // atanh - // - template - inline SPROUT_CONSTEXPR sprout::complex - acosh(sprout::complex const& x) { - return T(2) * sprout::log(sprout::sqrt(T(0.5) * (x + T(1))) + sprout::sqrt(T(0.5) * (x - T(1)))); - } - template - inline SPROUT_CONSTEXPR sprout::complex - asinh(sprout::complex const& x) { - return sprout::log( - sprout::sqrt( - sprout::complex( - (x.real() - x.imag()) * (x.real() + x.imag()) + T(1), - T(2) * x.real() * x.imag() - ) - ) - + x - ); - } - namespace detail { - template - inline SPROUT_CONSTEXPR sprout::complex - atanh_impl_1(sprout::complex const& x, T const& i2, T const& z, T const& num, T const& den) { - return sprout::complex( - T(0.25) * (sprout::log(i2 + num * num) - sprout::log(i2 + den * den)), - T(0.5) * sprout::atan2(T(2) * x.imag(), z) - ); - } - template - inline SPROUT_CONSTEXPR sprout::complex - atanh_impl(sprout::complex 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 - inline SPROUT_CONSTEXPR sprout::complex - atanh(sprout::complex const& x) { - return sprout::detail::atanh_impl(x, x.imag() * x.imag()); - } - - // - // cos - // cosh - // - template - inline SPROUT_CONSTEXPR sprout::complex - cos(sprout::complex const& x) { - return sprout::complex( - sprout::cos(x.real()) * sprout::cosh(x.imag()), - -(sprout::sin(x.real()) * sprout::sinh(x.imag())) - ); - } - template - inline SPROUT_CONSTEXPR sprout::complex - cosh(sprout::complex const& x) { - return sprout::complex( - sprout::cosh(x.real()) * sprout::cos(x.imag()), - sprout::sinh(x.real()) * sprout::sin(x.imag()) - ); - } - - // - // exp - // log - // log10 - // - template - inline SPROUT_CONSTEXPR sprout::complex - exp(sprout::complex const& x) { - return sprout::polar(sprout::exp(x.real()), x.imag()); - } - template - inline SPROUT_CONSTEXPR sprout::complex - log(sprout::complex const& x) { - return sprout::complex(sprout::log(sprout::abs(x)), sprout::arg(x)); - } - template - inline SPROUT_CONSTEXPR sprout::complex log10(sprout::complex const& x) { - return sprout::log(x) / sprout::log(T(10)); - } - - // - // pow - // - namespace detail { - template - inline SPROUT_CONSTEXPR sprout::complex pow_impl(sprout::complex const& t, T const& y) { - return sprout::polar(sprout::exp(y * t.real()), y * t.imag()); - } - } // namespace detail - template - inline SPROUT_CONSTEXPR sprout::complex - pow(sprout::complex 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 - inline SPROUT_CONSTEXPR sprout::complex - pow(sprout::complex const& x, sprout::complex const& y) { - return x == T() ? T() - : sprout::exp(y * sprout::log(x)) - ; - } - template - inline SPROUT_CONSTEXPR sprout::complex - pow(T const& x, sprout::complex const& y) { - return x > T() ? sprout::polar(sprout::pow(x, y.real()), y.imag() * sprout::log(x)) - : sprout::pow(sprout::complex(x), y) - ; - } - - // - // sin - // sinh - // - template - inline SPROUT_CONSTEXPR sprout::complex - sin(sprout::complex const& x) { - return sprout::complex( - sprout::sin(x.real()) * sprout::cosh(x.imag()), - sprout::cos(x.real()) * sprout::sinh(x.imag()) - ); - } - template - inline SPROUT_CONSTEXPR sprout::complex - sinh(sprout::complex const& x) { - return sprout::complex( - sprout::sinh(x.real()) * sprout::cos(x.imag()), - sprout::cosh(x.real()) * sprout::sin(x.imag()) - ); - } - - // - // sqrt - // - namespace detail { - template - inline SPROUT_CONSTEXPR sprout::complex - sqrt_impl_1(sprout::complex const& x, T const& t) { - return sprout::complex(t, x.imag() < T() ? -t : t); - } - template - inline SPROUT_CONSTEXPR sprout::complex - sqrt_impl_2_1(sprout::complex const& x, T const& t, T const& u) { - return x.real() > T() ? sprout::complex(u, x.imag() / t) - : sprout::complex(sprout::abs(x.imag()) / t, x.imag() < T() ? -u : u) - ; - } - template - inline SPROUT_CONSTEXPR sprout::complex - sqrt_impl_2(sprout::complex const& x, T const& t) { - return sprout::detail::sqrt_impl_2_1(x, t, t / 2); - } - } // namespace detail - template - inline SPROUT_CONSTEXPR sprout::complex - sqrt(sprout::complex 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 - inline SPROUT_CONSTEXPR sprout::complex - tan(sprout::complex const& x) { - return sprout::sin(x) / sprout::cos(x); - } - template - inline SPROUT_CONSTEXPR sprout::complex - tanh(sprout::complex const& x) { - return sprout::sinh(x) / sprout::cosh(x); - } -} // namespace sprout +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif // #ifndef SPROUT_COMPLEX_TRANSCENDENTALS_HPP diff --git a/sprout/complex/values.hpp b/sprout/complex/values.hpp index 0725f169..900135d4 100644 --- a/sprout/complex/values.hpp +++ b/sprout/complex/values.hpp @@ -8,176 +8,16 @@ #ifndef SPROUT_COMPLEX_VALUES_HPP #define SPROUT_COMPLEX_VALUES_HPP -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sprout { - template - SPROUT_CONSTEXPR T - norm(sprout::complex const& x); - - // - // 26.4.7, values: - // - template - inline SPROUT_CONSTEXPR T const& - real(sprout::complex const& x) { - return x.real(); - } - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - real(ArithmeticType x) { - return x; - } - - template - inline SPROUT_CONSTEXPR T const& - imag(sprout::complex const& x) { - return x.imag(); - } - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - imag(ArithmeticType) { - return 0; - } - - template - inline SPROUT_CONSTEXPR T& - real(sprout::complex& x) { - return x.real(); - } - template - inline SPROUT_CONSTEXPR T& - imag(sprout::complex& x) { - return x.imag(); - } - - template - inline SPROUT_CONSTEXPR T - abs(sprout::complex const& x) { - return sprout::sqrt(sprout::norm(x)); - } - - template - inline SPROUT_CONSTEXPR T - arg(sprout::complex const& x) { - return sprout::atan2(x.imag(), x.real()); - } - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - arg(ArithmeticType x) { - return sprout::atan2(ArithmeticType(0), x); - } - - template - inline SPROUT_CONSTEXPR T - norm(sprout::complex const& x) { - return x.real() * x.real() + x.imag() * x.imag(); - } - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::float_promote::type - norm(ArithmeticType x) { - typedef typename sprout::complex_promote::type type; - return type(x) * type(x); - } - - template - inline SPROUT_CONSTEXPR sprout::complex - conj(sprout::complex const& x) { - return sprout::complex(x.real(), -x.imag()); - } - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::complex_promote::type - conj(ArithmeticType x) { - typedef typename sprout::complex_promote::type type; - return type(x); - } - - template - inline SPROUT_CONSTEXPR sprout::complex - proj(sprout::complex const& x) { - return sprout::math::isinf(x.real()) || sprout::math::isinf(x.imag()) - ? sprout::complex(sprout::numeric_limits::infinity(), sprout::math::copysign(T(), x.imag())) - : x - ; - } - template< - typename ArithmeticType, - typename sprout::enabler_if::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::complex_promote::type - proj(ArithmeticType x) { - typedef typename sprout::complex_promote::type type; - return sprout::math::isinf(x) - ? type(sprout::numeric_limits::infinity()) - : type(x) - ; - } - - namespace detail { - template - inline SPROUT_CONSTEXPR sprout::complex - polar_impl(T const& x, T const& y) { - typedef sprout::complex type; - return type( - sprout::math::isnan(x) ? T() : x, - sprout::math::isnan(y) ? T() : y - ); - } - } // namespace detail - template - inline SPROUT_CONSTEXPR sprout::complex - polar(T const& rho, T const& theta = T()) { - typedef sprout::complex type; - return sprout::math::isnan(rho) || sprout::math::signbit(rho) - ? type(sprout::numeric_limits::quiet_NaN(), sprout::numeric_limits::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::quiet_NaN()) - : type(sprout::numeric_limits::quiet_NaN(), sprout::numeric_limits::quiet_NaN()) - : sprout::detail::polar_impl(rho * sprout::cos(theta), rho * sprout::sin(theta)) - ; - } - template< - typename ArithmeticType1, typename ArithmeticType2, - typename sprout::enabler_if::value && std::is_arithmetic::value>::type = sprout::enabler - > - inline SPROUT_CONSTEXPR typename sprout::complex_promote::type - polar(ArithmeticType1 const& rho, ArithmeticType2 const& theta) { - typedef typename sprout::complex_promote::type::value_type value_type; - return sprout::polar(rho, theta); - } -} // namespace sprout +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif // #ifndef SPROUT_COMPLEX_VALUES_HPP