From cc1b64c7914aebdc5e70db2623f54f62ad5b56a5 Mon Sep 17 00:00:00 2001 From: jtlap Date: Wed, 6 Sep 2023 11:10:14 +0200 Subject: [PATCH] Trigonometrics with Pi arguments --- include/kyosu/functions.hpp | 7 + include/kyosu/functions/cospi.hpp | 74 +++++++++ include/kyosu/functions/cotpi.hpp | 74 +++++++++ include/kyosu/functions/cscpi.hpp | 74 +++++++++ include/kyosu/functions/secpi.hpp | 74 +++++++++ include/kyosu/functions/sinpi.hpp | 74 +++++++++ include/kyosu/functions/sinpicospi.hpp | 74 +++++++++ include/kyosu/functions/tanpi.hpp | 74 +++++++++ include/kyosu/types/cayley_dickson.hpp | 1 + include/kyosu/types/impl/trigo_pi.hpp | 199 +++++++++++++++++++++++++ test/unit/function/cospi.cpp | 24 +++ test/unit/function/cotpi.cpp | 24 +++ test/unit/function/cscpi.cpp | 24 +++ test/unit/function/secpi.cpp | 24 +++ test/unit/function/sinpi.cpp | 24 +++ test/unit/function/tanpi.cpp | 24 +++ 16 files changed, 869 insertions(+) create mode 100644 include/kyosu/functions/cospi.hpp create mode 100644 include/kyosu/functions/cotpi.hpp create mode 100644 include/kyosu/functions/cscpi.hpp create mode 100644 include/kyosu/functions/secpi.hpp create mode 100644 include/kyosu/functions/sinpi.hpp create mode 100644 include/kyosu/functions/sinpicospi.hpp create mode 100644 include/kyosu/functions/tanpi.hpp create mode 100644 include/kyosu/types/impl/trigo_pi.hpp create mode 100644 test/unit/function/cospi.cpp create mode 100644 test/unit/function/cotpi.cpp create mode 100644 test/unit/function/cscpi.cpp create mode 100644 test/unit/function/secpi.cpp create mode 100644 test/unit/function/sinpi.cpp create mode 100644 test/unit/function/tanpi.cpp diff --git a/include/kyosu/functions.hpp b/include/kyosu/functions.hpp index 45e663a5..a1e4dc70 100644 --- a/include/kyosu/functions.hpp +++ b/include/kyosu/functions.hpp @@ -17,10 +17,13 @@ #include #include #include +#include #include +#include #include #include #include +#include #include #include #include @@ -75,16 +78,20 @@ #include #include #include +#include #include #include #include #include +#include +#include #include #include #include #include #include #include +#include #include #include diff --git a/include/kyosu/functions/cospi.hpp b/include/kyosu/functions/cospi.hpp new file mode 100644 index 00000000..40ab425e --- /dev/null +++ b/include/kyosu/functions/cospi.hpp @@ -0,0 +1,74 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_cospi : eve::elementwise + { + using callable_tag_type = callable_cospi; + + KYOSU_DEFERS_CALLABLE(cospi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return eve::cospi(v); } + + template + KYOSU_FORCEINLINE auto operator()(T const& target) const noexcept -> decltype(eve::tag_invoke(*this, target)) + { + return eve::tag_invoke(*this, target); + } + + template + eve::unsupported_call operator()(T&&... x) const + requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete; + }; +} + +namespace kyosu +{ +//====================================================================================================================== +//! @addtogroup functions +//! @{ +//! @var cospi +//! @brief Computes the cosine of the argument in \f$\pi\f$ mutiples. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr T cospi(T z) noexcept; +//! template constexpr T cospi(T z) noexcept; +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! Returns the cosine of the argument in \f$\pi\f$ mutiples. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/cospi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_cospi cospi = {}; +} diff --git a/include/kyosu/functions/cotpi.hpp b/include/kyosu/functions/cotpi.hpp new file mode 100644 index 00000000..44609705 --- /dev/null +++ b/include/kyosu/functions/cotpi.hpp @@ -0,0 +1,74 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_cotpi : eve::elementwise + { + using callable_tag_type = callable_cotpi; + + KYOSU_DEFERS_CALLABLE(cotpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return eve::cotpi(v); } + + template + KYOSU_FORCEINLINE auto operator()(T const& target) const noexcept -> decltype(eve::tag_invoke(*this, target)) + { + return eve::tag_invoke(*this, target); + } + + template + eve::unsupported_call operator()(T&&... x) const + requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete; + }; +} + +namespace kyosu +{ +//====================================================================================================================== +//! @addtogroup functions +//! @{ +//! @var cotpi +//! @brief Computes the cotangent of the argument in \f$\pi\f$ mutiples. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr T cotpi(T z) noexcept; +//! template constexpr T cotpi(T z) noexcept; +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! Returns the cotangent of the argument in \f$\pi\f$ mutiples. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/cotpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_cotpi cotpi = {}; +} diff --git a/include/kyosu/functions/cscpi.hpp b/include/kyosu/functions/cscpi.hpp new file mode 100644 index 00000000..7d3b55b2 --- /dev/null +++ b/include/kyosu/functions/cscpi.hpp @@ -0,0 +1,74 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_cscpi : eve::elementwise + { + using callable_tag_type = callable_cscpi; + + KYOSU_DEFERS_CALLABLE(cscpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return eve::cscpi(v); } + + template + KYOSU_FORCEINLINE auto operator()(T const& target) const noexcept -> decltype(eve::tag_invoke(*this, target)) + { + return eve::tag_invoke(*this, target); + } + + template + eve::unsupported_call operator()(T&&... x) const + requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete; + }; +} + +namespace kyosu +{ +//====================================================================================================================== +//! @addtogroup functions +//! @{ +//! @var cscpi +//! @brief Computes the cosecant of the argument in \f$\pi\f$ mutiples. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr T cscpi(T z) noexcept; +//! template constexpr T cscpi(T z) noexcept; +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! Returns the cosecant of the argument in \f$\pi\f$ mutiples. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/cscpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_cscpi cscpi = {}; +} diff --git a/include/kyosu/functions/secpi.hpp b/include/kyosu/functions/secpi.hpp new file mode 100644 index 00000000..6cdc661c --- /dev/null +++ b/include/kyosu/functions/secpi.hpp @@ -0,0 +1,74 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_secpi : eve::elementwise + { + using callable_tag_type = callable_secpi; + + KYOSU_DEFERS_CALLABLE(secpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return eve::secpi(v); } + + template + KYOSU_FORCEINLINE auto operator()(T const& target) const noexcept -> decltype(eve::tag_invoke(*this, target)) + { + return eve::tag_invoke(*this, target); + } + + template + eve::unsupported_call operator()(T&&... x) const + requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete; + }; +} + +namespace kyosu +{ +//====================================================================================================================== +//! @addtogroup functions +//! @{ +//! @var secpi +//! @brief Computes the secant of the argument in \f$\pi\f$ mutiples. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr T secpi(T z) noexcept; +//! template constexpr T secpi(T z) noexcept; +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! Returns the secant of the argument in \f$\pi\f$ mutiples. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/secpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_secpi secpi = {}; +} diff --git a/include/kyosu/functions/sinpi.hpp b/include/kyosu/functions/sinpi.hpp new file mode 100644 index 00000000..01418569 --- /dev/null +++ b/include/kyosu/functions/sinpi.hpp @@ -0,0 +1,74 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_sinpi : eve::elementwise + { + using callable_tag_type = callable_sinpi; + + KYOSU_DEFERS_CALLABLE(sinpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return eve::sinpi(v); } + + template + KYOSU_FORCEINLINE auto operator()(T const& target) const noexcept -> decltype(eve::tag_invoke(*this, target)) + { + return eve::tag_invoke(*this, target); + } + + template + eve::unsupported_call operator()(T&&... x) const + requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete; + }; +} + +namespace kyosu +{ +//====================================================================================================================== +//! @addtogroup functions +//! @{ +//! @var sinpi +//! @brief Computes the sine of the argument in \f$\pi\f$ mutiples. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr T sinpi(T z) noexcept; +//! template constexpr T sinpi(T z) noexcept; +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! Returns the sine of the argument in \f$\pi\f$ mutiples. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/sinpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_sinpi sinpi = {}; +} diff --git a/include/kyosu/functions/sinpicospi.hpp b/include/kyosu/functions/sinpicospi.hpp new file mode 100644 index 00000000..3f5d0559 --- /dev/null +++ b/include/kyosu/functions/sinpicospi.hpp @@ -0,0 +1,74 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_sinpicospi : eve::elementwise + { + using callable_tag_type = callable_sinpicospi; + + KYOSU_DEFERS_CALLABLE(sinpicospi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return eve::sinpicospi(v); } + + template + KYOSU_FORCEINLINE auto operator()(T const& target) const noexcept -> decltype(eve::tag_invoke(*this, target)) + { + return eve::tag_invoke(*this, target); + } + + template + eve::unsupported_call operator()(T&&... x) const + requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete; + }; +} + +namespace kyosu +{ +//====================================================================================================================== +//! @addtogroup functions +//! @{ +//! @var sinpicospi +//! @brief Computes simultaneously the sine and cosine of the argument in \f$\pi\f$ mutiples. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr auto sinpicospi(T z) noexcept; +//! template constexpr auto sinpicospi(T z) noexcept; +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! Returns simultaneously the sine and cosine of the argument in \f$\pi\f$ mutiples. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/sinpicospi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_sinpicospi sinpicospi = {}; +} diff --git a/include/kyosu/functions/tanpi.hpp b/include/kyosu/functions/tanpi.hpp new file mode 100644 index 00000000..3bc90d17 --- /dev/null +++ b/include/kyosu/functions/tanpi.hpp @@ -0,0 +1,74 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_tanpi : eve::elementwise + { + using callable_tag_type = callable_tanpi; + + KYOSU_DEFERS_CALLABLE(tanpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return eve::tanpi(v); } + + template + KYOSU_FORCEINLINE auto operator()(T const& target) const noexcept -> decltype(eve::tag_invoke(*this, target)) + { + return eve::tag_invoke(*this, target); + } + + template + eve::unsupported_call operator()(T&&... x) const + requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete; + }; +} + +namespace kyosu +{ +//====================================================================================================================== +//! @addtogroup functions +//! @{ +//! @var tanpi +//! @brief Computes the tangent of the argument in \f$\pi\f$ mutiples. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr T tanpi(T z) noexcept; +//! template constexpr T tanpi(T z) noexcept; +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! Returns the tangent of the argument in \f$\pi\f$ mutiples. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/tanpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_tanpi tanpi = {}; +} diff --git a/include/kyosu/types/cayley_dickson.hpp b/include/kyosu/types/cayley_dickson.hpp index c392fae3..7d18185a 100644 --- a/include/kyosu/types/cayley_dickson.hpp +++ b/include/kyosu/types/cayley_dickson.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/include/kyosu/types/impl/trigo_pi.hpp b/include/kyosu/types/impl/trigo_pi.hpp new file mode 100644 index 00000000..8a2f82cf --- /dev/null +++ b/include/kyosu/types/impl/trigo_pi.hpp @@ -0,0 +1,199 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::_ +{ + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& z) noexcept + { + if constexpr(concepts::complex ) + { + auto [rz, iz] = z; + iz *= eve::pi(as(iz)); + auto [s, c] = eve::sinpicospi(rz); + auto [sh, ch] = eve::sinhcosh(iz); + auto r = c*ch; + auto i = kyosu::if_else(is_imag(z) || kyosu::is_real(z),eve::zero, -s*sh); + if (eve::any(kyosu::is_not_finite(z))) + { + r = eve::if_else(eve::is_infinite(iz) && eve::is_not_finite(rz), eve::inf(as(r)), r); + i = eve::if_else(eve::is_infinite(iz) && eve::is_not_finite(rz), eve::nan(as(r)), i); + r = eve::if_else(eve::is_nan(iz) && eve::is_infinite(rz), eve::allbits, r); + i = eve::if_else(eve::is_nan(iz) && eve::is_infinite(rz), eve::allbits, i); + } + return kyosu::to_complex(r, i); + } + else + { + using u_t = eve::underlying_type_t; + auto pi = eve::pi(eve::as()); + auto p = kyosu::pure(z); + auto az = kyosu::abs(p)*eve::pi(eve::as(kyosu::abs(p))); + auto [s, c] = eve::sinpicospi(real(z)); + auto w = -s*eve::sinhc(az)*pi; + return c*cosh(az)+w*pure(z); + } + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& z) noexcept + { + return kyosu::rec(kyosu::cospi(z)); + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& z) noexcept + { + if constexpr(concepts::complex ) + { + auto rz = -kyosu::imag(z); + auto iz = kyosu::real(z); + rz *= eve::pi(as(rz)); + auto [s, c] = eve::sinpicospi(iz); + auto [sh, ch] = eve::sinhcosh(rz); + auto r = c*sh; + auto i = s*ch; + if (any(kyosu::is_not_finite(z))) + { + r = eve::if_else(eve::is_infinite(rz) && eve::is_not_finite(iz), rz, r); + i = eve::if_else(eve::is_infinite(rz) && eve::is_nan(iz), iz, i); + r = eve::if_else(eve::is_nan(rz), rz, r); + i = eve::if_else(eve::is_nan(rz), rz, i); + i = eve::if_else(kyosu::is_imag(z), eve::zero, i); + r = eve::if_else(kyosu::is_real(z), eve::zero, r); + } + return kyosu::to_complex(i, -r); + } + else + { + using u_t = eve::underlying_type_t; + auto pi = eve::pi(eve::as()); + auto p = kyosu::pure(z); + auto az = kyosu::abs(p)*pi; + auto [s, c] = eve::sinpicospi(kyosu::real(z)); + auto w = c*eve::sinhc(az)*pi; + return s*cosh(az)+w*p; + } + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& z) noexcept + { + return kyosu::rec(kyosu::sinpi(z)); + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& z) noexcept + { + if constexpr(concepts::complex ) + { + auto [rz, iz] = z; + iz *= eve::pi(as(iz)); + auto [s, c] = eve::sinpicospi(rz); + auto [sh, ch] = eve::sinhcosh(iz); + auto rc = c*ch; + auto ic = eve::if_else(kyosu::is_imag(z) || kyosu::is_real(z), eve::zero, -s*sh); + if (eve::any(kyosu::is_not_finite(z))) + { + rc = eve::if_else(eve::is_infinite(iz) && eve::is_not_finite(rz), eve::inf(eve::as(rc)), rc); + ic = eve::if_else(eve::is_infinite(iz) && eve::is_not_finite(rz), eve::allbits, ic); + rc = eve::if_else(eve::is_nan(iz) && eve::is_infinite(rz), eve::allbits, rc); + ic = eve::if_else(eve::is_nan(iz) && eve::is_infinite(rz), eve::allbits, ic); + } + auto cpi = kyosu::to_complex(rc, ic); + auto arz = -kyosu::imag(z); + auto aiz = kyosu::real(z); + arz*= eve::pi(as(arz)); + auto [as, ac] = eve::sinpicospi(aiz); + auto [ash, ach] = eve::sinhcosh(arz); + auto rs = ac*ash; + auto is = as*ach; + if (eve::any(kyosu::is_not_finite(z))) + { + rs = if_else(eve::is_infinite(aiz) && eve::is_not_finite(arz), arz, rs); + is = if_else(eve::is_infinite(aiz) && eve::is_nan(arz), iz, is); + rs = if_else(eve::is_nan(aiz), arz, rs); + is = if_else(eve::is_nan(aiz), arz, is); + is = if_else(eve::is_eqz(aiz), eve::zero, is); + rs = if_else(eve::is_eqz(arz), eve::zero, rs); + } + auto spi = kyosu::to_complex(is, -rs); + return kumi::tuple{spi, cpi}; + } + else + { + using u_t = eve::underlying_type_t; + auto pi = eve::pi(eve::as()); + auto p = kyosu::pure(z); + auto az = kyosu::abs(p)*pi; + auto [s, c] = eve::sinpicospi(kyosu::real(z)); + auto shc = eve::sinhc(az)*pi; + auto ch = eve::cosh(az); + auto wc = c*shc; + auto ws =-s*shc; + auto sq = s*ch + wc*p; + auto cq = c*ch + ws*p; + return kumi::tuple{sq, cq}; + } + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& z) noexcept + { + if constexpr(concepts::complex ) + { + auto machin = [](auto z){ + auto [rz, iz] = z+z; + auto [s, c] = eve::sinpicospi(iz); + auto [sh, ch] = eve::sinhcosh(eve::pi(eve::as(rz))*rz); + auto tmp = c+ch; + auto rr = eve::if_else(kyosu::is_imag(z), eve::zero, sh/tmp); + auto ii = eve::if_else(kyosu::is_real(z),eve:: zero, s/tmp); + return kyosu::if_else(eve::is_infinite(rz), kyosu::to_complex(sign(rz)), kyosu::to_complex(rr, ii)); + }; + auto r = machin(kyosu::to_complex(-kyosu::imag(z), kyosu::real(z))); + return kyosu::to_complex(kyosu::imag(r), -kyosu::real(r)); + } + else + { + auto [s, c] = kyosu::sinpicospi(z); + return s/c; + } + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& z) noexcept + { + if constexpr(concepts::complex ) + { + auto r = kyosu::tanpi(z); + r = kyosu::if_else(kyosu::is_infinite(r), C(), kyosu::rec(r)); + r = kyosu::if_else(kyosu::is_real(z) && eve::is_flint(kyosu::real(z)*2) && eve::is_not_flint(kyosu::real(z)), C{}, r); + return kyosu::if_else(kyosu::is_real(z), kyosu::to_complex(kyosu::real(r)), r); + } + else + { + auto [s, c] = kyosu::sinpicospi(z); + return c/s; + } + } + + +} diff --git a/test/unit/function/cospi.cpp b/test/unit/function/cospi.cpp new file mode 100644 index 00000000..5d1b023a --- /dev/null +++ b/test/unit/function/cospi.cpp @@ -0,0 +1,24 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include + +TTS_CASE_WITH ( "Check kyosu::cospi over quaternion" + , kyosu::simd_real_types + , tts::generate ( tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + ) + ) +(T r, T i, T j, T k) +{ + using ke_t = kyosu::as_quaternion_t; + using u_t = eve::underlying_type_t; + auto pi = eve::pi(eve::as()); + auto q = ke_t(r,i,j,k); + TTS_RELATIVE_EQUAL(kyosu::cospi(q), kyosu::cos(pi*q), 1e-5); +}; diff --git a/test/unit/function/cotpi.cpp b/test/unit/function/cotpi.cpp new file mode 100644 index 00000000..50630dab --- /dev/null +++ b/test/unit/function/cotpi.cpp @@ -0,0 +1,24 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include + +TTS_CASE_WITH ( "Check kyosu::cotpi over quaternion" + , kyosu::simd_real_types + , tts::generate ( tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + ) + ) +(T r, T i, T j, T k) +{ + using ke_t = kyosu::as_quaternion_t; + using u_t = eve::underlying_type_t; + auto pi = eve::pi(eve::as()); + auto q = ke_t(r,i,j,k); + TTS_RELATIVE_EQUAL(kyosu::cotpi(q), kyosu::cot(pi*q), 1e-5); +}; diff --git a/test/unit/function/cscpi.cpp b/test/unit/function/cscpi.cpp new file mode 100644 index 00000000..9e9a78c4 --- /dev/null +++ b/test/unit/function/cscpi.cpp @@ -0,0 +1,24 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include + +TTS_CASE_WITH ( "Check kyosu::cscpi over quaternion" + , kyosu::simd_real_types + , tts::generate ( tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + ) + ) +(T r, T i, T j, T k) +{ + using ke_t = kyosu::as_quaternion_t; + using u_t = eve::underlying_type_t; + auto pi = eve::pi(eve::as()); + auto q = ke_t(r,i,j,k); + TTS_RELATIVE_EQUAL(kyosu::cscpi(q), kyosu::csc(pi*q), 1e-5); +}; diff --git a/test/unit/function/secpi.cpp b/test/unit/function/secpi.cpp new file mode 100644 index 00000000..03ffe478 --- /dev/null +++ b/test/unit/function/secpi.cpp @@ -0,0 +1,24 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include + +TTS_CASE_WITH ( "Check kyosu::secpi over quaternion" + , kyosu::simd_real_types + , tts::generate ( tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + ) + ) +(T r, T i, T j, T k) +{ + using ke_t = kyosu::as_quaternion_t; + using u_t = eve::underlying_type_t; + auto pi = eve::pi(eve::as()); + auto q = ke_t(r,i,j,k); + TTS_RELATIVE_EQUAL(kyosu::secpi(q), kyosu::sec(pi*q), 1e-5); +}; diff --git a/test/unit/function/sinpi.cpp b/test/unit/function/sinpi.cpp new file mode 100644 index 00000000..68d8051c --- /dev/null +++ b/test/unit/function/sinpi.cpp @@ -0,0 +1,24 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include + +TTS_CASE_WITH ( "Check kyosu::sinpi over quaternion" + , kyosu::simd_real_types + , tts::generate ( tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + ) + ) +(T r, T i, T j, T k) +{ + using ke_t = kyosu::as_quaternion_t; + using u_t = eve::underlying_type_t; + auto pi = eve::pi(eve::as()); + auto q = ke_t(r,i,j,k); + TTS_RELATIVE_EQUAL(kyosu::sinpi(q), kyosu::sin(pi*q), 1e-5); +}; diff --git a/test/unit/function/tanpi.cpp b/test/unit/function/tanpi.cpp new file mode 100644 index 00000000..fe7c570f --- /dev/null +++ b/test/unit/function/tanpi.cpp @@ -0,0 +1,24 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include + +TTS_CASE_WITH ( "Check kyosu::tanpi over quaternion" + , kyosu::simd_real_types + , tts::generate ( tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + ) + ) +(T r, T i, T j, T k) +{ + using ke_t = kyosu::as_quaternion_t; + using u_t = eve::underlying_type_t; + auto pi = eve::pi(eve::as()); + auto q = ke_t(r,i,j,k); + TTS_RELATIVE_EQUAL(kyosu::tanpi(q), kyosu::tan(pi*q), 1e-5); +};