def CF2(self): B = self.B a0 = np.zeros(self.n, dtype=int) a0[0] = 1 # bring B to the Frobenius form P = self.A() B = gf2.dot(gf2.dot(gf2.inv(P), B), P) a = gf2.dot(gf2.inv(P), self.a) c = gf2.dot(self.c, P) # use the facts: A^{-1}.B.A = B and A^{-1}.a = a0 return XS(a0, B, gf2.dot(c, P))
def inv(self): assert (self.is_invertible()) if self.get_type() == 1: B1 = gf2.inv(self.B) a1 = gf2.dot(B1, self.a) c1 = gf2.dot(self.c, B1) else: M = gf2.inv(self.M()) a1 = M[:-1, -1] B1 = M[:-1, :-1] c1 = M[-1, :-1] return XS(a1, B1, c1)
def CF1(self): B = self.B c0 = np.zeros(self.n, dtype=int) c0[-1] = 1 # bring B to the Frobenius form P = self.A() B = gf2.dot(gf2.dot(gf2.inv(P), B), P) a = gf2.dot(gf2.inv(P), self.a) c = gf2.dot(self.c, P) # find P = P(c): P.B.P^{-1} = B and c.P^{-1} = c0 M = gf2.eye(self.n) P = gf2.dot(c, M) b = B[:, -1] for i in range(self.n - 1, 0, -1): M = gf2.dot(B, M) M = gf2.add(M, b[i] * gf2.eye(self.n)) P = np.vstack((gf2.dot(c, M), P)) return XS(gf2.dot(P, a), B, c0)
def rho2(self): v = self.c gamma = np.zeros(self.n) for i in range(0, self.n): gamma[i] = gf2.dot(v, self.a) v = gf2.dot(v, self.B) ret = 0 A1 = gf2.inv(self.A()) for r in range(0, self.n): y = np.zeros(self.n) y[r] = 1 y[r + 1:] = gamma[:self.n - 1 - r] y = gf2.dot(y, A1) for i in range(0, self.n): y = gf2.dot(y, self.B) t = 0 while True: t = t + 1 if gf2.dot(y, self.a) != gamma[self.n - r + t - 2]: break y = gf2.dot(y, self.B) if t > ret: ret = t return self.n + ret
def is_invertible(self): if gf2.det(self.B) == 0: return gf2.det(self.M()) == 1 return gf2.dot(gf2.dot(self.c, gf2.inv(self.B)), self.a) == 0