commit 77fa0fbdb1acf77fbf065262bac2d652bfb1a038
parent bfd1b8cd4086e3b10cdd55185fe55e5d00774b31
Author: [email protected] <[email protected]>
Date: Mon, 29 Aug 2016 05:53:16 +0300
Refactoring: Add slice and unpack function, remove typed and skip functions and many more
Diffstat:
17 files changed, 176 insertions(+), 204 deletions(-)
diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp
@@ -73,7 +73,7 @@ CMT_INLINE auto sequence(T x, Ts... rest)
{
const T seq[] = { x, static_cast<T>(rest)... };
constexpr size_t N = arraysize(seq);
- return typed<T>(lambda([=](size_t index) { return seq[index % N]; }));
+ return lambda<T>([=](size_t index) { return seq[index % N]; });
}
template <typename T = int>
@@ -169,27 +169,24 @@ internal::expression_writer<T, E1> writer(E1&& e1)
namespace internal
{
-template <typename E1, typename = void>
-struct inherit_value_type
-{
-};
-
template <typename E1>
-struct inherit_value_type<E1, void_t<typename decay<E1>::value_type>>
+struct expression_slice : expression<E1>
{
- using value_type = typename decay<E1>::value_type;
-};
-
-template <typename E1>
-struct expression_skip : expression<E1>, inherit_value_type<E1>
-{
- expression_skip(E1&& e1, size_t count) : expression<E1>(std::forward<E1>(e1)), count(count) {}
- template <typename T, size_t N>
+ using value_type = value_type_of<E1>;
+ using T = value_type;
+ expression_slice(E1&& e1, size_t start, size_t size)
+ : expression<E1>(std::forward<E1>(e1)), start(start),
+ new_size(minsize(size, std::get<0>(this->args).size()))
+ {
+ }
+ template <size_t N>
CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- return this->argument_first(index + count, y);
+ return this->argument_first(index + start, y);
}
- size_t count;
+ size_t size() const { return new_size; }
+ size_t start;
+ size_t new_size;
};
template <typename T, bool precise = false>
@@ -210,11 +207,11 @@ struct expression_linspace<T, false> : input_expression
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N> x) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> x) const
{
- using UI = itype<U>;
- return U(start) + (enumerate(x) + cast<U>(cast<UI>(index))) * U(offset);
+ using TI = itype<T>;
+ return T(start) + (enumerate(x) + cast<T>(cast<TI>(index))) * T(offset);
}
T start;
@@ -236,11 +233,11 @@ struct expression_linspace<T, true> : input_expression
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N> x) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> x) const
{
- using UI = itype<U>;
- return mix((enumerate(x) + cast<U>(cast<UI>(index))) * invsize, cast<U>(start), cast<U>(stop));
+ using TI = itype<T>;
+ return mix((enumerate(x) + cast<T>(cast<TI>(index))) * invsize, cast<T>(start), cast<T>(stop));
}
template <typename U, size_t N>
CMT_INLINE static vec<U, N> mix(vec<U, N> t, U x, U y)
@@ -259,6 +256,9 @@ struct expression_sequence : expression<E...>
public:
using base = expression<E...>;
+ using value_type = common_type<value_type_of<E>...>;
+ using T = value_type;
+
template <typename... Expr_>
CMT_INLINE expression_sequence(const size_t (&segments)[base::size], Expr_&&... expr) noexcept
: base(std::forward<Expr_>(expr)...)
@@ -268,7 +268,7 @@ public:
this->segments[base::size + 1] = size_t(-1);
}
- template <typename T, size_t N>
+ template <size_t N>
CMT_NOINLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
std::size_t sindex = size_t(std::upper_bound(std::begin(segments), std::end(segments), index) - 1 -
@@ -290,7 +290,7 @@ public:
}
protected:
- template <typename T, size_t N>
+ template <size_t N>
CMT_NOINLINE vec<T, N> get(size_t index, size_t expr_index, vec_t<T, N> y)
{
return cswitch(indicesfor<E...>, expr_index, [&](auto val) { return this->argument(val, index, y); },
@@ -304,9 +304,11 @@ template <typename Fn, typename E>
struct expression_adjacent : expression<E>
{
using value_type = value_type_of<E>;
+ using T = value_type;
+
expression_adjacent(Fn&& fn, E&& e) : expression<E>(std::forward<E>(e)), fn(std::forward<Fn>(fn)) {}
- template <typename T, size_t N>
+ template <size_t N>
vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
const vec<T, N> in = this->argument_first(index, vec_t<T, N>());
@@ -320,9 +322,9 @@ struct expression_adjacent : expression<E>
}
template <typename E1>
-CMT_INLINE internal::expression_skip<E1> skip(E1&& e1, size_t count = 1)
+CMT_INLINE internal::expression_slice<E1> slice(E1&& e1, size_t start, size_t size = infinite_size)
{
- return internal::expression_skip<E1>(std::forward<E1>(e1), count);
+ return internal::expression_slice<E1>(std::forward<E1>(e1), start, size);
}
template <typename T1, typename T2, bool precise = false, typename TF = ftype<common_type<T1, T2>>>
diff --git a/include/kfr/base/conversion.hpp b/include/kfr/base/conversion.hpp
@@ -35,22 +35,23 @@ namespace kfr
{
namespace internal
{
-template <typename From, typename E>
+template <typename To, typename E>
struct expression_convert : expression<E>
{
+ using value_type = To;
CMT_INLINE expression_convert(E&& expr) noexcept : expression<E>(std::forward<E>(expr)) {}
- template <typename T, size_t N>
- CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
+ template <size_t N>
+ CMT_INLINE vec<To, N> operator()(cinput_t, size_t index, vec_t<To, N>) const
{
- return this->argument_first(index, vec_t<From, N>());
+ return this->argument_first(index, vec_t<To, N>());
}
};
}
-template <typename From, typename E>
-CMT_INLINE internal::expression_convert<From, decay<E>> convert(E&& expr)
+template <typename To, typename E>
+CMT_INLINE internal::expression_convert<To, E> convert(E&& expr)
{
- return internal::expression_convert<From, decay<E>>(std::forward<E>(expr));
+ return internal::expression_convert<To, E>(std::forward<E>(expr));
}
}
diff --git a/include/kfr/base/expression.hpp b/include/kfr/base/expression.hpp
@@ -187,6 +187,7 @@ struct expression_function : expression<arg<Args>...>
using value_type =
subtype<decltype(std::declval<Fn>()(std::declval<vec<value_type_of<arg<Args>>, 1>>()...))>;
+ using T = value_type;
expression_function(Fn&& fn, arg<Args>&&... args) noexcept
: expression<arg<Args>...>(std::forward<arg<Args>>(args)...),
@@ -198,11 +199,9 @@ struct expression_function : expression<arg<Args>...>
fn(fn)
{
}
- template <typename T, size_t N>
+ template <size_t N>
CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> x) const
{
- static_assert(is_same<T, value_type_of<expression_function>>::value,
- "Can't cast from value_type to T");
return this->call(fn, index, x);
}
@@ -211,17 +210,6 @@ struct expression_function : expression<arg<Args>...>
protected:
Fn fn;
};
-
-template <typename Tout, typename Tin, size_t width, typename OutFn, typename Fn>
-CMT_INLINE void process_cycle(OutFn&& outfn, const Fn& fn, size_t& i, size_t size)
-{
- const size_t count = size / width * width;
- CMT_LOOP_NOUNROLL
- for (; i < count; i += width)
- {
- outfn(coutput, i, fn(cinput, i, vec_t<Tin, width>()));
- }
-}
}
template <typename A>
@@ -261,6 +249,21 @@ CMT_INLINE internal::expression_function<Fn, NewArgs...> rebind(
return internal::expression_function<Fn, NewArgs...>(e.get_fn(), std::forward<NewArgs>(args)...);
}
+namespace internal
+{
+template <size_t width, typename OutputExpr, typename InputExpr>
+CMT_INLINE void process_cycle(OutputExpr&& outfn, const InputExpr& fn, size_t& i, size_t size)
+{
+ using Tin = value_type_of<InputExpr>;
+ const size_t count = size / width * width;
+ CMT_LOOP_NOUNROLL
+ for (; i < count; i += width)
+ {
+ outfn(coutput, i, fn(cinput, i, vec_t<Tin, width>()));
+ }
+}
+}
+
template <typename Tout, cpu_t c = cpu_t::native, size_t width = 0, typename OutputExpr, typename InputExpr>
CMT_INLINE void process(OutputExpr&& out, const InputExpr& in, size_t size)
{
@@ -271,8 +274,6 @@ CMT_INLINE void process(OutputExpr&& out, const InputExpr& in, size_t size)
out.output_begin_block(size);
in.begin_block(size);
- using Tin = value_type_of<InputExpr>;
-
#ifdef NDEBUG
constexpr size_t w = width == 0 ? internal::get_vector_width<Tout, c>(2, 4) : width;
#else
@@ -280,63 +281,13 @@ CMT_INLINE void process(OutputExpr&& out, const InputExpr& in, size_t size)
#endif
size_t i = 0;
- internal::process_cycle<Tout, Tin, w>(std::forward<OutputExpr>(out), in, i, size);
- internal::process_cycle<Tout, Tin, comp>(std::forward<OutputExpr>(out), in, i, size);
+ internal::process_cycle<w>(std::forward<OutputExpr>(out), in, i, size);
+ internal::process_cycle<comp>(std::forward<OutputExpr>(out), in, i, size);
in.end_block(size);
out.output_end_block(size);
}
-namespace internal
-{
-
-template <typename T, typename E1>
-struct expressoin_typed : input_expression
-{
- using value_type = T;
-
- expressoin_typed(E1&& e1) : e1(std::forward<E1>(e1)) {}
-
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
- {
- return e1(cinput, index, vec_t<T, N>());
- }
- E1 e1;
-};
-
-template <typename T, typename E1>
-struct expressoin_sized : input_expression
-{
- using value_type = T;
- using size_type = size_t;
-
- expressoin_sized(E1&& e1, size_t size) : e1(std::forward<E1>(e1)), m_size(size) {}
-
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
- {
- auto val = e1(cinput, index, vec_t<T, N>());
- return val;
- }
-
- constexpr size_t size() const noexcept { return m_size; }
- E1 e1;
- size_t m_size;
-};
-}
-
-template <typename T, typename E1>
-inline internal::expressoin_typed<T, E1> typed(E1&& e1)
-{
- return internal::expressoin_typed<T, E1>(std::forward<E1>(e1));
-}
-template <typename T, typename E1>
-inline internal::expressoin_sized<T, E1> typed(E1&& e1, size_t size)
-{
- return internal::expressoin_sized<T, E1>(std::forward<E1>(e1), size);
-}
-
template <typename T>
struct input_expression_base : input_expression
{
diff --git a/include/kfr/base/operators.hpp b/include/kfr/base/operators.hpp
@@ -711,14 +711,26 @@ struct expression_pack : expression<E...>, output_expression
expression_pack(E&&... e) : expression<E...>(std::forward<E>(e)...) {}
using value_type = vec<common_type<value_type_of<E>...>, count>;
+ using T = value_type;
using expression<E...>::size;
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N> x) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- return this->call(fn_packtranspose(), index, x);
+ return this->call(fn_packtranspose(), index, y);
}
+};
+
+template <typename... E>
+struct expression_unpack : private expression<E...>, output_expression
+{
+ constexpr static size_t count = sizeof...(E);
+
+ expression_unpack(E&&... e) : expression<E...>(std::forward<E>(e)...) {}
+
+ using expression<E...>::size;
+
template <typename U, size_t N>
CMT_INLINE void operator()(coutput_t, size_t index, const vec<vec<U, count>, N>& x)
{
@@ -726,8 +738,9 @@ struct expression_pack : expression<E...>, output_expression
}
template <typename Input, KFR_ENABLE_IF(is_input_expression<Input>::value)>
- CMT_INLINE expression_pack& operator=(Input&& input)
+ CMT_INLINE expression_unpack& operator=(Input&& input)
{
+ using value_type = vec<common_type<value_type_of<E>...>, count>;
process<value_type>(*this, std::forward<Input>(input), size());
return *this;
}
@@ -742,6 +755,12 @@ private:
};
}
+template <typename... E, KFR_ENABLE_IF(is_output_expressions<E...>::value)>
+internal::expression_unpack<internal::arg<E>...> unpack(E&&... e)
+{
+ return internal::expression_unpack<internal::arg<E>...>(std::forward<E>(e)...);
+}
+
template <typename... E, KFR_ENABLE_IF(is_input_expressions<E...>::value)>
internal::expression_pack<internal::arg<E>...> pack(E&&... e)
{
diff --git a/include/kfr/base/pointer.hpp b/include/kfr/base/pointer.hpp
@@ -76,8 +76,8 @@ struct expression_pointer : input_expression
: instance(instance), vtable(vtable), resource(std::move(resource))
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
using func_t = simd<T, N> (*)(void*, size_t);
@@ -85,7 +85,7 @@ struct expression_pointer : input_expression
constexpr size_t findex = ilog2(N);
static_assert(N <= maxwidth, "N is greater than maxwidth");
func_t func = reinterpret_cast<func_t>((*vtable)[2 + findex]);
- vec<U, N> result = vec<T, N>(func(instance, index));
+ vec<T, N> result = vec<T, N>(func(instance, index));
return result;
}
CMT_INLINE void begin_block(size_t size) const
diff --git a/include/kfr/base/random.hpp b/include/kfr/base/random.hpp
@@ -128,8 +128,8 @@ struct expression_random_uniform : input_expression
{
using value_type = T;
constexpr expression_random_uniform(const random_bit_generator& gen) noexcept : gen(gen) {}
- template <typename U, size_t N>
- vec<U, N> operator()(cinput_t, size_t, vec_t<U, N>) const
+ template <size_t N>
+ vec<T, N> operator()(cinput_t, size_t, vec_t<T, N>) const
{
return random_uniform<T, N>(gen);
}
@@ -146,8 +146,8 @@ struct expression_random_range : input_expression
{
}
- template <typename U, size_t N>
- vec<U, N> operator()(cinput_t, size_t, vec_t<U, N>) const
+ template <size_t N>
+ vec<T, N> operator()(cinput_t, size_t, vec_t<T, N>) const
{
return random_range<N, T>(gen, min, max);
}
diff --git a/include/kfr/base/reduce.hpp b/include/kfr/base/reduce.hpp
@@ -66,14 +66,16 @@ struct expression_reduce : output_expression
{
constexpr static size_t width = vector_width<T, cpu> * bitness_const(1, 2);
+ using value_type = T;
+
expression_reduce(ReduceFn&& reducefn, TransformFn&& transformfn, FinalFn&& finalfn)
: counter(0), reducefn(std::move(reducefn)), transformfn(std::move(transformfn)),
finalfn(std::move(finalfn)), value(resize<width>(make_vector(reducefn(initialvalue<T>{}))))
{
}
- template <typename U, size_t N>
- CMT_INLINE void operator()(coutput_t, size_t, const vec<U, N>& x) const
+ template <size_t N>
+ CMT_INLINE void operator()(coutput_t, size_t, const vec<T, N>& x) const
{
counter += N;
process(x);
@@ -110,7 +112,7 @@ template <typename ReduceFn, typename TransformFn = fn_pass_through, typename Fi
KFR_SINTRIN T reduce(E1&& e1, ReduceFn&& reducefn, TransformFn&& transformfn = fn_pass_through(),
FinalFn&& finalfn = fn_pass_through())
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
const size_t size = e1.size();
using reducer_t = expression_reduce<T, decay<ReduceFn>, decay<TransformFn>, decay<FinalFn>>;
reducer_t red(std::forward<ReduceFn>(reducefn), std::forward<TransformFn>(transformfn),
@@ -134,7 +136,7 @@ KFR_FN(reduce)
template <typename E1, typename T = value_type_of<E1>, KFR_ENABLE_IF(is_input_expression<E1>::value)>
KFR_SINTRIN T sum(E1&& x)
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::forward<E1>(x), fn_add());
}
@@ -149,7 +151,7 @@ KFR_SINTRIN T sum(E1&& x)
template <typename E1, typename T = value_type_of<E1>, KFR_ENABLE_IF(is_input_expression<E1>::value)>
KFR_SINTRIN T mean(E1&& x)
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::forward<E1>(x), fn_add(), fn_pass_through(), fn_final_mean());
}
@@ -161,7 +163,7 @@ KFR_SINTRIN T mean(E1&& x)
template <typename E1, typename T = value_type_of<E1>, KFR_ENABLE_IF(is_input_expression<E1>::value)>
KFR_SINTRIN T minof(E1&& x)
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::forward<E1>(x), fn::min());
}
@@ -173,7 +175,7 @@ KFR_SINTRIN T minof(E1&& x)
template <typename E1, typename T = value_type_of<E1>, KFR_ENABLE_IF(is_input_expression<E1>::value)>
KFR_SINTRIN T maxof(E1&& x)
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::forward<E1>(x), fn::max());
}
@@ -185,7 +187,7 @@ KFR_SINTRIN T maxof(E1&& x)
template <typename E1, typename T = value_type_of<E1>, KFR_ENABLE_IF(is_input_expression<E1>::value)>
KFR_SINTRIN T absminof(E1&& x)
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::forward<E1>(x), fn::absmin());
}
@@ -197,7 +199,7 @@ KFR_SINTRIN T absminof(E1&& x)
template <typename E1, typename T = value_type_of<E1>, KFR_ENABLE_IF(is_input_expression<E1>::value)>
KFR_SINTRIN T absmaxof(E1&& x)
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::forward<E1>(x), fn::absmax());
}
@@ -215,7 +217,7 @@ KFR_SINTRIN T dotproduct(E1&& x, E2&& y)
{
auto m = std::forward<E1>(x) * std::forward<E2>(y);
using E12 = decltype(m);
- static_assert(!is_infinite<E12>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E12>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::move(m), fn_add());
}
@@ -230,7 +232,7 @@ KFR_SINTRIN T dotproduct(E1&& x, E2&& y)
template <typename E1, typename T = value_type_of<E1>, KFR_ENABLE_IF(is_input_expression<E1>::value)>
KFR_SINTRIN T rms(E1&& x)
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::forward<E1>(x), fn_add(), fn_sqr(), fn_final_rootmean());
}
@@ -245,7 +247,7 @@ KFR_SINTRIN T rms(E1&& x)
template <typename E1, typename T = value_type_of<E1>, KFR_ENABLE_IF(is_input_expression<E1>::value)>
KFR_SINTRIN T sumsqr(E1&& x)
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::forward<E1>(x), fn_add(), fn_sqr());
}
@@ -260,7 +262,7 @@ KFR_SINTRIN T sumsqr(E1&& x)
template <typename E1, typename T = value_type_of<E1>, KFR_ENABLE_IF(is_input_expression<E1>::value)>
KFR_SINTRIN T product(E1&& x)
{
- static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use typed<T>())");
+ static_assert(!is_infinite<E1>::value, "e1 must be a sized expression (use slice())");
return internal::reduce(std::forward<E1>(x), fn_mul());
}
}
diff --git a/include/kfr/dft/conv.hpp b/include/kfr/dft/conv.hpp
@@ -55,7 +55,7 @@ KFR_INTRIN univector<T> convolve(const univector<T, Tag1>& src1, const univector
plan.execute(src2padded, src2padded, temp);
src1padded = src1padded * src2padded;
plan.execute(src1padded, src1padded, temp, true);
- return typed<T>(real(src1padded), src1.size() + src2.size() - 1) / T(size);
+ return slice(real(src1padded), 0, src1.size() + src2.size() - 1) / T(size);
}
}
#pragma clang diagnostic pop
diff --git a/include/kfr/dsp/delay.hpp b/include/kfr/dsp/delay.hpp
@@ -37,9 +37,10 @@ template <size_t delay, typename E>
struct expression_delay : expression<E>
{
using value_type = value_type_of<E>;
+ using T = value_type;
using expression<E>::expression;
- template <typename T, size_t N, KFR_ENABLE_IF(N <= delay)>
+ template <size_t N, KFR_ENABLE_IF(N <= delay)>
vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
vec<T, N> out;
@@ -49,7 +50,6 @@ struct expression_delay : expression<E>
data.ringbuf_write(cursor, in);
return out;
}
- template <typename T>
vec<T, 1> operator()(cinput_t, size_t index, vec_t<T, 1>) const
{
T out;
@@ -59,7 +59,7 @@ struct expression_delay : expression<E>
data.ringbuf_write(cursor, in);
return out;
}
- template <typename T, size_t N, KFR_ENABLE_IF(N > delay)>
+ template <size_t N, KFR_ENABLE_IF(N > delay)>
vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
vec<T, delay> out;
@@ -78,9 +78,10 @@ template <typename E>
struct expression_delay<1, E> : expression<E>
{
using value_type = value_type_of<E>;
+ using T = value_type;
using expression<E>::expression;
- template <typename T, size_t N>
+ template <size_t N>
vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
const vec<T, N> in = this->argument_first(index, vec_t<T, N>());
diff --git a/include/kfr/dsp/fir.hpp b/include/kfr/dsp/fir.hpp
@@ -54,17 +54,17 @@ struct expression_short_fir : expression<E1>
: expression<E1>(std::forward<E1>(e1)), taps(taps), delayline(0)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N> x) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> x) const
{
- vec<T, N> in = cast<T>(this->argument_first(index, x));
+ vec<T, N> in = this->argument_first(index, x);
vec<T, N> out = in * taps[0];
cfor(csize<1>, csize<tapcount>,
[&](auto I) { out = out + concat_and_slice<tapcount - 1 - I, N>(delayline, in) * taps[I]; });
delayline = concat_and_slice<N, tapcount - 1>(delayline, in);
- return cast<U>(out);
+ return out;
}
vec<T, tapcount> taps;
mutable vec<T, tapcount - 1> delayline;
@@ -77,11 +77,11 @@ struct expression_fir : expression<E1>
: expression<E1>(std::forward<E1>(e1)), taps(taps), delayline(taps.size(), T()), delayline_cursor(0)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N> x) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> x) const
{
const size_t tapcount = taps.size();
- const vec<T, N> input = cast<T>(this->argument_first(index, x));
+ const vec<T, N> input = this->argument_first(index, x);
vec<T, N> output;
size_t cursor = delayline_cursor;
@@ -93,7 +93,7 @@ struct expression_fir : expression<E1>
dotproduct(taps.slice(tapcount - cursor), delayline /*, cursor*/);
}
delayline_cursor = cursor;
- return cast<U>(output);
+ return output;
}
univector_dyn<T> taps;
mutable univector_dyn<T> delayline;
diff --git a/include/kfr/dsp/oscillators.hpp b/include/kfr/dsp/oscillators.hpp
@@ -34,15 +34,15 @@ namespace kfr
template <typename T = fbase>
auto jaehne(identity<T> magn, size_t size)
{
- return typed<T>(magn * sin(c_pi<T, 1, 2> * sqr(linspace(T(0), T(size), size, false)) / size), size);
+ return slice(magn * sin(c_pi<T, 1, 2> * sqr(linspace(T(0), T(size), size, false)) / size), 0, size);
}
template <typename T = fbase>
auto swept(identity<T> magn, size_t size)
{
- return typed<T>(
+ return slice(
magn * sin(c_pi<T, 1, 4> * sqr(sqr(linspace(T(0), T(size), size, false)) / sqr(T(size))) * T(size)),
- size);
+ 0, size);
}
template <typename T = fbase>
diff --git a/include/kfr/dsp/sample_rate_conversion.hpp b/include/kfr/dsp/sample_rate_conversion.hpp
@@ -211,13 +211,15 @@ template <typename E>
struct expression_upsample<2, E> : expression<E>
{
using expression<E>::expression;
- template <typename T, size_t N>
+ using value_type = value_type_of<E>;
+ using T = value_type;
+
+ template <size_t N>
vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
const vec<T, N / 2> x = this->argument_first(index / 2, vec_t<T, N / 2>());
return interleave(x, zerovector(x));
}
- template <typename T>
vec<T, 1> operator()(cinput_t, size_t index, vec_t<T, 1>) const
{
if (index & 1)
@@ -231,14 +233,16 @@ template <typename E>
struct expression_upsample<4, E> : expression<E>
{
using expression<E>::expression;
- template <typename T, size_t N>
+ using value_type = value_type_of<E>;
+ using T = value_type;
+
+ template <size_t N>
vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
const vec<T, N / 4> x = this->argument_first(index / 4, vec_t<T, N / 4>());
const vec<T, N / 2> xx = interleave(x, zerovector(x));
return interleave(xx, zerovector(xx));
}
- template <typename T>
vec<T, 2> operator()(cinput_t, size_t index, vec_t<T, 2>) const
{
switch (index & 3)
@@ -265,7 +269,10 @@ template <typename E, size_t offset>
struct expression_downsample<2, offset, E> : expression<E>
{
using expression<E>::expression;
- template <typename T, size_t N>
+ using value_type = value_type_of<E>;
+ using T = value_type;
+
+ template <size_t N>
vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
const vec<T, N* 2> x = this->argument_first(index * 2, vec_t<T, N * 2>());
@@ -277,7 +284,10 @@ template <typename E, size_t offset>
struct expression_downsample<4, offset, E> : expression<E>
{
using expression<E>::expression;
- template <typename T, size_t N>
+ using value_type = value_type_of<E>;
+ using T = value_type;
+
+ template <size_t N>
vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
const vec<T, N* 4> x = this->argument_first(index * 4, vec_t<T, N * 4>());
diff --git a/include/kfr/dsp/window.hpp b/include/kfr/dsp/window.hpp
@@ -124,12 +124,12 @@ struct expression_rectangular : input_expression
expression_rectangular(size_t size, T = T(), window_symmetry = window_symmetry::symmetric) : m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
- using UI = utype<U>;
- const vec<UI, N> i = enumerate(vec<UI, N>()) + cast<UI>(index);
- return select(i < cast<UI>(m_size), U(1), U(0));
+ using TI = utype<T>;
+ const vec<TI, N> i = enumerate(vec<TI, N>()) + cast<TI>(index);
+ return select(i < cast<TI>(m_size), T(1), T(0));
}
size_t size() const { return m_size; }
@@ -146,10 +146,9 @@ struct expression_triangular : input_expression
: linspace(size, symmetry), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
return 1 - abs(linspace(cinput, index, y));
}
size_t size() const { return m_size; }
@@ -168,10 +167,9 @@ struct expression_bartlett : input_expression
: linspace(size, symmetry), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
return 1 - abs(linspace(cinput, index, y));
}
size_t size() const { return m_size; }
@@ -190,10 +188,9 @@ struct expression_cosine : input_expression
: linspace(size, symmetry), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
return sin(c_pi<T> * linspace(cinput, index, y));
}
size_t size() const { return m_size; }
@@ -212,10 +209,9 @@ struct expression_hann : input_expression
: linspace(size, symmetry), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
return T(0.5) * (T(1) - cos(c_pi<T, 2> * linspace(cinput, index, y)));
}
size_t size() const { return m_size; }
@@ -234,10 +230,9 @@ struct expression_bartlett_hann : input_expression
: linspace(size, symmetry), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
const vec<T, N> xx = 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)));
}
@@ -257,10 +252,9 @@ struct expression_hamming : input_expression
: linspace(size, symmetry), alpha(alpha), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
return alpha - (1.0 - alpha) * (cos(c_pi<T, 2> * linspace(cinput, index, y)));
}
size_t size() const { return m_size; }
@@ -280,11 +274,10 @@ struct expression_bohman : input_expression
: linspace(size, symmetry), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
- const vec<U, N> n = abs(linspace(cinput, index, y));
+ const vec<T, N> n = abs(linspace(cinput, index, y));
return (T(1) - n) * cos(c_pi<T> * n) + (T(1) / c_pi<T>)*sin(c_pi<T> * n);
}
size_t size() const { return m_size; }
@@ -303,10 +296,9 @@ struct expression_blackman : input_expression
: linspace(size, symmetry), a0((1 - alpha) * 0.5), a1(0.5), a2(alpha * 0.5), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
const vec<T, N> n = linspace(cinput, index, y);
return a0 - a1 * cos(c_pi<T, 2> * n) + a2 * cos(c_pi<T, 4> * n);
}
@@ -327,12 +319,10 @@ struct expression_blackman_harris : input_expression
: linspace(size, symmetry), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
const vec<T, N> n = 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);
}
size_t size() const { return m_size; }
@@ -352,10 +342,9 @@ struct expression_kaiser : input_expression
m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
return modzerobessel(beta * sqrt(1 - sqr(linspace(cinput, index, y)))) * m;
}
size_t size() const { return m_size; }
@@ -376,10 +365,9 @@ struct expression_flattop : input_expression
: linspace(size, symmetry), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
const vec<T, N> n = linspace(cinput, index, y) * c_pi<T, 2>;
constexpr T a0 = 1;
constexpr T a1 = 1.93;
@@ -404,10 +392,9 @@ struct expression_gaussian : input_expression
: linspace(size, symmetry), alpha(alpha), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
return exp(-0.5 * sqr(alpha * linspace(cinput, index, y)));
}
@@ -427,10 +414,9 @@ struct expression_lanczos : input_expression
: linspace(size, symmetry), alpha(alpha), m_size(size)
{
}
- template <typename U, size_t N>
- CMT_INLINE vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ CMT_INLINE vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N> y) const
{
- constexpr vec_t<T, N> y{};
return sinc(linspace(cinput, index, y));
}
size_t size() const { return m_size; }
diff --git a/include/kfr/io/file.hpp b/include/kfr/io/file.hpp
@@ -83,8 +83,8 @@ template <typename T>
struct expression_file_writer : expression_file_base, output_expression
{
using expression_file_base::expression_file_base;
- template <typename U, size_t N>
- void operator()(coutput_t, size_t index, const vec<U, N>& value)
+ template <size_t N>
+ void operator()(coutput_t, size_t index, const vec<T, N>& value)
{
if (position != index)
fseeko(file, static_cast<off_t>(index * sizeof(T)), SEEK_SET);
@@ -99,8 +99,8 @@ template <typename T>
struct expression_file_reader : expression_file_base, input_expression
{
using expression_file_base::expression_file_base;
- template <typename U, size_t N>
- vec<U, N> operator()(cinput_t, size_t index, vec_t<U, N>) const
+ template <size_t N>
+ vec<T, N> operator()(cinput_t, size_t index, vec_t<T, N>) const
{
if (position != index)
fseeko(file, static_cast<off_t>(index * sizeof(T)), SEEK_SET);
diff --git a/tests/dft_test.cpp b/tests/dft_test.cpp
@@ -51,7 +51,7 @@ TEST(fft_accuracy)
const size_t size = 1 << log2size;
univector<complex<float_type>> in =
- typed<float_type>(gen_random_range(gen, -1.0, +1.0), size * 2);
+ slice(gen_random_range<float_type>(gen, -1.0, +1.0), 0, size * 2);
univector<complex<float_type>> out = in;
univector<complex<float_type>> refout = out;
const dft_plan<float_type> dft(size);
diff --git a/tests/dsp_test.cpp b/tests/dsp_test.cpp
@@ -62,7 +62,7 @@ TEST(mixdown_stereo)
const univector<double, 21> right = counter() * 2 + 100;
univector<double, 21> mid;
univector<double, 21> side;
- pack(mid, side) = mixdown_stereo(left, right, matrix_sum_diff());
+ unpack(mid, side) = mixdown_stereo(left, right, matrix_sum_diff());
CHECK(mid[0] == 100);
CHECK(side[0] == -100);
diff --git a/tests/vec_test.cpp b/tests/vec_test.cpp
@@ -281,7 +281,7 @@ TEST(test_delay)
TEST(test_adjacent)
{
- univector<int, 20> v1 = adjacent(fn_mul(), typed<int>(counter()));
+ univector<int, 20> v1 = adjacent(fn_mul(), counter());
CHECK(v1[0] == 0);
CHECK(v1[1] == 0);
CHECK(v1[2] == 2);