From 30923ad1dd94619e8286b6da4cef37bfbff352a6 Mon Sep 17 00:00:00 2001 From: jtlap Date: Sun, 20 Aug 2023 14:56:03 +0200 Subject: [PATCH 01/10] sqr --- include/kyosu/functions/sqr.hpp | 73 +++++++++++++++++++++++++ include/kyosu/types/impl/arithmetic.hpp | 11 ++++ 2 files changed, 84 insertions(+) create mode 100644 include/kyosu/functions/sqr.hpp diff --git a/include/kyosu/functions/sqr.hpp b/include/kyosu/functions/sqr.hpp new file mode 100644 index 00000000..acdb742b --- /dev/null +++ b/include/kyosu/functions/sqr.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_sqr : eve::elementwise + { + using callable_tag_type = callable_sqr; + + KYOSU_DEFERS_CALLABLE(sqr_); + + template + static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return v*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 sqr +//! @brief Computes the square value. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr T sqr(T z) noexcept; +//! template constexpr T sqr(T z) noexcept; +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z` : Value to for which square is computed. +//! +//! **Return value** +//! +//! Returns the square of its argument. i.e. `z*z` in an optimized way. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/sqr.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_sqr sqr = {}; +} diff --git a/include/kyosu/types/impl/arithmetic.hpp b/include/kyosu/types/impl/arithmetic.hpp index 3417553a..3f48ea85 100644 --- a/include/kyosu/types/impl/arithmetic.hpp +++ b/include/kyosu/types/impl/arithmetic.hpp @@ -95,4 +95,15 @@ namespace kyosu::_ { return C{kumi::map([](auto const& e) { return eve::frac(e); }, c)}; } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C c) noexcept + { + auto squares = kumi::map_index([](I, auto const& m) { if constexpr(I::value>0) return -m*m; else return m*m;}, c); + auto r = kumi::sum( squares, 0); + auto a = 2*real(c); + real(c) = 0; + return r+a*c; + } } From 15e411a82e249ce6c4c6f60273b863fb85fc977f Mon Sep 17 00:00:00 2001 From: jtlap Date: Sun, 20 Aug 2023 15:04:29 +0200 Subject: [PATCH 02/10] sqr --- include/kyosu/functions.hpp | 1 + include/kyosu/types/impl/arithmetic.hpp | 9 ++++++++ test/doc/sqr.cpp | 30 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 test/doc/sqr.cpp diff --git a/include/kyosu/functions.hpp b/include/kyosu/functions.hpp index a4a3f217..78a005bc 100644 --- a/include/kyosu/functions.hpp +++ b/include/kyosu/functions.hpp @@ -23,5 +23,6 @@ #include #include #include +#include #include #include diff --git a/include/kyosu/types/impl/arithmetic.hpp b/include/kyosu/types/impl/arithmetic.hpp index 3f48ea85..2f1931e0 100644 --- a/include/kyosu/types/impl/arithmetic.hpp +++ b/include/kyosu/types/impl/arithmetic.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace kyosu::_ { @@ -104,6 +105,14 @@ namespace kyosu::_ auto r = kumi::sum( squares, 0); auto a = 2*real(c); real(c) = 0; +<<<<<<< HEAD return r+a*c; +======= + std::cout << "a "<< a << std::endl; + std::cout << "c "<< c << std::endl; + std::cout << "a*c " << a*c << std::endl; + return c; +// return r+a*c; +>>>>>>> 8229c13 (sqr) } } diff --git a/test/doc/sqr.cpp b/test/doc/sqr.cpp new file mode 100644 index 00000000..c68c919c --- /dev/null +++ b/test/doc/sqr.cpp @@ -0,0 +1,30 @@ +#include +#include +#include + +int main() +{ + using kyosu::sqr; + using kyosu::complex; + using kyosu::quaternion; + + std::cout << "Real: "<< "\n"; + std::cout << 72.9f << " -> " << sqr(72.9f) << "\n"; + std::cout << 72.9f << " -> " << (72.9f)*(72.9f) << "\n"; + + std::cout << "Complex: "<< "\n"; + std::cout << complex(3.5f,-2.9f) << " -> " << sqr(complex(3.5f,-2.9f)) << "\n"; + std::cout << complex(3.5f,-2.9f) << " -> " << (complex(3.5f,-2.9f))*(complex(3.5f,-2.9f)) << "\n"; + + + std::cout << "Quaternion: "<< "\n"; + std::cout << quaternion(1.1,2.2,-3.3,4.4) << " -> " << sqr(quaternion(1.1,2.2,-3.3,4.4)) << "\n"; + std::cout << quaternion(1.1,2.2,-3.3,4.4) << " -> " << (quaternion(1.1,2.2,-3.3,4.4))*(quaternion(1.1,2.2,-3.3,4.4))<< "\n"; + + std::cout << "SIMD: "; + using wc_t = eve::wide, eve::fixed<2>>; + std::cout << wc_t(complex(1.3,-3.7)) << " -> " << sqr(wc_t(complex(1.3,-3.7))) << "\n"; + std::cout << wc_t(complex(1.3,-3.7)) << " -> " << (wc_t(complex(1.3,-3.7)))*(wc_t(complex(1.3,-3.7)))<< "\n"; + + return 0; +} From a72b2e2b67ef7a81b942905e02c98ed22ea476cf Mon Sep 17 00:00:00 2001 From: jtlap Date: Sun, 20 Aug 2023 15:40:08 +0200 Subject: [PATCH 03/10] sqr --- include/kyosu/types/impl/arithmetic.hpp | 8 ----- test/unit/function/sqr.cpp | 42 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 test/unit/function/sqr.cpp diff --git a/include/kyosu/types/impl/arithmetic.hpp b/include/kyosu/types/impl/arithmetic.hpp index 2f1931e0..eaa8645b 100644 --- a/include/kyosu/types/impl/arithmetic.hpp +++ b/include/kyosu/types/impl/arithmetic.hpp @@ -105,14 +105,6 @@ namespace kyosu::_ auto r = kumi::sum( squares, 0); auto a = 2*real(c); real(c) = 0; -<<<<<<< HEAD return r+a*c; -======= - std::cout << "a "<< a << std::endl; - std::cout << "c "<< c << std::endl; - std::cout << "a*c " << a*c << std::endl; - return c; -// return r+a*c; ->>>>>>> 8229c13 (sqr) } } diff --git a/test/unit/function/sqr.cpp b/test/unit/function/sqr.cpp new file mode 100644 index 00000000..f184ee4a --- /dev/null +++ b/test/unit/function/sqr.cpp @@ -0,0 +1,42 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include + +TTS_CASE_WITH ( "Check kyosu::sqr over real" + , kyosu::real_types + , tts::generate(tts::between(-10,10)) + ) +(auto data) +{ + TTS_EQUAL(kyosu::sqr(data), eve::sqr(data)); +}; + +TTS_CASE_WITH ( "Check kyosu::sqr over complex" + , kyosu::real_types + , tts::generate(tts::between(-10,10), tts::between(-10,10)) + ) +(auto r, auto i) +{ + auto c = kyosu::to_complex(r,i); + TTS_EQUAL(kyosu::sqr(c), c*c); +}; + +TTS_CASE_WITH ( "Check kyosu::sqr over quaternion" + , kyosu::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 type = kyosu::as_quaternion_t; + auto o = type(r,i,j,k); + + TTS_EQUAL(kyosu::sqr(o), o*o); +}; From ce576aaeed7a1626a9d26f9e43b1f7c244ab2169 Mon Sep 17 00:00:00 2001 From: Joel Falcou Date: Sun, 20 Aug 2023 16:28:17 +0200 Subject: [PATCH 04/10] Prevent as_cayley_dickson to fail with non-standard size wides --- include/kyosu/types/traits.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/include/kyosu/types/traits.hpp b/include/kyosu/types/traits.hpp index 8301a1f3..5ce85dc8 100644 --- a/include/kyosu/types/traits.hpp +++ b/include/kyosu/types/traits.hpp @@ -18,9 +18,14 @@ namespace kyosu namespace kyosu::_ { - // Force a type to be looked at as a wide so we can apply wide-like type presrving semantic in type computations - template struct sema { using type = T; }; - template struct sema { using type = eve::wide>; }; + // Force a type to be looked at as a wide so we can apply wide-like type preserving semantic in type computations + template struct sema { using type = T; }; + template struct sema> : sema {}; + template + struct sema> { using type = eve::wide>; }; + template + struct sema { using type = eve::wide>; }; + template using sema_t = typename sema::type; // Convert a Base type to a potential wide if any appear in T... From 58e9e00b6387b07fb06b4cc61fc4b483690f6624 Mon Sep 17 00:00:00 2001 From: jtlap Date: Sun, 20 Aug 2023 22:59:47 +0200 Subject: [PATCH 05/10] dist reldist sqr --- include/kyosu/functions.hpp | 2 + include/kyosu/functions/abs.hpp | 44 -------------- include/kyosu/functions/dist.hpp | 79 ++++++++++++++++++++++++ include/kyosu/functions/reldist.hpp | 80 +++++++++++++++++++++++++ include/kyosu/types/impl/arithmetic.hpp | 15 +++++ test/doc/dist.cpp | 38 ++++++++++++ test/test.hpp | 1 + test/unit/function/dist.cpp | 39 ++++++++++++ test/unit/function/sqr.cpp | 9 ++- 9 files changed, 258 insertions(+), 49 deletions(-) create mode 100644 include/kyosu/functions/dist.hpp create mode 100644 include/kyosu/functions/reldist.hpp create mode 100644 test/doc/dist.cpp create mode 100644 test/unit/function/dist.cpp diff --git a/include/kyosu/functions.hpp b/include/kyosu/functions.hpp index 78a005bc..53f538e4 100644 --- a/include/kyosu/functions.hpp +++ b/include/kyosu/functions.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/include/kyosu/functions/abs.hpp b/include/kyosu/functions/abs.hpp index f2cf603b..fbbbcc64 100644 --- a/include/kyosu/functions/abs.hpp +++ b/include/kyosu/functions/abs.hpp @@ -1,47 +1,3 @@ -//! -//! **Defined in Header** -//! -//! @code -//! #include -//! @endcode -//! -//! @groupheader{Callable Signatures} -//! -//! @code -//! namespace eve -//! { -//! template< eve::value T > -//! T abs(T x) noexcept; //1 -//! -//! template< eve::floating_value T > -//! T abs(eve::as_complex z) noexcept; //2 -//! -//! } -//! @endcode -//! -//! **Parameters** -//! -//! * `x` : [real argument](@ref eve::value). -//! * `z` : [complex argument ](@ref eve::complex). -//! -//! **Return value** -//! -//! 1. value containing the [elementwise](@ref glossary_elementwise) -//! absolute value of `x` if it is representable in this type. -//! -//! More specifically, for signed integers : the absolute value of eve::valmin -//! is not representable and the result is undefined. -//! -//! -//! 2. -//! -//! @warning -//! abs is also a standard library function name and there possibly -//! exists a C macro version which may be called instead of the EVE version. -//! To avoid confusion, use the eve::abs notation. -//! - - //====================================================================================================================== /* Kyosu - Complex Without Complexes diff --git a/include/kyosu/functions/dist.hpp b/include/kyosu/functions/dist.hpp new file mode 100644 index 00000000..f0ae4f5b --- /dev/null +++ b/include/kyosu/functions/dist.hpp @@ -0,0 +1,79 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include + +namespace kyosu::tags +{ + struct callable_dist : eve::elementwise + { + using callable_tag_type = callable_dist; + + KYOSU_DEFERS_CALLABLE(dist_); + + static KYOSU_FORCEINLINE auto deferred_call(auto + , eve::ordered_value auto const& v0 + , eve::ordered_value auto const& v1) noexcept + { + return eve::dist(v0, v1); + } + + KYOSU_FORCEINLINE auto operator()(auto const& target0, auto const& target1 ) const noexcept + -> decltype(eve::tag_invoke(*this, target0, target1)) + { + return eve::tag_invoke(*this, target0, target1); + } + + template + eve::unsupported_call operator()(T&&... x) const + requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete; + }; +} + +namespace kyosu +{ +//====================================================================================================================== +//! @addtogroup functions +//! @{ +//! @var dist +//! @brief Computes the distance of the two parameters. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr auto dist(T0 z0, T1, z1) noexcept; +//! template > constexpr auto dist(T0 z0, T1, z1) noexcept; +//! template constexpr auto dist(T0 z0, T1, z1) noexcept; +//! template > constexpr auto dist(T0 z0, T1, z1) noexcept; +///! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z0, z1` : Value to process. +//! +//! **Return value** +//! +//! Returns the absolute value of the arguments difference. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/dist.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_dist dist = {}; +} diff --git a/include/kyosu/functions/reldist.hpp b/include/kyosu/functions/reldist.hpp new file mode 100644 index 00000000..3bd02ca0 --- /dev/null +++ b/include/kyosu/functions/reldist.hpp @@ -0,0 +1,80 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#pragma once + +#include + +namespace kyosu::tags +{ + struct callable_reldist : eve::elementwise + { + using callable_tag_type = callable_reldist; + + KYOSU_DEFERS_CALLABLE(reldist_); + + + static KYOSU_FORCEINLINE auto deferred_call(auto + , eve::ordered_value auto const& v0 + , eve::ordered_value auto const& v1) noexcept + { + return eve::reldist(v0, v1); + } + + KYOSU_FORCEINLINE auto operator()(auto const& target0, auto const& target1 ) const noexcept + -> decltype(eve::tag_invoke(*this, target0, target1)) + { + return eve::tag_invoke(*this, target0, target1); + } + + template + eve::unsupported_call operator()(T&&... x) const + requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete; + }; +} + +namespace kyosu +{ +//====================================================================================================================== +//! @addtogroup functions +//! @{ +//! @var reldist +//! @brief Computes the relative distance of the two parameters. +//! +//! **Defined in Header** +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace kyosu +//! { +//! template constexpr auto reldist(T0 z0, T1, z1) noexcept; +//! template > constexpr auto reldist(T0 z0, T1, z1) noexcept; +//! template constexpr auto reldist(T0 z0, T1, z1) noexcept; +//! template > constexpr auto reldist(T0 z0, T1, z1) noexcept; +///! } +//! @endcode +//! +//! **Parameters** +//! +//! * `z0, z1` : Value to process. +//! +//! **Return value** +//! +//! Returns the absolute value of the arguments difference dived by the maximum of their absolute values and 1. +//! +//! @groupheader{Example} +//! +//! @godbolt{doc/reldist.cpp} +//! @} +//====================================================================================================================== +inline constexpr tags::callable_reldist reldist = {}; +} diff --git a/include/kyosu/types/impl/arithmetic.hpp b/include/kyosu/types/impl/arithmetic.hpp index eaa8645b..1621db98 100644 --- a/include/kyosu/types/impl/arithmetic.hpp +++ b/include/kyosu/types/impl/arithmetic.hpp @@ -107,4 +107,19 @@ namespace kyosu::_ real(c) = 0; return r+a*c; } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C0 const & c0, C1 const & c1) noexcept + { + return kyosu::abs(c0-c1); + } + + template + KYOSU_FORCEINLINE constexpr + auto dispatch(eve::tag_of const&, C0 const & c0, C1 const & c1) noexcept + { + return kyosu::dist(c0, c1)/eve::max(kyosu::abs(c0), kyosu::abs(c1), eve::one(eve::as(abs(c0)))); + } + } diff --git a/test/doc/dist.cpp b/test/doc/dist.cpp new file mode 100644 index 00000000..2eaf5f78 --- /dev/null +++ b/test/doc/dist.cpp @@ -0,0 +1,38 @@ +#include +#include +#include + +int main() +{ + using kyosu::dist; + using kyosu::complex; + using kyosu::quaternion; + using e_t = float; + using c_t = complex; + using q_t = quaternion; + + std::cout << "Real: "<< "\n"; + e_t e0(1); + e_t e1(2); + std::cout << e0 << ", " << e1 << " -> " << dist(e0, e1) << "\n"; + + std::cout << "Complex: "<< "\n"; + c_t c0(1, 5); + c_t c1(5, 9); + std::cout << c0 << ", " << c1 << " -> " << dist(c0, c1) << "\n"; + + + + std::cout << "Quaternion: "<< "\n"; + q_t q0(1, 5); + q_t q1(5, 9); + std::cout << q0 << ", " << q1 << " -> " << dist(q0, q1) << "\n"; + + +// std::cout << "SIMD: "; +// using wc_t = eve::wide, eve::fixed<2>>; +// std::cout << wc_t(complex(1.3,-3.7)) << " -> " << dist(wc_t(complex(1.3,-3.7))) << "\n"; +// std::cout << wc_t(complex(1.3,-3.7)) << " -> " << (wc_t(complex(1.3,-3.7)))*(wc_t(complex(1.3,-3.7)))<< "\n"; + + return 0; +} diff --git a/test/test.hpp b/test/test.hpp index 666ebb5c..b1cd4855 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -86,6 +86,7 @@ int main(int argc, char const **argv) namespace tts { + template auto relative_distance(T const &l, T const &r) { auto [rl,il] = l; diff --git a/test/unit/function/dist.cpp b/test/unit/function/dist.cpp new file mode 100644 index 00000000..20e4a1be --- /dev/null +++ b/test/unit/function/dist.cpp @@ -0,0 +1,39 @@ +#include +#include +#include + +int main() +{ + using kyosu::dist; + using kyosu::complex; + using kyosu::quaternion; + using e_t = float; + using c_t = complex; + using q_t = quaternion; + + std::cout << "Real: "<< "\n"; + e_t e0(1); + e_t e1(2); + std::cout << e0 << ", " << e1 << " -> " << dist(e0, e1) << "\n"; + + std::cout << "Complex: "<< "\n"; + c_t c0(1, 5); + c_t c1(4, 9); + std::cout << c0 << ", " << c1 << " -> " << dist(c0, c1) << "\n"; + + + + std::cout << "Quaternion: "<< "\n"; + q_t q0(1, 5, 2, 3); + q_t q1(5, 9, 6, 7); + std::cout << q0 << ", " << q1 << " -> " << dist(q0, q1) << "\n"; + + + std::cout << "SIMD: "<< "\n"; + using wq_t = eve::wide, eve::fixed<2>>; + wq_t wq0(1, 5, 2, 3); + wq_t wq1(5, 9, 6, 7); + std::cout << wq0 << ", " << wq1 << " -> " << dist(wq0, wq1) << "\n"; + + return 0; +} diff --git a/test/unit/function/sqr.cpp b/test/unit/function/sqr.cpp index f184ee4a..e893b123 100644 --- a/test/unit/function/sqr.cpp +++ b/test/unit/function/sqr.cpp @@ -14,7 +14,7 @@ TTS_CASE_WITH ( "Check kyosu::sqr over real" ) (auto data) { - TTS_EQUAL(kyosu::sqr(data), eve::sqr(data)); + TTS_ULP_EQUAL(kyosu::sqr(data), eve::sqr(data), 0.5); }; TTS_CASE_WITH ( "Check kyosu::sqr over complex" @@ -24,7 +24,7 @@ TTS_CASE_WITH ( "Check kyosu::sqr over complex" (auto r, auto i) { auto c = kyosu::to_complex(r,i); - TTS_EQUAL(kyosu::sqr(c), c*c); + TTS_EXPECT(eve::all(kyosu::reldist(kyosu::sqr(c), c*c) <= 0.0001)); }; TTS_CASE_WITH ( "Check kyosu::sqr over quaternion" @@ -36,7 +36,6 @@ TTS_CASE_WITH ( "Check kyosu::sqr over quaternion" (T r, T i, T j, T k) { using type = kyosu::as_quaternion_t; - auto o = type(r,i,j,k); - - TTS_EQUAL(kyosu::sqr(o), o*o); + auto q = type(r,i,j,k); + TTS_EXPECT(eve::all(kyosu::reldist(kyosu::sqr(q), q*q) <= 0.0001)); }; From 42a80592e5016c815f3bf1ae5a363788daf1b389 Mon Sep 17 00:00:00 2001 From: jtlap Date: Mon, 21 Aug 2023 09:30:06 +0200 Subject: [PATCH 06/10] joel's remarks --- include/kyosu/functions/dist.hpp | 4 +-- include/kyosu/functions/reldist.hpp | 5 ++-- test/doc/dist.cpp | 24 ++++++++++------- test/doc/reldist.cpp | 42 +++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 test/doc/reldist.cpp diff --git a/include/kyosu/functions/dist.hpp b/include/kyosu/functions/dist.hpp index f0ae4f5b..b1d4bf25 100644 --- a/include/kyosu/functions/dist.hpp +++ b/include/kyosu/functions/dist.hpp @@ -42,7 +42,7 @@ namespace kyosu //! @addtogroup functions //! @{ //! @var dist -//! @brief Computes the distance of the two parameters. +//! @brief Computes the distance between the two parameters. //! //! **Defined in Header** //! @@ -68,7 +68,7 @@ namespace kyosu //! //! **Return value** //! -//! Returns the absolute value of the arguments difference. +//! Returns the distance between the two arguments computed as the absolute value of the arguments difference. //! //! @groupheader{Example} //! diff --git a/include/kyosu/functions/reldist.hpp b/include/kyosu/functions/reldist.hpp index 3bd02ca0..b0d8cfb6 100644 --- a/include/kyosu/functions/reldist.hpp +++ b/include/kyosu/functions/reldist.hpp @@ -43,7 +43,7 @@ namespace kyosu //! @addtogroup functions //! @{ //! @var reldist -//! @brief Computes the relative distance of the two parameters. +//! @brief Computes the relative distance between the two parameters. //! //! **Defined in Header** //! @@ -69,7 +69,8 @@ namespace kyosu //! //! **Return value** //! -//! Returns the absolute value of the arguments difference dived by the maximum of their absolute values and 1. +//! Returns the the relative distance computed as the absolute value of the arguments difference +//! divided by the maximum of their absolute values and 1. //! //! @groupheader{Example} //! diff --git a/test/doc/dist.cpp b/test/doc/dist.cpp index 2eaf5f78..7db417d4 100644 --- a/test/doc/dist.cpp +++ b/test/doc/dist.cpp @@ -10,29 +10,33 @@ int main() using e_t = float; using c_t = complex; using q_t = quaternion; + using we_t = eve::wide>; + using wc_t = eve::wide, eve::fixed<2>>; + using wq_t = eve::wide, eve::fixed<2>>; std::cout << "Real: "<< "\n"; e_t e0(1); e_t e1(2); std::cout << e0 << ", " << e1 << " -> " << dist(e0, e1) << "\n"; + we_t we0(e0); + we_t we1(e1); + std::cout << we0 << ", " << we1 << " -> " << dist(we0, we1) << "\n"; std::cout << "Complex: "<< "\n"; c_t c0(1, 5); c_t c1(5, 9); std::cout << c0 << ", " << c1 << " -> " << dist(c0, c1) << "\n"; - - + wc_t wc0(c0); + wc_t wc1(c1); + std::cout << wc0 << ", " << wc1 << " -> " << dist(wc0, wc1) << "\n"; std::cout << "Quaternion: "<< "\n"; - q_t q0(1, 5); - q_t q1(5, 9); + q_t q0(1, 5, 2, 3); + q_t q1(5, 9, 6, 7); std::cout << q0 << ", " << q1 << " -> " << dist(q0, q1) << "\n"; - - -// std::cout << "SIMD: "; -// using wc_t = eve::wide, eve::fixed<2>>; -// std::cout << wc_t(complex(1.3,-3.7)) << " -> " << dist(wc_t(complex(1.3,-3.7))) << "\n"; -// std::cout << wc_t(complex(1.3,-3.7)) << " -> " << (wc_t(complex(1.3,-3.7)))*(wc_t(complex(1.3,-3.7)))<< "\n"; + wq_t wq0(q0); + wq_t wq1(q1); + std::cout << wq0 << ", " << wq1 << " -> " << dist(wq0, wq1) << "\n"; return 0; } diff --git a/test/doc/reldist.cpp b/test/doc/reldist.cpp new file mode 100644 index 00000000..6ebc78c5 --- /dev/null +++ b/test/doc/reldist.cpp @@ -0,0 +1,42 @@ +#include +#include +#include + +int main() +{ + using kyosu::reldist; + using kyosu::complex; + using kyosu::quaternion; + using e_t = float; + using c_t = complex; + using q_t = quaternion; + using we_t = eve::wide>; + using wc_t = eve::wide, eve::fixed<2>>; + using wq_t = eve::wide, eve::fixed<2>>; + + std::cout << "Real: "<< "\n"; + e_t e0(1); + e_t e1(2); + std::cout << e0 << ", " << e1 << " -> " << reldist(e0, e1) << "\n"; + we_t we0(e0); + we_t we1(e1); + std::cout << we0 << ", " << we1 << " -> " << reldist(we0, we1) << "\n"; + + std::cout << "Complex: "<< "\n"; + c_t c0(1, 5); + c_t c1(5, 9); + std::cout << c0 << ", " << c1 << " -> " << reldist(c0, c1) << "\n"; + wc_t wc0(c0); + wc_t wc1(c1); + std::cout << wc0 << ", " << wc1 << " -> " << reldist(wc0, wc1) << "\n"; + + std::cout << "Quaternion: "<< "\n"; + q_t q0(1, 5, 2, 3); + q_t q1(5, 9, 6, 7); + std::cout << q0 << ", " << q1 << " -> " << reldist(q0, q1) << "\n"; + wq_t wq0(q0); + wq_t wq1(q1); + std::cout << wq0 << ", " << wq1 << " -> " << reldist(wq0, wq1) << "\n"; + + return 0; +} From b327003d8f584f91412e734c00eea34ff77211a7 Mon Sep 17 00:00:00 2001 From: Joel Falcou Date: Mon, 21 Aug 2023 09:00:06 +0200 Subject: [PATCH 07/10] Fix dist/reldist usage in tts adaptors --- test/test.hpp | 12 +++++------- test/unit/function/sqr.cpp | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/test/test.hpp b/test/test.hpp index b1cd4855..6f8e01ab 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -87,17 +87,14 @@ int main(int argc, char const **argv) namespace tts { - template auto relative_distance(T const &l, T const &r) + template double relative_distance(T const &l, T const &r) { - auto [rl,il] = l; - auto [rr,ir] = r; - - return eve::max(relative_distance(rl,rr), relative_distance(il,ir)); + return kyosu::reldist(l,r); } - template auto absolute_distance(T const &l, T const &r) + template double absolute_distance(T const &l, T const &r) { - return eve::maximum(eve::dist(l, r)); + return kyosu::dist(l, r); } template @@ -109,6 +106,7 @@ namespace tts return max_ulp; } + template inline double relative_distance(eve::wide const &l, eve::wide const &r) { diff --git a/test/unit/function/sqr.cpp b/test/unit/function/sqr.cpp index e893b123..51eea541 100644 --- a/test/unit/function/sqr.cpp +++ b/test/unit/function/sqr.cpp @@ -24,7 +24,7 @@ TTS_CASE_WITH ( "Check kyosu::sqr over complex" (auto r, auto i) { auto c = kyosu::to_complex(r,i); - TTS_EXPECT(eve::all(kyosu::reldist(kyosu::sqr(c), c*c) <= 0.0001)); + TTS_RELATIVE_EQUAL(kyosu::sqr(c), c*c, 1e-7); }; TTS_CASE_WITH ( "Check kyosu::sqr over quaternion" @@ -37,5 +37,5 @@ TTS_CASE_WITH ( "Check kyosu::sqr over quaternion" { using type = kyosu::as_quaternion_t; auto q = type(r,i,j,k); - TTS_EXPECT(eve::all(kyosu::reldist(kyosu::sqr(q), q*q) <= 0.0001)); + TTS_RELATIVE_EQUAL(kyosu::sqr(q), q*q, 1e-7); }; From f29919ff4d20f4b58c8edf4fb096fdea1fc00e11 Mon Sep 17 00:00:00 2001 From: jtlap Date: Mon, 21 Aug 2023 09:54:45 +0200 Subject: [PATCH 08/10] unit tests for dist and reldist --- test/unit/function/dist.cpp | 84 +++++++++++++++++++--------------- test/unit/function/reldist.cpp | 53 +++++++++++++++++++++ 2 files changed, 100 insertions(+), 37 deletions(-) create mode 100644 test/unit/function/reldist.cpp diff --git a/test/unit/function/dist.cpp b/test/unit/function/dist.cpp index 20e4a1be..2dd9e0f5 100644 --- a/test/unit/function/dist.cpp +++ b/test/unit/function/dist.cpp @@ -1,39 +1,49 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== #include -#include -#include - -int main() +#include + +TTS_CASE_WITH ( "Check kyosu::dist over real" + , kyosu::real_types + , tts::generate(tts::between(-10,10) + ,tts::between(-10,10) + ) + ) +(auto r0, auto r1) { - using kyosu::dist; - using kyosu::complex; - using kyosu::quaternion; - using e_t = float; - using c_t = complex; - using q_t = quaternion; - - std::cout << "Real: "<< "\n"; - e_t e0(1); - e_t e1(2); - std::cout << e0 << ", " << e1 << " -> " << dist(e0, e1) << "\n"; - - std::cout << "Complex: "<< "\n"; - c_t c0(1, 5); - c_t c1(4, 9); - std::cout << c0 << ", " << c1 << " -> " << dist(c0, c1) << "\n"; - - - - std::cout << "Quaternion: "<< "\n"; - q_t q0(1, 5, 2, 3); - q_t q1(5, 9, 6, 7); - std::cout << q0 << ", " << q1 << " -> " << dist(q0, q1) << "\n"; - - - std::cout << "SIMD: "<< "\n"; - using wq_t = eve::wide, eve::fixed<2>>; - wq_t wq0(1, 5, 2, 3); - wq_t wq1(5, 9, 6, 7); - std::cout << wq0 << ", " << wq1 << " -> " << dist(wq0, wq1) << "\n"; - - return 0; -} + TTS_EQUAL(kyosu::dist(r0, r1), eve::dist(r0, r1)); +}; + +TTS_CASE_WITH ( "Check kyosu::dist over complex" + , kyosu::real_types + , tts::generate(tts::between(-10,10), tts::between(-10,10) + ,tts::between(-10,10), tts::between(-10,10) + ) + ) +(auto r0, auto i0, auto r1, auto i1) +{ + auto c0 = kyosu::to_complex(r0,i0); + auto c1 = kyosu::to_complex(r1,i1); + TTS_RELATIVE_EQUAL(kyosu::dist(c0, c1), kyosu::abs(c0-c1), 1e-7); +}; + +TTS_CASE_WITH ( "Check kyosu::dist over quaternion" + , kyosu::real_types + , tts::generate ( tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + ) + ) +(T r0, T i0, T j0, T k0, T r1, T i1, T j1, T k1) +{ + using type = kyosu::as_quaternion_t; + auto q0 = type(r0,i0,j0,k0); + auto q1 = type(r1,i1,j1,k1); + TTS_RELATIVE_EQUAL(kyosu::dist(q0, q1), kyosu::abs(q0-q1) , 1e-7); +}; diff --git a/test/unit/function/reldist.cpp b/test/unit/function/reldist.cpp new file mode 100644 index 00000000..fce28e95 --- /dev/null +++ b/test/unit/function/reldist.cpp @@ -0,0 +1,53 @@ +//====================================================================================================================== +/* + Kyosu - Complex Without Complexes + Copyright : KYOSU Contributors & Maintainers + SPDX-License-Identifier: BSL-1.0 +*/ +//====================================================================================================================== +#include +#include + +TTS_CASE_WITH ( "Check kyosu::reldist over real" + , kyosu::real_types + , tts::generate(tts::between(-10,10) + ,tts::between(-10,10) + ) + ) +(auto r0, auto r1) +{ + TTS_EQUAL(kyosu::reldist(r0, r1), eve::reldist(r0, r1)); +}; + +TTS_CASE_WITH ( "Check kyosu::reldist over complex" + , kyosu::real_types + , tts::generate(tts::between(-10,10), tts::between(-10,10) + ,tts::between(-10,10), tts::between(-10,10) + ) + ) +(auto r0, auto i0, auto r1, auto i1) +{ + auto c0 = kyosu::to_complex(r0,i0); + auto c1 = kyosu::to_complex(r1,i1); + using kyosu::abs; + auto one = eve::one(eve::as(r0)); + TTS_RELATIVE_EQUAL(kyosu::reldist(c0, c1), abs(c0-c1)/eve::max(abs(c0), abs(c1), one), 1e-7); +}; + +TTS_CASE_WITH ( "Check kyosu::reldist over quaternion" + , kyosu::real_types + , tts::generate ( tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + , tts::between(-10,10), tts::between(-10,10) + ) + ) +(T r0, T i0, T j0, T k0, T r1, T i1, T j1, T k1) +{ + using type = kyosu::as_quaternion_t; + auto q0 = type(r0,i0,j0,k0); + auto q1 = type(r1,i1,j1,k1); + using kyosu::abs; + auto one = eve::one(eve::as(r0)); + TTS_RELATIVE_EQUAL(kyosu::reldist(q0, q1), abs(q0-q1)/eve::max(abs(q0), abs(q1), one), 1e-7); +}; From 3b1390e2a5fc46ed00d945f706ce0bbf9aebbbd8 Mon Sep 17 00:00:00 2001 From: jtlap Date: Mon, 21 Aug 2023 10:19:42 +0200 Subject: [PATCH 09/10] no test for sqr --- include/kyosu/types/impl/arithmetic.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/kyosu/types/impl/arithmetic.hpp b/include/kyosu/types/impl/arithmetic.hpp index 1621db98..2ced6061 100644 --- a/include/kyosu/types/impl/arithmetic.hpp +++ b/include/kyosu/types/impl/arithmetic.hpp @@ -101,7 +101,9 @@ namespace kyosu::_ KYOSU_FORCEINLINE constexpr auto dispatch(eve::tag_of const&, C c) noexcept { - auto squares = kumi::map_index([](I, auto const& m) { if constexpr(I::value>0) return -m*m; else return m*m;}, c); + auto squares = kumi::map_index([](I, auto const& m) + { constexpr auto sgn = (I::value == 0)-(I::value > 0); + return sgn*m*m; }, c); auto r = kumi::sum( squares, 0); auto a = 2*real(c); real(c) = 0; From add709da3d4fec05bed382e446af3483737d18d4 Mon Sep 17 00:00:00 2001 From: jtlap Date: Mon, 21 Aug 2023 13:49:31 +0200 Subject: [PATCH 10/10] sqr for complex --- include/kyosu/types/impl/arithmetic.hpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/include/kyosu/types/impl/arithmetic.hpp b/include/kyosu/types/impl/arithmetic.hpp index 2ced6061..ab0ca3c1 100644 --- a/include/kyosu/types/impl/arithmetic.hpp +++ b/include/kyosu/types/impl/arithmetic.hpp @@ -101,13 +101,19 @@ namespace kyosu::_ KYOSU_FORCEINLINE constexpr auto dispatch(eve::tag_of const&, C c) noexcept { - auto squares = kumi::map_index([](I, auto const& m) - { constexpr auto sgn = (I::value == 0)-(I::value > 0); - return sgn*m*m; }, c); - auto r = kumi::sum( squares, 0); - auto a = 2*real(c); - real(c) = 0; - return r+a*c; + if constexpr(kyosu::dimension_v <= 2) + { + return c*c; + }else + { + auto squares = kumi::map_index([](I, auto const& m) + { constexpr auto sgn = (I::value == 0)-(I::value > 0); + return sgn*m*m; }, c); + auto r = kumi::sum( squares, 0); + auto a = 2*real(c); + real(c) = 0; + return r+a*c; + } } template