def __init__(self, n, t, prim_choice=0, ref=None): """ Построение БЧХ кода с параметрами n, t prim_choice - задаёт, который из возможных неприводимых многочленов (отсортированных по двоичной записи) выбрать для поля GF. В качестве ref можно задать уже построенный объект BCH с теми же n и prim_choice, но меньшим t, чтобы облегчить построение данного BCH (если эти условия не выполняются, ref игнорируется) """ if '0' in bin(n)[2:]: raise ValueError("invalid n") self.n = n if 2 * t + 1 > n: raise ValueError("too big t") self.t = t self.prim_choice = prim_choice if ref is None or (ref.n, ref.prim_choice) != ( self.n, self.prim_choice) or self.t < ref.t: primpolys = sorted( list(filter(lambda x: n + 1 < x <= n * 2 + 1, primpoly_list))) primpoly = primpolys[self.prim_choice] self.pm = gf.gen_pow_matrix(primpoly) self.R = self.pm[:2 * self.t, 1] self.g, self.g_roots = gf.minpoly(self.R, self.pm) else: self.pm = ref.pm self.R = self.pm[:2 * self.t, 1] if self.t > ref.t: new_roots = set(self.R) - set(ref.g_roots) if new_roots: g_rem, new_g_roots = gf.minpoly(_np.array(list(new_roots)), pm=self.pm) self.g = gf.binpolyprod(ref.g, g_rem) self.g_roots = _np.array( sorted(list(set(ref.g_roots) | set(new_g_roots)))) else: self.g = ref.g self.g_roots = ref.g_roots else: # self.t == ref.t self.g = ref.g self.g_roots = ref.g_roots # поделим x^n - 1 на g(x) binome = _np.pad(_np.zeros(n - 1, dtype=int), 1, mode="constant", constant_values=1) _, r = gf.binpolydiv(binome, self.g) if not gf.isnull(r): raise Exception("programmer error") self.m = gf.polydeg(self.g) self.k = self.n - self.m self.dist_ = None
def __init__(self, n, t): self.n = n self.t = t q = -1 n_copy = n + 1 while n_copy: n_copy = n_copy // 2 q += 1 if 2**q - 1 != n: raise ValueError('n is not 2^{q} - 1') with open('primpoly.txt', 'r') as file: primpoly_list = file.read().split(', ') for primpoly in primpoly_list: if int(primpoly) // 2**(q): # if degree == q break primpoly = int(primpoly) self.pm = gf.gen_pow_matrix(primpoly) alpha = np.array([2], np.int) curr_poly = alpha degrees_list = [alpha[0]] for i in range(2 * t - 1): curr_poly = gf.prod(curr_poly, alpha, self.pm) degrees_list.append(curr_poly[0]) self.g, self.R = gf.minpoly(np.array(degrees_list), self.pm) self.deg_g = self.g.shape[0] - 1
def speed(): all_polynoms = numpy.loadtxt('primpoly.txt', dtype=int, delimiter=',') for n in [7, 15, 31, 63]: for poly in all_polynoms: poly = int(poly) cur_poly_pow = poly.bit_length() - 1 if 2**cur_poly_pow - 1 == n: polynom = poly break pm = gf.gen_pow_matrix(polynom) roots = list() alpha = 2 cur = 2 r = numpy.zeros((n - 1) >> 1) all_t_for_n = [t for t in range(1, ((n - 1) >> 1) + 1)] for t in all_t_for_n: roots = [] for j in range(2 * t): roots.append(cur) cur = gf.prod_zero_dim(cur, alpha, pm) cur = 2 g = gf.minpoly(numpy.array(roots), pm)[0] k = n - (g.shape[0] - 1) r[t - 1] = k / n plt.plot(all_t_for_n, r) plt.title('code length, n = ' + str(n)) plt.xlabel('number of correctioned errors, t') plt.ylabel('code speed, r') plt.grid(color='k', linestyle='-', linewidth=0.5) plt.show() return
def __init__(self, n, t): self.n = n self.t = t all_polynoms = numpy.loadtxt('primpoly.txt', dtype=int, delimiter=',') for poly in all_polynoms: poly = int(poly) cur_poly_pow = poly.bit_length() - 1 if 2**cur_poly_pow - 1 == n: self.polynom = poly break self.pm = gf.gen_pow_matrix(self.polynom) roots = list() alpha = 2 cur = 2 for i in range(2 * self.t): roots.append(cur) cur = gf.prod_zero_dim(cur, alpha, self.pm) self.R_for_pgz = numpy.array(roots) roots.reverse() self.R = numpy.array(roots) roots.reverse() self.g = gf.minpoly(numpy.array(roots), self.pm)[0] for i in range(2 * self.t, self.n): roots.append(cur) cur = gf.prod_zero_dim(cur, alpha, self.pm) self.all_roots = numpy.array(roots) self.m = self.g.shape[0] - 1 self.k = self.n - self.m
def test_minpoly(): pm = gf.gen_pow_matrix(37) x = np.array([19, 25, 31, 3, 14, 29]) right_answer = (np.array([1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1]), np.array([ 3, 5, 6, 8, 9, 10, 11, 12, 14, 15, 17, 18, 19, 20, 22, 25, 26, 29, 30, 31])) result = gf.minpoly(x, pm) assert_equal(right_answer[0], result[0]) assert_equal(right_answer[1], result[1])
def __init__(self, n, t): self.n = n self.t = t prim = gf.find_prim(n + 1) self.pm = gf.gen_pow_matrix(prim) self.R = self.pm[0:2 * t, 1] self.g = gf.minpoly(self.R, self.pm)[0] self.m = gf.deg(self.g) self.k = self.n - self.m # word lenght
def genpoly(n, t): # Very-very bad style: prim_poly_array = np.array([ 0, 0, 7, 11, 19, 37, 67, 131, 285, 529, 1033, 2053, 4179, 8219, 16427, 32771, 65581 ]) q = np.log2(n + 1).astype(int) if q < 2 or q > 16: raise ValueError("log2(n + 1) should be in [2, 16]") pm = gf.gen_pow_matrix(prim_poly_array[q]) bch_zeros = pm[:(2 * t), 1] g = gf.minpoly(bch_zeros, pm)[0] return (g, bch_zeros, pm)
def __init__(self, n, t): assert t <= int((n - 1) / 2) q = int(np.log2(n + 1)) assert (q >= 2) and (q <= 16) assert 2**q - 1 == n self.pm = gf.gen_pow_matrix(self.primpolies[q]) self.R = self.pm[:2 * t, 1] self.g, _ = gf.minpoly(self.R, self.pm) check_poly = np.zeros(n + 1, dtype=np.int64) check_poly[0] = 1 check_poly[-1] = 1 assert gf.polydivmod(check_poly, self.g, self.pm)[1] == 0 mask = (self.g == 0) | (self.g == 1) assert mask.all()
def __init__(self, n, t): file = open('primpoly.txt', 'r') self.pm = np.empty(0, int) for line in file: for val in line.split(','): val = int(val) if (val > n): self.pm = gf.gen_pow_matrix(val) break if self.pm.size: break self.R = self.pm[:t * 2, 1] self.g = gf.minpoly(self.R, self.pm)[0] file.close() return
def __init__(self, n, t): self.n, self.t, self.q = n, t, int(np.log2(n + 1)) with open('./primpoly.txt', 'r') as file: primpolys = np.array( list(map(int, file.readline().strip().split(',')))) primpolys = primpolys[np.argwhere( np.log2(primpolys).astype(np.int) == self.q)].reshape(-1) self.pm = gf.gen_pow_matrix(primpolys[0]) self.R = self.pm[0:2 * t, 1] self.g, _ = gf.minpoly(self.R, self.pm) self.m, self.k = self.g.shape[0] - 1, self.n - (self.g.shape[0] - 1)
def __init__(self, n, t): self.n = n self.t = t q = P(n + 1).pw data = np.loadtxt("primpoly.txt", delimiter=', ', dtype=np.int) for i in data: if P(i).pw == q: self.pm = gen_pow_matrix(i) break zeros = [] for i in range(1, 2 * t + 1): zeros.append(self.pm[i][1]) self.R = np.asarray(zeros, dtype=int) p, roots = minpoly(self.R, self.pm) self.g = p self.k = self.n - self.g.size + 1
def __init__(self, n, t): dc = 2 * t + 1 q = 1 while (2 ** q < n + 1): q += 1 f = open('primpoly.txt') poly = 0 c = 0 for s in f: for i in s.split(', '): a = int(i) if (a > 2**q): poly = a break self.pm = gf.gen_pow_matrix(poly) self.g, self.R = gf.minpoly(self.pm.T[1][:dc-1], self.pm) self.k = n - self.g.shape[0] + 1 self.t = t
def __init__(self, n, t): self.n = n self.t = t q = int(np.log2(n + 1)) primpoly = open("primpoly.txt").readlines() primpoly = primpoly[0].replace(" ", "").split(',') primpoly = [int(poly) for poly in primpoly] primpoly_deg = np.log2(np.array(primpoly)).astype('int') prim_poly = primpoly[np.where(primpoly_deg >= q)[0][0]] self.pm = gf.gen_pow_matrix(prim_poly) self.R = [self.pm[i % self.pm.shape[0] - 1, 1] for i in range(1, 2 * self.t + 1)] self.R = np.array(self.R) self.g, _ = gf.minpoly(self.R, self.pm) self.m = self.g.shape[0] - 1
def __init__(self, n, t): q = n.bit_length() if (n+1).bit_length() <= q: raise ValueError("n != 2^q - 1") if t > (n-1)//2: raise ValueError("t > (n-1)/2") poly = open("primpoly.txt").readline() poly = poly.replace(" ", "").split(',') poly = list(map(int, poly)) i = np.array(list(map(int.bit_length,poly))) i = np.flatnonzero(i-1 == q) if i.size == 0: raise ValueError("No matching primitive polynomial found in primpoly.txt") poly = poly[random.choice(i)] # print("Primitive polynomial: " + str(poly) + " ~ " + np.binary_repr(poly)) self.pm = gf.gen_pow_matrix(poly) self.R = self.pm[:(2*t), 1] self.g = gf.minpoly(self.R, self.pm)[0]
def __init__(self, n, t): primpoly = [ 7, 11, 19, 37, 67, 131, 285, 529, 1033, 2053, 4179, 8219, 16427, 32771, 65581 ] q = int(np.log2(n + 1)) for i in range(len(primpoly)): if primpoly[i] >= 2**q: prim_poly = primpoly[i] break self.pm = gf.gen_pow_matrix(prim_poly) arr = [2] for i in range(2, 2 * t + 1): arr = arr + [self.pm[i % self.pm.shape[0] - 1, 1]] self.R = np.array(arr) self.g = gf.minpoly(self.R, self.pm)[0] self.n = n self.t = t
def test_minpoly_2(self): minpoly = gf.minpoly(np.array([0, 0b10]), gf.gen_pow_matrix(19)) assert_array_equal(minpoly[0], [1, 0, 0, 1, 1, 0]) assert_array_equal(minpoly[1], [0, 2, 3, 4, 5])
def test_minpoly(self): minpoly = gf.minpoly(np.array([0b10]), gf.gen_pow_matrix(0b1011)) assert_array_equal([1, 0, 1, 1], minpoly[0]) assert_array_equal([2, 4, 6], minpoly[1])