kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

commit 475023fe63b61360f2f5182e2f0ce7d24389bc33
parent 63f38f6ad61921481979a09abd234c41d48ab3ee
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Wed, 13 Nov 2019 14:53:32 +0000

Format source using clang-format 9

Diffstat:
Mexamples/fir.cpp | 3++-
Minclude/kfr/base/basic_expressions.hpp | 6+++---
Minclude/kfr/base/conversion.hpp | 1-
Minclude/kfr/base/generators.hpp | 3+--
Minclude/kfr/base/pointer.hpp | 10+++++-----
Minclude/kfr/dft/impl/dft-impl.hpp | 55++++++++++++++++++++++++++++---------------------------
Minclude/kfr/dft/impl/fft-impl.hpp | 27++++++++++++++-------------
Minclude/kfr/dft/impl/ft.hpp | 19++++++++++---------
Minclude/kfr/dsp/biquad.hpp | 23++++++++++++-----------
Minclude/kfr/dsp/delay.hpp | 4++--
Minclude/kfr/dsp/units.hpp | 7+++++--
Minclude/kfr/dsp/window.hpp | 46+++++++++++++++++++++++-----------------------
Minclude/kfr/simd/impl/simd.hpp | 2+-
Minclude/kfr/simd/operators.hpp | 2+-
Minclude/kfr/simd/vec.hpp | 3++-
Minclude/kfr/testo/testo.hpp | 1-
Mtests/generate_data.cpp | 69++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mtests/unit/math/abs.cpp | 5+++--
Mtests/unit/math/min_max.cpp | 36++++++++++++++++++++----------------
Mtests/unit/math/round.cpp | 51+++++++++++++++++++++++++--------------------------
Mtests/unit/math/select.cpp | 26++++++++++++++------------
Mtests/unit/simd/operators.cpp | 133++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
22 files changed, 289 insertions(+), 243 deletions(-)

diff --git a/examples/fir.cpp b/examples/fir.cpp @@ -102,7 +102,8 @@ int main() // -------------------------------------------------------------------------------------- // Prepare 10000 samples of white noise - univector<float> noise = truncate(gen_random_range(random_bit_generator{1, 2, 3, 4}, -1.f, +1.f), 10000); + univector<float> noise = + truncate(gen_random_range(random_bit_generator{ 1, 2, 3, 4 }, -1.f, +1.f), 10000); // Apply band stop filter univector<float> filtered_noise = fir(noise, taps127); diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp @@ -370,9 +370,9 @@ protected: KFR_INTRINSIC friend vec<T, N> get_elements(const expression_sequence& self, cinput_t cinput, size_t index, size_t expr_index, vec_shape<T, N> y) { - return cswitch(indicesfor_t<E...>(), expr_index, - [&](auto val) { return self.argument(cinput, val, index, y); }, - [&]() { return zerovector(y); }); + return cswitch( + indicesfor_t<E...>(), expr_index, [&](auto val) { return self.argument(cinput, val, index, y); }, + [&]() { return zerovector(y); }); } std::array<size_t, base::count + 2> segments; diff --git a/include/kfr/base/conversion.hpp b/include/kfr/base/conversion.hpp @@ -47,7 +47,6 @@ enum class audio_sample_type first_float = f32 }; - inline constexpr size_t audio_sample_sizeof(audio_sample_type type) { switch (type) diff --git a/include/kfr/base/generators.hpp b/include/kfr/base/generators.hpp @@ -48,8 +48,7 @@ struct generator : input_expression constexpr static bool is_incremental = true; template <typename U, size_t N> - friend KFR_INTRINSIC vec<U, N> get_elements(const generator& self, cinput_t, size_t, - vec_shape<U, N> t) + friend KFR_INTRINSIC vec<U, N> get_elements(const generator& self, cinput_t, size_t, vec_shape<U, N> t) { return self.generate(t); } diff --git a/include/kfr/base/pointer.hpp b/include/kfr/base/pointer.hpp @@ -149,7 +149,7 @@ struct expression_pointer : input_expression } template <size_t N, KFR_ENABLE_IF(N <= maximum_expression_width<T>)> friend KFR_INTRINSIC vec<T, N> get_elements(const expression_pointer& self, cinput_t, size_t index, - vec_shape<T, N>) + vec_shape<T, N>) { static_assert(is_poweroftwo(N), "N must be a power of two"); vec<T, N> result; @@ -157,8 +157,8 @@ struct expression_pointer : input_expression return result; } template <size_t N, KFR_ENABLE_IF(N > maximum_expression_width<T>)> - friend KFR_INTRINSIC vec<T, N> get_elements(const expression_pointer& self, cinput_t cinput, - size_t index, vec_shape<T, N>) + friend KFR_INTRINSIC vec<T, N> get_elements(const expression_pointer& self, cinput_t cinput, size_t index, + vec_shape<T, N>) { static_assert(is_poweroftwo(N), "N must be a power of two"); const vec<T, N / 2> r1 = get_elements(self, cinput, index, vec_shape<T, N / 2>()); @@ -225,8 +225,8 @@ public: using value_type = T; expression_placeholder() CMT_NOEXCEPT = default; template <typename U, size_t N> - friend KFR_INTRINSIC vec<U, N> get_elements(const expression_placeholder& self, cinput_t, - size_t index, vec_shape<U, N>) + friend KFR_INTRINSIC vec<U, N> get_elements(const expression_placeholder& self, cinput_t, size_t index, + vec_shape<U, N>) { return self.pointer ? elemcast<U>(get_elements(self.pointer, cinput, index, vec_shape<T, N>())) : 0; } diff --git a/include/kfr/dft/impl/dft-impl.hpp b/include/kfr/dft/impl/dft-impl.hpp @@ -424,37 +424,38 @@ protected: template <bool inverse> KFR_MEM_INTRINSIC void do_execute(complex<T>* out, const complex<T>* in, u8*) { - cswitch(dft_radices, radices[0], - [&](auto first_radix) { - if (count == 3) - { - dft_permute(out, in, radices[2], radices[1], first_radix); - } - else - { - const size_t rlast = radices[count - 1]; - for (size_t p = 0; p < rlast; p++) - { - dft_permute_deep(out, in, radices, count, count - 2, 1, inner_size, first_radix); - in += size / rlast; - } - } - }, - [&]() { - if (count == 3) + cswitch( + dft_radices, radices[0], + [&](auto first_radix) { + if (count == 3) + { + dft_permute(out, in, radices[2], radices[1], first_radix); + } + else + { + const size_t rlast = radices[count - 1]; + for (size_t p = 0; p < rlast; p++) { - dft_permute(out, in, radices[2], radices[1], radices[0]); + dft_permute_deep(out, in, radices, count, count - 2, 1, inner_size, first_radix); + in += size / rlast; } - else + } + }, + [&]() { + if (count == 3) + { + dft_permute(out, in, radices[2], radices[1], radices[0]); + } + else + { + const size_t rlast = radices[count - 1]; + for (size_t p = 0; p < rlast; p++) { - const size_t rlast = radices[count - 1]; - for (size_t p = 0; p < rlast; p++) - { - dft_permute_deep(out, in, radices, count, count - 2, 1, inner_size, radices[0]); - in += size / rlast; - } + dft_permute_deep(out, in, radices, count, count - 2, 1, inner_size, radices[0]); + in += size / rlast; } - }); + } + }); } }; } // namespace intrinsics diff --git a/include/kfr/dft/impl/fft-impl.hpp b/include/kfr/dft/impl/fft-impl.hpp @@ -925,19 +925,20 @@ template <typename T> KFR_INTRINSIC void init_fft(dft_plan<T>* self, size_t size, dft_order) { const size_t log2n = ilog2(size); - cswitch(csizes_t<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>(), log2n, - [&](auto log2n) { - (void)log2n; - constexpr size_t log2nv = val_of(decltype(log2n)()); - add_stage<intrinsics::fft_specialization<T, log2nv>>(self, size); - }, - [&]() { - cswitch(cfalse_true, is_even(log2n), [&](auto is_even) { - make_fft(self, size, is_even, ctrue); - constexpr size_t is_evenv = val_of(decltype(is_even)()); - add_stage<intrinsics::fft_reorder_stage_impl<T, is_evenv>>(self, size); - }); + cswitch( + csizes_t<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>(), log2n, + [&](auto log2n) { + (void)log2n; + constexpr size_t log2nv = val_of(decltype(log2n)()); + add_stage<intrinsics::fft_specialization<T, log2nv>>(self, size); + }, + [&]() { + cswitch(cfalse_true, is_even(log2n), [&](auto is_even) { + make_fft(self, size, is_even, ctrue); + constexpr size_t is_evenv = val_of(decltype(is_even)()); + add_stage<intrinsics::fft_reorder_stage_impl<T, is_evenv>>(self, size); }); + }); } template <typename T> @@ -1089,7 +1090,7 @@ public: { using namespace intrinsics; constexpr size_t width = vector_width<T> * 2; - size_t real_size = this->stage_size; + size_t real_size = this->stage_size; complex<T>* rtwiddle = ptr_cast<complex<T>>(this->data); block_process(real_size / 4, csizes_t<width, 1>(), [=](size_t i, auto w) { constexpr size_t width = val_of(decltype(w)()); diff --git a/include/kfr/dft/impl/ft.hpp b/include/kfr/dft/impl/ft.hpp @@ -1690,15 +1690,16 @@ template <typename T, bool inverse, typename Tstride = csize_t<1>> KFR_INTRINSIC void generic_butterfly(size_t radix, cbool_t<inverse>, complex<T>* out, const complex<T>* in, complex<T>*, const complex<T>* twiddle, Tstride ostride = {}) { - cswitch(csizes_t<11, 13>(), radix, - [&](auto radix_) CMT_INLINE_LAMBDA { - constexpr size_t width = vector_width<T>; - spec_generic_butterfly_w<width>(radix_, cbool_t<inverse>(), out, in, twiddle, ostride); - }, - [&]() CMT_INLINE_LAMBDA { - constexpr size_t width = vector_width<T>; - generic_butterfly_w<width>(radix, cbool_t<inverse>(), out, in, twiddle, ostride); - }); + cswitch( + csizes_t<11, 13>(), radix, + [&](auto radix_) CMT_INLINE_LAMBDA { + constexpr size_t width = vector_width<T>; + spec_generic_butterfly_w<width>(radix_, cbool_t<inverse>(), out, in, twiddle, ostride); + }, + [&]() CMT_INLINE_LAMBDA { + constexpr size_t width = vector_width<T>; + generic_butterfly_w<width>(radix, cbool_t<inverse>(), out, in, twiddle, ostride); + }); } template <typename T, size_t N> diff --git a/include/kfr/dsp/biquad.hpp b/include/kfr/dsp/biquad.hpp @@ -152,8 +152,8 @@ struct expression_biquads_l : public expression_with_arguments<E1> { } template <size_t width> - friend KFR_INTRINSIC vec<T, width> get_elements(const expression_biquads_l& self, cinput_t cinput, size_t index, - vec_shape<T, width> t) + friend KFR_INTRINSIC vec<T, width> get_elements(const expression_biquads_l& self, cinput_t cinput, + size_t index, vec_shape<T, width> t) { const vec<T, width> in = self.argument_first(cinput, index, t); vec<T, width> out; @@ -202,8 +202,8 @@ struct expression_biquads : expression_with_arguments<E1> void end_block(cinput_t, size_t) const { state = saved_state; } template <size_t width> - friend KFR_INTRINSIC vec<T, width> get_elements(const expression_biquads& self, cinput_t cinput, size_t index, - vec_shape<T, width> t) + friend KFR_INTRINSIC vec<T, width> get_elements(const expression_biquads& self, cinput_t cinput, + size_t index, vec_shape<T, width> t) { index += filters - 1; vec<T, width> out{}; @@ -311,13 +311,14 @@ template <size_t maxfiltercount = 4, typename T, typename E1> KFR_FUNCTION expression_pointer<T> biquad(const biquad_params<T>* bq, size_t count, E1&& e1) { constexpr csizes_t<1, 2, 4, 8, 16, 32, 64> sizes; - return cswitch(cfilter(sizes, sizes <= csize_t<maxfiltercount>{}), next_poweroftwo(count), - [&](auto x) { - constexpr size_t filters = x; - return to_pointer(internal::expression_biquads<filters, T, E1>( - internal::biquad_block<T, filters>(bq, count), std::forward<E1>(e1))); - }, - [&] { return to_pointer(zeros<T>()); }); + return cswitch( + cfilter(sizes, sizes <= csize_t<maxfiltercount>{}), next_poweroftwo(count), + [&](auto x) { + constexpr size_t filters = x; + return to_pointer(internal::expression_biquads<filters, T, E1>( + internal::biquad_block<T, filters>(bq, count), std::forward<E1>(e1))); + }, + [&] { return to_pointer(zeros<T>()); }); } template <typename T, size_t maxfiltercount = 4> diff --git a/include/kfr/dsp/delay.hpp b/include/kfr/dsp/delay.hpp @@ -44,7 +44,7 @@ struct expression_delay : expression_with_arguments<E> template <size_t N, KFR_ENABLE_IF(N <= delay)> friend KFR_INTRINSIC vec<T, N> get_elements(const expression_delay& self, cinput_t cinput, size_t index, - vec_shape<T, N>) + vec_shape<T, N>) { vec<T, N> out; size_t c = self.cursor; @@ -88,7 +88,7 @@ struct expression_delay<1, E> : expression_with_arguments<E> template <size_t N> friend KFR_INTRINSIC vec<T, N> get_elements(const expression_delay& self, cinput_t cinput, size_t index, - vec_shape<T, N>) + vec_shape<T, N>) { const vec<T, N> in = self.argument_first(cinput, index, vec_shape<T, N>()); const vec<T, N> out = insertleft(self.data, in); diff --git a/include/kfr/dsp/units.hpp b/include/kfr/dsp/units.hpp @@ -48,7 +48,8 @@ KFR_INTRINSIC common_type<T1, T2> fix_nans(const T1& val, const T2& replacement) template <typename T, typename TF = flt_type<T>> KFR_INTRINSIC TF amp_to_dB(const T& amp) { - return fix_nans(log(static_cast<TF>(abs(amp))) * subtype<TF>(8.6858896380650365530225783783322), -c_infinity<T>); + return fix_nans(log(static_cast<TF>(abs(amp))) * subtype<TF>(8.6858896380650365530225783783322), + -c_infinity<T>); // return T( 20.0 ) * log10( level ); } @@ -62,7 +63,9 @@ KFR_INTRINSIC TF dB_to_amp(const T& dB) template <typename T, typename TF = flt_type<T>> KFR_INTRINSIC TF amp_to_dB(const T& amp, const T& offset) { - return fix_nans(log_fmadd(static_cast<TF>(abs(amp)), subtype<TF>(8.6858896380650365530225783783322), offset), -c_infinity<T>); + return fix_nans( + log_fmadd(static_cast<TF>(abs(amp)), subtype<TF>(8.6858896380650365530225783783322), offset), + -c_infinity<T>); // return T( 20.0 ) * log10( level ); } diff --git a/include/kfr/dsp/window.hpp b/include/kfr/dsp/window.hpp @@ -67,7 +67,7 @@ enum class window_symmetry inline namespace CMT_ARCH_NAME { - + namespace internal { @@ -128,8 +128,8 @@ struct expression_rectangular : input_expression { } template <size_t N> - KFR_INTRINSIC friend vec<T, N> get_elements(const expression_rectangular& self, cinput_t, - size_t index, vec_shape<T, N>) + KFR_INTRINSIC friend vec<T, N> get_elements(const expression_rectangular& self, cinput_t, size_t index, + vec_shape<T, N>) { using TI = utype<T>; const vec<TI, N> i = enumerate(vec_shape<TI, N>()) + static_cast<TI>(index); @@ -152,7 +152,7 @@ struct expression_triangular : input_expression } template <size_t N> KFR_INTRINSIC friend vec<T, N> get_elements(const expression_triangular& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + size_t index, vec_shape<T, N> y) { return 1 - abs(get_elements(self.linspace, cinput, index, y)); } @@ -174,7 +174,7 @@ struct expression_bartlett : input_expression } template <size_t N> KFR_INTRINSIC friend vec<T, N> get_elements(const expression_bartlett& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + size_t index, vec_shape<T, N> y) { return 1 - abs(get_elements(self.linspace, cinput, index, y)); } @@ -195,8 +195,8 @@ struct expression_cosine : input_expression { } template <size_t N> - KFR_INTRINSIC friend vec<T, N> get_elements(const expression_cosine& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + KFR_INTRINSIC friend vec<T, N> get_elements(const expression_cosine& self, cinput_t cinput, size_t index, + vec_shape<T, N> y) { return sin(c_pi<T> * get_elements(self.linspace, cinput, index, y)); } @@ -217,8 +217,8 @@ struct expression_hann : input_expression { } template <size_t N> - KFR_INTRINSIC friend vec<T, N> get_elements(const expression_hann& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + KFR_INTRINSIC friend vec<T, N> get_elements(const expression_hann& self, cinput_t cinput, size_t index, + vec_shape<T, N> y) { return T(0.5) * (T(1) - cos(c_pi<T, 2> * get_elements(self.linspace, cinput, index, y))); } @@ -240,7 +240,7 @@ struct expression_bartlett_hann : input_expression } template <size_t N> KFR_INTRINSIC friend vec<T, N> get_elements(const expression_bartlett_hann& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + size_t index, vec_shape<T, N> y) { const vec<T, N> xx = get_elements(self.linspace, cinput, index, y); return T(0.62) - T(0.48) * abs(xx - T(0.5)) + T(0.38) * cos(c_pi<T, 2> * (xx - T(0.5))); @@ -262,8 +262,8 @@ struct expression_hamming : input_expression { } template <size_t N> - KFR_INTRINSIC friend vec<T, N> get_elements(const expression_hamming& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + KFR_INTRINSIC friend vec<T, N> get_elements(const expression_hamming& self, cinput_t cinput, size_t index, + vec_shape<T, N> y) { return self.alpha - (T(1.0) - self.alpha) * (cos(c_pi<T, 2> * get_elements(self.linspace, cinput, index, y))); @@ -286,8 +286,8 @@ struct expression_bohman : input_expression { } template <size_t N> - KFR_INTRINSIC friend vec<T, N> get_elements(const expression_bohman& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + KFR_INTRINSIC friend vec<T, N> get_elements(const expression_bohman& self, cinput_t cinput, size_t index, + vec_shape<T, N> y) { const vec<T, N> n = abs(get_elements(self.linspace, cinput, index, y)); return (T(1) - n) * cos(c_pi<T> * n) + (T(1) / c_pi<T>)*sin(c_pi<T> * n); @@ -310,7 +310,7 @@ struct expression_blackman : input_expression } template <size_t N> KFR_INTRINSIC friend vec<T, N> get_elements(const expression_blackman& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + size_t index, vec_shape<T, N> y) { const vec<T, N> n = get_elements(self.linspace, cinput, index, y); return self.a0 - self.a1 * cos(c_pi<T, 2> * n) + self.a2 * cos(c_pi<T, 4> * n); @@ -334,7 +334,7 @@ struct expression_blackman_harris : input_expression } template <size_t N> KFR_INTRINSIC friend vec<T, N> get_elements(const expression_blackman_harris& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + size_t index, vec_shape<T, N> y) { const vec<T, N> n = get_elements(self.linspace, cinput, index, y) * c_pi<T, 2>; return T(0.35875) - T(0.48829) * cos(n) + T(0.14128) * cos(2 * n) - T(0.01168) * cos(3 * n); @@ -357,8 +357,8 @@ struct expression_kaiser : input_expression { } template <size_t N> - KFR_INTRINSIC friend vec<T, N> get_elements(const expression_kaiser& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + KFR_INTRINSIC friend vec<T, N> get_elements(const expression_kaiser& self, cinput_t cinput, size_t index, + vec_shape<T, N> y) { return modzerobessel(self.beta * sqrt(1 - sqr(get_elements(self.linspace, cinput, index, y)))) * self.m; @@ -382,8 +382,8 @@ struct expression_flattop : input_expression { } template <size_t N> - KFR_INTRINSIC friend vec<T, N> get_elements(const expression_flattop& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + KFR_INTRINSIC friend vec<T, N> get_elements(const expression_flattop& self, cinput_t cinput, size_t index, + vec_shape<T, N> y) { const vec<T, N> n = get_elements(self.linspace, cinput, index, y) * c_pi<T, 2>; constexpr T a0 = 0.21557895; @@ -411,7 +411,7 @@ struct expression_gaussian : input_expression } template <size_t N> KFR_INTRINSIC friend vec<T, N> get_elements(const expression_gaussian& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + size_t index, vec_shape<T, N> y) { return exp(T(-0.5) * sqr(self.alpha * get_elements(self.linspace, cinput, index, y))); } @@ -434,8 +434,8 @@ struct expression_lanczos : input_expression { } template <size_t N> - KFR_INTRINSIC friend vec<T, N> get_elements(const expression_lanczos& self, cinput_t cinput, - size_t index, vec_shape<T, N> y) + KFR_INTRINSIC friend vec<T, N> get_elements(const expression_lanczos& self, cinput_t cinput, size_t index, + vec_shape<T, N> y) { return sinc(get_elements(self.linspace, cinput, index, y)); } diff --git a/include/kfr/simd/impl/simd.hpp b/include/kfr/simd/impl/simd.hpp @@ -22,8 +22,8 @@ */ #pragma once -#include "../platform.hpp" #include "../constants.hpp" +#include "../platform.hpp" namespace kfr { diff --git a/include/kfr/simd/operators.hpp b/include/kfr/simd/operators.hpp @@ -127,7 +127,7 @@ KFR_VEC_OPERATOR2(/, /=, div) KFR_VEC_OPERATOR2(&, &=, band) KFR_VEC_OPERATOR2(|, |=, bor) -KFR_VEC_OPERATOR2 (^, ^=, bxor) +KFR_VEC_OPERATOR2(^, ^=, bxor) KFR_VEC_SHIFT_OPERATOR(<<, <<=, shl) KFR_VEC_SHIFT_OPERATOR(>>, >>=, shr) diff --git a/include/kfr/simd/vec.hpp b/include/kfr/simd/vec.hpp @@ -162,7 +162,8 @@ struct compoundcast<vec<vec<T, N1>, N2>> } // namespace internal template <typename T, size_t N> -struct alignas(force_compiletime_size_t<const_max(alignof(intrinsics::simd<typename compound_type_traits<T>::deep_subtype, +struct alignas(force_compiletime_size_t< + const_max(alignof(intrinsics::simd<typename compound_type_traits<T>::deep_subtype, N * compound_type_traits<T>::deep_width>), const_min(size_t(platform<>::native_vector_alignment), next_poweroftwo(sizeof(typename compound_type_traits<T>::deep_subtype) * diff --git a/include/kfr/testo/testo.hpp b/include/kfr/testo/testo.hpp @@ -382,7 +382,6 @@ CMT_UNUSED static int run_all(const std::string& name = std::string(), bool show return static_cast<int>(failed.size()); } - template <typename T1, typename T2> void assert_is_same() { diff --git a/tests/generate_data.cpp b/tests/generate_data.cpp @@ -86,29 +86,48 @@ int main() { using num = mpfr::number; mpfr::scoped_precision prec(512); - generate_test(cint<1>, "sin", [](const num& x) { return mpfr::sin(x); }, 0, M_PI * 2); - generate_test(cint<1>, "cos", [](const num& x) { return mpfr::cos(x); }, 0, M_PI * 2); - generate_test(cint<1>, "tan", [](const num& x) { return mpfr::tan(x); }, 0, M_PI); - - generate_test(cint<1>, "asin", [](const num& x) { return mpfr::asin(x); }, 0, 1); - generate_test(cint<1>, "acos", [](const num& x) { return mpfr::acos(x); }, 0, 1); - generate_test(cint<1>, "atan", [](const num& x) { return mpfr::atan(x); }, 0, 1); - generate_test(cint<2>, "atan2", [](const num& x, const num& y) { return mpfr::atan2(x, y); }, 0, 10); - - generate_test(cint<1>, "sinh", [](const num& x) { return mpfr::sinh(x); }, 0, 10 * 2); - generate_test(cint<1>, "cosh", [](const num& x) { return mpfr::cosh(x); }, 0, 10 * 2); - generate_test(cint<1>, "tanh", [](const num& x) { return mpfr::tanh(x); }, 0, 10 * 2); - generate_test(cint<1>, "coth", [](const num& x) { return mpfr::coth(x); }, 0, 10 * 2); - - generate_test(cint<1>, "gamma", [](const num& x) { return mpfr::gamma(x); }, 0, 10); - - generate_test(cint<1>, "log", [](const num& x) { return mpfr::log(x); }, 0, 100); - generate_test(cint<1>, "log2", [](const num& x) { return mpfr::log2(x); }, 0, 100); - generate_test(cint<1>, "log10", [](const num& x) { return mpfr::log10(x); }, 0, 100); - - generate_test(cint<1>, "exp", [](const num& x) { return mpfr::exp(x); }, -10, 10); - generate_test(cint<1>, "exp2", [](const num& x) { return mpfr::exp2(x); }, -10, 10); - generate_test(cint<1>, "exp10", [](const num& x) { return mpfr::exp10(x); }, -10, 10); - - generate_test(cint<1>, "cbrt", [](const num& x) { return mpfr::cbrt(x); }, 0, 1000); + generate_test( + cint<1>, "sin", [](const num& x) { return mpfr::sin(x); }, 0, M_PI * 2); + generate_test( + cint<1>, "cos", [](const num& x) { return mpfr::cos(x); }, 0, M_PI * 2); + generate_test( + cint<1>, "tan", [](const num& x) { return mpfr::tan(x); }, 0, M_PI); + + generate_test( + cint<1>, "asin", [](const num& x) { return mpfr::asin(x); }, 0, 1); + generate_test( + cint<1>, "acos", [](const num& x) { return mpfr::acos(x); }, 0, 1); + generate_test( + cint<1>, "atan", [](const num& x) { return mpfr::atan(x); }, 0, 1); + generate_test( + cint<2>, "atan2", [](const num& x, const num& y) { return mpfr::atan2(x, y); }, 0, 10); + + generate_test( + cint<1>, "sinh", [](const num& x) { return mpfr::sinh(x); }, 0, 10 * 2); + generate_test( + cint<1>, "cosh", [](const num& x) { return mpfr::cosh(x); }, 0, 10 * 2); + generate_test( + cint<1>, "tanh", [](const num& x) { return mpfr::tanh(x); }, 0, 10 * 2); + generate_test( + cint<1>, "coth", [](const num& x) { return mpfr::coth(x); }, 0, 10 * 2); + + generate_test( + cint<1>, "gamma", [](const num& x) { return mpfr::gamma(x); }, 0, 10); + + generate_test( + cint<1>, "log", [](const num& x) { return mpfr::log(x); }, 0, 100); + generate_test( + cint<1>, "log2", [](const num& x) { return mpfr::log2(x); }, 0, 100); + generate_test( + cint<1>, "log10", [](const num& x) { return mpfr::log10(x); }, 0, 100); + + generate_test( + cint<1>, "exp", [](const num& x) { return mpfr::exp(x); }, -10, 10); + generate_test( + cint<1>, "exp2", [](const num& x) { return mpfr::exp2(x); }, -10, 10); + generate_test( + cint<1>, "exp10", [](const num& x) { return mpfr::exp10(x); }, -10, 10); + + generate_test( + cint<1>, "cbrt", [](const num& x) { return mpfr::cbrt(x); }, 0, 1000); } diff --git a/tests/unit/math/abs.cpp b/tests/unit/math/abs.cpp @@ -12,8 +12,9 @@ inline namespace CMT_ARCH_NAME { TEST(abs) { - test_function1(test_catogories::all, [](auto x) { return kfr::abs(x); }, - [](auto x) -> decltype(x) { return x >= 0 ? x : -x; }); + test_function1( + test_catogories::all, [](auto x) { return kfr::abs(x); }, + [](auto x) -> decltype(x) { return x >= 0 ? x : -x; }); } } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/tests/unit/math/min_max.cpp b/tests/unit/math/min_max.cpp @@ -12,34 +12,38 @@ inline namespace CMT_ARCH_NAME { TEST(min) { - test_function2(test_catogories::all, [](auto x, auto y) { return kfr::min(x, y); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x <= y ? x : y; }); + test_function2( + test_catogories::all, [](auto x, auto y) { return kfr::min(x, y); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x <= y ? x : y; }); } TEST(max) { - test_function2(test_catogories::all, [](auto x, auto y) { return kfr::max(x, y); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x >= y ? x : y; }); + test_function2( + test_catogories::all, [](auto x, auto y) { return kfr::max(x, y); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x >= y ? x : y; }); } TEST(absmin) { - test_function2(test_catogories::all, [](auto x, auto y) { return kfr::absmin(x, y); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - x = x >= 0 ? x : -x; - y = y >= 0 ? y : -y; - return x <= y ? x : y; - }); + test_function2( + test_catogories::all, [](auto x, auto y) { return kfr::absmin(x, y); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + x = x >= 0 ? x : -x; + y = y >= 0 ? y : -y; + return x <= y ? x : y; + }); } TEST(absmax) { - test_function2(test_catogories::all, [](auto x, auto y) { return kfr::absmax(x, y); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - x = x >= 0 ? x : -x; - y = y >= 0 ? y : -y; - return x >= y ? x : y; - }); + test_function2( + test_catogories::all, [](auto x, auto y) { return kfr::absmax(x, y); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + x = x >= 0 ? x : -x; + y = y >= 0 ? y : -y; + return x >= y ? x : y; + }); } } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/tests/unit/math/round.cpp b/tests/unit/math/round.cpp @@ -12,48 +12,47 @@ inline namespace CMT_ARCH_NAME { TEST(floor) { - test_function1(test_catogories::all, [](auto x) { return kfr::floor(x); }, - [](auto x) -> decltype(x) { - return std::is_integral<decltype(x)>::value ? x - : static_cast<decltype(x)>(std::floor(x)); - }); + test_function1( + test_catogories::all, [](auto x) { return kfr::floor(x); }, + [](auto x) -> decltype(x) { + return std::is_integral<decltype(x)>::value ? x : static_cast<decltype(x)>(std::floor(x)); + }); } TEST(ceil) { - test_function1(test_catogories::all, [](auto x) { return kfr::ceil(x); }, - [](auto x) -> decltype(x) { - return std::is_integral<decltype(x)>::value ? x - : static_cast<decltype(x)>(std::ceil(x)); - }); + test_function1( + test_catogories::all, [](auto x) { return kfr::ceil(x); }, + [](auto x) -> decltype(x) { + return std::is_integral<decltype(x)>::value ? x : static_cast<decltype(x)>(std::ceil(x)); + }); } TEST(trunc) { - test_function1(test_catogories::all, [](auto x) { return kfr::trunc(x); }, - [](auto x) -> decltype(x) { - return std::is_integral<decltype(x)>::value ? x - : static_cast<decltype(x)>(std::trunc(x)); - }); + test_function1( + test_catogories::all, [](auto x) { return kfr::trunc(x); }, + [](auto x) -> decltype(x) { + return std::is_integral<decltype(x)>::value ? x : static_cast<decltype(x)>(std::trunc(x)); + }); } TEST(round) { - test_function1(test_catogories::all, [](auto x) { return kfr::round(x); }, - [](auto x) -> decltype(x) { - return std::is_integral<decltype(x)>::value ? x - : static_cast<decltype(x)>(std::round(x)); - }); + test_function1( + test_catogories::all, [](auto x) { return kfr::round(x); }, + [](auto x) -> decltype(x) { + return std::is_integral<decltype(x)>::value ? x : static_cast<decltype(x)>(std::round(x)); + }); } TEST(fract) { - test_function1(test_catogories::all, [](auto x) { return kfr::fract(x); }, - [](auto x) -> decltype(x) { - return std::is_integral<decltype(x)>::value - ? 0 - : static_cast<decltype(x)>(x - std::floor(x)); - }); + test_function1( + test_catogories::all, [](auto x) { return kfr::fract(x); }, + [](auto x) -> decltype(x) { + return std::is_integral<decltype(x)>::value ? 0 : static_cast<decltype(x)>(x - std::floor(x)); + }); } } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/tests/unit/math/select.cpp b/tests/unit/math/select.cpp @@ -12,22 +12,24 @@ inline namespace CMT_ARCH_NAME { TEST(select_true) { - test_function2(test_catogories::vectors, - [](auto x, auto y) { - mask<subtype<decltype(x)>, decltype(x)::scalar_size()> m(true); - return kfr::select(m, x, y); - }, - [](auto x, auto) { return x; }); + test_function2( + test_catogories::vectors, + [](auto x, auto y) { + mask<subtype<decltype(x)>, decltype(x)::scalar_size()> m(true); + return kfr::select(m, x, y); + }, + [](auto x, auto) { return x; }); } TEST(select_false) { - test_function2(test_catogories::vectors, - [](auto x, auto y) { - mask<subtype<decltype(x)>, decltype(x)::scalar_size()> m(false); - return kfr::select(m, x, y); - }, - [](auto, auto y) { return y; }); + test_function2( + test_catogories::vectors, + [](auto x, auto y) { + mask<subtype<decltype(x)>, decltype(x)::scalar_size()> m(false); + return kfr::select(m, x, y); + }, + [](auto, auto y) { return y; }); } } // namespace CMT_ARCH_NAME } // namespace kfr diff --git a/tests/unit/simd/operators.cpp b/tests/unit/simd/operators.cpp @@ -13,35 +13,40 @@ inline namespace CMT_ARCH_NAME { TEST(neg) { - test_function1(test_catogories::vectors, [](auto x) -> decltype(x) { return -x; }, - [](auto x) -> decltype(x) { return -x; }); + test_function1( + test_catogories::vectors, [](auto x) -> decltype(x) { return -x; }, + [](auto x) -> decltype(x) { return -x; }); } TEST(bnot) { - test_function1(test_catogories::vectors, [](auto x) -> decltype(x) { return ~x; }, - [](auto x) -> decltype(x) { - utype<decltype(x)> u = ~ubitcast(x); - return bitcast<decltype(x)>(u); - }); + test_function1( + test_catogories::vectors, [](auto x) -> decltype(x) { return ~x; }, + [](auto x) -> decltype(x) { + utype<decltype(x)> u = ~ubitcast(x); + return bitcast<decltype(x)>(u); + }); } TEST(add) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return x + y; }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x + y; }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return x + y; }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x + y; }); } TEST(sub) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return x - y; }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x - y; }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return x - y; }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x - y; }); } TEST(mul) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return x * y; }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x * y; }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return x * y; }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { return x * y; }); } template <typename T> @@ -52,40 +57,44 @@ inline bool is_safe_division(T x, T y) TEST(div) { - test_function2(test_catogories::vectors, - [](auto x, auto y) { - return is_safe_division<subtype<decltype(x)>>(x.front(), y.front()) ? x / y : 0; - }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - return is_safe_division(x, y) ? x / y : 0; - }); + test_function2( + test_catogories::vectors, + [](auto x, auto y) { + return is_safe_division<subtype<decltype(x)>>(x.front(), y.front()) ? x / y : 0; + }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + return is_safe_division(x, y) ? x / y : 0; + }); } TEST(bor) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return x | y; }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - using T = common_type<decltype(x), decltype(y)>; - return bitcast<T>(static_cast<utype<T>>(ubitcast(T(x)) | ubitcast(T(y)))); - }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return x | y; }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + using T = common_type<decltype(x), decltype(y)>; + return bitcast<T>(static_cast<utype<T>>(ubitcast(T(x)) | ubitcast(T(y)))); + }); } TEST(bxor) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return x ^ y; }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - using T = common_type<decltype(x), decltype(y)>; - return bitcast<T>(static_cast<utype<T>>(ubitcast(T(x)) ^ ubitcast(T(y)))); - }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return x ^ y; }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + using T = common_type<decltype(x), decltype(y)>; + return bitcast<T>(static_cast<utype<T>>(ubitcast(T(x)) ^ ubitcast(T(y)))); + }); } TEST(band) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return x & y; }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - using T = common_type<decltype(x), decltype(y)>; - return bitcast<T>(static_cast<utype<T>>(ubitcast(T(x)) & ubitcast(T(y)))); - }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return x & y; }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + using T = common_type<decltype(x), decltype(y)>; + return bitcast<T>(static_cast<utype<T>>(ubitcast(T(x)) & ubitcast(T(y)))); + }); } TEST(shl) @@ -146,50 +155,56 @@ TEST(shr) TEST(eq) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return (x == y).asvec(); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - return maskbits<subtype<decltype(x)>>(x == y); - }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return (x == y).asvec(); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + return maskbits<subtype<decltype(x)>>(x == y); + }); } TEST(ne) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return (x != y).asvec(); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - return maskbits<subtype<decltype(x)>>(x != y); - }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return (x != y).asvec(); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + return maskbits<subtype<decltype(x)>>(x != y); + }); } TEST(ge) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return (x >= y).asvec(); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - return maskbits<subtype<decltype(x)>>(x >= y); - }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return (x >= y).asvec(); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + return maskbits<subtype<decltype(x)>>(x >= y); + }); } TEST(le) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return (x <= y).asvec(); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - return maskbits<subtype<decltype(x)>>(x <= y); - }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return (x <= y).asvec(); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + return maskbits<subtype<decltype(x)>>(x <= y); + }); } TEST(gt) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return (x > y).asvec(); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - return maskbits<subtype<decltype(x)>>(x > y); - }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return (x > y).asvec(); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + return maskbits<subtype<decltype(x)>>(x > y); + }); } TEST(lt) { - test_function2(test_catogories::vectors, [](auto x, auto y) { return (x < y).asvec(); }, - [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { - return maskbits<subtype<decltype(x)>>(x < y); - }); + test_function2( + test_catogories::vectors, [](auto x, auto y) { return (x < y).asvec(); }, + [](auto x, auto y) -> common_type<decltype(x), decltype(y)> { + return maskbits<subtype<decltype(x)>>(x < y); + }); } TEST(horner)