Skip to content

Commit

Permalink
[FEATURES] sqr, dist, reldist
Browse files Browse the repository at this point in the history
  • Loading branch information
jfalcou committed Aug 21, 2023
2 parents 3dc9242 + add709d commit cc13065
Show file tree
Hide file tree
Showing 14 changed files with 542 additions and 54 deletions.
3 changes: 3 additions & 0 deletions include/kyosu/functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
#include <kyosu/functions/conj.hpp>
#include <kyosu/functions/floor.hpp>
#include <kyosu/functions/frac.hpp>
#include <kyosu/functions/dist.hpp>
#include <kyosu/functions/if_else.hpp>
#include <kyosu/functions/ipart.hpp>
#include <kyosu/functions/jpart.hpp>
#include <kyosu/functions/kpart.hpp>
#include <kyosu/functions/nearest.hpp>
#include <kyosu/functions/purepart.hpp>
#include <kyosu/functions/real.hpp>
#include <kyosu/functions/reldist.hpp>
#include <kyosu/functions/sqr.hpp>
#include <kyosu/functions/sqr_abs.hpp>
#include <kyosu/functions/trunc.hpp>
44 changes: 0 additions & 44 deletions include/kyosu/functions/abs.hpp
Original file line number Diff line number Diff line change
@@ -1,47 +1,3 @@
//!
//! **Defined in Header**
//!
//! @code
//! #include <eve/module/core.hpp>
//! @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<T> 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
Expand Down
79 changes: 79 additions & 0 deletions include/kyosu/functions/dist.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//======================================================================================================================
/*
Kyosu - Complex Without Complexes
Copyright : KYOSU Contributors & Maintainers
SPDX-License-Identifier: BSL-1.0
*/
//======================================================================================================================
#pragma once

#include <kyosu/details/invoke.hpp>

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<typename... T>
eve::unsupported_call<callable_dist(T&&...)> operator()(T&&... x) const
requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete;
};
}

namespace kyosu
{
//======================================================================================================================
//! @addtogroup functions
//! @{
//! @var dist
//! @brief Computes the distance between the two parameters.
//!
//! **Defined in Header**
//!
//! @code
//! #include <kyosu/functions.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace kyosu
//! {
//! template<kyosu::concepts::cayley_dickson T0, kyosu::concepts::cayley_dickson T1 > constexpr auto dist(T0 z0, T1, z1) noexcept;
//! template<eve::ordered_value T0, kyosu::concepts::cayley_dickson T1> > constexpr auto dist(T0 z0, T1, z1) noexcept;
//! template<kyosu::concepts::cayley_dickson T0, eve::ordered_value T1 > constexpr auto dist(T0 z0, T1, z1) noexcept;
//! template<eve::ordered_value T0, ordered_value T1> > constexpr auto dist(T0 z0, T1, z1) noexcept;
///! }
//! @endcode
//!
//! **Parameters**
//!
//! * `z0, z1` : Value to process.
//!
//! **Return value**
//!
//! Returns the distance between the two arguments computed as the absolute value of the arguments difference.
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/dist.cpp}
//! @}
//======================================================================================================================
inline constexpr tags::callable_dist dist = {};
}
81 changes: 81 additions & 0 deletions include/kyosu/functions/reldist.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//======================================================================================================================
/*
Kyosu - Complex Without Complexes
Copyright : KYOSU Contributors & Maintainers
SPDX-License-Identifier: BSL-1.0
*/
//======================================================================================================================
#pragma once

#include <kyosu/details/invoke.hpp>

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<typename... T>
eve::unsupported_call<callable_reldist(T&&...)> 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 between the two parameters.
//!
//! **Defined in Header**
//!
//! @code
//! #include <kyosu/functions.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace kyosu
//! {
//! template<kyosu::concepts::cayley_dickson T0, kyosu::concepts::cayley_dickson T1 > constexpr auto reldist(T0 z0, T1, z1) noexcept;
//! template<eve::ordered_value T0, kyosu::concepts::cayley_dickson T1> > constexpr auto reldist(T0 z0, T1, z1) noexcept;
//! template<kyosu::concepts::cayley_dickson T0, eve::ordered_value T1 > constexpr auto reldist(T0 z0, T1, z1) noexcept;
//! template<eve::ordered_value T0, ordered_value T1> > constexpr auto reldist(T0 z0, T1, z1) noexcept;
///! }
//! @endcode
//!
//! **Parameters**
//!
//! * `z0, z1` : Value to process.
//!
//! **Return value**
//!
//! 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}
//!
//! @godbolt{doc/reldist.cpp}
//! @}
//======================================================================================================================
inline constexpr tags::callable_reldist reldist = {};
}
73 changes: 73 additions & 0 deletions include/kyosu/functions/sqr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//======================================================================================================================
/*
Kyosu - Complex Without Complexes
Copyright : KYOSU Contributors & Maintainers
SPDX-License-Identifier: BSL-1.0
*/
//======================================================================================================================
#pragma once

#include <kyosu/details/invoke.hpp>

namespace kyosu::tags
{
struct callable_sqr : eve::elementwise
{
using callable_tag_type = callable_sqr;

KYOSU_DEFERS_CALLABLE(sqr_);

template<eve::ordered_value T>
static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return v*v; }

template<typename T>
KYOSU_FORCEINLINE auto operator()(T const& target) const noexcept -> decltype(eve::tag_invoke(*this, target))
{
return eve::tag_invoke(*this, target);
}

template<typename... T>
eve::unsupported_call<callable_sqr(T&&...)> 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 <kyosu/functions.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace kyosu
//! {
//! template<kyosu::concepts::cayley_dickson T> constexpr T sqr(T z) noexcept;
//! template<eve::ordered_value T> 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 = {};
}
35 changes: 35 additions & 0 deletions include/kyosu/types/impl/arithmetic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <eve/module/core.hpp>
#include <eve/module/math.hpp>
#include <iostream>

namespace kyosu::_
{
Expand Down Expand Up @@ -95,4 +96,38 @@ namespace kyosu::_
{
return C{kumi::map([](auto const& e) { return eve::frac(e); }, c)};
}

template<concepts::cayley_dickson C>
KYOSU_FORCEINLINE constexpr
auto dispatch(eve::tag_of<sqr> const&, C c) noexcept
{
if constexpr(kyosu::dimension_v<C> <= 2)
{
return c*c;
}else
{
auto squares = kumi::map_index([]<typename I>(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<typename C0, typename C1>
KYOSU_FORCEINLINE constexpr
auto dispatch(eve::tag_of<dist> const&, C0 const & c0, C1 const & c1) noexcept
{
return kyosu::abs(c0-c1);
}

template<typename C0, typename C1>
KYOSU_FORCEINLINE constexpr
auto dispatch(eve::tag_of<reldist> 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))));
}

}
11 changes: 8 additions & 3 deletions include/kyosu/types/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename T> struct sema { using type = T; };
template<concepts::cayley_dickson T> struct sema<T> { using type = eve::wide<eve::underlying_type_t<T>>; };
// Force a type to be looked at as a wide so we can apply wide-like type preserving semantic in type computations
template<typename T> struct sema { using type = T; };
template<typename T> struct sema<eve::logical<T>> : sema<T> {};
template<typename T, typename N>
struct sema<eve::wide<T,N>> { using type = eve::wide<eve::underlying_type_t<T>>; };
template<concepts::cayley_dickson T>
struct sema<T> { using type = eve::wide<eve::underlying_type_t<T>>; };

template<typename T> using sema_t = typename sema<T>::type;

// Convert a Base type to a potential wide if any appear in T...
Expand Down
Loading

0 comments on commit cc13065

Please sign in to comment.