예제 #1
0
 def get_lag(self):
     l = 1
     v = self.c
     while l <= self.n and gf2.dot(v, self.a) == 0:
         l = l + 1
         v = gf2.dot(v, self.B)
     return l
예제 #2
0
 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))
예제 #3
0
 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)
예제 #4
0
 def is_strong_regular(self):
     if self.is_regular() == False:
         return False
     l = self.get_lag()
     if l == 1:
         return True
     Bl = self.B
     for i in range(1, l):
         Bl = gf2.dot(Bl, self.B)
     m = v = self.c
     for i in range(1, self.n):
         v = gf2.dot(v, Bl)
         m = np.vstack((m, v))
     return gf2.det(m) == 1
예제 #5
0
 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)
예제 #6
0
def GNAF2(circ, t):
    a, B, c = circ.aBc()
    if t < circ.n:
        return 0
    if t == circ.n:
        return 1
    f = gf2.add(a, B[:, -1])
    min_d = t
    for s0 in itertools.product([0, 1], repeat=circ.n):
        d = np.sum(s0)
        if d == 0:
            continue
        s = list(s0)
        for i in range(t - circ.n):
            s = np.append(s[1:], gf2.dot(s, f))
            d = d + s[-1]
        if d < min_d:
            min_d = d
    return min_d
예제 #7
0
 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
예제 #8
0
 def A(self):
     m = v = self.a
     for i in range(1, self.n):
         v = gf2.dot(v, self.B.T)
         m = np.vstack((m, v))
     return m.T
예제 #9
0
 def C(self):
     m = v = self.c
     for i in range(1, self.n):
         v = gf2.dot(v, self.B)
         m = np.vstack((v, m))
     return m
예제 #10
0
 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