From 17c713095bef79a0f2b2a825f7f0e918e48fb68f Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Fri, 3 Nov 2023 16:03:15 -0700 Subject: [PATCH] experiments --- bitset.cpp | 26 ++++++++++++++++ distance.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++ hamming.cpp | 39 ++++++++++++++++++++++++ hamming.py | 3 +- hamming2.py | 73 +++++++++++++++++++++++++++++++++++++++++++++ matrix.cpp | 39 ++++++++++++++++++++++++ matrix.py | 67 +++++++++++++++++++++++++++++++++++++++++ matrix2.py | 4 +++ test.cpp | 9 ++++++ 9 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 bitset.cpp create mode 100644 distance.c create mode 100644 hamming.cpp create mode 100644 hamming2.py create mode 100644 matrix.cpp create mode 100644 matrix.py create mode 100644 matrix2.py create mode 100644 test.cpp diff --git a/bitset.cpp b/bitset.cpp new file mode 100644 index 0000000..06eb26f --- /dev/null +++ b/bitset.cpp @@ -0,0 +1,26 @@ +#include +#include + + + + +static const unsigned char BitsSetTable256[256] = +{ +# define B2(n) n, n+1, n+1, n+2 +# define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2) +# define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2) + B6(0), B6(1), B6(1), B6(2) +}; + +uint32_t main(uint32_t v) +{ + unsigned int c; // c is the total bits set in v + + // Option 1: + c = BitsSetTable256[v & 0xff] + + BitsSetTable256[(v >> 8) & 0xff] + + BitsSetTable256[(v >> 16) & 0xff] + + BitsSetTable256[v >> 24]; + + return c; +} diff --git a/distance.c b/distance.c new file mode 100644 index 0000000..fc49ebe --- /dev/null +++ b/distance.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include +#include + +static inline int hamming_distance(uint32_t x, uint32_t y) +{ + uint32_t val = x ^ y; + return __builtin_popcount(val); +} + +uint32_t print_list(uint32_t * nums, int len) +{ + for (uint32_t i = 0; i < len; i++) { + printf("0x%06" PRIx32 ", ", nums[i]); + } + printf("\n"); +} + +static const int target = 14; + +bool is_prime(int num) { + if (num <= 1) return false; + if (num <= 3) return true; + + int range = sqrt(num); + // This is checked so that we can skip + // middle five numbers in below loop + if (num % 2 == 0 || num % 3 == 0) + return false; + + for (int i = 5; i <= range; i += 6) + if (num % i == 0 || num % (i + 2) == 0) + return false; + + return true; +} + +static uint32_t primes[1 << 24]; +static int primes_length = 0; + +int foo(uint32_t * nums, int len) +{ + uint32_t nums1[len + 1]; + + for (uint32_t j = 0xaaaaaa; j > 1; j--) { + if (__builtin_popcount(j) > 12 || __builtin_popcount(j) < 8) continue; + for (int i = 0; i < len; i++) { + if (hamming_distance(nums[i], j) < target) { + goto next_n; + } + } + + memcpy(nums1, nums, (sizeof (uint32_t)) * len); + nums1[len] = j; + if (len + 1 >= 6) { + print_list(&nums1[0], len + 1); + return 1; + } + + if (len < 6) { + int n = foo(&nums1[0], len + 1); + } + + next_n: + continue; + } + + return 0; +} + +int main() +{ + for (uint32_t j = 0xaaaaaa; j > 1; j--) { + if (__builtin_popcount(j) > 12 || __builtin_popcount(j) < 8) continue; + if (!is_prime(j)) continue; + primes[primes_length++] = j; + } + printf("%d\n", primes_length); + + foo(NULL, 0); +} diff --git a/hamming.cpp b/hamming.cpp new file mode 100644 index 0000000..540d3f7 --- /dev/null +++ b/hamming.cpp @@ -0,0 +1,39 @@ +#include + +template +struct hamming_code { + typedef std::bitset<(1 << bits)> value_type; + + static inline int block_length() { + return (1 << bits) - 1; + } + + static inline int message_length() { + return (1 << bits) - bits - 1; + } + + static inline bool parity(value_type b, int power) + { + T mask = 1 << power; + int sum = 0; + for (int bit_ix = 0; bit_ix < block_length(); bit_ix++) { + if (!(bit_ix & mask)) continue; + sum += b[ix]; + } + return sum & 1; + } + + static inline bool extended_parity(value_type b) + { + int sum = 0; + for (int bit_ix = 0; bit_ix < block_length(); bit_ix++) { + sum += b[ix]; + } + return sum & 1; + } + + static inline value_type encode(T t) + { + value_type ba(t); + } +} diff --git a/hamming.py b/hamming.py index ee8d976..cbffc43 100644 --- a/hamming.py +++ b/hamming.py @@ -17,7 +17,6 @@ def bit_array(b): def data_bit_pred(pn, n): return (n & (1 << (pn - 1))) != 0 - class ParityResult(Enum): zero_bit = auto() one_bit = auto() @@ -100,7 +99,7 @@ class HammingCode: for power in range(self.bits): parity_ix = 2 ** power yield self.parity(pba, power) == pba[parity_ix] - + def check_parity(self, pba): error_bits = set(self.all_data_bits()) errors = 0 diff --git a/hamming2.py b/hamming2.py new file mode 100644 index 0000000..a9617a5 --- /dev/null +++ b/hamming2.py @@ -0,0 +1,73 @@ +from itertools import takewhile + +def log2(n): + m = 0 + while True: + n >>= 1 + if not n: + break + m += 1 + return m + +def data_bits_for_power(power): + mask = 2 ** power + i = 3 + while True: + if i & mask and i != mask: + yield i + i += 1 + +def max_bit(power): + return (2 ** power) - 1 + +def max_data_bit(power): + return (2 ** power) - power - 1 + +def filter_max_bit(power, it): + return list(takewhile(lambda i: i <= max_bit(power), it)) + +def input_data_bits(max_power): + def go(): + for power in range(max_power): + yield set(map(output_index.data_bit, + filter_max_bit(max_power, data_bits_for_power(power)))) + return list(go()) + +def generator_matrix(max_power): + idb = input_data_bits(max_power) + def go(): + for d in range(max_data_bit(max_power)): + yield [ + int(d in idb[p]) + for p in range(max_power) + ] + return list(go()) + +def identity_matrix(max_power): + max_bit = max_data_bit(max_power) + def go(): + for d in range(max_bit): + l = [0] * max_bit + l[d] = 1 + yield l + return list(go()) + +def rowwise_concatenate(ma, mb): + assert len(ma) == len(mb) + def go(): + for row_ix in range(len(ma)): + yield [*ma[row_ix], *mb[row_ix]] + return list(go()) + +class input_index: + @staticmethod + def data_bit(n): + assert n > 2 + return n - log2(n) - 2 + + @staticmethod + def parity_bit(n): + assert 2 ** log2(n) == n + return log2(n) + +# list(map(input_index.data_bit, filter_max_bit(3, data_bits_for_power(0)))) diff --git a/matrix.cpp b/matrix.cpp new file mode 100644 index 0000000..4ffc2d6 --- /dev/null +++ b/matrix.cpp @@ -0,0 +1,39 @@ +#include + +template +struct mat; + +template +struct mat<4, 8, T> +{ + typedef std::array row_type; + typedef std::array row_type; + + std::array value; + + inline constexpr mat + ( + T const& a00, T const& a01, T const& a02, T const& a03, T const& a04, T const& a05, T const& a06, T const& a07, + T const& a10, T const& a11, T const& a12, T const& a13, T const& a14, T const& a15, T const& a16, T const& a17, + T const& a20, T const& a21, T const& a22, T const& a23, T const& a24, T const& a25, T const& a26, T const& a27, + T const& a30, T const& a31, T const& a32, T const& a33, T const& a34, T const& a35, T const& a36, T const& a37, + ) + : value{std::move(row_type(a00, a01, a02, a03, a04, a05, a06, a07)), + std::move(row_type(a10, a11, a12, a13, a14, a15, a16, a17)), + std::move(row_type(a20, a21, a22, a23, a24, a25, a26, a27)), + std::move(row_type(a30, a31, a32, a33, a34, a35, a36, a37))} + {} + + operator[](int i) const + { + switch (i) { + default: [[fallthrough]]; + case 0: return value[0]; + case 1: return value[1]; + case 2: return value[2]; + case 3: return value[3]; + } + } + + operator*( +} diff --git a/matrix.py b/matrix.py new file mode 100644 index 0000000..7055e86 --- /dev/null +++ b/matrix.py @@ -0,0 +1,67 @@ + + + +def cij(i, j, a, b): + assert len(a[0]) == len(b) + N = len(b) + #print("sum") + #[print(f" a[{i}][{n}] * b[{n}][{j}]") for n in range(N)] + return sum( + a[i][n] * b[n][j] + for n in range(N) + ) + +def mult(a, b): + return [ + [ + cij(i, j, a, b) + for j in range(len(b[0])) + ] + for i in range(len(a)) + ] + +genmat1 = [[1, 0, 0, 0, 1, 1, 0], + [0, 1, 0, 0, 1, 0, 1], + [0, 0, 1, 0, 0, 1, 1], + [0, 0, 0, 1, 1, 1, 1]] + +genmat = [[1, 1, 1, 0, 0, 0, 0, 1], + [1, 0, 0, 1, 1, 0, 0, 1], + [0, 1, 0, 1, 0, 1, 0, 1], + [1, 1, 0, 1, 0, 0, 1, 0]] + +a = [[1, 0, 1, 1]] + +def gendat(): + def do(i): + for bit in reversed(range(4)): + b = i >> bit & 1 + yield b + for i in range(16): + yield [list(do(i))] + +for mat in gendat(): + m2 = mult(mat, genmat1) + print(m2, end=' ') + ext = sum(m2[0]) + print(ext, ext % 2, end=' | ') + ext1 = sum(mat[0][0:3]) + print(ext1, ext1 % 2) + +# [1, 0, 1, 1, 2, 3, 2, 3] + +chkmat = [[1, 0, 1, 0, 1, 0, 1, 0], + [0, 1, 1, 0, 0, 1, 1, 0], + [0, 0, 0, 1, 1, 1, 1, 0], + [1, 1, 1, 1, 1, 1, 1, 1]] + +b = [[0], + [1], + [1], + [0], + [0], + [1], + [1], + [0]] + +#print(mult(chkmat, b)) diff --git a/matrix2.py b/matrix2.py new file mode 100644 index 0000000..c25482a --- /dev/null +++ b/matrix2.py @@ -0,0 +1,4 @@ +def data_bit_pred(pn, n): + return (n & (1 << (pn - 1))) != 0 + +def data_bits(): diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..b3a333e --- /dev/null +++ b/test.cpp @@ -0,0 +1,9 @@ +#include +#include + +int main() +{ + std::bitset<8> b(0b001); + + std::cerr << b[0] << '\n'; +}