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
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))
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("@"))
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
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
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]
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
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)