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 a92f4352d611566e7bbf3590d0768a9f444d8c14
parent 8e6230b42eff654a74c36e5b9f0013ee7e71d509
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Tue, 27 Nov 2018 18:36:00 +0000

Small fixes for kfr::complex

Diffstat:
Minclude/kfr/base/complex.hpp | 66+++++++++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 45 insertions(+), 21 deletions(-)

diff --git a/include/kfr/base/complex.hpp b/include/kfr/base/complex.hpp @@ -60,6 +60,7 @@ using complex = std::complex<T>; template <typename T> struct complex { + static_assert(is_simd_type<T>::value, "Incorrect type for complex"); constexpr static bool is_pod = true; constexpr complex() noexcept = default; constexpr complex(T re) noexcept : re(re), im(0) {} @@ -151,7 +152,7 @@ struct complex }; #endif #endif -} +} // namespace kfr namespace cometa { template <typename T> @@ -173,7 +174,7 @@ struct compound_type_traits<kfr::complex<T>> return index == 0 ? value.real() : value.imag(); } }; -} +} // namespace cometa namespace kfr { @@ -188,7 +189,7 @@ constexpr inline vec<T, 2> vcomplex(const complex<T>& v) { return vec<T, 2>(v.real(), v.imag()); } -} +} // namespace internal template <typename T, size_t N> struct vec<complex<T>, N> : private vec<T, 2 * N> @@ -206,7 +207,7 @@ struct vec<complex<T>, N> : private vec<T, 2 * N> constexpr vec() noexcept = default; constexpr vec(const vec&) noexcept = default; CMT_GNU_CONSTEXPR vec& operator=(const vec&) CMT_GNU_NOEXCEPT = default; - template <int = 0> + template <int = 0> constexpr vec(const simd_type& simd) noexcept : base(simd) { } @@ -285,13 +286,13 @@ struct vec<complex<T>, N> : private vec<T, 2 * N> KFR_I_CE friend vec& operator++(vec& x) noexcept { return x = x + vec(1); } KFR_I_CE friend vec& operator--(vec& x) noexcept { return x = x - vec(1); } - KFR_I_CE friend vec operator++(vec& x, int)noexcept + KFR_I_CE friend vec operator++(vec& x, int) noexcept { const vec z = x; ++x; return z; } - KFR_I_CE friend vec operator--(vec& x, int)noexcept + KFR_I_CE friend vec operator--(vec& x, int) noexcept { const vec z = x; --x; @@ -332,10 +333,9 @@ struct vec<complex<T>, N> : private vec<T, 2 * N> KFR_I_CE void set(csize_t<index>, const value_type& s) noexcept { *this = vec(static_cast<const base&>(*this)) - .shuffle(s, csizeseq_t<N>() + - (csizeseq_t<N>() >= csize_t<index * 2>() && - csizeseq_t<N>() < csize_t<(index + 1) * 2>()) * - N); + .shuffle(s, csizeseq_t<N>() + (csizeseq_t<N>() >= csize_t<index * 2>() && + csizeseq_t<N>() < csize_t<(index + 1) * 2>()) * + N); } struct element { @@ -345,6 +345,19 @@ struct vec<complex<T>, N> : private vec<T, 2 * N> v.set(index, s); return *this; } + + element& operator=(const element& s) noexcept + { + v.set(index, static_cast<value_type>(s)); + return *this; + } + template <typename U, size_t M> + element& operator=(const typename vec<U, M>::element& s) noexcept + { + v.set(index, static_cast<value_type>(static_cast<U>(s))); + return *this; + } + vec& v; size_t index; }; @@ -400,12 +413,6 @@ CMT_INLINE vec<complex<T>, N> cnegimag(const vec<complex<T>, N>& x) } KFR_FN(cnegimag) -template <typename T, size_t N> -CMT_INLINE vec<complex<T>, N> cconj(const vec<complex<T>, N>& x) -{ - return cnegimag(x); -} -KFR_FN(cconj) namespace internal { @@ -442,7 +449,8 @@ struct conversion<vec<complex<To>, N>, vec<From, N>> return *interleave(casted, zerovector(casted)); } }; -} + +} // namespace internal template <typename T, size_t N> constexpr CMT_INLINE vec<complex<T>, N / 2> ccomp(const vec<T, N>& x) @@ -515,7 +523,11 @@ constexpr CMT_INLINE complex<T> make_complex(T1 real, T2 imag = T2(0)) namespace intrinsics { - +template <typename T, size_t N> +CMT_INLINE vec<complex<T>, N> cconj(const vec<complex<T>, N>& x) +{ + return cnegimag(x); +} template <typename T, size_t N> KFR_SINTRIN vec<complex<T>, N> csin(const vec<complex<T>, N>& x) { @@ -607,6 +619,7 @@ KFR_SINTRIN vec<complex<T>, N> csqrt(const vec<complex<T>, N>& x) return ccomp(select(dupodd(x) < T(), cdecom(cnegimag(ccomp(t))), t)); } +KFR_I_CONVERTER(cconj) KFR_I_CONVERTER(csin) KFR_I_CONVERTER(csinh) KFR_I_CONVERTER(ccos) @@ -643,8 +656,9 @@ KFR_SINTRIN realtype<T1> carg(const T1& a) using vecout = vec1<T1>; return to_scalar(intrinsics::carg(vecout(a))); } -} +} // namespace intrinsics +KFR_I_FN(cconj) KFR_I_FN(csin) KFR_I_FN(csinh) KFR_I_FN(ccos) @@ -722,6 +736,16 @@ KFR_FUNC internal::expression_function<fn::carg, E1> carg(E1&& x) return { fn::carg(), std::forward<E1>(x) }; } template <typename T1, KFR_ENABLE_IF(is_numeric<T1>::value)> +KFR_FUNC T1 cconj(const T1& x) +{ + return intrinsics::cconj(x); +} +template <typename E1, KFR_ENABLE_IF(is_input_expression<E1>::value)> +KFR_FUNC internal::expression_function<fn::cconj, E1> cconj(E1&& x) +{ + return { fn::cconj(), std::forward<E1>(x) }; +} +template <typename T1, KFR_ENABLE_IF(is_numeric<T1>::value)> KFR_FUNC T1 clog(const T1& x) { return intrinsics::clog(x); @@ -811,7 +835,7 @@ KFR_FUNC internal::expression_function<fn::csqrt, E1> csqrt(E1&& x) { return { fn::csqrt(), std::forward<E1>(x) }; } -} +} // namespace kfr namespace std { @@ -850,6 +874,6 @@ struct common_type<kfr::vec<T1, N>, kfr::complex<T2>> { using type = kfr::vec<kfr::complex<typename common_type<T1, T2>::type>, N>; }; -} +} // namespace std CMT_PRAGMA_MSVC(warning(pop))