def test_divide(): X = np.array([[1, 5], [14, 2], [13, 5]]) Y = np.array([[2, 3], [2, 4], [2, 11]]) pm = np.array([[12, 2], [13, 4], [ 0, 8], [14, 1], [ 0, 2], [ 0, 4], [ 0, 8], [15, 1], [ 0, 2], [ 0, 4], [ 0, 8], [ 0, 1], [ 0, 2], [ 0, 4], [ 0, 8]]) right_div = np.array([[4, 8], [4, 4], [4, 8]]) assert_equal(right_div, gf.divide(X, Y, pm))
def decode(self, W, method='euclid'): assert method == 'euclid' or method == 'pgz' t = self.R.shape[0] // 2 n = W.shape[1] is_nan = False assert n == self.pm.shape[0] res = np.zeros_like(W, dtype=object) for i in range(W.shape[0]): w = W[i] s = gf.polyval(w, self.R, self.pm) if (s == 0).all(): res[i] = w continue if method == 'euclid': s = s[::-1] z = np.zeros(2 * t + 2, dtype=np.int64) z[0] = 1 s = np.concatenate((s, np.array([1]))) r, a, lam = gf.euclid(z, s, self.pm, max_deg=t) else: lam = np.nan for errors in range(t, 0, -1): A = [[s[k] for k in range(j, j + errors)] for j in range(errors)] A = np.array(A) b = [s[k] for k in range(errors, errors * 2)] b = np.array(b) lam = gf.linsolve(A, b, self.pm) if lam is not np.nan: break if lam is np.nan: res[i] = np.nan is_nan = True continue lam = np.concatenate((lam, np.array([1]))) values = gf.polyval(lam, self.pm[:, 1], self.pm) num_roots = 0 #res[i] = w for j in range(values.shape[0]): if values[j] == 0: root = self.pm[j, 1] alpha = gf.divide(1, root, self.pm) index = self.pm[alpha - 1, 0] w[n - index - 1] = 1 - w[n - index - 1] num_roots += 1 if num_roots != lam.shape[0] - 1: res[i] = np.nan is_nan = True continue res[i] = w if not is_nan: res = res.astype(np.int64) return res
def _decode(self, w, method): t = self.R.shape[0] // 2 syndromes = gf.polyval(w, self.R, self.pm) if np.sum(syndromes != 0) == 0: return w if method == 'pgz': lambda_ = np.nan for nu in range(t, 0, -1): a = np.array([[syndromes[j] for j in range(i, nu + i)] for i in range(nu)], dtype=np.int) b = np.array([syndromes[i] for i in range(nu, 2 * nu)], dtype=np.int) lambda_ = gf.linsolve(a, b, self.pm) if lambda_ is not np.nan: break if lambda_ is np.nan: return np.full(self.n, np.nan, dtype=np.int) lambda_ = np.concatenate([lambda_, [1]]) elif method == 'euclid': z = np.zeros([2 * t + 2], dtype=np.int) z[0] = 1 syndromic_polynom = np.concatenate([syndromes[::-1], [1]]) _, _, lambda_ = gf.euclid(z, syndromic_polynom, self.pm, max_deg=t) else: raise ValueError n_roots = 0 locators_values = gf.polyval(lambda_, np.arange(1, self.n + 1), self.pm) for idx in range(1, self.n + 1): if not locators_values[idx - 1]: position = self.n - self.pm[gf.divide(1, idx, self.pm) - 1, 0] - 1 w[position] = 1 - w[position] n_roots += 1 if n_roots != lambda_.shape[0] - 1: return np.full(self.n, np.nan, dtype=np.int) return w
def test_divide_all(self): pm = gf.gen_pow_matrix(357) for elem1 in pm[:, 1]: for elem2 in pm[:, 1]: a = gf.divide(np.array([[elem1]]), np.array([[elem2]]), pm) self.assertEqual(elem1, gf.prod(a, np.array([[elem2]]), pm))
def test_divide_inverse(self): pm = gf.gen_pow_matrix(88479) for elem in pm[:, 1]: inverse = gf.divide(np.array([[1]]), np.array([[elem]]), pm) self.assertEqual(1, gf.prod(inverse, np.array([[elem]]), pm))
def test_divide_itself(self): pm = gf.gen_pow_matrix(54193) for elem in pm[:, 1]: self.assertEqual( 1, gf.divide(np.array([[elem]]), np.array([[elem]]), pm))
def test_divide_zero_2(self): pm = gf.gen_pow_matrix(10187) for elem in pm[:, 1]: self.assertEqual( 0, gf.divide(np.array([[0]]), np.array([[elem]]), pm))
def test_divide_zero(self): pm = gf.gen_pow_matrix(104155) self.assertRaises( BaseException, lambda: gf.divide(np.array([[pm[-1, 1]]]), np.array([[0]]), pm))