Skip to content

Commit a628632

Browse files
committed
secxxx
1 parent 61e7294 commit a628632

File tree

6 files changed

+96
-64
lines changed

6 files changed

+96
-64
lines changed

include/eve/module/math/regular/secd.hpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,23 @@ namespace eve
8787
template<typename T, callable_options O>
8888
constexpr EVE_FORCEINLINE T secd_(EVE_REQUIRES(cpu_), O const& o, T const& a0) noexcept
8989
{
90-
if constexpr( O::contains(quarter_circle) )
91-
return eve::rec[pedantic](eve::cosd[o](a0));
90+
using elt_t = element_type_t<T>;
91+
if constexpr(std::same_as<elt_t, eve::float16_t>)
92+
return eve::detail::apply_fp16_as_fp32(eve::secd[o], a0);
9293
else
9394
{
94-
auto a0_180 = div_180(a0);
95-
auto test = is_not_flint(a0_180) && is_flint(a0_180 + mhalf(eve::as(a0_180)));
96-
if constexpr( scalar_value<T> ) // early return for nans in scalar case
95+
if constexpr( O::contains(quarter_circle) )
96+
return eve::rec[pedantic](eve::cosd[o](a0));
97+
else
9798
{
98-
if( test ) return nan(eve::as<T>());
99+
auto a0_180 = div_180(a0);
100+
auto test = is_not_flint(a0_180) && is_flint(a0_180 + mhalf(eve::as(a0_180)));
101+
if constexpr( scalar_value<T> ) // early return for nans in scalar case
102+
{
103+
if( test ) return nan(eve::as<T>());
104+
}
105+
return if_else(test, eve::allbits, rec[pedantic](cosd[o](a0)));
99106
}
100-
return if_else(test, eve::allbits, rec[pedantic](cosd[o](a0)));
101107
}
102108
}
103109
}

include/eve/module/math/regular/sech.hpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,28 @@ namespace eve
8383
namespace detail
8484
{
8585
template<typename T, callable_options O>
86-
constexpr EVE_FORCEINLINE T sech_(EVE_REQUIRES(cpu_), O const&, T const& a0)
86+
constexpr EVE_FORCEINLINE T sech_(EVE_REQUIRES(cpu_), O const& o, T const& a0)
8787
{
88-
//////////////////////////////////////////////////////////////////////////////
89-
// if x = abs(a0) according x < Threshold e = exp(x) or exp(x/2) is
90-
// respectively computed
91-
// * in the first case sech (e+rec[pedantic](e))/2
92-
// * in the second sech is (e/2)*e (avoiding undue overflow)
93-
// Threshold is maxlog - Log_2
94-
//////////////////////////////////////////////////////////////////////////////
95-
T x = eve::abs(a0);
96-
auto test1 = (x > maxlog(eve::as<T>()) - log_2(eve::as<T>()));
97-
auto fac = if_else(test1, half(eve::as<T>()), eve::one);
98-
T tmp1 = exp(-x * fac);
99-
T tmp = T(2) * tmp1;
100-
if constexpr( scalar_value<T> ) { return test1 ? tmp1 * tmp : tmp / fma(tmp1, tmp1, T(1)); }
101-
else { return if_else(test1, tmp1 * tmp, tmp / fma(tmp1, tmp1, T(1))); }
88+
using elt_t = element_type_t<T>;
89+
if constexpr(std::same_as<elt_t, eve::float16_t>)
90+
return eve::detail::apply_fp16_as_fp32(eve::sech[o], a0);
91+
else
92+
{
93+
//////////////////////////////////////////////////////////////////////////////
94+
// if x = abs(a0) according x < Threshold e = exp(x) or exp(x/2) is
95+
// respectively computed
96+
// * in the first case sech (e+rec[pedantic](e))/2
97+
// * in the second sech is (e/2)*e (avoiding undue overflow)
98+
// Threshold is maxlog - Log_2
99+
//////////////////////////////////////////////////////////////////////////////
100+
T x = eve::abs(a0);
101+
auto test1 = (x > maxlog(eve::as<T>()) - log_2(eve::as<T>()));
102+
auto fac = if_else(test1, half(eve::as<T>()), eve::one);
103+
T tmp1 = exp(-x * fac);
104+
T tmp = T(2) * tmp1;
105+
if constexpr( scalar_value<T> ) { return test1 ? tmp1 * tmp : tmp / fma(tmp1, tmp1, T(1)); }
106+
else { return if_else(test1, tmp1 * tmp, tmp / fma(tmp1, tmp1, T(1))); }
107+
}
102108
}
103109
}
104110
}

include/eve/module/math/regular/secpi.hpp

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -88,32 +88,38 @@ namespace eve
8888
template<typename T, callable_options O>
8989
constexpr EVE_FORCEINLINE T secpi_(EVE_REQUIRES(cpu_), O const& o, T a0) noexcept
9090
{
91-
if constexpr(O::contains(quarter_circle))
92-
{
93-
auto x = abs(a0);
94-
auto test = is_not_less_equal(x, T(0.25));
95-
if constexpr( scalar_value<T> )
96-
{
97-
if( test ) return nan(eve::as<T>());
98-
}
99-
else { a0 = if_else(test, eve::allbits, a0); }
100-
101-
a0 *= pi(eve::as<T>());
102-
auto x2 = sqr(a0);
103-
return rec[pedantic](cos_eval(x2));
104-
}
91+
using elt_t = element_type_t<T>;
92+
if constexpr(std::same_as<elt_t, eve::float16_t>)
93+
return eve::detail::apply_fp16_as_fp32(eve::secpi[o], a0);
10594
else
10695
{
107-
const T x = eve::abs(a0);
108-
if constexpr( scalar_value<T> )
96+
if constexpr(O::contains(quarter_circle))
10997
{
110-
if( is_not_finite(x) ) return nan(eve::as<T>());
111-
if( x > maxflint(eve::as<T>()) ) return T(1);
98+
auto x = abs(a0);
99+
auto test = is_not_less_equal(x, T(0.25));
100+
if constexpr( scalar_value<T> )
101+
{
102+
if( test ) return nan(eve::as<T>());
103+
}
104+
else { a0 = if_else(test, eve::allbits, a0); }
105+
106+
a0 *= pi(eve::as<T>());
107+
auto x2 = sqr(a0);
108+
return rec[pedantic](cos_eval(x2));
112109
}
110+
else
111+
{
112+
const T x = eve::abs(a0);
113+
if constexpr( scalar_value<T> )
114+
{
115+
if( is_not_finite(x) ) return nan(eve::as<T>());
116+
if( x > maxflint(eve::as<T>()) ) return T(1);
117+
}
113118

114-
T z = cospi[o](x);
115-
if constexpr( scalar_value<T> ) { return (z) ? rec[pedantic](z) : nan(eve::as<T>()); }
116-
else { return if_else(is_nez(z) && is_finite(a0), rec[pedantic](z), eve::allbits); }
119+
T z = cospi[o](x);
120+
if constexpr( scalar_value<T> ) { return (z) ? rec[pedantic](z) : nan(eve::as<T>()); }
121+
else { return if_else(is_nez(z) && is_finite(a0), rec[pedantic](z), eve::allbits); }
122+
}
117123
}
118124
}
119125
}

test/unit/module/math/secd.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//==================================================================================================
1616
// Types tests
1717
//==================================================================================================
18-
TTS_CASE_TPL("Check return types of secd", eve::test::simd::ieee_reals)
18+
TTS_CASE_TPL("Check return types of secd", eve::test::simd::ieee_reals_wf16)
1919
<typename T>(tts::type<T>)
2020
{
2121
using v_t = eve::element_type_t<T>;
@@ -28,26 +28,28 @@ TTS_CASE_TPL("Check return types of secd", eve::test::simd::ieee_reals)
2828
// secd tests
2929
//==================================================================================================
3030
TTS_CASE_WITH("Check behavior of secd on wide",
31-
eve::test::simd::ieee_reals,
31+
eve::test::simd::ieee_reals_wf16,
3232
tts::generate(tts::randoms(-45, 45),
33-
tts::randoms(-90, 90),
34-
tts::randoms(-5000, 5000)))
35-
<typename T>(T const& a0, T const& a1, T const& a2)
33+
tts::randoms(-90, 90)))
34+
<typename T>(T const& a0, T const& a1)
3635
{
3736
using eve::secd;
3837

3938
using eve::deginrad;
4039
using v_t = eve::element_type_t<T>;
41-
// auto ref = [](auto e) -> v_t { return 1.0l / eve::cospi(double(e / 180.0l)); };
42-
auto ref = [](auto e) -> v_t { return 1.0 / eve::cosd(e); };
40+
auto ref = [](auto e) -> v_t {
41+
if constexpr(sizeof(v_t) == 2)
42+
return eve::convert(1 / eve::cosd(eve::convert(e, eve::as<float>())), eve::as<eve::float16_t>());
43+
else
44+
return (1 / eve::cosd(e));
45+
};
4346

4447
TTS_ULP_EQUAL(secd[eve::quarter_circle](a0), tts::map(ref, a0), 4);
4548
TTS_ULP_EQUAL(secd(a0), tts::map(ref, a0), 4);
4649
TTS_ULP_EQUAL(secd(a1), tts::map(ref, a1), 4);
47-
TTS_ULP_EQUAL(secd(a2), tts::map(ref, a2), 512);
4850
};
4951

50-
TTS_CASE_TPL("Check return types of secd", eve::test::simd::ieee_reals)
52+
TTS_CASE_TPL("Check return types of secd", eve::test::simd::ieee_reals_wf16)
5153
<typename T>(tts::type<T>)
5254
{
5355
if constexpr( eve::platform::supports_invalids )
@@ -66,7 +68,7 @@ TTS_CASE_TPL("Check return types of secd", eve::test::simd::ieee_reals)
6668
// Tests for masked secd
6769
//==================================================================================================
6870
TTS_CASE_WITH("Check behavior of eve::masked(eve::secd)(eve::wide)",
69-
eve::test::simd::ieee_reals,
71+
eve::test::simd::ieee_reals_wf16,
7072
tts::generate(tts::randoms(eve::valmin, eve::valmax),
7173
tts::logicals(0, 3)))
7274
<typename T, typename M>(T const& a0,

test/unit/module/math/sech.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//==================================================================================================
1616
// Types tests
1717
//==================================================================================================
18-
TTS_CASE_TPL("Check return types of sech", eve::test::simd::ieee_reals)
18+
TTS_CASE_TPL("Check return types of sech", eve::test::simd::ieee_reals_wf16)
1919
<typename T>(tts::type<T>)
2020
{
2121
using v_t = eve::element_type_t<T>;
@@ -36,7 +36,7 @@ auto maxi = []<typename T>(eve::as<T> const&)
3636
auto mini = []<typename T>(eve::as<T> const& tgt) { return -maxi(tgt); };
3737

3838
TTS_CASE_WITH("Check behavior of sech on wide",
39-
eve::test::simd::ieee_reals,
39+
eve::test::simd::ieee_reals_wf16,
4040
tts::generate(tts::randoms(tts::constant(mini), tts::constant(maxi)),
4141
tts::randoms(-1.0, 1.0)))
4242
<typename T>(T const& a0, T const& a1)
@@ -46,17 +46,22 @@ TTS_CASE_WITH("Check behavior of sech on wide",
4646
using eve::sech;
4747

4848
auto rel = std::is_same_v<v_t, float> ? 2e-5 : 1e-13;
49-
50-
TTS_RELATIVE_EQUAL(sech(a0), tts::map([](auto e) -> v_t { return 1 / std::cosh(e); }, a0), rel);
51-
TTS_RELATIVE_EQUAL(sech(a1), tts::map([](auto e) -> v_t { return 1 / std::cosh(e); }, a1), rel);
49+
auto ref = [](auto e) -> v_t {
50+
if constexpr(sizeof(v_t) == 2)
51+
return eve::convert(1 / std::cosh(eve::convert(e, eve::as<float>())), eve::as<eve::float16_t>());
52+
else
53+
return (1 / std::cosh(e));
54+
};
55+
TTS_RELATIVE_EQUAL(sech(a0), tts::map(ref, a0), rel);
56+
TTS_RELATIVE_EQUAL(sech(a1), tts::map(ref, a1), rel);
5257
};
5358

5459

5560
//==================================================================================================
5661
// Tests for masked sech
5762
//==================================================================================================
5863
TTS_CASE_WITH("Check behavior of eve::masked(eve::sech)(eve::wide)",
59-
eve::test::simd::ieee_reals,
64+
eve::test::simd::ieee_reals_wf16,
6065
tts::generate(tts::randoms(eve::valmin, eve::valmax),
6166
tts::logicals(0, 3)))
6267
<typename T, typename M>(T const& a0,

test/unit/module/math/secpi.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//==================================================================================================
1616
// Types tests
1717
//==================================================================================================
18-
TTS_CASE_TPL("Check return types of secpi", eve::test::simd::ieee_reals)
18+
TTS_CASE_TPL("Check return types of secpi", eve::test::simd::ieee_reals_wf16)
1919
<typename T>(tts::type<T>)
2020
{
2121
using v_t = eve::element_type_t<T>;
@@ -33,7 +33,7 @@ auto med = []<typename T>(eve::as<T> const& tgt)
3333
{ return eve::Rempio2_limit[eve::medium](tgt) * eve::inv_pi(tgt); };
3434

3535
TTS_CASE_WITH("Check behavior of secpi on wide",
36-
eve::test::simd::ieee_reals,
36+
eve::test::simd::ieee_reals_wf16,
3737
tts::generate(tts::randoms(-0.25, 0.25),
3838
tts::randoms(-0.5, 0.5),
3939
tts::randoms(tts::constant(mmed), tts::constant(med)),
@@ -45,11 +45,18 @@ TTS_CASE_WITH("Check behavior of secpi on wide",
4545
using eve::deginrad;
4646
using eve::pi;
4747
using v_t = eve::element_type_t<T>;
48+
4849
auto ref = [](auto e) -> v_t
4950
{
50-
auto c =eve::cospi(e);
51-
return c ? eve::rec(c) : eve::nan(eve::as(e));
51+
if constexpr(sizeof(v_t) == 2)
52+
return eve::convert(eve::secpi(eve::convert(e, eve::as<float>())), eve::as<eve::float16_t>());
53+
else
54+
{
55+
auto c =eve::cospi(e);
56+
return c ? eve::rec(c) : eve::nan(eve::as(e));
57+
}
5258
};
59+
5360
TTS_ULP_EQUAL(secpi[eve::quarter_circle](a0), tts::map(ref, a0), 2);
5461
TTS_ULP_EQUAL(secpi(a0), tts::map(ref, a0), 2);
5562
TTS_ULP_EQUAL(secpi(a1), tts::map(ref, a1), 2);
@@ -62,7 +69,7 @@ TTS_CASE_WITH("Check behavior of secpi on wide",
6269
// Tests for masked secpi
6370
//==================================================================================================
6471
TTS_CASE_WITH("Check behavior of eve::masked(eve::secpi)(eve::wide)",
65-
eve::test::simd::ieee_reals,
72+
eve::test::simd::ieee_reals_wf16,
6673
tts::generate(tts::randoms(eve::valmin, eve::valmax),
6774
tts::logicals(0, 3)))
6875
<typename T, typename M>(T const& a0,

0 commit comments

Comments
 (0)