diff --git a/include/kyosu/complex/acospi.hpp b/include/kyosu/complex/acospi.hpp new file mode 100644 index 00000000..c3bed466 --- /dev/null +++ b/include/kyosu/complex/acospi.hpp @@ -0,0 +1,80 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_acospi : eve::elementwise + { + using callable_tag_type = callable_acospi; + + KYOSU_DEFERS_CALLABLE(acospi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept + { + auto fn = callable_acospi{}; + return fn(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 acospi +//! @brief Computes the arc cosine of the argument times \f$\pi\f$. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr auto acospi(T z) noexcept; //1 +//! template constexpr auto acospi(T z) noexcept; //2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! 1. a real input z is treated as if to_complex(z) was entered. +//! +//! 2. Returns `pi(as(z))*acos(z)` +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/acospi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_acospi acospi = {}; +} diff --git a/include/kyosu/complex/acotpi.hpp b/include/kyosu/complex/acotpi.hpp new file mode 100644 index 00000000..28c0f444 --- /dev/null +++ b/include/kyosu/complex/acotpi.hpp @@ -0,0 +1,80 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_acotpi : eve::elementwise + { + using callable_tag_type = callable_acotpi; + + KYOSU_DEFERS_CALLABLE(acotpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept + { + auto fn = callable_acotpi{}; + return fn(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 acotpi +//! @brief Computes the arc cotangent of the argument times \f$\pi\f$. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr auto acotpi(T z) noexcept; //1 +//! template constexpr auto acotpi(T z) noexcept; //2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! 1. a real input z is treated as if to_complex(z) was entered. +//! +//! 2. Returns `pi(as(z))*acot(z)` +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/acotpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_acotpi acotpi = {}; +} diff --git a/include/kyosu/complex/acscpi.hpp b/include/kyosu/complex/acscpi.hpp new file mode 100644 index 00000000..f260d088 --- /dev/null +++ b/include/kyosu/complex/acscpi.hpp @@ -0,0 +1,80 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_acscpi : eve::elementwise + { + using callable_tag_type = callable_acscpi; + + KYOSU_DEFERS_CALLABLE(acscpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept + { + auto fn = callable_acscpi{}; + return fn(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 acscpi +//! @brief Computes the arc cosecant of the argument times \f$\pi\f$. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr auto acscpi(T z) noexcept; //1 +//! template constexpr auto acscpi(T z) noexcept; //2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! 1. a real input z is treated as if to_complex(z) was entered. +//! +//! 2. Returns `pi(as(z))*acsc(z)` +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/acscpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_acscpi acscpi = {}; +} diff --git a/include/kyosu/complex/asecpi.hpp b/include/kyosu/complex/asecpi.hpp new file mode 100644 index 00000000..9e368c70 --- /dev/null +++ b/include/kyosu/complex/asecpi.hpp @@ -0,0 +1,80 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_asecpi : eve::elementwise + { + using callable_tag_type = callable_asecpi; + + KYOSU_DEFERS_CALLABLE(asecpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept + { + auto fn = callable_asecpi{}; + return fn(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 asecpi +//! @brief Computes the arc secant of the argument times \f$\pi\f$. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr auto asecpi(T z) noexcept; //1 +//! template constexpr auto asecpi(T z) noexcept; //2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! 1. a real input z is treated as if to_complex(z) was entered. +//! +//! 2. Returns `pi(as(z))*asec(z)` +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/asecpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_asecpi asecpi = {}; +} diff --git a/include/kyosu/complex/asinpi.hpp b/include/kyosu/complex/asinpi.hpp new file mode 100644 index 00000000..62156b09 --- /dev/null +++ b/include/kyosu/complex/asinpi.hpp @@ -0,0 +1,80 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_asinpi : eve::elementwise + { + using callable_tag_type = callable_asinpi; + + KYOSU_DEFERS_CALLABLE(asinpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept + { + auto fn = callable_asinpi{}; + return fn(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 asinpi +//! @brief Computes the arc sine of the argument times \f$\pi\f$. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr auto asinpi(T z) noexcept; //1 +//! template constexpr auto asinpi(T z) noexcept; //2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! 1. a real input z is treated as if to_complex(z) was entered. +//! +//! 2. Returns `pi(as(z))*asin(z)` +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/asinpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_asinpi asinpi = {}; +} diff --git a/include/kyosu/complex/atanpi.hpp b/include/kyosu/complex/atanpi.hpp new file mode 100644 index 00000000..2fe9bcdd --- /dev/null +++ b/include/kyosu/complex/atanpi.hpp @@ -0,0 +1,80 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include +#include + +namespace kyosu::tags +{ + struct callable_atanpi : eve::elementwise + { + using callable_tag_type = callable_atanpi; + + KYOSU_DEFERS_CALLABLE(atanpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept + { + auto fn = callable_atanpi{}; + return fn(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 atanpi +//! @brief Computes the arc tangent of the argument times \f$\pi\f$. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr auto atanpi(T z) noexcept; //1 +//! template constexpr auto atanpi(T z) noexcept; //2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! 1. a real input z is treated as if to_complex(z) was entered. +//! +//! 2. Returns `pi(as(z))*atan(z)` +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/atanpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_atanpi atanpi = {}; +} diff --git a/include/kyosu/functions.hpp b/include/kyosu/functions.hpp index 79d6629e..2197a603 100644 --- a/include/kyosu/functions.hpp +++ b/include/kyosu/functions.hpp @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -105,16 +106,22 @@ #include #include #include +#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/radinpi.hpp b/include/kyosu/functions/radinpi.hpp new file mode 100644 index 00000000..6e828357 --- /dev/null +++ b/include/kyosu/functions/radinpi.hpp @@ -0,0 +1,73 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include + +namespace kyosu::tags +{ + struct callable_radinpi : eve::elementwise + { + using callable_tag_type = callable_radinpi; + + KYOSU_DEFERS_CALLABLE(radinpi_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return T(0); }//eve::radinpi(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 radinpi +//! @brief Computes the parameter divided by \f$\pi\f$. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr as_real_t radinpi(T z) noexcept; +//! template constexpr T radinpi(T z) noexcept; +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to process. +//! +//! **Return value** +//! +//! Returns argument divided by \f$\pi\f$. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/radinpi.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_radinpi radinpi = {}; +} diff --git a/include/kyosu/types/impl/arithmetic.hpp b/include/kyosu/types/impl/arithmetic.hpp index dd44931c..cc11562b 100644 --- a/include/kyosu/types/impl/arithmetic.hpp +++ b/include/kyosu/types/impl/arithmetic.hpp @@ -239,4 +239,14 @@ namespace kyosu::_ return res; } } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C c) noexcept + { + using u_t = eve::element_type_t; + return c*eve::inv_pi(eve::as()); ; + } + + } diff --git a/include/kyosu/types/impl/complex/invtrig.hpp b/include/kyosu/types/impl/complex/invtrig.hpp index cbc70246..10d88a22 100644 --- a/include/kyosu/types/impl/complex/invtrig.hpp +++ b/include/kyosu/types/impl/complex/invtrig.hpp @@ -537,4 +537,47 @@ namespace kyosu::_ { return kyosu::atanh(kyosu::rec(a0)); } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& a0) noexcept + { + return kyosu::radinpi(kyosu::acos(a0)); + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& a0) noexcept + { + return kyosu::radinpi(kyosu::acot(a0)); + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& a0) noexcept + { + return kyosu::radinpi(kyosu::acsc(a0)); + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& a0) noexcept + { + return kyosu::radinpi(kyosu::asec(a0)); + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& a0) noexcept + { + return kyosu::radinpi(kyosu::asin(a0)); + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C const& a0) noexcept + { + return kyosu::radinpi(kyosu::atan(a0)); + } + } diff --git a/test/unit/complex/acospi.cpp b/test/unit/complex/acospi.cpp new file mode 100644 index 00000000..1c3ade37 --- /dev/null +++ b/test/unit/complex/acospi.cpp @@ -0,0 +1,39 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include +#include + +TTS_CASE_WITH( "Check behavior of acospi on scalar" + , tts::bunch + , tts::generate( tts::randoms(-10, 10), tts::randoms(-10, 10)) + ) + (T const& a0, T const& a1 ) +{ + using e_t = typename T::value_type; + auto inv_pi = eve::inv_pi(eve::as()); + for(size_t i = 0; i < a0.size(); ++i) + { + auto e = a0[i]; + auto f = a1[i]; + auto z = kyosu::to_complex(e, f); + TTS_RELATIVE_EQUAL(kyosu::acospi(z), inv_pi*kyosu::acos(z), 1.0e-6); + } +}; + +TTS_CASE_WITH( "Check behavior of acospi on wide" + , kyosu::simd_real_types + , tts::generate( tts::between(-10, 10) + , tts::between(-10, 10)) + ) + (T const& a0, T const& a1 ) +{ + auto inv_pi = eve::inv_pi(eve::as(a0)); + auto z = kyosu::to_complex(a0, a1); + TTS_RELATIVE_EQUAL(kyosu::acospi(z), inv_pi*kyosu::acos(z), 1.0e-6); +}; diff --git a/test/unit/complex/acotpi.cpp b/test/unit/complex/acotpi.cpp new file mode 100644 index 00000000..99dfc1e7 --- /dev/null +++ b/test/unit/complex/acotpi.cpp @@ -0,0 +1,36 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include +#include + +TTS_CASE_WITH ( "Check behavior of acotpi on scalar" + , tts::bunch + , tts::generate( tts::randoms(-10, 10) + , tts::randoms(-10, 10) + ) + ) + (T const& a0, T const& a1 ) +{ + for(size_t i = 0; i < a0.size(); ++i) + { + auto z = kyosu::to_complex(a0[i], a1[i]); + TTS_RELATIVE_EQUAL(kyosu::acotpi(z), kyosu::atanpi(kyosu::rec(z)), 1.0e-5); + } +}; + +TTS_CASE_WITH( "Check behavior of acot on wide" + , kyosu::simd_real_types + , tts::generate( tts::randoms(-10, 10) + , tts::randoms(-10, 10)) + ) + (T const& a0, T const& a1) +{ + auto z = kyosu::to_complex(a0, a1); + TTS_RELATIVE_EQUAL(kyosu::acotpi(z), kyosu::atanpi(kyosu::rec(z)), 1.0e-5); +}; diff --git a/test/unit/complex/acscpi.cpp b/test/unit/complex/acscpi.cpp new file mode 100644 index 00000000..4eb9877c --- /dev/null +++ b/test/unit/complex/acscpi.cpp @@ -0,0 +1,36 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include +#include + +TTS_CASE_WITH ( "Check behavior of acscpi on scalar" + , tts::bunch + , tts::generate( tts::randoms(-10, 10) + , tts::randoms(-10, 10) + ) + ) + (T const& a0, T const& a1 ) +{ + for(size_t i = 0; i < a0.size(); ++i) + { + auto z = kyosu::to_complex(a0[i], a1[i]); + TTS_RELATIVE_EQUAL(kyosu::acscpi(z), kyosu::asinpi(kyosu::rec(z)), 1.0e-5); + } +}; + +TTS_CASE_WITH( "Check behavior of acsc on wide" + , kyosu::simd_real_types + , tts::generate( tts::randoms(-10, 10) + , tts::randoms(-10, 10)) + ) + (T const& a0, T const& a1) +{ + auto z = kyosu::to_complex(a0, a1); + TTS_RELATIVE_EQUAL(kyosu::acscpi(z), kyosu::asinpi(kyosu::rec(z)), 1.0e-5); +}; diff --git a/test/unit/complex/asecpi.cpp b/test/unit/complex/asecpi.cpp new file mode 100644 index 00000000..0b0ef736 --- /dev/null +++ b/test/unit/complex/asecpi.cpp @@ -0,0 +1,36 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include +#include + +TTS_CASE_WITH ( "Check behavior of acscpi on scalar" + , tts::bunch + , tts::generate( tts::randoms(-10, 10) + , tts::randoms(-10, 10) + ) + ) + (T const& a0, T const& a1 ) +{ + for(size_t i = 0; i < a0.size(); ++i) + { + auto z = kyosu::to_complex(a0[i], a1[i]); + TTS_RELATIVE_EQUAL(kyosu::asecpi(z), kyosu::acospi(kyosu::rec(z)), 1.0e-5); + } +}; + +TTS_CASE_WITH( "Check behavior of acsc on wide" + , kyosu::simd_real_types + , tts::generate( tts::randoms(-10, 10) + , tts::randoms(-10, 10)) + ) + (T const& a0, T const& a1) +{ + auto z = kyosu::to_complex(a0, a1); + TTS_RELATIVE_EQUAL(kyosu::asecpi(z), kyosu::acospi(kyosu::rec(z)), 1.0e-5); +}; diff --git a/test/unit/complex/asinpi.cpp b/test/unit/complex/asinpi.cpp new file mode 100644 index 00000000..60d27158 --- /dev/null +++ b/test/unit/complex/asinpi.cpp @@ -0,0 +1,39 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include +#include + +TTS_CASE_WITH( "Check behavior of asinpi on scalar" + , tts::bunch + , tts::generate( tts::randoms(-10, 10), tts::randoms(-10, 10)) + ) + (T const& a0, T const& a1 ) +{ + using e_t = typename T::value_type; + auto inv_pi = eve::inv_pi(eve::as()); + for(size_t i = 0; i < a0.size(); ++i) + { + auto e = a0[i]; + auto f = a1[i]; + auto z = kyosu::to_complex(e, f); + TTS_RELATIVE_EQUAL(kyosu::asinpi(z), inv_pi*kyosu::asin(z), 1.0e-6); + } +}; + +TTS_CASE_WITH( "Check behavior of asinpi on wide" + , kyosu::simd_real_types + , tts::generate( tts::between(-10, 10) + , tts::between(-10, 10)) + ) + (T const& a0, T const& a1 ) +{ + auto inv_pi = eve::inv_pi(eve::as(a0)); + auto z = kyosu::to_complex(a0, a1); + TTS_RELATIVE_EQUAL(kyosu::asinpi(z), inv_pi*kyosu::asin(z), 1.0e-6); +}; diff --git a/test/unit/complex/atanpi.cpp b/test/unit/complex/atanpi.cpp new file mode 100644 index 00000000..1e17f823 --- /dev/null +++ b/test/unit/complex/atanpi.cpp @@ -0,0 +1,39 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include +#include + +TTS_CASE_WITH ( "Check behavior of atanpi on scalar" + , tts::bunch + , tts::generate( tts::randoms(-10, 10) + , tts::randoms(-10, 10) + ) + ) + (T const& a0, T const& a1 ) +{ + using e_t = typename T::value_type; + auto inv_pi = eve::inv_pi(eve::as()); + for(size_t i = 0; i < a0.size(); ++i) + { + auto z = kyosu::to_complex(a0[i], a1[i]); + TTS_RELATIVE_EQUAL(kyosu::atanpi(z), inv_pi*kyosu::atan(z), 1.0e-5); + } +}; + +TTS_CASE_WITH( "Check behavior of atan on wide" + , kyosu::simd_real_types + , tts::generate( tts::randoms(-10, 10) + , tts::randoms(-10, 10)) + ) + (T const& a0, T const& a1) +{ + auto inv_pi = eve::inv_pi(eve::as(a0)); + auto z = kyosu::to_complex(a0, a1); + TTS_RELATIVE_EQUAL(kyosu::atanpi(z), inv_pi*kyosu::atan(z), 1.0e-5); +};