Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complex domain converter #1528

Merged
merged 6 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 169 additions & 2 deletions include/eve/module/complex/detail/math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
namespace eve::detail
{


//==============================================================================================
// sqrt cosh cos acosh asinh atan exp exp_i exp_ipi log rec are here.
// acos asin atanh are in specific files included at the end
//==============================================================================================


//===-------------------------------------------------------------------------------------------
// Unary functions : cbrt
//===-------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -762,10 +762,177 @@ namespace eve::detail
{
return d(lpnorm)(p, abs(z1), abs(z2)...);
}

}

#include <eve/module/complex/detail/math/acos.hpp>
#include <eve/module/complex/detail/math/asin.hpp>
#include <eve/module/complex/detail/math/atanh.hpp>
#include <eve/module/complex/detail/math/pow.hpp>

namespace eve::detail
{

//==============================================================================================
// non-complex => complex kind of functions
//==============================================================================================
//sqrt
template<value T>
EVE_FORCEINLINE constexpr auto
sqrt_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return sqrt(v);
else if(floating_ordered_value<T>)
{
auto s = sqrt(eve::abs(v));
return if_else(is_gez(v), eve::as_complex_t<T>{s,T{0}}, eve::as_complex_t<T>{T{0}, s} );
}
}

//log
template<value T>
EVE_FORCEINLINE constexpr auto
log_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return log(v);
else if(floating_ordered_value<T>)
{
auto s = log_abs(v);
return if_else(is_positive(v), eve::as_complex_t<T>{s,T{0}}, eve::as_complex_t<T>{s, pi(as(v))} );
}
}

//log2
template<value T>
EVE_FORCEINLINE constexpr auto
log2_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return log2(v);
else if(floating_ordered_value<T>)
{
auto s = log2(eve::abs(v));
return if_else(is_positive(v), eve::as_complex_t<T>{s,T{0}}, eve::as_complex_t<T>{s, pi(as(v))*invlog_2(as(v))} );
}
}

//log10
template<value T>
EVE_FORCEINLINE constexpr auto
log10_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return log10(v);
else if(floating_ordered_value<T>)
{
auto s = log10(eve::abs(v));
return if_else(is_positive(v), eve::as_complex_t<T>{s,T{0}}, eve::as_complex_t<T>{s, pi(as(v))*invlog_10(as(v))} );
}
}

//asin
template<value T>
EVE_FORCEINLINE constexpr auto
asin_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return asin(v);
else if(floating_ordered_value<T>)
{
return if_else(abs(v) <= one(as(v)), eve::as_complex_t<T>{asin(v),T{0}}, asin(eve::as_complex_t<T>(v)));
}
}

//acos
template<value T>
EVE_FORCEINLINE constexpr auto
acos_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return acos(v);
else if(floating_ordered_value<T>)
{
return if_else(abs(v) < one(as(v)), eve::as_complex_t<T>{acos(v),T{0}}, acos(eve::as_complex_t<T>(v)));
}
}

//acsc
template<value T>
EVE_FORCEINLINE constexpr auto
acsc_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return acsc(v);
else if(floating_ordered_value<T>)
{
return if_else(abs(v) >= one(as(v)), eve::as_complex_t<T>{acsc(v),T{0}}, acsc(eve::as_complex_t<T>(v)));
}
}

//asec
template<value T>
EVE_FORCEINLINE constexpr auto
asec_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return asec(v);
else if(floating_ordered_value<T>)
{
return if_else(abs(v) >= one(as(v)), eve::as_complex_t<T>{asec(v),T{0}}, asec(eve::as_complex_t<T>(v)));
}
}

//acosh
template<value T>
EVE_FORCEINLINE constexpr auto
acosh_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return acosh(v);
else if(floating_ordered_value<T>)
{
return if_else(v >= one(as(v)), eve::as_complex_t<T>{acosh(v),T{0}}, acosh(eve::as_complex_t<T>(v)));
}
}

//atanh
template<value T>
EVE_FORCEINLINE constexpr auto
atanh_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return atanh(v);
else if(floating_ordered_value<T>)
{
return if_else(eve::abs(v) <= one(as(v)), eve::as_complex_t<T>{atanh(v),T{0}}, atanh(eve::as_complex_t<T>(v)));
}
}

//acoth
template<value T>
EVE_FORCEINLINE constexpr auto
acoth_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& v) noexcept
{
if constexpr(is_complex_v<T>)
return acoth(v);
else if(floating_ordered_value<T>)
{
return if_else(eve::abs(v) >= one(as(v)), eve::as_complex_t<T>{acoth(v),T{0}}, acoth(eve::as_complex_t<T>(v)));
}
}

//pow
template<value T, value U>
EVE_FORCEINLINE constexpr auto
pow_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& t, U const& u) noexcept
{
if constexpr(is_complex_v<T>|| is_complex_v<U>)
return pow(t, u);
else if(floating_ordered_value<T>)
{
return if_else(is_positive(t), eve::as_complex_t<T>{pow_abs(t, u), T{0}}, pow(eve::as_complex_t<T>(t), u));
}
}

}
8 changes: 8 additions & 0 deletions include/eve/module/complex/detail/math/atanh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ namespace eve
rtype inf = eve::inf(as(a0r));
rtype x = eve::abs(a0r);
rtype y = eve::abs(a0i);
auto special = is_eqz(y) && (x < one(as(a0r)));
auto sr = atanh(a0r);
if (eve::all(special)) {
return Z{sr, zero(as(sr))};
}

rtype r = zero(as(a0r));
rtype i = zero(as(a0r));
auto gtxmax = (x > s_max);
Expand Down Expand Up @@ -162,6 +168,8 @@ namespace eve
i = eve::if_else( ltzia0,-i, i);
r = if_else(realinf, zero(as(a0r)), r);
i = if_else(realinf, -sign(a0r)*pio_2(as(a0r)), i);
r = if_else(special, sr, r);
i = if_else(special, zero, i);
return Z{r, i};
}
}
Expand Down
24 changes: 24 additions & 0 deletions include/eve/module/complex/detail/math/pow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,29 @@ namespace eve
return pow(inc(z1), z2);
}

//powm1
template<value T, value U>
EVE_FORCEINLINE constexpr auto
powm1_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& t, U const& u) noexcept
{
if constexpr(is_complex_v<T>|| is_complex_v<U>)
return powm1(t, u);
else if(floating_ordered_value<T>)
{
return if_else(is_positive(t), eve::as_complex_t<T>{powm1(t, u), T{0}}, powm1(eve::as_complex_t<T>(t), u));
}
}

template<value T, value U>
EVE_FORCEINLINE constexpr auto
pow1p_(EVE_SUPPORTS(cpu_), eve::domain::complex_converter const&, T const& t, U const& u) noexcept
{
if constexpr(is_complex_v<T>|| is_complex_v<U>)
return pow1p(t, u);
else if(floating_ordered_value<T>)
{
return if_else(is_positive(t), eve::as_complex_t<T>{pow1p(t, u), T{0}}, pow1p(eve::as_complex_t<T>(t), u));
}
}
}
}
7 changes: 7 additions & 0 deletions include/eve/module/complex/regular/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//==================================================================================================
#pragma once
#include <eve/concept/value.hpp>
#include <eve/module/core/regular/converter.hpp>
#include <eve/traits.hpp>

namespace eve
Expand Down Expand Up @@ -60,4 +61,10 @@ namespace eve
>
{
};

namespace domain
{
using complex_converter = eve::decorated<eve::convert_by_<eve::as_complex, false>()>;
inline constexpr complex_converter const complex = {};
}
}
8 changes: 8 additions & 0 deletions include/eve/module/core/regular/sqrt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ namespace eve
//!
//! @}
//================================================================================================
namespace tag
{
struct sqrt_;
}

template<> struct supports_optimized_conversion<tag::sqrt_> : std::true_type
{};

EVE_MAKE_CALLABLE(sqrt_, sqrt);
}

Expand Down
7 changes: 7 additions & 0 deletions include/eve/module/math/regular/acos.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ namespace eve
//! [floating real values](@ref floating_value) which can be slightly less accurate near 1.
//! @}
//================================================================================================
namespace tag
{
struct acos_;
}

template<> struct supports_optimized_conversion<tag::acos_> : std::true_type
{};

EVE_MAKE_CALLABLE(acos_, acos);
}
Expand Down
8 changes: 8 additions & 0 deletions include/eve/module/math/regular/acosh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ namespace eve
//!
//! @}
//================================================================================================
namespace tag
{
struct acosh_;
}

template<> struct supports_optimized_conversion<tag::acosh_> : std::true_type
{};

EVE_MAKE_CALLABLE(acosh_, acosh);
}

Expand Down
7 changes: 7 additions & 0 deletions include/eve/module/math/regular/acoth.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ namespace eve
//! @godbolt{doc/math/regular/acoth.cpp}
//! @}
//================================================================================================
namespace tag
{
struct acoth_;
}

template<> struct supports_optimized_conversion<tag::acoth_> : std::true_type
{};
EVE_MAKE_CALLABLE(acoth_, acoth);
}

Expand Down
7 changes: 7 additions & 0 deletions include/eve/module/math/regular/acsc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ namespace eve
//! @godbolt{doc/math/regular/acsc.cpp}
//! @}
//================================================================================================
namespace tag
{
struct acsc_;
}

template<> struct supports_optimized_conversion<tag::acsc_> : std::true_type
{};

EVE_MAKE_CALLABLE(acsc_, acsc);
}
Expand Down
7 changes: 7 additions & 0 deletions include/eve/module/math/regular/asec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ namespace eve
//! @godbolt{doc/math/regular/asec.cpp}
//! @}
//================================================================================================
namespace tag
{
struct asec_;
}

template<> struct supports_optimized_conversion<tag::asec_> : std::true_type
{};

EVE_MAKE_CALLABLE(asec_, asec);
}
Expand Down
7 changes: 7 additions & 0 deletions include/eve/module/math/regular/asin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ namespace eve
//! @godbolt{doc/complex/regular/asin.cpp}
//! @}
//================================================================================================
namespace tag
{
struct asin_;
}

template<> struct supports_optimized_conversion<tag::asin_> : std::true_type
{};

EVE_MAKE_CALLABLE(asin_, asin);
}
Expand Down
10 changes: 9 additions & 1 deletion include/eve/module/math/regular/atanh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,15 @@ namespace eve
//! @godbolt{doc/complex/regular/atanh.cpp}
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(atanh_, atanh);
namespace tag
{
struct atanh_;
}

template<> struct supports_optimized_conversion<tag::atanh_> : std::true_type
{};

EVE_MAKE_CALLABLE(atanh_, atanh);
}

#include <eve/module/math/regular/impl/atanh.hpp>
10 changes: 9 additions & 1 deletion include/eve/module/math/regular/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,15 @@ namespace eve
//! @godbolt{doc/math/masked/log.cpp}
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(log_, log);
namespace tag
{
struct log_;
}

template<> struct supports_optimized_conversion<tag::log_> : std::true_type
{};

EVE_MAKE_CALLABLE(log_, log);
}

#include <eve/module/math/regular/impl/log.hpp>
Expand Down
Loading