示例#1
0
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)
示例#2
0
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()