def test(): p = argv.get("p") ps = [p] if p else all_primes(200) for p in ps: if p==2: continue field = FiniteField(p) #ring = PolynomialRing(field) #x = ring.x items = [field.promote(i) for i in range(p)] has_imag = [i for i in items if i*i == -1] #print(p, has_imag) if not has_imag: continue i4 = has_imag[0] assert -i4 == has_imag[1] has_root2 = [i for i in items if i*i == 2] if not has_root2: continue r2 = has_root2[0] assert -r2 == has_root2[1] has_i8 = [i for i in items if i*i == i4] if not has_i8: continue i8 = has_i8[0] assert -i8 == has_i8[1] print("p =", p) #print(i4, r2, i8) build_gates(field, i4, r2, i8)
def test(): d = argv.get("d", 3) r = argv.get("r", 3) field = FiniteField(d) ring = PolynomialRing(field) funcs = [] one = ring.one x = ring.x f = x**r # if r==d and is prime then this is the Frobenius: it's the identity function on the field. for i in range(d): print(f(i))
def main(): p = argv.get("p", 3) field = FiniteField(p) ring = PolynomialRing(field) x = ring.x found = set() items = [list(field.elements)] * p for cs in cross(items): f = ring.zero for c in cs: f = x * f f = f + c vals = tuple(f(j) for j in field.elements) found.add(vals) print(' '.join([str(v) for v in vals])) print(len(found), p**p)
def test(): # ------------------------- # check we can build galois field GF(8) field = FiniteField(2) ring = PolynomialRing(field) one = ring.one x = ring.x f = x**3 - x - 1 assert f == x**3 + x + 1 assert f(0) != 0 assert f(1) != 0 b = x**5 div, rem = f.reduce(b) assert f * div + rem == b group = [] for i in range(2): for j in range(2): for k in range(2): a = i + j * x + k * x**2 if a != 0: group.append(a) div = {} for a in group: for b in group: c = f.reduce(a * b)[1] div[c, a] = b div[c, b] = a # all non-zero pairs elements of GF(8) should be divisable: assert len(div) == 49 # -------------------------------------------------- # GF(4) x = ring.x F = GaloisField(ring, (x**2 + x + 1)) omega = F.x one = F.one a, b = omega, omega + one assert a * a == b assert a * b == b * a assert a * b == one assert b * b == a assert one / omega == one + omega frobenius = lambda a: a**2 assert frobenius(one) == one assert frobenius(one + one) == one + one assert frobenius(omega) == omega + 1 assert frobenius(omega + 1) == omega # # -------------------------------------------------- # # for p in all_primes(20): # assert p>1 # field = FiniteField(p) # ring = PolynomialRing(field) # zero = ring.zero # one = ring.one # x = ring.x # poly = 1+x+x**2 # for i in range(1, p): # assert poly(i) != zero, "p=%d, poly=%s, i=%d"%(p, poly, i) # -------------------------------------------------- p = argv.get("p", 2) r = argv.get("r", 2) print("q =", p**r) F = GF(p**r) print(F.mod) zero = 0 els = F.elements assert len(els) == len(set(els)) == p**r for a in els: for b in els: if b != 0: c = a / b # XXX fails for p=3, r=4 assert c * b == a # build the hexacode w = F.x w2 = w**2 words = [] for a in els: for b in els: for c in els: f = lambda x: a * x**2 + b * x + c v = [a, b, c, f(1), f(w), f(w2)] words.append(v) code = numpy.array(words) for word in code: print(' '.join("%4s" % (c) for c in word)) print(code.shape) assert len(code) == 4**3 def inner(w0, w1): assert len(w0) == len(w1) n = len(w0) #r = sum([F.hermitian(a, b) for (a, b) in zip(w0, w1)]) r = sum([a * F.frobenius(b) for (a, b) in zip(w0, w1)]) return r for w0 in code: for w1 in code: print(inner(w0, w1), end=" ") print()
def GF(q): ps = factorize(q) assert len(set(ps)) == 1 p = ps[0] r = len(ps) assert q == p**r #print(p, r) field = FiniteField(p) if r == 1: return field ring = PolynomialRing(field) zero = ring.zero one = ring.one x = ring.x itemss = [tuple(range(p)) for i in range(r)] for idxs in cross(itemss): poly = x**r for i, idx in enumerate(idxs): poly += idx * (x**i) #print(poly) for i in range(p): if poly(i) == zero: #print("i=", i) break else: break #print("poly:", poly) #print([str(poly(i)) for i in range(p)]) F = GaloisField(ring, poly) def frobenius(a): return a**p def hermitian(a, b): return a * (b**p) def trace_hermitian(a, b): return (a**p) * b + a * (b**p) F.frobenius = frobenius F.hermitian = hermitian one = F.one zero = F.zero def order(u): count = 1 v = u assert v != zero while v != one: v = u * v count += 1 assert count < 2 * q return count for u in F.elements: if u == zero: continue #print(u, order(u)) if order(u) == q - 1: F.omega = u # generator of multiplicative group break else: assert 0 return F
def clifford(): p = argv.get("p", 17) field = FiniteField(p) #ring = PolynomialRing(field) #x = ring.x for fgen in range(1, p): items = set() j = fgen while j not in items: items.add(j) j = (j*fgen)%p if len(items) == p-1: break else: assert 0 finv = {} for i in range(1, p): for j in range(1, p): if (i*j)%p == 1: finv[i] = j finv[j] = i assert len(finv) == p-1 #print("fgen:", fgen) items = [field.promote(i) for i in range(p)] has_imag = [i for i in items if i*i == -1] #print(p, has_imag) if not has_imag: assert 0 i4 = has_imag[0] assert -i4 == has_imag[1] has_root2 = [i for i in items if i*i == 2] if not has_root2: assert 0 r2 = has_root2[0] assert -r2 == has_root2[1] has_i8 = [i for i in items if i*i == i4] if not has_i8: assert 0 i8 = has_i8[0] assert -i8 == has_i8[1] print("p =", p) #print(i4, r2, i8) #print(has_imag, has_root2, has_i8) for i in items: if i*i8 == 1: i8_dag = i #print(i8_dag) # try to take a daggar... doesn't really work tho. assert p==17 dag = { 0:0, 1:1, 2:9, 3:3, 4:13, 5:12, 6:6, 7:7, 8:15, 9:2, 10:10, 11:11, 12:5, 13:4, 14:14, 15:8, 16:16, } for (k, v) in list(dag.items()): dag[k] = field.promote(v) dag[field.promote(k)] = field.promote(v) assert dag[i4] == -i4 qubit = Space(2, field) hom = Hom(qubit, qubit) def getdag(A): items = [((j, i), dag[v]) for ((i, j), v) in A.items] return Map(items, hom) I = Map.from_array([[1, 0], [0, 1]], hom) X = Map.from_array([[0, 1], [1, 0]], hom) Z = Map.from_array([[1, 0], [0, -1]], hom) H = (1/r2)*(X+Z) assert H*H == I S = Map.from_array([[1, 0], [0, i4]], hom) Sdag = Map.from_array([[1, 0], [0, dag[i4]]], hom) assert S*S == Z assert S*Sdag == I assert getdag(S) == Sdag T = Map.from_array([[1, 0], [0, i8]], hom) assert S*S == Z C1 = mulclose([X, Z]) assert len(C1) == 8 # C1 is Pauli group + phases #P = fgen*I # phase P = i4*I C1 = mulclose([X, Z, P]) # add phases # assert len(C1) == 64, len(C1) assert len(C1) == 32, len(C1) C1_lookup = set(C1) #gen = [X, Z, S, H] #C2 = mulclose(gen) #assert len(C2) == 192 G = [] for a in range(p): for b in range(p): for c in range(p): for d in range(p): if (a*d - b*c)%p: G.append(Map.from_array([[a, b], [c, d]], hom)) G_lookup = set(G) print("|GL(%d, 2)|=%d" % (p, len(G))) U = [] for g in G: if g*getdag(g) == I: U.append(g) print("|U|=", len(U)) gen = [X, Z, S, H, P] # Clifford group + phases C2 = mulclose(gen) # assert len(C2) == 384, len(C2) assert len(C2) == 192, len(C2) C2_lookup = set(C2) print("|C2| =", len(C2)) print(C2_lookup == set(U)) for g in C2: assert g in G_lookup #assert g*getdag(g) == I, str(g) # FAIL # inv = {I:I} # for a in G: # if a in inv: # continue # for b in G: # ab = a*b # ci = inv.get(ab) # if ci is None: # continue # inv[a] = b*ci # inv[b] = ci*a # print(len(inv), end=" ", flush=True) # print() inv = {I:I} remain = set(G) remain.remove(I) while remain: a = iter(remain).__next__() assert a not in inv for b in G: ab = a*b ci = inv.get(ab) if ci is None: continue if a not in inv: inv[a] = b*ci remain.remove(a) if b not in inv: inv[b] = ci*a remain.remove(b) print(len(inv), end=" ", flush=True) print() assert len(inv) == len(G) if 0: for g2 in C2: for g in C1: assert g2 * g * inv[g2] in C1 C2 = [] for g2 in G: for g in C1: if g2*g*inv[g2] not in C1_lookup: break else: C2.append(g2) assert len(C2) == 384 # same as above C2_lookup = set(C2) C3 = [] for g3 in G: for g in C1: if g3*g*inv[g3] not in C2_lookup: break else: C3.append(g3) print("|C3| =", len(C3)) C3_lookup = set(C3) shuffle(C3) # count = 0 # for a in C3: # for b in C3: # if a*b in C3_lookup: # count += 1 # print(count) def src(a): return set([b for b in C3 if a*b in C3_lookup]) def tgt(a): return set([b for b in C3 if b*a in C3_lookup]) if 0: items = iter(C3) a = items.__next__() src_a = src(a) print("|src_a| =", len(src_a)) srcs = [] for b in C3: src_b = src(b) if src_b not in srcs: print("|src_b| = ", len(src_b)) srcs.append(src_b) if len(srcs)==4: # there is only 4 of these to be found break obs = list(srcs) tgts = [] for b in C3: tgt_b = tgt(b) if tgt_b not in obs: obs.append(tgt_b) if tgt_b not in tgts: print("|tgt_b| = ", len(tgt_b)) tgts.append(tgt_b) if len(tgts)==4: # there is only 4 of these to be found break done = False while not done: done = True #print("obs:", len(obs)) obs.sort(key = len, reverse=True) obs1 = list(obs) for s in obs: for t in obs: st = s.intersection(t) a = ' ' if st not in obs1: a = '*' obs1.append(st) done = False #print("%4d"%(len(st)), end=a) #print() obs = obs1 obs.sort(key = len, reverse=True) print("obs:", len(obs), [len(ob) for ob in obs]) for ob in obs: #print(len(ob), end=" ") iob = [inv[a] for a in ob if inv[a] in ob] print((len(ob), len(iob)), end=" ") print()
def test_graded_2(): if argv.rational: ring = Q elif argv.gf2: ring = FiniteField(2) else: return zero = Poly({}, ring) one = Poly({():1}, ring) h = Poly("h", ring) x = Poly("x", ring) y = Poly("y", ring) z = Poly("z", ring) lookup = {h:1, x:3, y:4, z:5} vs = list(lookup.keys()) vs.sort(key = str) print("vs", vs) rels = [ #z*x + y*y, #x**3 + z*y, #z*z + y*x*h*h*h, y*x*h, #z*x*h, # grade 9 #z*z, # grade 10 #z*y*h, ] print("rels:") for rel in rels: print(rel) print() rels = grobner(rels) n = argv.get("n", 10) grades = dict((i, []) for i in range(n)) for i in range(n): for j in range(n): for k in range(n): #for l in range(n): g = 1*i + 2*j + 3*k # + 5*l if g >= n: continue for mh in all_monomials([h], i, ring): for mx in all_monomials([x], j, ring): for my in all_monomials([y], k, ring): #for mz in all_monomials([z], l, ring): rem = mh*mx*my #*mz while 1: rem0 = rem for rel in rels: div, rem = rel.reduce(rem) if rem == rem0: break grades[g].append(rem) for i in range(n): gens = grades[i] #print(gens) if argv.sage: count = sage_grobner(gens) else: basis = grobner(gens) if gens else [] count = len(basis) print(count, end=",", flush=True) print()
def main(): p = argv.get("p", 3) deg = argv.get("deg", 1) field = FiniteField(p) if deg == 1: G = GL2(field) return base, field = field, field.extend(deg) assert len(field.elements) == p**deg print("GF(%d)"%len(field.elements)) print(field.mod) print() items = [a for a in field.elements if a!=0] perm = Perm(dict((a, a**p) for a in items), items) G = Group.generate([perm]) print("|G| =", len(G)) orbits = G.orbits() print("orbits:", len(orbits), end=", ") fixed = 0 for orbit in orbits: if len(orbit)==1: fixed += 1 print(len(orbit), end=" ") print() print("fixed points:", fixed) if 0: # find other solutions to the extension polynomial ring = PolynomialRing(field) poly = ring.evaluate(field.mod) assert str(poly) == str(field.mod) assert poly(field.x) == 0 subs = [] for a in field.elements: if poly(a) == field.zero: subs.append(a) print(a) return lin = Linear(deg, base) zero = field.zero one = field.one x = field.x a = one basis = [] for i in range(deg): basis.append(a) a = x*a for a in field.elements: if a == zero: continue op = [[0 for j in range(deg)] for i in range(deg)] for j, b in enumerate(basis): c = a*b poly = c.value # unwrap for i in range(deg): op[i][j] = poly[i] op = lin.get(op) print(str(op).replace("\n", ""), a) print() if argv.check: zero = field.zero div = {} for a in field.elements: for b in field.elements: c = a*b div[c, a] = b div[c, b] = a for a in field.elements: for b in field.elements: if b != zero: assert (a, b) in div