Skip to content

Commit

Permalink
Implementation of the pow functions family
Browse files Browse the repository at this point in the history
  • Loading branch information
jtlap committed Sep 4, 2023
1 parent 0c4112e commit 586f4d2
Show file tree
Hide file tree
Showing 16 changed files with 912 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@

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

KYOSU_DEFERS_CALLABLE(is_imag_);
KYOSU_DEFERS_CALLABLE(arg_);

template<eve::ordered_value T>
static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept { return eve::is_eqz(v); }
static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept {
return eve::if_else(eve::is_positive(v), eve::zero, eve::pi(eve::as(v)));
}

template<typename T>
KYOSU_FORCEINLINE auto operator()(T const& target) const noexcept -> decltype(eve::tag_invoke(*this, target))
Expand All @@ -27,7 +29,7 @@ namespace kyosu::tags
}

template<typename... T>
eve::unsupported_call<callable_is_imag(T&&...)> operator()(T&&... x) const
eve::unsupported_call<callable_arg(T&&...)> operator()(T&&... x) const
requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete;
};
}
Expand All @@ -37,8 +39,8 @@ namespace kyosu
//======================================================================================================================
//! @addtogroup functions
//! @{
//! @var is_imag
//! @brief test if the complex parameter is pure imaginary.
//! @var arg
//! @brief complex number argument.
//!
//! **Defined in Header**
//!
Expand All @@ -51,8 +53,8 @@ namespace kyosu
//! @code
//! namespace kyosu
//! {
//! template<kyosu::concepts::cayley_dickson T> constexpr auto is_imag(T z) noexcept;
//! template<eve::ordered_value T> constexpr auto is_imag(T z) noexcept;
//! template<kyosu::concepts::complex T> constexpr auto arg(T z) noexcept;
//! template<eve::ordered_value T> constexpr auto arg(T z) noexcept;
//! }
//! @endcode
//!
Expand All @@ -62,12 +64,12 @@ namespace kyosu
//!
//! **Return value**
//!
//! Returns the value of real(z) == 0.
//! Returns elementwise true the argument of the complex number i.e. `atan2(imag(z), real(z))`.
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/is_imag.cpp}
//! @godbolt{doc/arg.cpp}
//! @}
//======================================================================================================================
inline constexpr tags::callable_is_imag is_imag = {};
inline constexpr tags::callable_arg arg = {};
}
19 changes: 19 additions & 0 deletions include/kyosu/complex/impl/arithmetic.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//======================================================================================================================
/*
Kyosu - Complex Without Complexes
Copyright : KYOSU Contributors & Maintainers
SPDX-License-Identifier: BSL-1.0
*/
//======================================================================================================================
#pragma once
#include <eve/module/math.hpp>

namespace kyosu::_
{
template<kyosu::concepts::complex C>
KYOSU_FORCEINLINE constexpr
auto dispatch(eve::tag_of<kyosu::arg> const&, C const& c) noexcept
{
return eve::pedantic(eve::atan2(kyosu::imag(c), kyosu::real(c));
}
}
78 changes: 78 additions & 0 deletions include/kyosu/complex/polar.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//======================================================================================================================
/*
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_polar : eve::elementwise
{
using callable_tag_type = callable_polar;

KYOSU_DEFERS_CALLABLE(polar_);

template<eve::ordered_value T0, eve::ordered_value T1>
static KYOSU_FORCEINLINE auto deferred_call(auto, T0 const& rho, T1 const & theta) noexcept
{
auto [s, c] = eve::sincos(theta);
return kyosu::to_complex(rho*c, eve::if_else(eve::is_eqz(s), eve::zero, rho*s));
}

template<typename T0, typename T1>
KYOSU_FORCEINLINE auto operator()(T0 const& target0, T1 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_polar(T&&...)> operator()(T&&... x) const
requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete;
};
}

namespace kyosu
{
//======================================================================================================================
//! @addtogroup functions
//! @{
//! @var polar
//! @brief complex number from modulus and argument.
//!
//! **Defined in Header**
//!
//! @code
//! #include <kyosu/functions.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace kyosu
//! {
//! template<eve::ordered_value T0, eve::ordered_value T1> constexpr auto polar(T0 rho, T1 theta) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `rho` : modulus.
//! * `theta` : argument.
//!
//! **Return value**
//!
//! Returns elementwise true the polarument of the complex number i.e. \f$\rho e^{i\theta}\f$.
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/polar.cpp}
//! @}
//======================================================================================================================
inline constexpr tags::callable_polar polar = {};
}
18 changes: 15 additions & 3 deletions include/kyosu/functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#pragma once

//======================================================================================================================
//! @defgroup functions Functions
//! @brief Functions performing computations over complex, quaternions and octonions.
//! @defgroup functions Cayley-Dickson Functions
//! @brief Functions performing computations over all caylet-dickson types complex, quaternions, octonions...
//======================================================================================================================
#include <kyosu/functions/abs.hpp>
#include <kyosu/functions/average.hpp>
Expand Down Expand Up @@ -42,7 +42,6 @@
#include <kyosu/functions/is_equal.hpp>
#include <kyosu/functions/is_eqz.hpp>
#include <kyosu/functions/is_finite.hpp>
#include <kyosu/functions/is_imag.hpp>
#include <kyosu/functions/is_infinite.hpp>
#include <kyosu/functions/is_nan.hpp>
#include <kyosu/functions/is_nez.hpp>
Expand All @@ -57,6 +56,7 @@
#include <kyosu/functions/kpart.hpp>
#include <kyosu/functions/lerp.hpp>
#include <kyosu/functions/log.hpp>
#include <kyosu/functions/log_abs.hpp>
#include <kyosu/functions/log1p.hpp>
#include <kyosu/functions/log10.hpp>
#include <kyosu/functions/log2.hpp>
Expand All @@ -65,6 +65,10 @@
#include <kyosu/functions/minus.hpp>
#include <kyosu/functions/nearest.hpp>
#include <kyosu/functions/oneminus.hpp>
#include <kyosu/functions/pow.hpp>
#include <kyosu/functions/powm1.hpp>
#include <kyosu/functions/pow1p.hpp>
#include <kyosu/functions/pow_abs.hpp>
#include <kyosu/functions/pure.hpp>
#include <kyosu/functions/purepart.hpp>
#include <kyosu/functions/real.hpp>
Expand All @@ -83,3 +87,11 @@
#include <kyosu/functions/tan.hpp>
#include <kyosu/functions/tanh.hpp>
#include <kyosu/functions/trunc.hpp>

//======================================================================================================================
//! @brief Functions performing computations over complex or real elements only.
//======================================================================================================================

#include <kyosu/complex/arg.hpp>
#include <kyosu/complex/is_imag.hpp>
#include <kyosu/complex/polar.hpp>
79 changes: 79 additions & 0 deletions include/kyosu/functions/log_abs.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>
#include <kyosu/functions/to_complex.hpp>
#include <eve/module/math.hpp>

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

KYOSU_DEFERS_CALLABLE(log_abs_);

template<eve::ordered_value T>
static KYOSU_FORCEINLINE auto deferred_call(auto, T const& v) noexcept
{
auto fn = callable_log_abs{};
return fn( kyosu::to_complex(v, T(0)));
}

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

namespace kyosu
{
//======================================================================================================================
//! @addtogroup functions
//! @{
//! @var log_abs
//! @brief Computes the natural logarithm of the absolute value of the argument.
//!
//! **Defined in Header**
//!
//! @code
//! #include <kyosu/functions.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace kyosu
//! {
//! template<kyosu::concepts::cayley_dickson T> constlog_absr T log_abs(T z) noexcept;
//! template<eve::ordered_value T> constlog_absr T log_abs(T z) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `z` : Value to process.
//!
//! **Return value**
//!
//! Returns the `log(abs(z))`.
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/log_abs.cpp}
//! @}
//======================================================================================================================
inline constexpr tags::callable_log_abs log_abs = {};
}
78 changes: 78 additions & 0 deletions include/kyosu/functions/pow.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//======================================================================================================================
/*
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_pow : eve::elementwise
{
using callable_tag_type = callable_pow;

KYOSU_DEFERS_CALLABLE(pow_);

static KYOSU_FORCEINLINE auto deferred_call(auto
, eve::ordered_value auto const& v0
, eve::ordered_value auto const& v1) noexcept
{
return eve::pow(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_pow(T&&...)> operator()(T&&... x) const
requires(!requires { eve::tag_invoke(*this, KYOSU_FWD(x)...); }) = delete;
};
}

namespace kyosu
{
//======================================================================================================================
//! @addtogroup functions
//! @{
//! @var pow
//! @brief Computes the computing the pow operation \f$x^y\f$.
//!
//! **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 pow(T0 z0, T1, z1) noexcept;
//! template<eve::ordered_value T0, kyosu::concepts::cayley_dickson T1> > constexpr auto pow(T0 z0, T1, z1) noexcept;
//! template<kyosu::concepts::cayley_dickson T0, eve::ordered_value T1 > constexpr auto pow(T0 z0, T1, z1) noexcept;
//! template<eve::ordered_value T0, ordered_value T1> > constexpr auto pow(T0 z0, T1, z1) noexcept;
///! }
//! @endcode
//!
//! **Parameters**
//!
//! * `z0, z1` : Values to process.
//!
//! **Return value**
//!
//! the call is semantically equivalent to `eve::exp(z1*eve::log(z0))`
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/pow.cpp}
//! @}
//======================================================================================================================
inline constexpr tags::callable_pow pow = {};
}
Loading

0 comments on commit 586f4d2

Please sign in to comment.