예제 #1
0
파일: algebra.py 프로젝트: punkdit/qupy
 def get_projector(self):
     G = mulclose_fast(self.ops)
     #print("get_projector:", len(G))
     # build projector onto codespace
     #P = (1./len(G))*reduce(add, G)
     P = reduce(add, G)
     return P
예제 #2
0
파일: symplectic.py 프로젝트: punkdit/qupy
def test_isotropic():

    n = 3
    gen, _ = get_gen(n)
    assert len(mulclose_fast(gen)) == 1451520
    return

    n = argv.get("n", 3)
    F = Matrix.symplectic_form(n).A

    found = []
    for A in all_codes(n, 2 * n):
        B = dot2(dot2(A, F), A.transpose())
        if B.sum() == 0:
            A = Matrix(A)
            found.append(A)
            #print(A)

    found = set(found)
    print(len(found))

    gen, _ = get_gen(n)
    #gen = get_transvect(n)

    orbit = set()
    A = iter(found).__next__()

    bdy = [A]
    orbit = set(bdy)
    while bdy:
        _bdy = []
        for A in bdy:
            print(A)
            for g in gen:
                B = A * g
                print(B)
                print()
                B = B.normal_form()
                print(B)
                print()
                assert B in found
                if B not in orbit:
                    _bdy.append(B)
                    orbit.add(B)
        bdy = _bdy

    print(len(orbit))
예제 #3
0
파일: algebra.py 프로젝트: punkdit/qupy
def test_random():

    "build a small random stabilizer code"

    algebra = build_algebra(
        "IXZY", "X*X=I Z*Z=I Y*Y=-I X*Z=Y Z*X=-Y X*Y=Z Y*X=-Z Z*Y=-X Y*Z=X")

    I, X, Z, Y = algebra.basis

    n = argv.get("n", 4)
    ops = []
    negi = -reduce(matmul, [I] * n)
    items = [I, X, Z, Y]
    itemss = [[I, X], [I, Z]]
    while len(ops) < n - 1:
        if argv.css:
            items = choice(itemss)
        op = [choice(items) for _ in range(n)]
        op = reduce(matmul, op)
        for op1 in ops:
            if op1 * op != op * op1:
                break
        else:
            #print(op)
            ops.append(op)
            G = mulclose_fast(ops)
            if negi in G:
                ops = []

    for op in ops:
        print(op, end=" ")
    print()
    code = StabilizerCode(algebra, ops)
    #G = mulclose_fast(ops)
    #for g in G:
    #    print(g, negi==g)

    P = code.get_projector()
    print(P.str())
    print(P.str("@"))
예제 #4
0
def main():

    space = vecspace(4)

    # test beta is a 2-cocycle
    for g in space:
        for h in space:
            for k in space:
                lhs = (beta(g, h) - beta(h, k)) % 4
                rhs = (beta(g, h + k) - beta(g + h, k)) % 4
                assert lhs == rhs  # [2] eq. 3.65

    for u in space:
        for v in space:
            assert beta(u, v) % 2 == sy(u, v)
            assert (beta(u, v) - beta(v, u)) % 4 == 2 * sy(u,
                                                           v)  # [2] eq. 3.67
            rhs = (gamma(u + v) - gamma(u) - gamma(v) + 2 *
                   (dot(u.Z, v.X))) % 4
            assert beta(u, v) == rhs

    # ------------------------------------------------

    # wtf is going on here, i don't know...

    I = Heisenberg([0, 0])
    w = Heisenberg([0, 0], 1)
    X = Heisenberg([1, 0])
    Z = Heisenberg([0, 1])
    Y = Heisenberg([1, 1], 2)  # ?
    XZ = Heisenberg([1, 1], 1)  # ?
    ZX = Heisenberg([1, 1], 3)  # ?

    assert X * X == I
    assert Z * Z == I
    assert XZ != ZX
    assert XZ == -ZX
    assert X * Z == XZ
    assert Z * X == ZX
    assert Y == w * X * Z

    assert w != I
    assert w**2 != I
    assert w**3 != I
    assert w**4 == I

    XI = X @ I
    ZI = Z @ I
    IX = I @ X
    IZ = I @ Z
    XZ = X @ Z
    ZX = Z @ X
    wII = w @ I

    #    assert XI*IX == X@X
    #    assert ZI*XI == -XI*ZI
    #    assert XZ * ZX == ZX * XZ

    G = mulclose_fast([w, X, Y, Z])
    assert w in G
    assert len(G) == 16, len(G)

    HW = mulclose_fast([wII, XI, ZI, IX, IZ])
    assert len(HW) == 64

    return

    # ------------------------------------------------

    n = 1
    S = Symplectic.s_gate(n)
    H = Symplectic.h_gate(n)

    Sp2 = mulclose_fast([S, H])
    assert len(Sp2) == 6

    # ------------------------------------------------

    n = 2
    SI = Symplectic.s_gate(n)
    HI = Symplectic.h_gate(n)
    IS = Symplectic.s_gate(n, 1)
    IH = Symplectic.h_gate(n, 1)
    CZ = Symplectic.cz_gate(n)

    Sp4 = mulclose_fast([SI, HI, IS, IH, CZ])
    assert len(Sp4) == 720, len(Sp4)

    # ------------------------------------------------

    space = vecspace(2 * n)
    assert len(space) == 2**(2 * n)

    Sp4 = list(Sp4)
    shuffle(Sp4)
    #g = Sp4[0]
    #print(len([alpha for alpha in find_alpha(g)]))

    gen = []
    for g in Sp4:
        #print(g)
        for alpha in find_alpha(g):
            #print(alpha)
            op = ASymplectic(g, alpha)
            gen.append(op)
            break
        if len(gen) > 5:
            break

    for g in gen:
        for h in gen:
            for a in HW:
                assert (g * h)(a) == g(h(a))

    ASp = mulclose_fast(gen, maxsize=None, verbose=False)
    assert len(ASp) == 11520
    #for g in ASp:
    #    g.check()

    # ------------------------------------------------

    if 0:
        found = []
        for g in Sp4:
            total = 0
            for v in space:
                for w in space:
                    lhs = (beta(g(v), g(w)) - beta(v, w)) % 4
                    total += lhs
            #print(total, end=" ")
            if total == 0:
                found.append(g)
        assert len(mulclose_fast(found)) == 6  # hmmm
예제 #5
0
파일: asymplectic.py 프로젝트: punkdit/qupy
def test():

    n = 3
    F = symplectic_form(n)
    I = identity2(2 * n)
    assert numpy.alltrue(I == dot2(F, F))

    # --------------------------------------------
    # Clifford group order is 24

    n = 1
    I = Clifford.identity(n)

    X = Clifford.x(n, 0)
    Z = Clifford.z(n, 0)
    S = Clifford.s(n, 0)
    Si = S.inverse()
    H = Clifford.hadamard(n, 0)
    Y = X * Z

    print("X =")
    print(X)
    print("Z =")
    print(Z)
    print("S =")
    print(S)
    print("Si =")
    print(Si)
    print()

    assert X != I
    assert Z != I
    assert X * X == I
    assert Z * Z == I
    assert Z * X == X * Z  # looses the phase

    assert Si * S == S * Si == I
    assert Si * Si == Z
    assert S * Z == Z * S
    assert S * X == Y * S
    assert S * Y * Si == X
    assert S * S == Z
    assert S * X != X * S
    assert S * S * S * S == I
    assert S * S * S == Si

    assert H * H == I
    assert H * X * H == Z
    assert H * Z * H == X

    assert S * H * S * H * S * H == I

    G = mulclose_fast([S, H])
    assert len(G) == 24

    #    # --------------------------------------------
    #    # Look for group central extension
    #
    #    G = list(G)
    #    G.sort()
    #    P = [g for g in G if g.is_translation()] # Pauli group
    #    N = len(G)
    #    lookup = dict((g, idx) for (idx, g) in enumerate(G))
    #    coord = lambda g, h : lookup[h] + N*lookup[g]
    #    #phi = numpy.zeros((N, N), dtype=int)
    #
    #    phi = {}
    #    for g in P:
    #      for h in P:
    #        phi[g, h] = 0
    #
    #    pairs = [(g, h) for g in G for h in G]
    #    triples = [(g, h, k) for g in G for h in G for k in G]
    #    done = False
    #    while not done:
    #      done = True
    #      print(len([phi.get(k) for k in pairs if phi.get(k) is None]))
    #      for (g, h, k) in triples:
    #        vals = [
    #            phi.get((g, h)),
    #            phi.get((h, k)),
    #            phi.get((g, h*k)),
    #            phi.get((g*h, k))]
    #        if vals.count(None) == 1:
    #            phi[g, h] = 0
    #            phi[h, k] = 0
    #            phi[g, h*k] = 0
    #            phi[g*h, k] = 0
    #            done = False
    #    print(len([phi.get(k) for k in pairs if phi.get(k) is None]))
    #    print(len(phi))
    #    print(len(pairs))
    #
    #    return

    # --------------------------------------------
    # Clifford group order is 11520

    n = 2
    II = Clifford.identity(n)

    XI = Clifford.x(n, 0)
    IX = Clifford.x(n, 1)
    ZI = Clifford.z(n, 0)
    IZ = Clifford.z(n, 1)
    SI = Clifford.s(n, 0)
    IS = Clifford.s(n, 1)
    SS = SI * IS
    HI = Clifford.hadamard(n, 0)
    IH = Clifford.hadamard(n, 1)
    XX = XI * IX
    ZZ = ZI * IZ
    XZ = XI * IZ
    ZX = IX * ZI
    YI = XI * ZI
    IY = IX * IZ
    YY = YI * IY
    XY = XI * IY
    YX = IX * YI
    ZY = ZI * IY
    YZ = IZ * YI

    CX = Clifford.cnot(n, 0, 1)
    CX1 = Clifford.cnot(n, 1, 0)
    CZ = Clifford.cz(n, 0, 1)
    CZ1 = Clifford.cz(n, 1, 0)

    print("CZ =")
    print(CZ)

    print("CX =")
    print(CX)

    assert SI * SI == ZI

    assert SI * ZI == ZI * SI
    assert SI * XI != XI * SI
    assert SI * SI * SI * SI == II

    assert CX * CX == II
    assert CZ * CZ == II
    assert CZ1 == CZ

    assert CX * IX == IX * CX
    assert CX * XI * CX == XX

    assert CX * ZI == ZI * CX
    assert CX * IZ * CX == ZZ

    SWAP = Clifford.swap(n, 0, 1)
    assert SWAP * ZI == IZ * SWAP
    assert SWAP * XI == IX * SWAP

    assert CX * CX1 * CX == SWAP

    assert CZ == IH * CX * IH

    assert CZ * ZI == ZI * CZ
    assert CZ * IZ == IZ * CZ

    assert CZ * XI * CZ == XI * IZ
    assert CZ * IX * CZ == IX * ZI

    assert CX * IZ * CX == ZZ
    assert CX * ZZ * CX == IZ
    assert CX * XI * CX == XX
    assert CZ * XX * CZ == YY
    assert CX * XZ * CX == YY

    assert CX * CZ == CZ * CX
    print("CX * CZ =")
    print(CX * CZ)

    #print(CX*CX1)
    #print()
    #print(SWAP)

    G = mulclose_fast([SI, IS, CX, HI, IH])
    assert len(G) == 11520

    for g in G:
        assert g.check()
        h = g.inverse()
        assert h.check()
        assert g * h == II

    # --------------------------------------------

    n = 5
    I = Clifford.identity(n)
    CZ = Clifford.cz(n, 0, 1)
    SWAP = Clifford.swap(n, 0, 1)
    assert CZ * CZ == I
    assert SWAP * CZ == CZ * SWAP
예제 #6
0
파일: clifford.py 프로젝트: punkdit/qupy
def main():

    I = Clifford.identity(1)
    iI = Clifford.phase(1)
    nI = iI * iI
    X = Clifford.xgate()
    Z = Clifford.zgate()
    Y = Clifford.ygate()
    S = Clifford.sgate()

    assert I != X != Z != S
    assert X * X == I
    assert Z * Z == I
    assert Y * Y == I
    assert X * Z != Z * X
    assert X * Z == nI * Z * X
    assert S * S == Z
    assert S * S * S * S == I
    assert S * X * S * X == iI

    H = Clifford.hgate()
    assert H * H == iI
    assert H * H * H * H == -I
    Hinv = H * H * H * H * H * H * H
    assert H * H.inv == I

    assert H * X * H.inv == Z
    assert H * Z * H.inv == X
    assert H * Y * H.inv == -Y

    gen = [H, S, X]
    G = mulclose_fast(gen)
    assert len(G) == 4 * 24

    for g in G:
        assert g * g.inv == I

    # -----------------------------------------------

    ASp = asymplectic.build()

    if 0:
        hom = mulclose_hom([H, S, X], [ASp.H, ASp.S, ASp.X])

        print("|Clifford| =", len(hom))
        kernel = []
        image = set()
        for g in hom:
            image.add(hom[g])
            if hom[g] == ASp.I:
                kernel.append(g)
        print("kernel:", len(kernel))
        print("image:", len(image))

        for g in hom:
            for h in hom:
                assert hom[g * h] == hom[g] * hom[h]

    # -----------------------------------------------

    II = Clifford.identity(2)
    iII = Clifford.phase(2)
    nII = iII * iII
    CX = Clifford.cx(2)
    CZ = Clifford.cz(2)

    IX = I @ X
    XI = X @ I
    IZ = I @ Z
    ZI = Z @ I
    IS = I @ S
    SI = S @ I
    IH = I @ H
    HI = H @ I
    XZ = XI * IZ
    ZX = IX * ZI

    assert CZ * CZ == II

    assert XI * XI == II
    assert Z @ X == ZI * IX

    assert CZ == IH * CX * IH.inv

    assert CZ * ZI == ZI * CZ
    assert CZ * IZ == IZ * CZ

    assert CZ * XI * CZ == XI * IZ
    assert CZ * IX * CZ == IX * ZI

    if argv.slow:
        gen = [IX, XI, SI, IS, HI, IH, CZ]
        G = mulclose_fast(gen)
        assert len(G) == 4 * 11520
        for g in G:
            assert g * g.inv == II


#    CZCX = CZ*CX
#    CXCZ = CX*CZ
#    phases = [II, iII, nII, nII*iII]
#    def table(op):
#        gen = [p*op for op in [II, XI, IX, ZI, IZ, XZ, ZX] for p in phases]
#        for src in gen:
#            tgt = op * src * op.inv
#            for idx, h in enumerate(gen):
#                if tgt == h:
#                    break
#            else:
#                assert 0
#    table(CZCX)
#    table(CXCZ)
#    return

# -----------------------------------------------

    src = [IX, XI, SI, IS, HI, IH, CZ]
    ASp = asymplectic.build_stim()
    tgt = [ASp.IX, ASp.XI, ASp.SI, ASp.IS, ASp.HI, ASp.IH, ASp.CZ]
    G = mulclose_fast(tgt)
    hom = mulclose_hom(src, tgt)

    print("|Clifford| =", len(hom))
    kernel = []
    image = set()
    G = list(hom.keys())
    shuffle(G)
    for g in G:
        image.add(hom[g])
        if hom[g] == ASp.II:
            kernel.append(g)
    print("kernel:", len(kernel))
    print("image:", len(image))

    return

    for g in G:
        for h in G:
            assert hom[g * h] == hom[g] * hom[h]
예제 #7
0
def test():

    d = 3

    n = 3
    F = symplectic_form(d, n)
    Ft = F.transpose()
    I = identity_d(2 * n)
    assert numpy.alltrue(I == dot_d(d, F, Ft))

    # --------------------------------------------
    # qubit Clifford group order is 24
    # qutrit Clifford group order is 216

    n = 1
    I = Clifford.identity(d, n)

    X = Clifford.x(d, n, 0)
    Z = Clifford.z(d, n, 0)
    S = Clifford.s(d, n, 0)
    Si = S.inverse()
    H = Clifford.hadamard(d, n, 0)
    Hi = H.inverse()
    Y = X * Z

    if 1:
        print("X =")
        print(X)
        print("Z =")
        print(Z)
        print("S =")
        print(S)
        print("Si =")
        print(Si)
        print()

    assert X != I
    assert Z != I
    assert X**d == I
    assert Z**d == I
    assert Z * X == X * Z  # looses the phase

    G = mulclose_fast([H, S, X])
    assert len(G) == d**3 * (d**2 - 1), len(G)
    for g in G:
        assert g * g.inverse() == I
    pauli = [g for g in G if g.is_translation()]
    assert len(pauli) == d**(2 * n)

    assert Si * S == S * Si == I
    assert S * Z == Z * S
    assert S * X != X * S

    assert H * X * Hi == Z
    assert Hi * Z * H == X

    assert S * H * S * H * S * H == I

    def get_order(g):
        count = 1
        op = g
        while op != I:
            op = g * op
            count += 1
        return count

    S = Clifford.sy_s(d, n, 0)
    assert get_order(S) == 3
    Si = S.inverse()

    op = S * X * Si
    assert op == Z * X
    op = S * op * Si
    assert S * op * Si == X

    return

    # --------------------------------------------
    # 2 qubit Clifford group order is 11520
    # 2 qutrit Clifford group order is 4199040

    n = 2
    II = Clifford.identity(d, n)

    XI = Clifford.x(d, n, 0)
    IX = Clifford.x(d, n, 1)
    XX = XI * IX
    ZI = Clifford.z(d, n, 0)
    IZ = Clifford.z(d, n, 1)
    ZZ = ZI * IZ
    SI = Clifford.s(d, n, 0)
    IS = Clifford.s(d, n, 1)
    SS = SI * IS
    HI = Clifford.hadamard(d, n, 0)
    IH = Clifford.hadamard(d, n, 1)

    CX = Clifford.cnot(d, n, 0, 1)
    CX1 = Clifford.cnot(d, n, 1, 0)
    CZ = Clifford.cz(d, n, 0, 1)
    CZ1 = Clifford.cz(d, n, 1, 0)

    print("CZ =")
    print(CZ)

    print("CX =")
    print(CX)

    assert CX**d == II
    assert CZ**d == II
    assert CZ1 == CZ

    assert CX * IX == IX * CX
    #assert CX * XI * CX == XX
    #assert CX * ZI == ZI * CX
    #assert CX * IZ * CX == ZZ

    SWAP = Clifford.swap(d, n, 0, 1)
    assert SWAP * ZI == IZ * SWAP
    assert SWAP * XI == IX * SWAP

    #assert CX * CX1 * CX == SWAP
    #assert CZ == IH * CX * IH

    #assert CZ * ZI == ZI * CZ
    #assert CZ * IZ == IZ * CZ

    #assert CZ * XI * CZ == XI*IZ
    #assert CZ * IX * CZ == IX*ZI

    #print(CX*CX1)
    #print()
    #print(SWAP)

    if argv.slow:
        G = mulclose_fast([SI, IS, CX, HI, IH])
        assert len(G) == d**4 * d**(n**2) * (d**(2 * n) -
                                             1) * (d**(2 * n - 2) - 1)
        if d == 3:
            assert len(G) == 4199040

        for g in G:
            assert g.check()
            h = g.inverse()
            assert h.check()
            assert g * h == II
예제 #8
0
파일: symplectic.py 프로젝트: punkdit/qupy
def test_symplectic():

    n = 3
    I = Matrix.identity(n)
    for idx in range(n):
        for jdx in range(n):
            if idx == jdx:
                continue
            CN_01 = Matrix.cnot(n, idx, jdx)
            CN_10 = Matrix.cnot(n, jdx, idx)
            assert CN_01 * CN_01 == I
            assert CN_10 * CN_10 == I
            lhs = CN_10 * CN_01 * CN_10
            rhs = Matrix.swap(n, idx, jdx)
            assert lhs == rhs
            lhs = CN_01 * CN_10 * CN_01
            assert lhs == rhs

    #print(Matrix.cnot(3, 0, 2))

    #if 0:
    cnot = Matrix.cnot
    hadamard = Matrix.hadamard
    n = 2
    gen = [cnot(n, 0, 1), cnot(n, 1, 0), hadamard(n, 0), hadamard(n, 1)]
    for A in gen:
        assert A.is_symplectic()
    Cliff2 = mulclose_fast(gen)
    assert len(Cliff2) == 72  # index 10 in Sp(2, 4)

    CZ = array2([[1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 1, 0], [1, 0, 0, 1]])
    CZ = Matrix(CZ)
    assert CZ.is_symplectic()
    assert CZ in Cliff2

    n = 3
    gen = [
        cnot(n, 0, 1),
        cnot(n, 1, 0),
        cnot(n, 0, 2),
        cnot(n, 2, 0),
        cnot(n, 1, 2),
        cnot(n, 2, 1),
        hadamard(n, 0),
        hadamard(n, 1),
        hadamard(n, 2),
    ]
    for A in gen:
        assert A.is_symplectic()
    assert len(mulclose_fast(gen)) == 40320  # index 36 in Sp(2,4)

    if 0:
        # cnot's generate GL(2, n)
        n = 4
        gen = []
        for i in range(n):
            for j in range(n):
                if i != j:
                    gen.append(cnot(n, i, j))
        assert len(mulclose_fast(gen)) == 20160

    if 0:
        n = 2
        count = 0
        for A in enum2(4 * n * n):
            A.shape = (2 * n, 2 * n)
            A = Matrix(A)
            try:
                assert A.is_symplectic()
                count += 1
            except:
                pass
        print(count)  # 720 = |Sp(2, 4)|
        return

    for n in [1, 2]:
        gen = []
        for x in enum2(2 * n):
            A = Matrix.transvect(x)
            assert A.is_symplectic()
            gen.append(A)
        G = mulclose_fast(gen)
        assert len(G) == [6, 720][n - 1]

    n = 2
    Sp = G
    #print(len(Sp))
    found = set()
    for g in Sp:
        A = g.A.copy()
        A[:n, n:] = 0
        A[n:, :n] = 0
        found.add(str(A))
    #print(len(A))

    #return

    n = 4
    I = Matrix.identity(n)
    H = Matrix.hadamard(n, 0)
    assert H * H == I

    CN_01 = Matrix.cnot(n, 0, 1)
    assert CN_01 * CN_01 == I

    n = 3
    trivial = CSSCode(Lx=parse("1.."),
                      Lz=parse("1.."),
                      Hx=zeros2(0, n),
                      Hz=parse(".1. ..1"))

    assert trivial.row_equal(CSSCode.get_trivial(3, 0))

    repitition = CSSCode(Lx=parse("111"),
                         Lz=parse("1.."),
                         Hx=zeros2(0, n),
                         Hz=parse("11. .11"))

    assert not trivial.row_equal(repitition)

    CN_01 = Matrix.cnot(n, 0, 1)
    CN_12 = Matrix.cnot(n, 1, 2)
    CN_21 = Matrix.cnot(n, 2, 1)
    CN_10 = Matrix.cnot(n, 1, 0)
    encode = CN_12 * CN_01

    code = CN_01(trivial)
    assert not code.row_equal(repitition)
    code = CN_12(code)
    assert code.row_equal(repitition)

    A = get_encoder(trivial, repitition)

    gen, names = get_gen(3)
    word = mulclose_find(gen, names, A)

    if 1:
        assert type(word) is tuple
        #print("word:")
        #print(repr(word))

        items = [gen[names.index(op)] for op in word]
        op = reduce(mul, items)

        #print(op)
        #assert op*(src) == (tgt)

        #print(op(trivial).longstr())
        assert op(trivial).row_equal(repitition)