Skip to content

Commit

Permalink
New functor style for combinatorial
Browse files Browse the repository at this point in the history
  • Loading branch information
jtlap authored Jan 19, 2024
1 parent df15ea6 commit 226df22
Show file tree
Hide file tree
Showing 22 changed files with 1,670 additions and 1,662 deletions.
25 changes: 15 additions & 10 deletions include/eve/module/combinatorial/regular/bernouilli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,22 @@
//==================================================================================================
#pragma once

#include <eve/detail/overload.hpp>
#include <eve/arch.hpp>
#include <eve/traits/overload.hpp>
#include <eve/module/core/decorator/core.hpp>

namespace eve
{
template<typename Options>
struct bernouilli_t : elementwise_callable<bernouilli_t, Options>
{
template<eve::unsigned_value T>
constexpr EVE_FORCEINLINE
as_wide_as_t<double, T> operator()(T v) const noexcept { return EVE_DISPATCH_CALL(v); }

EVE_CALLABLE_OBJECT(bernouilli_t, bernouilli_);
};

//================================================================================================
//! @addtogroup combinatorial
//! @{
Expand All @@ -29,7 +41,7 @@ namespace eve
//! namespace eve
//! {
//! template< eve::unsigned_value N >
//! eve::as_wide_as<double, N> bernouilli(N n) noexcept;
//! constexpr eve::as_wide_as<double, N> bernouilli(N n) noexcept;
//! }
//! @endcode
//!
Expand All @@ -47,14 +59,7 @@ namespace eve
//! @godbolt{doc/combinatorial/regular/bernouilli.cpp}
//! @}
//================================================================================================
namespace tag
{
struct bernouilli_;
}
template<> struct supports_conditional<tag::bernouilli_> : std::false_type
{};

EVE_MAKE_CALLABLE(bernouilli_, bernouilli);
inline constexpr auto bernouilli = functor<bernouilli_t>;
}

#include <eve/module/combinatorial/regular/impl/bernouilli.hpp>
19 changes: 16 additions & 3 deletions include/eve/module/combinatorial/regular/fibonacci.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,22 @@
//==================================================================================================
#pragma once

#include <eve/detail/overload.hpp>
#include <eve/arch.hpp>
#include <eve/traits/overload.hpp>
#include <eve/module/core/decorator/core.hpp>

namespace eve
{
template<typename Options>
struct fibonacci_t : elementwise_callable<fibonacci_t, Options>
{
template<eve::unsigned_value N, floating_ordered_value T0, floating_ordered_value T1>
constexpr EVE_FORCEINLINE as_wide_as_t<common_value_t<T0, T1>, N>
operator()(N n, T0 t0, T1 t1) const noexcept { return EVE_DISPATCH_CALL(n, t0, t1); }

EVE_CALLABLE_OBJECT(fibonacci_t, fibonacci_);
};

//================================================================================================
//! @addtogroup combinatorial
//! @{
Expand Down Expand Up @@ -38,7 +50,7 @@ namespace eve
//! namespace eve
//! {
//! template< eve::unsigned_value N, eve::floating_ordered_value T, eve::floating_ordered_value U>
//! eve::common_value_t<T, U> fibonacci(N n, T x, U y) noexcept
//! constexpr eve::common_value_t<T, U> fibonacci(N n, T x, U y) noexcept
//! }
//! @endcode
//!
Expand All @@ -57,7 +69,8 @@ namespace eve
//! @godbolt{doc/combinatorial/regular/fibonacci.cpp}
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(fibonacci_, fibonacci);
inline constexpr auto fibonacci = functor<fibonacci_t>;

}

#include <eve/module/combinatorial/regular/impl/fibonacci.hpp>
22 changes: 15 additions & 7 deletions include/eve/module/combinatorial/regular/gcd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,22 @@
//==================================================================================================
#pragma once

#include <eve/detail/overload.hpp>
#include <eve/arch.hpp>
#include <eve/traits/overload.hpp>
#include <eve/module/core/decorator/core.hpp>

namespace eve
{
template<typename Options>
struct gcd_t : elementwise_callable<gcd_t, Options, raw_option>
{
template<eve::ordered_value T, ordered_value U>
constexpr EVE_FORCEINLINE common_value_t<T, U>
operator()(T v, U w) const noexcept { return EVE_DISPATCH_CALL(v, w); }

EVE_CALLABLE_OBJECT(gcd_t, gcd_);
};

//================================================================================================
//! @addtogroup combinatorial
//! @{
Expand All @@ -29,7 +41,7 @@ namespace eve
//! namespace eve
//! {
//! template< eve::ordered_value T, eve::ordered_value U >
//! T gcd(T p, U n) noexcept;
//! constexpr common_value_t<T, U> gcd(T p, U n) noexcept;
//! }
//! @endcode
//!
Expand All @@ -53,12 +65,8 @@ namespace eve
//!
//! @}
//================================================================================================
namespace tag
{
struct gcd_;
}
inline constexpr auto gcd = functor<gcd_t>;

EVE_MAKE_CALLABLE(gcd_, gcd);
}

#include <eve/module/combinatorial/regular/impl/gcd.hpp>
56 changes: 28 additions & 28 deletions include/eve/module/combinatorial/regular/impl/bernouilli.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
namespace eve::detail
{

template<unsigned_value T>
EVE_FORCEINLINE auto
bernouilli_(EVE_SUPPORTS(cpu_), T n) noexcept
{
constexpr std::array<double, 130> dbernouilli_b2ns = {
template<unsigned_value T, callable_options O>
constexpr EVE_FORCEINLINE auto
bernouilli_(EVE_REQUIRES(cpu_), O const&, T n)
{
constexpr std::array<double, 130> dbernouilli_b2ns = {
{+1.00000000000000000000000000000000000000000,
+0.166666666666666666666666666666666666666667,
-0.0333333333333333333333333333333333333333333,
Expand Down Expand Up @@ -149,30 +149,30 @@ bernouilli_(EVE_SUPPORTS(cpu_), T n) noexcept
+4.80793212775015697668878704043264072227967e299,
-7.95021250458852528538243631671158693036798e302,
+1.33527841873546338750122832017820518292039e306}};
if constexpr( has_native_abi_v<T> )
{
if constexpr( scalar_value<T> )
if constexpr( has_native_abi_v<T> )
{
if( n == one(as(n)) ) return -0.5; // mhalf(as<double>());
if( is_odd(n) ) return 0.0;
auto no2 = n / 2;
if constexpr( sizeof(T) == 1 ) return dbernouilli_b2ns[no2];
else return (no2 < 130) ? dbernouilli_b2ns[no2] : inf(as<double>());
}
else
{
auto no2 = n / 2;
auto even_n = is_even(n);
auto nlt130 = no2 < T(130);
auto test = nlt130 && even_n;
auto nn = if_else(test, no2, zero);
auto r = gather(&dbernouilli_b2ns[0], nn);
r = if_else(even_n, r, zero(as(r))); // TODO why zero is not good here ?
r = if_else(n == one(as(n)), mhalf(as(r)), r);
if constexpr( sizeof(element_type_t<T>) == 1 ) return r;
return if_else(nlt130, r, inf(as(r)));
if constexpr( scalar_value<T> )
{
if( n == one(as(n)) ) return -0.5; // mhalf(as<double>());
if( is_odd(n) ) return 0.0;
auto no2 = n / 2;
if constexpr( sizeof(T) == 1 ) return dbernouilli_b2ns[no2];
else return (no2 < 130) ? dbernouilli_b2ns[no2] : inf(as<double>());
}
else
{
auto no2 = n / 2;
auto even_n = is_even(n);
auto nlt130 = no2 < T(130);
auto test = nlt130 && even_n;
auto nn = if_else(test, no2, zero);
auto r = gather(&dbernouilli_b2ns[0], nn);
r = if_else(even_n, r, zero(as(r))); // TODO why zero is not good here ?
r = if_else(n == one(as(n)), mhalf(as(r)), r);
if constexpr( sizeof(element_type_t<T>) == 1 ) return r;
return if_else(nlt130, r, inf(as(r)));
}
}
else return apply_over(bernouilli, n);
}
else return apply_over(bernouilli, n);
}
}
47 changes: 22 additions & 25 deletions include/eve/module/combinatorial/regular/impl/fibonacci.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,29 @@

namespace eve::detail
{

template<unsigned_value N, floating_value T, floating_value U>
EVE_FORCEINLINE auto
fibonacci_(EVE_SUPPORTS(cpu_), N n, T a, U b) noexcept
{
return indexed_call(fibonacci, n, a, b);
}

template<unsigned_value N, floating_value T>
EVE_FORCEINLINE auto
fibonacci_(EVE_SUPPORTS(cpu_), N n, T a, T b) noexcept
{
if constexpr( has_native_abi_v<T> && has_native_abi_v<N>)
template<typename N, typename T, typename U, callable_options O>
constexpr EVE_FORCEINLINE as_wide_as_t<common_value_t<T, U>, N>
fibonacci_(EVE_REQUIRES(cpu_), O const&, N n, T a, U b)
{
using w_t = as_wide_as_t<T, N>;
using elt_t = element_type_t<T>;
using eli_t = as_integer_t<elt_t, unsigned>;
auto gold = w_t(1.61803398874989484820458683436563811772030917980575);
auto goldbar = w_t(-0.61803398874989484820458683436563811772030917980575);
using c_t = as_wide_as_t<common_value_t<T, U>, N>;
using elt_t = element_type_t<c_t>;
using eli_t = as_integer_t<elt_t, unsigned>;
auto gold = c_t(1.61803398874989484820458683436563811772030917980575);
auto goldbar = c_t(-0.61803398874989484820458683436563811772030917980575);
constexpr elt_t oneosqrt5 = 0.4472135954999579392818347337462552470881236719223;
auto nm1 = to_<eli_t>((n));
auto c2 = fms(gold, a, b) * oneosqrt5;
auto c1 = a - c2;
auto f = fma(c1, pow(gold, nm1), c2 * pow(goldbar, nm1));
return if_else(is_flint(a) && is_flint(b), nearest(f), f);
if constexpr(std::same_as<T, U>)
{
if constexpr( has_native_abi_v<T> && has_native_abi_v<N>)
{
auto nm1 = to_<eli_t>((n));
auto c2 = fms(gold, a, b) * oneosqrt5;
auto c1 = a - c2;
auto f = fma(c1, eve::pow(gold, nm1), c2 * eve::pow(goldbar, nm1));
return nearest[is_flint(a) && is_flint(b)](f);
}
else return apply_over(fibonacci, n, a, b);
}
else
return indexed_call(fibonacci, n, a, b);
}
else return apply_over(fibonacci, n, a, b);
}
}
Loading

0 comments on commit 226df22

Please sign in to comment.