commit d158ef1c1736136db9f21ca4326021b8a91d0383
parent eb1e2ce68272882c1f8c8b14b6b31fc8f5501f41
Author: samuriddle@gmail.com <samuriddle@gmail.com>
Date: Sun, 31 Jul 2016 17:13:35 +0300
merge misc and base folders
Diffstat:
15 files changed, 483 insertions(+), 484 deletions(-)
diff --git a/examples/dft.cpp b/examples/dft.cpp
@@ -12,6 +12,7 @@
// print(), format()
#include <kfr/cometa/string.hpp>
+#include <kfr/base/random.hpp>
#include <kfr/dft/fft.hpp>
#include <kfr/dft/reference_dft.hpp>
#include <kfr/dsp/oscillators.hpp>
@@ -19,7 +20,6 @@
#include <kfr/expressions/basic.hpp>
#include <kfr/expressions/reduce.hpp>
#include <kfr/math.hpp>
-#include <kfr/misc/random.hpp>
using namespace kfr;
diff --git a/include/kfr/all.hpp b/include/kfr/all.hpp
@@ -27,6 +27,7 @@
#include "base/asin_acos.hpp"
#include "base/atan.hpp"
#include "base/clamp.hpp"
+#include "base/compiletime.hpp"
#include "base/complex.hpp"
#include "base/constants.hpp"
#include "base/digitreverse.hpp"
@@ -39,12 +40,15 @@
#include "base/min_max.hpp"
#include "base/modzerobessel.hpp"
#include "base/operators.hpp"
+#include "base/random.hpp"
#include "base/read_write.hpp"
#include "base/round.hpp"
#include "base/saturation.hpp"
#include "base/select.hpp"
#include "base/shuffle.hpp"
#include "base/sin_cos.hpp"
+#include "base/small_buffer.hpp"
+#include "base/sort.hpp"
#include "base/sqrt.hpp"
#include "base/tan.hpp"
#include "base/types.hpp"
@@ -59,11 +63,6 @@
#include "expressions/reduce.hpp"
#include "version.hpp"
-#include "misc/compiletime.hpp"
-#include "misc/random.hpp"
-#include "misc/small_buffer.hpp"
-#include "misc/sort.hpp"
-
#include "data/bitrev.hpp"
#include "data/sincos.hpp"
#include "dsp/biquad.hpp"
diff --git a/include/kfr/base/compiletime.hpp b/include/kfr/base/compiletime.hpp
@@ -0,0 +1,81 @@
+/**
+ * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
+ * This file is part of KFR
+ *
+ * KFR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KFR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KFR.
+ *
+ * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
+ * Buying a commercial license is mandatory as soon as you develop commercial activities without
+ * disclosing the source code of your own applications.
+ * See http://www.kfrlib.com for details.
+ */
+#pragma once
+#include "constants.hpp"
+#include "operators.hpp"
+#include "types.hpp"
+
+namespace kfr
+{
+
+namespace compiletime
+{
+
+template <typename T>
+constexpr inline T select(bool c, T x, T y)
+{
+ return c ? x : y;
+}
+template <typename T>
+constexpr inline T trunc(T x)
+{
+ return static_cast<T>(static_cast<long long>(x));
+}
+template <typename T>
+constexpr inline T abs(T x)
+{
+ return x < T() ? -x : x;
+}
+template <typename T>
+constexpr inline T mulsign(T x, T y)
+{
+ return y < T() ? -x : x;
+}
+template <typename T>
+constexpr inline T sin(T x)
+{
+ x = x - trunc(x / c_pi<T, 2>) * c_pi<T, 2>;
+ constexpr T c2 = -0.16665853559970855712890625;
+ constexpr T c4 = +8.31427983939647674560546875e-3;
+ constexpr T c6 = -1.85423981747590005397796630859375e-4;
+
+ x -= c_pi<T>;
+ T y = abs(x);
+ y = select(y > c_pi<T, 1, 2>, c_pi<T> - y, y);
+ y = mulsign(y, -x);
+
+ const T y2 = y * y;
+ T formula = c6;
+ const T y3 = y2 * y;
+ formula = fmadd(formula, y2, c4);
+ formula = fmadd(formula, y2, c2);
+ formula = formula * y3 + y;
+ return formula;
+}
+template <typename T>
+constexpr inline T cos(T x)
+{
+ return sin(x + c_pi<T, 1, 2>);
+}
+}
+}
diff --git a/include/kfr/base/random.hpp b/include/kfr/base/random.hpp
@@ -0,0 +1,180 @@
+/**
+ * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
+ * This file is part of KFR
+ *
+ * KFR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KFR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KFR.
+ *
+ * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
+ * Buying a commercial license is mandatory as soon as you develop commercial activities without
+ * disclosing the source code of your own applications.
+ * See http://www.kfrlib.com for details.
+ */
+#pragma once
+#include "function.hpp"
+#include "operators.hpp"
+#include "shuffle.hpp"
+#include "vec.hpp"
+
+namespace kfr
+{
+
+using random_state = u32x4;
+
+struct seed_from_rdtsc_t
+{
+};
+
+constexpr seed_from_rdtsc_t seed_from_rdtsc{};
+
+struct random_bit_generator
+{
+ random_bit_generator(seed_from_rdtsc_t) noexcept
+ : state(bitcast<u32>(make_vector(__builtin_readcyclecounter(),
+ (__builtin_readcyclecounter() << 11) ^ 0x710686d615e2257bull)))
+ {
+ (void)operator()();
+ }
+ constexpr random_bit_generator(u32 x0, u32 x1, u32 x2, u32 x3) noexcept : state(x0, x1, x2, x3)
+ {
+ (void)operator()();
+ }
+ constexpr random_bit_generator(u64 x0, u64 x1) noexcept : state(bitcast<u32>(make_vector(x0, x1)))
+ {
+ (void)operator()();
+ }
+
+ inline random_state operator()()
+ {
+ constexpr static random_state mul{ 214013u, 17405u, 214013u, 69069u };
+ constexpr static random_state add{ 2531011u, 10395331u, 13737667u, 1u };
+ state = bitcast<u32>(rotateright<3>(bitcast<u8>(fmadd(state, mul, add))));
+ return state;
+ }
+
+protected:
+ random_state state;
+};
+
+template <size_t N, KFR_ENABLE_IF(N <= sizeof(random_state))>
+inline vec<u8, N> random_bits(random_bit_generator& gen)
+{
+ return narrow<N>(bitcast<u8>(gen()));
+}
+template <size_t N, KFR_ENABLE_IF(N > sizeof(random_state))>
+inline vec<u8, N> random_bits(random_bit_generator& gen)
+{
+ constexpr size_t N2 = prev_poweroftwo(N - 1);
+ return concat(random_bits<N2>(gen), random_bits<N - N2>(gen));
+}
+
+template <typename T, size_t N, KFR_ENABLE_IF(std::is_integral<T>::value)>
+inline vec<T, N> random_uniform(random_bit_generator& gen)
+{
+ return bitcast<T>(random_bits<N * sizeof(T)>(gen));
+}
+
+template <typename T, size_t N, KFR_ENABLE_IF(std::is_same<T, f32>::value)>
+inline vec<f32, N> randommantissa(random_bit_generator& gen)
+{
+ return bitcast<f32>((random_uniform<u32, N>(gen) & 0x7FFFFFu) | 0x3f800000u) + 0.0f;
+}
+
+template <typename T, size_t N, KFR_ENABLE_IF(std::is_same<T, f64>::value)>
+inline vec<f64, N> randommantissa(random_bit_generator& gen)
+{
+ return bitcast<f64>((random_uniform<u64, N>(gen) & 0x000FFFFFFFFFFFFFull) | 0x3FF0000000000000ull) + 0.0;
+}
+
+template <typename T, size_t N>
+inline enable_if_f<vec<T, N>> random_uniform(random_bit_generator& gen)
+{
+ return randommantissa<T, N>(gen) - 1.f;
+}
+
+template <size_t N, typename T>
+inline enable_if_f<vec<T, N>> random_range(random_bit_generator& gen, T min, T max)
+{
+ return mix(random_uniform<T, N>(gen), min, max);
+}
+
+template <size_t N, typename T>
+inline enable_if_not_f<vec<T, N>> random_range(random_bit_generator& gen, T min, T max)
+{
+ using big_type = findinttype<sqr(std::numeric_limits<T>::min()), sqr(std::numeric_limits<T>::max())>;
+
+ vec<T, N> u = random_uniform<T, N>(gen);
+ const vec<big_type, N> tmp = cast<big_type>(u);
+ return cast<T>((tmp * (max - min) + min) >> typebits<T>::bits);
+}
+
+namespace internal
+{
+template <typename T>
+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
+ {
+ return cast<U>(random_uniform<T, N>(gen));
+ }
+ mutable random_bit_generator gen;
+};
+
+template <typename T>
+struct expression_random_range : input_expression
+{
+ using value_type = T;
+ constexpr expression_random_range(const random_bit_generator& gen, T min, T max) noexcept : gen(gen),
+ min(min),
+ max(max)
+ {
+ }
+
+ template <typename U, size_t N>
+ vec<U, N> operator()(cinput_t, size_t, vec_t<U, N>) const
+ {
+ return cast<U>(random_range<N, T>(gen, min, max));
+ }
+ mutable random_bit_generator gen;
+ const T min;
+ const T max;
+};
+}
+
+template <typename T>
+inline internal::expression_random_uniform<T> gen_random_uniform(const random_bit_generator& gen)
+{
+ return internal::expression_random_uniform<T>(gen);
+}
+
+template <typename T>
+inline internal::expression_random_range<T> gen_random_range(const random_bit_generator& gen, T min, T max)
+{
+ return internal::expression_random_range<T>(gen, min, max);
+}
+
+template <typename T>
+inline internal::expression_random_uniform<T> gen_random_uniform()
+{
+ return internal::expression_random_uniform<T>(random_bit_generator(seed_from_rdtsc));
+}
+
+template <typename T>
+inline internal::expression_random_range<T> gen_random_range(T min, T max)
+{
+ return internal::expression_random_range<T>(random_bit_generator(seed_from_rdtsc), min, max);
+}
+}
diff --git a/include/kfr/base/small_buffer.hpp b/include/kfr/base/small_buffer.hpp
@@ -0,0 +1,113 @@
+/**
+ * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
+ * This file is part of KFR
+ *
+ * KFR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KFR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KFR.
+ *
+ * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
+ * Buying a commercial license is mandatory as soon as you develop commercial activities without
+ * disclosing the source code of your own applications.
+ * See http://www.kfrlib.com for details.
+ */
+#pragma once
+
+#include "memory.hpp"
+#include <algorithm>
+#include <cstdint>
+
+namespace kfr
+{
+
+template <typename T, std::size_t Capacity = 16>
+struct small_buffer
+{
+public:
+ small_buffer() noexcept : m_size(0), m_data(m_preallocated) {}
+
+ small_buffer(std::size_t size) : small_buffer() { resize(size); }
+
+ friend void swap(small_buffer<T, Capacity>& first, small_buffer<T, Capacity>& second) noexcept
+ {
+ using std::swap;
+
+ swap(first.m_size, second.m_size);
+ swap(first.m_data, second.m_data);
+ swap(first.m_preallocated, second.m_preallocated);
+ first.m_data = first.m_size <= Capacity ? first.m_preallocated : first.m_data;
+ second.m_data = second.m_size <= Capacity ? second.m_preallocated : second.m_data;
+ }
+ small_buffer(small_buffer<T, Capacity>&& other) : small_buffer() { swap(other, *this); }
+
+ small_buffer(const small_buffer<T, Capacity>& other) : small_buffer() { assign(other); }
+ small_buffer<T, Capacity>& operator=(small_buffer<T, Capacity> other)
+ {
+ swap(other, *this);
+ return *this;
+ }
+
+ ~small_buffer() { clear(); }
+
+ void assign(const small_buffer<T, Capacity>& other)
+ {
+ resize(other.m_size);
+ std::copy_n(other.m_data, m_size, m_data);
+ }
+
+ void resize(std::size_t newsize)
+ {
+ T* m_newdata;
+ if (newsize <= Capacity)
+ {
+ m_newdata = m_preallocated;
+ }
+ else
+ {
+ m_newdata = aligned_allocate<T>(newsize);
+ }
+ std::copy_n(std::make_move_iterator(m_data), std::min(newsize, m_size), m_newdata);
+ if (m_data != m_preallocated)
+ aligned_deallocate(m_data);
+ m_data = m_newdata;
+ m_size = newsize;
+ }
+ bool empty() const { return !size(); }
+ std::size_t size() const { return m_size; }
+ const T* begin() const { return m_data; }
+ const T* end() const { return m_data + m_size; }
+ const T* cbegin() const { return m_data; }
+ const T* cend() const { return m_data + m_size; }
+ T* begin() { return m_data; }
+ T* end() { return m_data + m_size; }
+ void clear() { resize(0); }
+ const T& front() const { return m_data[0]; }
+ const T& back() const { return m_data[m_size - 1]; }
+ T& front() { return m_data[0]; }
+ T& back() { return m_data[m_size - 1]; }
+ void pop_back() { resize(m_size - 1); }
+ T* data() { return m_data; }
+ const T* data() const { return m_data; }
+ T& operator[](std::size_t i) { return m_data[i]; }
+ const T& operator[](std::size_t i) const { return m_data[i]; }
+ void push_back(const T& value)
+ {
+ resize(m_size + 1);
+ m_data[m_size - 1] = value;
+ }
+
+protected:
+ T m_preallocated[Capacity];
+ std::size_t m_size;
+ T* m_data;
+};
+}
diff --git a/include/kfr/base/sort.hpp b/include/kfr/base/sort.hpp
@@ -0,0 +1,96 @@
+/**
+ * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
+ * This file is part of KFR
+ *
+ * KFR is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KFR is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KFR.
+ *
+ * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
+ * Buying a commercial license is mandatory as soon as you develop commercial activities without
+ * disclosing the source code of your own applications.
+ * See http://www.kfrlib.com for details.
+ */
+#pragma once
+
+#include "min_max.hpp"
+#include "shuffle.hpp"
+#include "vec.hpp"
+
+namespace kfr
+{
+/**
+ * Sort the elements in the vector in ascending order
+ * @param x input vector
+ * @return sorted vector
+ * @code
+ * CHECK(sort(make_vector(1000, 1, 2, -10)) == make_vector(-10, 1, 2, 1000));
+ * @endcode
+ */
+template <typename T, size_t N>
+KFR_INLINE vec<T, N> sort(const vec<T, N>& x)
+{
+ constexpr size_t Nhalf = N / 2;
+ vec<T, Nhalf> e = low(x);
+ vec<T, Nhalf> o = high(x);
+ constexpr auto blend0 = cconcat(csizes<1>, csizeseq<Nhalf - 1, 0, 0>);
+ for (size_t i = 0; i < Nhalf; i++)
+ {
+ vec<T, Nhalf> t;
+ t = min(e, o);
+ o = max(e, o);
+ o = rotateright<1>(o);
+ e = t;
+ t = max(e, o);
+ o = min(e, o);
+ e = t;
+ t = blend(e, o, blend0);
+ o = blend(o, e, blend0);
+ o = rotateleft<1>(o);
+ e = t;
+ }
+ return interleavehalfs(concat(e, o));
+}
+
+/**
+ * Sort the elements in the vector in descending order
+ * @param x input vector
+ * @return sorted vector
+ * @code
+ * CHECK(sort(make_vector(1000, 1, 2, -10)) == make_vector(1000, 2, 1, -10));
+ * @endcode
+ */
+template <typename T, size_t N>
+KFR_INLINE vec<T, N> sortdesc(const vec<T, N>& x)
+{
+ constexpr size_t Nhalf = N / 2;
+ vec<T, Nhalf> e = low(x);
+ vec<T, Nhalf> o = high(x);
+ constexpr auto blend0 = cconcat(csizes<1>, csizeseq<Nhalf - 1, 0, 0>);
+ for (size_t i = 0; i < Nhalf; i++)
+ {
+ vec<T, Nhalf> t;
+ t = max(e, o);
+ o = min(e, o);
+ o = rotateright<1>(o);
+ e = t;
+ t = min(e, o);
+ o = max(e, o);
+ e = t;
+ t = blend(e, o, blend0);
+ o = blend(o, e, blend0);
+ o = rotateleft<1>(o);
+ e = t;
+ }
+ return interleavehalfs(concat(e, o));
+}
+}
diff --git a/include/kfr/dft/fft.hpp b/include/kfr/dft/fft.hpp
@@ -26,8 +26,8 @@
#include "../base/constants.hpp"
#include "../base/memory.hpp"
#include "../base/read_write.hpp"
+#include "../base/small_buffer.hpp"
#include "../base/vec.hpp"
-#include "../misc/small_buffer.hpp"
#include "../cometa/string.hpp"
diff --git a/include/kfr/dft/ft.hpp b/include/kfr/dft/ft.hpp
@@ -27,9 +27,9 @@
#include "../base/digitreverse.hpp"
#include "../base/read_write.hpp"
#include "../base/sin_cos.hpp"
+#include "../base/small_buffer.hpp"
#include "../base/univector.hpp"
#include "../base/vec.hpp"
-#include "../misc/small_buffer.hpp"
#include "../base/memory.hpp"
#include "../data/sincos.hpp"
diff --git a/include/kfr/dft/reference_dft.hpp b/include/kfr/dft/reference_dft.hpp
@@ -26,8 +26,8 @@
#include "../base/constants.hpp"
#include "../base/memory.hpp"
#include "../base/read_write.hpp"
+#include "../base/small_buffer.hpp"
#include "../base/vec.hpp"
-#include "../misc/small_buffer.hpp"
#include <cmath>
namespace kfr
diff --git a/include/kfr/misc/compiletime.hpp b/include/kfr/misc/compiletime.hpp
@@ -1,81 +0,0 @@
-/**
- * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
- * This file is part of KFR
- *
- * KFR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KFR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KFR.
- *
- * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
- * Buying a commercial license is mandatory as soon as you develop commercial activities without
- * disclosing the source code of your own applications.
- * See http://www.kfrlib.com for details.
- */
-#pragma once
-#include "../base/constants.hpp"
-#include "../base/operators.hpp"
-#include "../base/types.hpp"
-
-namespace kfr
-{
-
-namespace compiletime
-{
-
-template <typename T>
-constexpr inline T select(bool c, T x, T y)
-{
- return c ? x : y;
-}
-template <typename T>
-constexpr inline T trunc(T x)
-{
- return static_cast<T>(static_cast<long long>(x));
-}
-template <typename T>
-constexpr inline T abs(T x)
-{
- return x < T() ? -x : x;
-}
-template <typename T>
-constexpr inline T mulsign(T x, T y)
-{
- return y < T() ? -x : x;
-}
-template <typename T>
-constexpr inline T sin(T x)
-{
- x = x - trunc(x / c_pi<T, 2>) * c_pi<T, 2>;
- constexpr T c2 = -0.16665853559970855712890625;
- constexpr T c4 = +8.31427983939647674560546875e-3;
- constexpr T c6 = -1.85423981747590005397796630859375e-4;
-
- x -= c_pi<T>;
- T y = abs(x);
- y = select(y > c_pi<T, 1, 2>, c_pi<T> - y, y);
- y = mulsign(y, -x);
-
- const T y2 = y * y;
- T formula = c6;
- const T y3 = y2 * y;
- formula = fmadd(formula, y2, c4);
- formula = fmadd(formula, y2, c2);
- formula = formula * y3 + y;
- return formula;
-}
-template <typename T>
-constexpr inline T cos(T x)
-{
- return sin(x + c_pi<T, 1, 2>);
-}
-}
-}
diff --git a/include/kfr/misc/random.hpp b/include/kfr/misc/random.hpp
@@ -1,180 +0,0 @@
-/**
- * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
- * This file is part of KFR
- *
- * KFR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KFR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KFR.
- *
- * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
- * Buying a commercial license is mandatory as soon as you develop commercial activities without
- * disclosing the source code of your own applications.
- * See http://www.kfrlib.com for details.
- */
-#pragma once
-#include "../base/function.hpp"
-#include "../base/operators.hpp"
-#include "../base/shuffle.hpp"
-#include "../base/vec.hpp"
-
-namespace kfr
-{
-
-using random_state = u32x4;
-
-struct seed_from_rdtsc_t
-{
-};
-
-constexpr seed_from_rdtsc_t seed_from_rdtsc{};
-
-struct random_bit_generator
-{
- random_bit_generator(seed_from_rdtsc_t) noexcept
- : state(bitcast<u32>(make_vector(__builtin_readcyclecounter(),
- (__builtin_readcyclecounter() << 11) ^ 0x710686d615e2257bull)))
- {
- (void)operator()();
- }
- constexpr random_bit_generator(u32 x0, u32 x1, u32 x2, u32 x3) noexcept : state(x0, x1, x2, x3)
- {
- (void)operator()();
- }
- constexpr random_bit_generator(u64 x0, u64 x1) noexcept : state(bitcast<u32>(make_vector(x0, x1)))
- {
- (void)operator()();
- }
-
- inline random_state operator()()
- {
- constexpr static random_state mul{ 214013u, 17405u, 214013u, 69069u };
- constexpr static random_state add{ 2531011u, 10395331u, 13737667u, 1u };
- state = bitcast<u32>(rotateright<3>(bitcast<u8>(fmadd(state, mul, add))));
- return state;
- }
-
-protected:
- random_state state;
-};
-
-template <size_t N, KFR_ENABLE_IF(N <= sizeof(random_state))>
-inline vec<u8, N> random_bits(random_bit_generator& gen)
-{
- return narrow<N>(bitcast<u8>(gen()));
-}
-template <size_t N, KFR_ENABLE_IF(N > sizeof(random_state))>
-inline vec<u8, N> random_bits(random_bit_generator& gen)
-{
- constexpr size_t N2 = prev_poweroftwo(N - 1);
- return concat(random_bits<N2>(gen), random_bits<N - N2>(gen));
-}
-
-template <typename T, size_t N, KFR_ENABLE_IF(std::is_integral<T>::value)>
-inline vec<T, N> random_uniform(random_bit_generator& gen)
-{
- return bitcast<T>(random_bits<N * sizeof(T)>(gen));
-}
-
-template <typename T, size_t N, KFR_ENABLE_IF(std::is_same<T, f32>::value)>
-inline vec<f32, N> randommantissa(random_bit_generator& gen)
-{
- return bitcast<f32>((random_uniform<u32, N>(gen) & 0x7FFFFFu) | 0x3f800000u) + 0.0f;
-}
-
-template <typename T, size_t N, KFR_ENABLE_IF(std::is_same<T, f64>::value)>
-inline vec<f64, N> randommantissa(random_bit_generator& gen)
-{
- return bitcast<f64>((random_uniform<u64, N>(gen) & 0x000FFFFFFFFFFFFFull) | 0x3FF0000000000000ull) + 0.0;
-}
-
-template <typename T, size_t N>
-inline enable_if_f<vec<T, N>> random_uniform(random_bit_generator& gen)
-{
- return randommantissa<T, N>(gen) - 1.f;
-}
-
-template <size_t N, typename T>
-inline enable_if_f<vec<T, N>> random_range(random_bit_generator& gen, T min, T max)
-{
- return mix(random_uniform<T, N>(gen), min, max);
-}
-
-template <size_t N, typename T>
-inline enable_if_not_f<vec<T, N>> random_range(random_bit_generator& gen, T min, T max)
-{
- using big_type = findinttype<sqr(std::numeric_limits<T>::min()), sqr(std::numeric_limits<T>::max())>;
-
- vec<T, N> u = random_uniform<T, N>(gen);
- const vec<big_type, N> tmp = cast<big_type>(u);
- return cast<T>((tmp * (max - min) + min) >> typebits<T>::bits);
-}
-
-namespace internal
-{
-template <typename T>
-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
- {
- return cast<U>(random_uniform<T, N>(gen));
- }
- mutable random_bit_generator gen;
-};
-
-template <typename T>
-struct expression_random_range : input_expression
-{
- using value_type = T;
- constexpr expression_random_range(const random_bit_generator& gen, T min, T max) noexcept : gen(gen),
- min(min),
- max(max)
- {
- }
-
- template <typename U, size_t N>
- vec<U, N> operator()(cinput_t, size_t, vec_t<U, N>) const
- {
- return cast<U>(random_range<N, T>(gen, min, max));
- }
- mutable random_bit_generator gen;
- const T min;
- const T max;
-};
-}
-
-template <typename T>
-inline internal::expression_random_uniform<T> gen_random_uniform(const random_bit_generator& gen)
-{
- return internal::expression_random_uniform<T>(gen);
-}
-
-template <typename T>
-inline internal::expression_random_range<T> gen_random_range(const random_bit_generator& gen, T min, T max)
-{
- return internal::expression_random_range<T>(gen, min, max);
-}
-
-template <typename T>
-inline internal::expression_random_uniform<T> gen_random_uniform()
-{
- return internal::expression_random_uniform<T>(random_bit_generator(seed_from_rdtsc));
-}
-
-template <typename T>
-inline internal::expression_random_range<T> gen_random_range(T min, T max)
-{
- return internal::expression_random_range<T>(random_bit_generator(seed_from_rdtsc), min, max);
-}
-}
diff --git a/include/kfr/misc/small_buffer.hpp b/include/kfr/misc/small_buffer.hpp
@@ -1,113 +0,0 @@
-/**
- * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
- * This file is part of KFR
- *
- * KFR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KFR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KFR.
- *
- * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
- * Buying a commercial license is mandatory as soon as you develop commercial activities without
- * disclosing the source code of your own applications.
- * See http://www.kfrlib.com for details.
- */
-#pragma once
-
-#include "../base/memory.hpp"
-#include <algorithm>
-#include <cstdint>
-
-namespace kfr
-{
-
-template <typename T, std::size_t Capacity = 16>
-struct small_buffer
-{
-public:
- small_buffer() noexcept : m_size(0), m_data(m_preallocated) {}
-
- small_buffer(std::size_t size) : small_buffer() { resize(size); }
-
- friend void swap(small_buffer<T, Capacity>& first, small_buffer<T, Capacity>& second) noexcept
- {
- using std::swap;
-
- swap(first.m_size, second.m_size);
- swap(first.m_data, second.m_data);
- swap(first.m_preallocated, second.m_preallocated);
- first.m_data = first.m_size <= Capacity ? first.m_preallocated : first.m_data;
- second.m_data = second.m_size <= Capacity ? second.m_preallocated : second.m_data;
- }
- small_buffer(small_buffer<T, Capacity>&& other) : small_buffer() { swap(other, *this); }
-
- small_buffer(const small_buffer<T, Capacity>& other) : small_buffer() { assign(other); }
- small_buffer<T, Capacity>& operator=(small_buffer<T, Capacity> other)
- {
- swap(other, *this);
- return *this;
- }
-
- ~small_buffer() { clear(); }
-
- void assign(const small_buffer<T, Capacity>& other)
- {
- resize(other.m_size);
- std::copy_n(other.m_data, m_size, m_data);
- }
-
- void resize(std::size_t newsize)
- {
- T* m_newdata;
- if (newsize <= Capacity)
- {
- m_newdata = m_preallocated;
- }
- else
- {
- m_newdata = aligned_allocate<T>(newsize);
- }
- std::copy_n(std::make_move_iterator(m_data), std::min(newsize, m_size), m_newdata);
- if (m_data != m_preallocated)
- aligned_deallocate(m_data);
- m_data = m_newdata;
- m_size = newsize;
- }
- bool empty() const { return !size(); }
- std::size_t size() const { return m_size; }
- const T* begin() const { return m_data; }
- const T* end() const { return m_data + m_size; }
- const T* cbegin() const { return m_data; }
- const T* cend() const { return m_data + m_size; }
- T* begin() { return m_data; }
- T* end() { return m_data + m_size; }
- void clear() { resize(0); }
- const T& front() const { return m_data[0]; }
- const T& back() const { return m_data[m_size - 1]; }
- T& front() { return m_data[0]; }
- T& back() { return m_data[m_size - 1]; }
- void pop_back() { resize(m_size - 1); }
- T* data() { return m_data; }
- const T* data() const { return m_data; }
- T& operator[](std::size_t i) { return m_data[i]; }
- const T& operator[](std::size_t i) const { return m_data[i]; }
- void push_back(const T& value)
- {
- resize(m_size + 1);
- m_data[m_size - 1] = value;
- }
-
-protected:
- T m_preallocated[Capacity];
- std::size_t m_size;
- T* m_data;
-};
-}
diff --git a/include/kfr/misc/sort.hpp b/include/kfr/misc/sort.hpp
@@ -1,96 +0,0 @@
-/**
- * Copyright (C) 2016 D Levin (http://www.kfrlib.com)
- * This file is part of KFR
- *
- * KFR is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KFR is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KFR.
- *
- * If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
- * Buying a commercial license is mandatory as soon as you develop commercial activities without
- * disclosing the source code of your own applications.
- * See http://www.kfrlib.com for details.
- */
-#pragma once
-
-#include "../base/min_max.hpp"
-#include "../base/shuffle.hpp"
-#include "../base/vec.hpp"
-
-namespace kfr
-{
-/**
- * Sort the elements in the vector in ascending order
- * @param x input vector
- * @return sorted vector
- * @code
- * CHECK(sort(make_vector(1000, 1, 2, -10)) == make_vector(-10, 1, 2, 1000));
- * @endcode
- */
-template <typename T, size_t N>
-KFR_INLINE vec<T, N> sort(vec<T, N> x)
-{
- constexpr size_t Nhalf = N / 2;
- vec<T, Nhalf> e = low(x);
- vec<T, Nhalf> o = high(x);
- constexpr auto blend0 = cconcat(csizes<1>, csizeseq<Nhalf - 1, 0, 0>);
- for (size_t i = 0; i < Nhalf; i++)
- {
- vec<T, Nhalf> t;
- t = min(e, o);
- o = max(e, o);
- o = rotateright<1>(o);
- e = t;
- t = max(e, o);
- o = min(e, o);
- e = t;
- t = blend(e, o, blend0);
- o = blend(o, e, blend0);
- o = rotateleft<1>(o);
- e = t;
- }
- return interleavehalfs(concat(e, o));
-}
-
-/**
- * Sort the elements in the vector in descending order
- * @param x input vector
- * @return sorted vector
- * @code
- * CHECK(sort(make_vector(1000, 1, 2, -10)) == make_vector(1000, 2, 1, -10));
- * @endcode
- */
-template <typename T, size_t N>
-KFR_INLINE vec<T, N> sortdesc(vec<T, N> x)
-{
- constexpr size_t Nhalf = N / 2;
- vec<T, Nhalf> e = low(x);
- vec<T, Nhalf> o = high(x);
- constexpr auto blend0 = cconcat(csizes<1>, csizeseq<Nhalf - 1, 0, 0>);
- for (size_t i = 0; i < Nhalf; i++)
- {
- vec<T, Nhalf> t;
- t = max(e, o);
- o = min(e, o);
- o = rotateright<1>(o);
- e = t;
- t = min(e, o);
- o = max(e, o);
- e = t;
- t = blend(e, o, blend0);
- o = blend(o, e, blend0);
- o = rotateleft<1>(o);
- e = t;
- }
- return interleavehalfs(concat(e, o));
-}
-}
diff --git a/sources.cmake b/sources.cmake
@@ -82,10 +82,10 @@ set(
${PROJECT_SOURCE_DIR}/include/kfr/io/python_plot.hpp
${PROJECT_SOURCE_DIR}/include/kfr/io/tostring.hpp
${PROJECT_SOURCE_DIR}/include/kfr/math.hpp
- ${PROJECT_SOURCE_DIR}/include/kfr/misc/compiletime.hpp
- ${PROJECT_SOURCE_DIR}/include/kfr/misc/random.hpp
- ${PROJECT_SOURCE_DIR}/include/kfr/misc/small_buffer.hpp
- ${PROJECT_SOURCE_DIR}/include/kfr/misc/sort.hpp
+ ${PROJECT_SOURCE_DIR}/include/kfr/base/compiletime.hpp
+ ${PROJECT_SOURCE_DIR}/include/kfr/base/random.hpp
+ ${PROJECT_SOURCE_DIR}/include/kfr/base/small_buffer.hpp
+ ${PROJECT_SOURCE_DIR}/include/kfr/base/sort.hpp
${PROJECT_SOURCE_DIR}/include/kfr/version.hpp
${PROJECT_SOURCE_DIR}/include/kfr/base/kfr.h
${PROJECT_SOURCE_DIR}/include/kfr/base/intrinsics.h
diff --git a/tests/dft_test.cpp b/tests/dft_test.cpp
@@ -10,6 +10,7 @@
#include <tuple>
#include "testo/testo.hpp"
+#include <kfr/base/random.hpp>
#include <kfr/cometa/string.hpp>
#include <kfr/dft/fft.hpp>
#include <kfr/dft/reference_dft.hpp>
@@ -17,7 +18,6 @@
#include <kfr/expressions/reduce.hpp>
#include <kfr/io/tostring.hpp>
#include <kfr/math.hpp>
-#include <kfr/misc/random.hpp>
#include <kfr/version.hpp>
using namespace kfr;