예제 #1
0
def test_1():

    assert S*S == Z

    i = 1.j
    phase = numpy.exp(i*pi/8)
    C1 = mulclose([X, Z, phase*I]) # Pauli group
    C2 = mulclose([H, S, phase*I]) # Clifford group

    assert len(C1) == 64, len(C1)
    assert len(C2) == 384, len(C2)

    r = numpy.exp(-pi*i/8)/sqrt(2)
    v = r*numpy.array([[1., i], [i, 1.]])
    M = Qu((2, 2), 'ud', v)

    for g in C2:
        ginv = inv(g)
        assert g*ginv == I

    for g2 in C2:
        g2inv = inv(g2)
        assert g2*g2inv == I
        for g in C1:
            k = g2 * g * g2inv
            assert find(k, C1)

    print(M)
    print(find(M, C2))
    for g in C1:
        k = M * g * inv(M)
        assert find(k, C1)
예제 #2
0
파일: groups.py 프로젝트: punkdit/qupy
def build_octa(idx=0):
    " binary _octahedral group "

    x = cyclotomic(8)

    r2 = x - x**3  # sqrt(2)
    i = x**2

    gen = [
        [[[(-1 + i) / 2, (-1 + i) / 2], [(1 + i) / 2, (-1 - i) / 2]],
         [[(1 + i) / r2, 0], [0, (1 - i) / r2]]],
        [  # 2A
            [[(1. + i) / r2, 0.], [0., (1 - i) / r2]],
            [[1. / r2, -i / r2], [-i / r2, 1. / r2]],
        ],
        [  # 2B
            [[(-1. - i) / r2, 0.], [0., (-1. + i) / r2]],
            [[-1. / r2, i / r2], [i / r2, -1. / r2]],
        ],
        #        [ # 2C
        #        [[1., 0.], [-1., -1.]],
        #        [[0., 1.], [1., 0.]],
        #        ],
    ][idx]
    gen = [Qu((2, 2), 'ud', v) for v in gen]
    octa_gen = gen
    #a, b = gen
    #print((a**3*b).trace())

    Octa = mulclose(gen)
    assert len(Octa) == 48, len(Octa)
    #print("Octa:", Octa.words.values())

    return gen, Octa
예제 #3
0
파일: icosa.py 프로젝트: punkdit/qupy
    def mk_stab(reflects):
        # build commutative subgroup from these
        size = 0
        for trials in range(100):
            remain = list(reflects)
            gen = []
            S = []
            while remain:
                idx = randint(0, len(remain) - 1)
                a = remain.pop(idx)
                for b in gen:
                    if a * b != b * a:
                        break
                else:
                    if a not in S:
                        S1 = mulclose(gen + [a])
                        if nI not in S1:
                            S = S1
                            gen.append(a)

            if len(S) > size:
                #print("|S| =", len(S))
                size = len(S)

        for op in S:
            assert op * op == I
        return gen, S
예제 #4
0
def uniq_codes(pauli, n):

    I = pauli.I
    X = pauli.X
    Y = pauli.Y
    Z = pauli.Z

    In = reduce(matmul, [I] * n)

    count = 0
    ops = {}
    for gen in all_codes_3(pauli, n):
        G = mulclose(gen)
        if len(G) != 8:
            continue
        if -In in G:
            continue
        count += 1
        P = reduce(add, G)
        s = str(P)
        if s not in ops:
            ops[s] = P
            yield P

    print("codes:", count)
    print("uniq:", len(ops))
예제 #5
0
 def build(self):
     if "G" in self.__dict__:
         return
     stabs = self.stabs
     G = mulclose(stabs)
     assert len(G) == 2**len(stabs)
     P = reduce(add, G)
     assert (P * P == 2**len(stabs) * P)
     self.G = G
     self.P = P
예제 #6
0
파일: groups.py 프로젝트: punkdit/qupy
def build_tetra(idx=0):
    " binary _tetrahedral group "

    i = cyclotomic(4)
    r2 = sqrt(2)
    r3 = sqrt(3)
    r6 = sqrt(6)

    gen = [
        [  # same as Natural repr ?
            [[(-1 + i) / 2, (-1 + i) / 2], [(1 + i) / 2,
                                            (-1 - i) / 2]],  # order 3
            [[-1 / 2 - 1 / 2 * i, -1 / 2 - 1 / 2 * i],
             [1 / 2 - 1 / 2 * i, -1 / 2 + 1 / 2 * i]]  # order 3
        ],
        [  # Natural repr
            [[(1 + i * r3) / 2, 0], [0, (1 - i * r3) / 2]],
            [[(r3 - i) / (2 * r3), (-i * 2 * r2) / (2 * r3)],
             [(-i * 2 * r2) / (2 * r3), (r3 + i) / (2 * r3)]],
        ],
        [  # 2A
            [[(-2) / 2., 0], [0, (1 + i * r3) / 2.]],
            [[(2 * i) / (2 * r3), (r6 + i * r2) / (2 * r3)],
             [(r6 + i * r2) / (2 * r3), (i - r3) / (2 * r3)]],
        ],
        [  # 2B
            [[(1 - i * r3) / 2., 0], [0, (-2) / 2.]],
            [[(-r3 - i) / (2 * r3), (-r6 + i * r2) / (2 * r3)],
             [(-r6 + i * r2) / (2 * r3), (-2 * i) / (2 * r3)]],
        ],
    ][idx]

    gen = [Qu((2, 2), 'ud', v) for v in gen]
    a, b = gen
    #print( len(mulclose([b], maxsize=32)))
    assert len(mulclose([a], maxsize=32)) in (3, 6)
    assert len(mulclose([b], maxsize=32)) in (3, 6)

    Tetra = mulclose(gen, maxsize=32)
    assert len(Tetra) == 24

    return gen, Tetra
예제 #7
0
파일: groups.py 프로젝트: punkdit/qupy
def build_pauli(*args):

    X = Qu((2, 2), 'ud', [[0., 1], [1., 0.]])
    Z = Qu((2, 2), 'ud', [[1., 0], [0., -1.]])
    gen = [X, Z]

    G = mulclose(gen)

    assert len(G) == 8

    return gen, G
예제 #8
0
파일: groups.py 프로젝트: punkdit/qupy
def build_icosa(idx=0):
    " binary _icosahedral group "

    i = cyclotomic(4)
    v = cyclotomic(10)
    z = v**2
    r5 = 2 * z**3 + 2 * z**2 + 1  #sqrt(5)
    gen = [
        [  # Same as Nat ?
            [[z**3, 0], [0, z**2]],
            [[(z**4 - z) / r5, (z**2 - z**3) / r5],
             [(z**2 - z**3) / r5, -(z**4 - z) / r5]]
        ],
        [  # Nat
            [[v, 0], [0, v**9]],
            [[(5 * (v - v**4) - r5 * (v + v**4)) / 10.,
              (-2 * r5 * (v + v**4)) / 10.],
             [(-2 * r5 * (v + v**4)) / 10.,
              (5 * (v - v**4) + r5 * (v + v**4)) / 10.]]
        ],
        [
            [[0, i], [i, (1 - r5) / 2]],
            [[-i, i], [-(1 - r5) / 2., (1 - r5) / 2 + i]],
        ]
    ][idx]

    gen = [Qu((2, 2), 'ud', v) for v in gen]
    #a, b = gen
    #H = mulclose([b], maxsize=100)
    #print(len(H))

    X = Qu((2, 2), 'ud', [[0., 1], [1., 0.]])
    Z = Qu((2, 2), 'ud', [[1., 0], [0., -1.]])

    G = mulclose(gen, maxsize=256)

    assert len(G) == 120

    if idx in (0, 1):
        assert X * Z in G
        assert X not in G
        assert Z not in G

    return gen, G
예제 #9
0
파일: icosa.py 프로젝트: punkdit/qupy
    def build_spin_chain(G):
        I = G.get_ident()
        In = G.get_ident(degree)
        nt_ops = [op for op in G if op != I and op.phase == 1]
        while 1:
            while 1:
                A = [I] * degree
                B = [I] * degree

                for i in range(weight):
                    a = choice(nt_ops)
                    A[i] = a
                    B[(i + 1) % degree] = a
                A = reduce(matmul, A)
                B = reduce(matmul, B)
                if A * B == B * A:
                    break

            gen = [A, B]
            for i in range(2, degree):
                idxs = [A.idxs[(-i + j) % degree] for j in range(degree)]
                op = Tensor(G, idxs, A.phase)
                gen.append(op)
            print("gen:")
            for op in gen:
                print("  ", op)

            S = mulclose(gen)
            print("|S| =", len(S))

            #ops = [G.get_dense(op) for op in S]
            #P = reduce(add, ops)
            P = G.get_dense(S[0])
            for op in S[1:]:
                P = P + G.get_dense(op)
            r = P.norm()
            if abs(r) > EPSILON:
                break
            write(".")

        show_spec(P)
        find_errors(G, P, degree)
        return
예제 #10
0
def test_clifford():

    # Clifford group:
    # https://www.mathstat.dal.ca/~selinger/papers/clifford.pdf

    i = 1.j
    phase = numpy.exp(i*pi/4)
    phase = -1.

    II = I@I
    XI = X@I
    IX = I@X
    ZI = Z@I
    IZ = I@Z
    gen = [XI, IX, ZI, IZ, phase*II]
    C1 = mulclose(gen) 
    assert len(C1) == 32, len(C1)

    assert (H*H) == I
    gen = gen + [H@I, I@H, CZ]
예제 #11
0
파일: gates.py 프로젝트: punkdit/qupy
 def get_projector(self):
     G = mulclose(self.ops)
 
     # build projector onto codespace
     P = (1./len(G))*reduce(add, G)
     return P
예제 #12
0
파일: icosa.py 프로젝트: punkdit/qupy
def main():

    name = argv.get("G", "icosa")
    G = groups.build(name)

    def get_reflects(G, I):
        reflects = []
        count = 0
        for ops in cross((G, ) * degree):
            op = reduce(matmul, ops)
            if op * op == I:
                count += 1
                reflects.append(op)
        reflects.remove(I)
        reflects.remove(nI)
        return reflects

    def rand_reflect(G, I, degree, weight=None):
        if weight is None:
            weight = degree
        while 1:
            #ops = [choice(G) for i in range(degree)]
            idxs = list(range(degree))
            ops = [G.get_ident() for i in idxs]
            for j in range(weight):
                idx = choice(idxs)
                idxs.remove(idx)
                ops[idx] = choice(G.non_central)
            op = reduce(matmul, ops)
            if op * op == I and op != I and op.phase == 1:
                return op

    def mk_stab(reflects):
        # build commutative subgroup from these
        size = 0
        for trials in range(100):
            remain = list(reflects)
            gen = []
            S = []
            while remain:
                idx = randint(0, len(remain) - 1)
                a = remain.pop(idx)
                for b in gen:
                    if a * b != b * a:
                        break
                else:
                    if a not in S:
                        S1 = mulclose(gen + [a])
                        if nI not in S1:
                            S = S1
                            gen.append(a)

            if len(S) > size:
                #print("|S| =", len(S))
                size = len(S)

        for op in S:
            assert op * op == I
        return gen, S

    print("|G| =", len(G))
    print("building...", end="", flush=True)
    G = Group(G)
    print("done")

    degree = argv.get("degree", 2)
    weight = argv.get("weight", degree)

    def build_spin_chain(G):
        I = G.get_ident()
        In = G.get_ident(degree)
        nt_ops = [op for op in G if op != I and op.phase == 1]
        while 1:
            while 1:
                A = [I] * degree
                B = [I] * degree

                for i in range(weight):
                    a = choice(nt_ops)
                    A[i] = a
                    B[(i + 1) % degree] = a
                A = reduce(matmul, A)
                B = reduce(matmul, B)
                if A * B == B * A:
                    break

            gen = [A, B]
            for i in range(2, degree):
                idxs = [A.idxs[(-i + j) % degree] for j in range(degree)]
                op = Tensor(G, idxs, A.phase)
                gen.append(op)
            print("gen:")
            for op in gen:
                print("  ", op)

            S = mulclose(gen)
            print("|S| =", len(S))

            #ops = [G.get_dense(op) for op in S]
            #P = reduce(add, ops)
            P = G.get_dense(S[0])
            for op in S[1:]:
                P = P + G.get_dense(op)
            r = P.norm()
            if abs(r) > EPSILON:
                break
            write(".")

        show_spec(P)
        find_errors(G, P, degree)
        return

    I = G.get_ident(degree)
    nI = -I

    n_reflects = argv.get("reflects", 4)

    reflects = []
    while 1:
        reflects += [
            rand_reflect(G, I, degree, weight) for i in range(n_reflects)
        ]

        if 0:
            #print("reflects:")
            idxs = set()
            for op in reflects:
                for idx in op.idxs:
                    idxs.add(idx)
            idxs = list(idxs)
            idxs.sort()
            ops = [G[idx] for idx in idxs]
            H = mulclose(ops)
            print("reflects:", idxs)
            print("|H|:", len(H))

        gen, S = mk_stab(reflects)
        write("%s," % len(S))
        if len(S) >= 2**degree:
            break
    print()
    print("gen:")
    for op in gen:
        print("  ", op)

    gen.pop(0)
    S = mulclose(gen)

    # build projector onto codespace
    ops = [G.get_dense(op) for op in S]
    P = reduce(add, ops)
    show_spec(P)

    find_errors(G, P, degree)
예제 #13
0
def main():

    t = argv.get("t", 0.02)

    T = build("""
    XZZXI 
    IXZZX
    XIXZZ 
    ZXIXZ
    XXXXX
    """)

    n = 5
    stabs = [ 
        X@Z@Z@X@I, 
        I@X@Z@Z@X, 
        X@I@X@Z@Z, 
        Z@X@I@X@Z]
    Lx = X@X@X@X@X
    #Lz = Z@Z@Z@Z@Z
    Lz = T[n-1]

    ops = stabs + [Lx]
    for i in range(n):
      for j in range(n):
        c = (T[i]*ops[j] == ops[j]*T[i])
        assert c == (i!=j)
        a = (T[i]*ops[j] == -ops[j]*T[i])
        assert a == (i==j)

    G = mulclose(stabs)
    assert len(G) == 16
    N = len(G)
    P = (1./N) * sumops(G)

    assert P*P == P

    for op in stabs:
        assert Lx*op == op*Lx
        assert Lz*op == op*Lz

    trials = argv.get("trials", 100)

    for trial in range(trials):

        if 1:
            # noise on one qubit
            U = errop(t)
            U = U@I@I@I@I
        else:
            # noise on all qubits
            Us = []
            for i in range(n):
                Us.append(errop(t))
            U = reduce(matmul, Us)

        v = Qu.random((2,)*n, "u"*n)
        v = P*v
        v.normalize()
        #print(v.flatstr())

        u = U*v
        u.normalize()
    
        for i, op in enumerate(stabs):
            val, u = measure(op, u)
            print(fstr(val), end=" ")
            if val < 0:
                #print("*")
                u = T[i]*u
        #print()
    
        #for i, op in enumerate(stabs):
            #val, v = measure(op, v)
            #print(fstr(val), end=" ")
        #print()
    
        assert P*u == u
        assert P*v == v

        phase = None
        for uu in [u, Lx*u, Lz*u, Lx*Lz*u]:
            r = ~uu * v
            if abs(1. - abs(r)) < EPSILON:
                #write("+")
                phase = r
            #else:
                #write(".")
        #write("\n")
        if phase is not None:
            print(phase)
        else:
            print()
예제 #14
0
def test_2():
    "two qubits"

    i = 1.j
    phase = numpy.exp(i*pi/8)

    II = I@I
    XI = X@I
    IX = I@X
    ZI = Z@I
    IZ = I@Z
    gen = [XI, IX, ZI, IZ, phase*II]
    gen = [op.flat() for op in gen]
    C1 = mulclose(gen)

    assert len(C1) == 256, len(C1)

#    CZ = Z.control()
#    op = CZ.flat()
#    print(op)
#    print(op.valence)

    r = numpy.exp(-pi*i/8)
    v = r*numpy.array([
        [1., 0., 0., 0.],
        [0., 1.j, 0., 0.],
        [0., 0., 1.j, 0.],
        [0., 0., 0., 1.]])
    CZ = Qu((4, 4), 'ud', v)

    II = II.flat()
    assert (CZ*~CZ) == II

    assert not find(CZ, C1)
    for g in C1:
        k = CZ * g * ~CZ
        assert find(k, C1)

    r = numpy.exp(pi*i/8)/sqrt(2)
    v = r*numpy.array([[1., i], [i, 1.]])
    H = Qu((2, 2), 'ud', v)

    plus = 1./sqrt(2) * (bitvec(0) + bitvec(1)) 
    #print(plus)
    #print(H*plus) # proportional to plus state

    IH = (I@H).flat()
    HI = (H@I).flat()
    HH = (H@H).flat()

    assert IH * CZ * IH == CZ * IH * CZ # Reidemeister III move

    g = CZ * HH * CZ
    assert g*g == II
    assert g != SWAP.flat()

    A = (CZ @ I).flat()
    B = (I @ CZ).flat()
    III = (II@I).flat()

    assert A*B == B*A

    ABA = A*B*A
    BAB = B*A*B
    r = numpy.exp(pi*i/8)
    print((ABA/r).shortstr())
    print((BAB/r).shortstr())
    #assert A*B*A == B*A*B
    op = III
    for i in range(1, 100):
        op = ABA * op
        if op == III:
            break
    else:
        assert 0
    print(i)

    assert ABA ** 16 == III
    assert BAB ** 16 == III