Skip to content

Instantly share code, notes, and snippets.

@luigi-rosso
Created May 20, 2021 03:07
Show Gist options
  • Save luigi-rosso/358d068569d029d9959785c5a2b1effd to your computer and use it in GitHub Desktop.
Save luigi-rosso/358d068569d029d9959785c5a2b1effd to your computer and use it in GitHub Desktop.
#ifndef _DAISY_BISTREAM_AUTOCORRELATION_HPP_
#define _DAISY_BISTREAM_AUTOCORRELATION_HPP_
#include <cmath>
#include <cstdint>
#include <type_traits>
#include <vector>
// smallest power of 2 that fits n
template <typename T> constexpr T smallest_pow2(T n, T m = 1)
{
return (m < n) ? smallest_pow2(n, m << 1) : m;
}
std::uint32_t count_bits(std::uint32_t i)
{
// GCC only!!!
return __builtin_popcount(i);
}
std::uint64_t count_bits(std::uint64_t i)
{
// GCC only!!!
return __builtin_popcountll(i);
}
template <typename T = std::uint32_t> struct bitstream
{
static_assert(std::is_unsigned<T>::value, "T must be unsigned");
static constexpr auto nbits = 8 * sizeof(T);
bitstream(std::size_t size_)
{
size = smallest_pow2(size_);
array_size = size / nbits;
bits.resize(array_size, 0);
}
void clear() { std::fill(bits.begin(), bits.end(), 0); }
void set(std::uint32_t i, bool val)
{
auto mask = 1 << (i % nbits);
auto& ref = bits[i / nbits];
ref ^= (-T(val) ^ ref) & mask;
}
bool get(std::uint32_t i) const
{
auto mask = 1 << (i % nbits);
return (bits[i / nbits] & mask) != 0;
}
template <typename F> void auto_correlate(std::size_t start_pos, F f)
{
auto mid_array = (array_size / 2) - 1;
auto mid_pos = size / 2;
auto index = start_pos / nbits;
auto shift = start_pos % nbits;
for (auto pos = start_pos; pos != mid_pos; ++pos)
{
auto* p1 = bits.data();
auto* p2 = bits.data() + index;
auto count = 0;
if (shift == 0)
{
for (auto i = 0; i != mid_array; ++i)
count += count_bits(*p1++ ^ *p2++);
}
else
{
auto shift2 = nbits - shift;
for (auto i = 0; i != mid_array; ++i)
{
auto v = *p2++ >> shift;
v |= *p2 << shift2;
count += count_bits(*p1++ ^ v);
}
}
++shift;
if (shift == nbits)
{
shift = 0;
++index;
}
f(pos, count);
}
}
std::vector<T> bits;
std::size_t size;
std::size_t array_size;
};
struct zero_cross
{
bool operator()(float s)
{
if (s < -0.1f)
y = 0;
else if (s > 0.0f)
y = 1;
return y;
}
bool y = 0;
};
struct noise
{
float operator()() const { return (float(rand()) / (RAND_MAX / 2)) - 1.0; }
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment