commit c9edbe9d27d94e6def11efde4cc5c54bb7e45ff4
parent d36482b2f6389d11d5fa031d316d7b25c20e8b25
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Wed, 27 Jul 2016 20:55:27 +0300
Generators: linear/exp/exp2/sin/sincos
Diffstat:
1 file changed, 166 insertions(+), 190 deletions(-)
diff --git a/include/kfr/expressions/generators.hpp b/include/kfr/expressions/generators.hpp
@@ -28,237 +28,213 @@
#include "../base/sin_cos.hpp"
#include "../base/vec.hpp"
-#pragma clang diagnostic push
-#if CID_HAS_WARNING("-Winaccessible-base")
-#pragma clang diagnostic ignored "-Winaccessible-base"
-#endif
-
namespace kfr
{
namespace internal
{
-template <cpu_t cpu = cpu_t::native>
-struct in_generators : in_log_exp<cpu>, in_select<cpu>, in_sin_cos<cpu>
+template <typename T, size_t width_, typename Class>
+struct generator: input_expression
{
-private:
- using in_log_exp<cpu>::exp;
- using in_log_exp<cpu>::exp2;
- using in_select<cpu>::select;
- using in_sin_cos<cpu>::cossin;
-
-public:
- template <typename T, size_t width_, typename Class>
- struct generator
+ constexpr static size_t width = width_;
+ using type = T;
+
+ template <typename U, size_t N>
+ KFR_INLINE vec<U, N> operator()(cinput_t, size_t, vec_t<U, N> t) const
{
- constexpr static size_t width = width_;
- using type = T;
-
- template <typename U, size_t N>
- KFR_INLINE vec<U, N> operator()(cinput_t, size_t, vec_t<U, N> t) const
- {
- return cast<U>(generate(t));
- }
-
- void resync(T start) const { ptr_cast<Class>(this)->sync(start); }
-
- protected:
- void call_next() const { ptr_cast<Class>(this)->next(); }
- template <size_t N>
- void call_shift(csize_t<N>) const
- {
- ptr_cast<Class>(this)->shift(csize<N>);
- }
-
- template <size_t N>
- void shift(csize_t<N>) const
- {
- const vec<T, width> oldvalue = value;
- call_next();
- value = slice<N, width>(oldvalue, value);
- }
-
- template <size_t N, KFR_ENABLE_IF(N == width)>
- KFR_INLINE vec<T, N> generate(vec_t<T, N>) const
- {
- const vec<T, N> result = value;
- call_next();
- return result;
- }
-
- template <size_t N, KFR_ENABLE_IF(N < width)>
- KFR_INLINE vec<T, N> generate(vec_t<T, N>) const
- {
- const vec<T, N> result = narrow<N>(value);
- shift(csize<N>);
- return result;
- }
-
- template <size_t N, KFR_ENABLE_IF(N > width)>
- KFR_INLINE vec<T, N> generate(vec_t<T, N> x) const
- {
- const auto lo = generate(low(x));
- const auto hi = generate(high(x));
- return concat(lo, hi);
- }
-
- mutable vec<T, width> value;
- };
-
- template <typename T, size_t width = get_vector_width<T, cpu>(1, 2)>
- struct generator_linear : generator<T, width, generator_linear<T, width>>
+ return cast<U>(generate(t));
+ }
+
+ void resync(T start) const { ptr_cast<Class>(this)->sync(start); }
+
+protected:
+ void call_next() const { ptr_cast<Class>(this)->next(); }
+ template <size_t N>
+ void call_shift(csize_t<N>) const
{
- constexpr generator_linear(T start, T step) noexcept : step(step), vstep(step* width)
- {
- this->resync(start);
- }
+ ptr_cast<Class>(this)->shift(csize<N>);
+ }
- KFR_INLINE void sync(T start) const noexcept { this->value = start + enumerate<T, width>() * step; }
+ template <size_t N>
+ void shift(csize_t<N>) const
+ {
+ const vec<T, width> oldvalue = value;
+ call_next();
+ value = slice<N, width>(oldvalue, value);
+ }
- KFR_INLINE void next() const noexcept { this->value += vstep; }
+ template <size_t N, KFR_ENABLE_IF(N == width)>
+ KFR_INLINE vec<T, N> generate(vec_t<T, N>) const
+ {
+ const vec<T, N> result = value;
+ call_next();
+ return result;
+ }
- protected:
- T step;
- T vstep;
- };
+ template <size_t N, KFR_ENABLE_IF(N < width)>
+ KFR_INLINE vec<T, N> generate(vec_t<T, N>) const
+ {
+ const vec<T, N> result = narrow<N>(value);
+ shift(csize<N>);
+ return result;
+ }
- template <typename T, size_t width = get_vector_width<T, cpu>(1, 2)>
- struct generator_exp : generator<T, width, generator_exp<T, width>>
+ template <size_t N, KFR_ENABLE_IF(N > width)>
+ KFR_INLINE vec<T, N> generate(vec_t<T, N> x) const
{
- generator_exp(T start, T step) noexcept : step(step), vstep(exp(make_vector(step* width))[0] - 1)
- {
- this->resync(start);
- }
+ const auto lo = generate(low(x));
+ const auto hi = generate(high(x));
+ return concat(lo, hi);
+ }
- KFR_INLINE void sync(T start) const noexcept
- {
- this->value = exp(start + enumerate<T, width>() * step);
- }
+ mutable vec<T, width> value;
+};
- KFR_INLINE void next() const noexcept { this->value += this->value * vstep; }
+template <typename T, size_t width = get_vector_width<T, cpu_t::native>(1, 2)>
+struct generator_linear : generator<T, width, generator_linear<T, width>>
+{
+ constexpr generator_linear(T start, T step) noexcept : step(step), vstep(step* width)
+ {
+ this->resync(start);
+ }
- protected:
- T step;
- T vstep;
- };
+ KFR_INLINE void sync(T start) const noexcept { this->value = start + enumerate<T, width>() * step; }
- template <typename T, size_t width = get_vector_width<T, cpu>(1, 2)>
- struct generator_exp2 : generator<T, width, generator_exp2<T, width>>
+ KFR_INLINE void next() const noexcept { this->value += vstep; }
+
+protected:
+ T step;
+ T vstep;
+};
+
+template <typename T, size_t width = get_vector_width<T, cpu_t::native>(1, 2)>
+struct generator_exp : generator<T, width, generator_exp<T, width>>
+{
+ generator_exp(T start, T step) noexcept : step(step), vstep(exp(make_vector(step* width))[0] - 1)
{
- generator_exp2(T start, T step) noexcept : step(step), vstep(exp2(make_vector(step* width))[0] - 1)
- {
- this->resync(start);
- }
+ this->resync(start);
+ }
- KFR_INLINE void sync(T start) const noexcept
- {
- this->value = exp2(start + enumerate<T, width>() * step);
- }
+ KFR_INLINE void sync(T start) const noexcept { this->value = exp(start + enumerate<T, width>() * step); }
- KFR_INLINE void next() const noexcept { this->value += this->value * vstep; }
+ KFR_INLINE void next() const noexcept { this->value += this->value * vstep; }
- protected:
- T step;
- T vstep;
- };
+protected:
+ T step;
+ T vstep;
+};
- template <typename T, size_t width = get_vector_width<T, cpu>(1, 2)>
- struct generator_cossin : generator<T, width, generator_cossin<T, width>>
+template <typename T, size_t width = get_vector_width<T, cpu_t::native>(1, 2)>
+struct generator_exp2 : generator<T, width, generator_exp2<T, width>>
+{
+ generator_exp2(T start, T step) noexcept : step(step), vstep(exp2(make_vector(step* width))[0] - 1)
{
- generator_cossin(T start, T step)
- : step(step), alpha(2 * sqr(sin(width / 2 * step / 2))), beta(-sin(width / 2 * step))
- {
- this->resync(start);
- }
- KFR_INLINE void sync(T start) const noexcept { this->value = init_cossin(step, start); }
-
- KFR_INLINE void next() const noexcept
- {
- this->value = this->value - subadd(alpha * this->value, beta * swap<2>(this->value));
- }
-
- protected:
- T step;
- T alpha;
- T beta;
- KFR_NOINLINE static vec<T, width> init_cossin(T w, T phase)
- {
- return cossin(dup(phase + enumerate<T, width / 2>() * w));
- }
- };
-
- template <typename T, size_t width = get_vector_width<T, cpu>(2, 4)>
- struct generator_sin : generator<T, width, generator_sin<T, width>>
+ this->resync(start);
+ }
+
+ KFR_INLINE void sync(T start) const noexcept { this->value = exp2(start + enumerate<T, width>() * step); }
+
+ KFR_INLINE void next() const noexcept { this->value += this->value * vstep; }
+
+protected:
+ T step;
+ T vstep;
+};
+
+template <typename T, size_t width = get_vector_width<T, cpu_t::native>(1, 2)>
+struct generator_cossin : generator<T, width, generator_cossin<T, width>>
+{
+ generator_cossin(T start, T step)
+ : step(step), alpha(2 * sqr(sin(width / 2 * step / 2))), beta(-sin(width / 2 * step))
+ {
+ this->resync(start);
+ }
+ KFR_INLINE void sync(T start) const noexcept { this->value = init_cossin(step, start); }
+
+ KFR_INLINE void next() const noexcept
+ {
+ this->value = this->value - subadd(alpha * this->value, beta * swap<2>(this->value));
+ }
+
+protected:
+ T step;
+ T alpha;
+ T beta;
+ KFR_NOINLINE static vec<T, width> init_cossin(T w, T phase)
+ {
+ return cossin(dup(phase + enumerate<T, width / 2>() * w));
+ }
+};
+
+template <typename T, size_t width = get_vector_width<T, cpu_t::native>(2, 4)>
+struct generator_sin : generator<T, width, generator_sin<T, width>>
+{
+ generator_sin(T start, T step)
+ : step(step), alpha(2 * sqr(sin(width * step / 2))), beta(sin(width * step))
+ {
+ this->resync(start);
+ }
+ KFR_INLINE void sync(T start) const noexcept
{
- generator_sin(T start, T step)
- : step(step), alpha(2 * sqr(sin(width * step / 2))), beta(sin(width * step))
- {
- this->resync(start);
- }
- KFR_INLINE void sync(T start) const noexcept
- {
- const vec<T, width* 2> cs = splitpairs(cossin(dup(start + enumerate<T, width>() * step)));
- this->cos_value = low(cs);
- this->value = high(cs);
- }
-
- KFR_INLINE void next() const noexcept
- {
- const vec<T, width> c = this->cos_value;
- const vec<T, width> s = this->value;
-
- const vec<T, width> cc = alpha * c + beta * s;
- const vec<T, width> ss = alpha * s - beta * c;
-
- this->cos_value = c - cc;
- this->value = s - ss;
- }
-
- template <size_t N>
- void shift(csize_t<N>) const noexcept
- {
- const vec<T, width> oldvalue = this->value;
- const vec<T, width> oldcosvalue = this->cos_value;
- next();
- this->value = slice<N, width>(oldvalue, this->value);
- this->cos_value = slice<N, width>(oldcosvalue, this->cos_value);
- }
-
- protected:
- T step;
- T alpha;
- T beta;
- mutable vec<T, width> cos_value;
- };
+ const vec<T, width* 2> cs = splitpairs(cossin(dup(start + enumerate<T, width>() * step)));
+ this->cos_value = low(cs);
+ this->value = high(cs);
+ }
+
+ KFR_INLINE void next() const noexcept
+ {
+ const vec<T, width> c = this->cos_value;
+ const vec<T, width> s = this->value;
+
+ const vec<T, width> cc = alpha * c + beta * s;
+ const vec<T, width> ss = alpha * s - beta * c;
+
+ this->cos_value = c - cc;
+ this->value = s - ss;
+ }
+
+ template <size_t N>
+ void shift(csize_t<N>) const noexcept
+ {
+ const vec<T, width> oldvalue = this->value;
+ const vec<T, width> oldcosvalue = this->cos_value;
+ next();
+ this->value = slice<N, width>(oldvalue, this->value);
+ this->cos_value = slice<N, width>(oldcosvalue, this->cos_value);
+ }
+
+protected:
+ T step;
+ T alpha;
+ T beta;
+ mutable vec<T, width> cos_value;
};
}
template <typename T1, typename T2, typename TF = ftype<common_type<T1, T2>>>
-KFR_SINTRIN internal::in_generators<>::generator_linear<TF> gen_linear(T1 start, T2 step)
+KFR_SINTRIN internal::generator_linear<TF> gen_linear(T1 start, T2 step)
{
- return internal::in_generators<>::generator_linear<TF>(start, step);
+ return internal::generator_linear<TF>(start, step);
}
template <typename T1, typename T2, typename TF = ftype<common_type<T1, T2>>>
-KFR_SINTRIN internal::in_generators<>::generator_exp<TF> gen_exp(T1 start, T2 step)
+KFR_SINTRIN internal::generator_exp<TF> gen_exp(T1 start, T2 step)
{
- return internal::in_generators<>::generator_exp<TF>(start, step);
+ return internal::generator_exp<TF>(start, step);
}
template <typename T1, typename T2, typename TF = ftype<common_type<T1, T2>>>
-KFR_SINTRIN internal::in_generators<>::generator_exp2<TF> gen_exp2(T1 start, T2 step)
+KFR_SINTRIN internal::generator_exp2<TF> gen_exp2(T1 start, T2 step)
{
- return internal::in_generators<>::generator_exp2<TF>(start, step);
+ return internal::generator_exp2<TF>(start, step);
}
template <typename T1, typename T2, typename TF = ftype<common_type<T1, T2>>>
-KFR_SINTRIN internal::in_generators<>::generator_sin<TF> gen_cossin(T1 start, T2 step)
+KFR_SINTRIN internal::generator_cossin<TF> gen_cossin(T1 start, T2 step)
{
- return internal::in_generators<>::generator_cossin<TF>(start, step);
+ return internal::generator_cossin<TF>(start, step);
}
template <typename T1, typename T2, typename TF = ftype<common_type<T1, T2>>>
-KFR_SINTRIN internal::in_generators<>::generator_sin<TF> gen_sin(T1 start, T2 step)
+KFR_SINTRIN internal::generator_sin<TF> gen_sin(T1 start, T2 step)
{
- return internal::in_generators<>::generator_sin<TF>(start, step);
+ return internal::generator_sin<TF>(start, step);
}
}
-
-#pragma clang diagnostic pop