def longstr(self): lines = [ "CSSCode:", "Lx:Lz =", shortstrx(self.Lx, self.Lz), "Hx:Tz =", shortstrx(self.Hx, self.Tz), "Tx:Hz =", shortstrx(self.Tx, self.Hz) ] return '\n'.join(lines)
def test_quantum(): m = argv.get("m", 4) n = argv.get("n", m + m + 1) dist = argv.get("dist", 3) N = argv.get("N", 2) M = argv.get("M", N) p = argv.get("p", 0.03) weight = argv.weight codes = [] code = None for i in range(N): Hx, Hz = make_quantum(n, m, dist, weight) #Hx, Hz = make_surface() print("Hx, Hz:") print(shortstrx(Hx, Hz)) c = CSSCode(Hx=Hx, Hz=Hz) codes.append(c) code = c if code is None else code + c for _ in range(2 * M): print(code) #code.save("glue.ldpc") counts, err = score(code, p) print("err = %.4f" % err) i0 = numpy.argmin(counts) i1 = numpy.argmax(counts) assert i0 != i1 print(counts, i0, i1) code = code.glue(i0, i1) code = code.dual() print(shortstrx(code.Hx, code.Hz)) return code = CSSCode(Hx=Hx, Hz=Hz) print(code) code = code + code print(shortstrx(code.Hx, code.Hz)) #Hx, Hz = glue1_quantum(code.Hx, code.Hz, 0, 1) #code = CSSCode(Hx=Hx, Hz=Hz) code = code.glue(0, n) print(code) print(shortstrx(code.Hx, code.Hz)) return k = argv.get("k", 1) pairs = [(i, i) for i in range(k)] H1x, H1z = glue_quantum(Hx, Hz, Hx, Hz, pairs) assert dot2(H1x, H1z.transpose()).sum() == 0 code = CSSCode(Hx=H1x, Hz=H1z) print(code) print(shortstrx(code.Hx, code.Hz))
def glue_logops(): m = argv.get("m", 4) n = argv.get("n", m + m + 1) dist = argv.get("dist", 3) N = argv.get("N", 2) M = argv.get("M", N) p = argv.get("p", 0.03) weight = argv.weight codes = [] code = None for i in range(N): Hx, Hz = make_quantum(n, m, dist, weight) #Hx, Hz = make_surface() print("Hx, Hz:") print(shortstrx(Hx, Hz)) c = CSSCode(Hx=Hx, Hz=Hz) codes.append(c) code = c if code is None else code + c A, B = codes code = A + B print(code) print("Lx, Lz:") print(shortstrx(code.Lx, code.Lz)) print("Hx, Hz:") print(shortstrx(code.Hx, code.Hz)) print() #Hx = cat((code.Lx, code.Hx)) Hx = code.Hx Hz = cat((code.Lz, code.Hz)) idxs = list(range(2 * n)) idxs.sort(key=lambda i: (-code.Lz[:, i].sum(), )) Hx = Hx[:, idxs] Hz = Hz[:, idxs] print(shortstrx(Hx, Hz)) i0 = argv.get("i0") i1 = argv.get("i1") if i0 is None: return # code = code.glue(0, n) # print(code) # print(shortstrx(code.Hx, code.Hz)) Hx, Hz = glue1_quantum(Hx, Hz, i0, i1) print("Hx, Hz:") print(shortstrx(Hx, Hz))
def glue_morth(): m = argv.get("m", 4) n = argv.get("n", m + m + 1) genus = argv.get("genus", 2) if 0: H = make_morthogonal(m, n, genus) elif 0: H = reed_muller.build(1, 4).G print(shortstrx(H)) else: H = find_triorth(m, 1) assert dot2(H, H.transpose()).sum() == 0 Hx = Hz = H if 0: print(classical_distance(Hx)) print(classical_distance(Hz)) i0 = 0 i1 = Hx.shape[1] Hx = direct_sum(Hx, Hx) Hz = direct_sum(Hz, Hz) print(shortstrx(Hx, Hz)) print(strong_morthogonal(Hx, genus)) print(strong_morthogonal(Hz, genus)) print() code = CSSCode(Hx=Hx, Hz=Hz) print(code) if 0: Hz = glue_self_classical(Hz, [(i0, i1), (i0, i1 + 1)]) print(shortstrx(Hz)) print(strong_morthogonal(Hz, genus)) print() return Hx, Hz = glue_self(Hx, Hz, [(i0, i1), (i0, i1 + 1)]) #Hx, Hz = glue_self(Hx, Hz, [(i0, i1)]) print(shortstrx(Hx, Hz)) print(strong_morthogonal(Hx, genus)) print(strong_morthogonal(Hz, genus)) print() code = CSSCode(Hx=Hx, Hz=Hz) # Hx, Hz = glue_self(Hx, Hz, [(0, n)]) # print(shortstrx(Hx, Hz)) # print(strong_morthogonal(Hx, genus)) # print(strong_morthogonal(Hz, genus)) # print() code = CSSCode(Hx=Hx, Hz=Hz) print(code)
def glue_gcolor(): from qupy.ldpc.gcolor import Lattice l = argv.get('l', 1) lattice = Lattice(l) #code = lattice.build_code() H = lattice.Hx print("H:", H.shape) print(shortstr(H)) m, n = H.shape H1 = zeros2(m + 1, n + 1) H1[1:, 1:] = H H1[0, :] = 1 # print() # print(shortstr(H1)) # for genus in range(1, 5): # print(genus, strong_morthogonal(H1, genus)) H = H1 genus = argv.get("genus", 3) H = H.astype(numpy.int32) n = H.shape[1] if argv.scramble: R = rand2(m, m) H = dot2(R, H) print("H:", H.shape) print(shortstrx(H)) assert dot2(H, H.transpose()).sum() == 0 i0 = argv.get("i0", 0) i1 = argv.get("i1", i0) i2 = argv.get("i2", n) i3 = argv.get("i3", i2 + 1) # glue i0<-->i2 and i1<-->i3 H2 = direct_sum(H, H) print(H2.shape) print(shortstrx(H2)) assert strong_morthogonal(H2, genus) print() H3 = glue_self_classical(H2, [(i0, i2), (i1, i3)]) print(H3.shape) print(shortstrx(H3)) assert strong_morthogonal(H3, genus) print() print(shortstr((H2[:m, 1:n] + H3[:m, 1:n]) % 2)) #print(eq2(H2[m+2:, i1+2:], H3[m:, i1:])) #print(classical_distance(H3)) return H3
def sparsecss(n, mx, mz, weight=8, **kw): print("sparsecss", n, mx, mz) k = n-mx-mz assert k>=0 vec = lambda n=n, weight=weight : rand2(1, n, weight=weight) Hz = zeros2(0, n) Hx = zeros2(0, n) Hx = append2(Hx, vec()) while len(Hz)<mz or len(Hx)<mx: # append2 Hz rows = shortstr(Hz).split() #print rows while Hz.shape[0]<mz: v = vec() u = dot2(Hx, v.transpose()) if u.sum() == 0 and shortstr(v) not in rows: Hz = append2(Hz, v) break # append2 Hx rows = shortstr(Hx).split() #print rows while Hx.shape[0]<mx: v = vec() u = dot2(Hz, v.transpose()) if u.sum() == 0 and shortstr(v) not in rows: Hx = append2(Hx, v) break print(shortstrx(Hz, Hx)) print() bits = [] for i in range(n): if Hx[:, i].sum() == 0: bits.append(i) elif Hz[:, i].sum() == 0: bits.append(i) for i in reversed(bits): Hx = numpy.concatenate( (Hx[:, :i], Hx[:, i+1:]), axis=1) Hz = numpy.concatenate( (Hz[:, :i], Hz[:, i+1:]), axis=1) #print shortstrx(Hx, Hz) C = CSSCode(Hx=Hx, Hz=Hz, **kw) return C
def main(): n = argv.get("n", 8) k = argv.get("k", 4) kt = argv.get("kt", 4) d = argv.get("d", 1) # distance na = argv.get("na", n) nb = argv.get("nb", n) ka = argv.get("ka", k) kat = argv.get("kat", kt) kb = argv.get("kb", k) kbt = argv.get("kbt", kt) A = random_code(na, ka, kat, d) B = random_code(nb, kb, kbt, d) #assert A.shape == (na-ka, na), (A.shape,) #assert B.shape == (nb-kb, nb), (B.shape,) print("A, B:") print(shortstrx(A, B)) if 1: # A tensor B kw = hypergraph_product(A, B) test_puncture(**kw) else: # -------------------------------------- #B, Bt = Bt, B KerA = find_kernel(A).transpose() ma = na-ka mb = nb-kb print("KerA:") print(shortstrx(KerA)) print() # print(shortstrx(kron(KerA, identity2(mb)))) print(shortstrx( kron(identity2(mb), KerA), kron(B, identity2(na))))
def shorten(G, i): print(shortstrx(G)) H = array2(list(find_kernel(G))) m, n = H.shape H1 = zeros2(m + 1, n) H1[:m, :] = H H1[m, i] = 1 print() print(shortstrx(H1)) print() G1 = array2(list(find_kernel(H1))) m, n = G1.shape G2 = zeros2(m, n - 1) G2[:, :i] = G1[:, :i] G2[:, i:] = G1[:, i + 1:] print() print(shortstrx(G2)) print(strong_morthogonal(G2, 2)) H2 = array2(list(find_kernel(G2))) print(classical_distance(H2))
def glue_classical(): from bruhat.triply_even import build genus = argv.get("genus", 3) m = argv.get("dim", 7) idx = argv.get("idx", 144) H = build.get(m, idx) H = H.astype(numpy.int32) n = H.shape[1] if argv.scramble: R = rand2(m, m) H = dot2(R, H) print(shortstrx(H)) assert dot2(H, H.transpose()).sum() == 0 i0 = argv.get("i0", 0) i1 = argv.get("i1", i0) i2 = argv.get("i2", n) i3 = argv.get("i3", i2 + 1) # glue i0<-->i2 and i1<-->i3 #H2 = direct_sum(H, H) H2 = H #print(shortstrx(H2)) assert strong_morthogonal(H2, genus) print() H3 = glue_self_classical(H2, [(i0, i2), (i1, i3)]) print(shortstrx(H3)) assert strong_morthogonal(H3, genus) print() print(shortstr((H2[:m, 1:n] + H3[:m, 1:n]) % 2)) #print(eq2(H2[m+2:, i1+2:], H3[m:, i1:])) #print(classical_distance(H3)) return H3
def sparsecss_FAIL(n, mx, mz, weight=3, **kw): print("sparsecss", n, mx, mz) k = n-mx-mz assert k>=0 Hz = rand2(mz, n, weight=weight) #print shortstrx(Hx) kern = numpy.array(solve.find_kernel(Hz)) mkern = kern.shape[0] print("kern:") print(shortstr(kern)) print() kern1 = zeros2(mkern, n) for i in range(mkern): v = rand2(1, mkern) kern1[i] = dot2(v, kern) print("kern1:") print(shortstr(kern1)) print() kern = kern1 Hx = [] for i in range(mx): j = randint(0, mkern-1) v = kern[j].copy() count = 0 while 1: v += kern[randint(0, mkern-1)] v %= 2 w = v.sum() if w==weight and count > 100: break count += 1 Hx.append(v) Hx = array2(Hx) print(shortstrx(Hx)) C = CSSCode(Hx=Hx, Hz=Hz, **kw) return C
def main(): # test that robustness is equiv. to full-rank property #n, k, kt, d = 8, 4, 0, 1 cw = argv.get("cw", 3) # column weight rw = argv.get("rw", 4) # row weight n = argv.get("n", 8) # cols m = argv.get("m", n * cw // rw) # rows d = argv.get("d", 1) # distance rank = argv.get("rank", 0) print("m =", m) trials = argv.get("trials", 1000) while 1: #H = random_code(n, k, kt, d) H = make_gallagher(m, n, cw, rw, d) if len(H) < rank: continue G = find_kernel(H) print() print("__" * 20) print("G:%sH:" % (' ' * (n - 1), )) print(shortstrx(G, H)) print(G.shape, H.shape) result = get_bipuncture(G, H, trials) print("get_bipuncture:", result) robust = result is not None if robust: idxs, jdxs = result build_echelon(G, H, idxs, jdxs) rhs = has_property(G, trials) assert robust == rhs, (robust, rhs) #assert not rhs or robust # rhs ==> robust #print(robust) print() if argv.robust: assert robust
def get_bipuncture(H, G=None, verbose=True): n = H.shape[1] if G is None: G = find_kernel(H) k = len(G) if verbose: print(shortstrx(G, H)) while 1: # copied from classical.py idxs = set() while len(idxs) < k: idx = randint(0, n - 1) idxs.add(idx) idxs = list(idxs) idxs.sort() G1 = in_support(G, idxs) if len(G1): continue jdxs = set() while len(jdxs) < k: jdx = randint(0, n - 1) if jdx not in idxs: jdxs.add(jdx) jdxs = list(jdxs) jdxs.sort() G2 = in_support(G, jdxs) if len(G2) == 0: break if 0: v = zeros2(1, n) v[:, idxs] = 1 print(shortstr(v)) v = zeros2(1, n) v[:, jdxs] = 1 print(shortstr(v)) if verbose: print("in_support(H):", in_support(H, idxs), in_support(H, jdxs)) return idxs, jdxs
def test_indep(Lx0, Lx1, Hxi, Hx, **kw): if argv.verbose: print("Lx0:", Lx0.shape) print(shortstr(Lx0)) print("Lx1:", Lx1.shape) print(shortstr(Lx1)) print("Hxi:", Hxi.shape) print(shortstr(Hxi)) Lx0 = independent_logops(Lx0, Hxi) Lx1 = independent_logops(Lx1, Hxi) i0, i1, i2 = len(Lx0), len(Lx1), len(Hxi) J = numpy.concatenate((Lx0, Lx1, Hxi)) K = find_cokernel(J) print("K:", K.shape) print(shortstrx(K[:, :i0], K[:, i0:i0 + i1], K[:, i0 + i1:i0 + i1 + i2])) assert dot2(K, J).sum() == 0
def dense(Gx, Gz, Hx, Hz, Rx, Rz, Pxt, Qx, Pz, Tx, **kw): r, n = Rx.shape N = 2**r gz = len(Gz) # print "Hz:" # print shortstr(Hz) print("Hx|Tx:") print(shortstrx(Hx, Tx)) print("Hx:") for i, h in enumerate(Hx): print(i, shortstr(h), h.sum()) print("GzTx") GzTx = dot2(Gz, Tx.transpose()) for i, h in enumerate(GzTx.transpose()): print(i, shortstr(h), h.sum()) # print "Rx:" # print shortstr(Rx) print("Tx:", len(Tx)) #print shortstr(Tx) RR = dot2(Gz, Rx.transpose()) PxtQx = dot2(Pxt, Qx) excite = argv.excite if excite is None: excite = kw.get("excite") if excite: excites = [excite] else: excites = genidx((2,)*len(Tx)) vec0 = None eigvals = [] for excite in excites: print("excite:", excite) assert len(excite)==len(Tx) t = zeros2(n) for i, ex in enumerate(excite): if ex: t = (t + Tx[i])%2 #print "t:", shortstr(t) Gzt = dot2(Gz, t) #print "Gzt:", shortstr(Gzt) if N<=1024: H = numpy.zeros((N, N)) else: H = None A = {} U = [] #for i in range(N): pos = neg = 0 for i, v in enumerate(genidx((2,)*r)): v = array2(v) syndrome = (dot2(Gz, Rx.transpose(), v) + Gzt)%2 value = gz - 2*syndrome.sum() #print shortstr(dot2(Rx.transpose(), v)), value if H is not None: H[i, i] = value U.append(value) for i, v in enumerate(genidx((2,)*r)): v = array2(v) #print shortstr(v), for g in Gx: u = (v + dot2(g, PxtQx))%2 j = eval('0b'+shortstr(u, zero='0')) if H is not None: H[i, j] += 1 A[i, j] = A.get((i, j), 0) + 1 #print H if argv.orbigraph: vals, vecs = do_orbigraph(A, U) show_eigs(vals) #if vec0 is not None: # Hv = numpy.dot(H, vec0) # print numpy.dot(vec0, Hv), # Hv /= numpy.linalg.norm(Hv) # print numpy.dot(vec0, Hv) if argv.solve: assert N <= 1024 assert numpy.allclose(H, H.transpose()) vals, vecs = numpy.linalg.eigh(H) if argv.show_eigs: show_eigs(vals) vals = list(vals) vals.sort() val0 = vals[-1] # top one is last assert vals[-2] < val0 - 1e-4 #print "excite:", excite, print("eigval:", val0) eigvals.append(val0) vec0 = vecs[:,-1] if vec0[0] < 0: vec0 = -vec0 #break if argv.plot: from pyx import graph xdata = U ydata = list(vec0) g = graph.graphxy( width=16, x=graph.axis.linear(reverse=True), y=graph.axis.log(min=0.8*vec0.min(), max=1.0)) # either provide lists of the individual coordinates g.plot(graph.data.values(x=xdata, y=ydata)) # or provide one list containing the whole points #g.plot(graph.data.points(list(zip(range(10), range(10))), x=1, y=2)) g.writePDFfile("pic-groundstate.pdf") return if eigvals: top = max(eigvals) idx = eigvals.index(top) eigvals.pop(idx) second = max(eigvals) print("gap:", top-second)
def main(): import models assert not argv.orbiham, "it's called orbigraph now" if argv.find_ideals: find_ideals() return Gx, Gz, Hx, Hz = models.build() if argv.chainmap: do_chainmap(Gx, Gz) if argv.symmetry: do_symmetry(Gx, Gz, Hx, Hz) return #print shortstrx(Gx, Gz) if argv.report: print("Hz:") for i, h in enumerate(Hz): print(i, shortstr(h), h.sum()) #print shortstr(find_stabilizers(Gx, Gz)) Lz = find_logops(Gx, Hz) Lx = find_logops(Gz, Hx) #print "Lz:", shortstr(Lz) if Lz.shape[0]*Lz.shape[1]: print(Lz.shape, Gx.shape) check_commute(Lz, Gx) check_commute(Lz, Hx) Px = get_reductor(Hx) # projector onto complement of rowspan of Hx Pz = get_reductor(Hz) Rz = [dot2(Pz, g) for g in Gz] Rz = array2(Rz) Rz = row_reduce(Rz, truncate=True) rz = len(Rz) n = Gx.shape[1] print("n =", n) if len(Lx): print("Lx Lz:") print(shortstrx(Lx, Lz)) print("Hx:", len(Hx), "Hz:", len(Hz)) print("Gx:", len(Gx), "Gz:", len(Gz)) Rx = [dot2(Px, g) for g in Gx] Rx = array2(Rx) Rx = row_reduce(Rx, truncate=True) rx = len(Rx) print("Rx:", rx, "Rz:", rz) if argv.show: print(shortstrx(Rx, Rz)) Qx = u_inverse(Rx) Pxt = Px.transpose() assert eq2(dot2(Rx, Qx), identity2(rx)) assert eq2(dot2(Rx, Pxt), Rx) #print shortstr(dot2(Pxt, Qx)) PxtQx = dot2(Pxt, Qx) lines = [shortstr(dot2(g, PxtQx)) for g in Gx] lines.sort() #print "PxtQx:" #for s in lines: # print s #print "RzRxt" #print shortstr(dot2(Rz, Rx.transpose())) offset = argv.offset if len(Hz): Tx = find_errors(Hz, Lz, Rz) else: Tx = zeros2(0, n) if argv.dense: dense(**locals()) return if argv.dense_full: dense_full(**locals()) return if argv.show_delta: show_delta(**locals()) return if argv.slepc: slepc(**locals()) return # if argv.orbigraph: # from linear import orbigraph # orbigraph(**locals()) # return v0 = None # excite = argv.excite # if excite is not None: # v0 = zeros2(n) # v0[excite] = 1 verts = [] lookup = {} for i, v in enumerate(span(Rx)): # XXX does not scale well if v0 is not None: v = (v+v0)%2 v = dot2(Px, v) lookup[v.tobytes()] = i verts.append(v) print("span:", len(verts)) assert len(lookup) == len(verts) mz = len(Gz) n = len(verts) if argv.lie: U = [] for i, v in enumerate(verts): count = dot2(Gz, v).sum() Pxv = dot2(Px, v) assert count == dot2(Gz, Pxv).sum() U.append(mz - 2*count) uniq = list(set(U)) uniq.sort(reverse=True) s = ', '.join("%d(%d)"%(val, U.count(val)) for val in uniq) print(s) print("sum:", sum(U)) return if n <= 1024 and argv.solve: H = numpy.zeros((n, n)) syndromes = [] for i, v in enumerate(verts): syndromes.append(dot2(Gz, v)) count = dot2(Gz, v).sum() Pxv = dot2(Px, v) assert count == dot2(Gz, Pxv).sum() H[i, i] = mz - 2*count for g in Gx: v1 = (g+v)%2 v1 = dot2(Px, v1) j = lookup[v1.tobytes()] H[i, j] += 1 if argv.showham: s = lstr2(H, 0).replace(', ', ' ') s = s.replace(' 0', ' .') s = s.replace(', -', '-') print(s) vals, vecs = numpy.linalg.eigh(H) show_eigs(vals) if argv.show_partition: beta = argv.get("beta", 1.0) show_partition(vals, beta) if argv.orbigraph: if argv.symplectic: H1 = build_orbigraph(H, syndromes) else: H1 = build_orbigraph(H) print("orbigraph:") print(H1) vals, vecs = numpy.linalg.eig(H1) show_eigs(vals) elif argv.sparse: print("building H", end=' ') A = {} # adjacency U = [] # potential if offset is None: offset = mz + 1 # make H positive definite for i, v in enumerate(verts): if i%1000==0: write('.') count = dot2(Gz, v).sum() #H[i, i] = mz - 2*count U.append(offset + mz - 2*count) for g in Gx: v1 = (g+v)%2 v1 = dot2(Px, v1) j = lookup[v1.tobytes()] A[i, j] = A.get((i, j), 0) + 1 print("\nnnz:", len(A)) if argv.lanczos: vals, vecs = do_lanczos(A, U) elif argv.orbigraph: vals, vecs = do_orbigraph(A, U) else: return vals -= offset # offset doesn't change vecs show_eigs(vals) elif argv.orbigraph: assert n<=1024 H = numpy.zeros((n, n)) syndromes = [] for i, v in enumerate(verts): syndromes.append(dot2(Gz, v)) count = dot2(Gz, v).sum() Pxv = dot2(Px, v) assert count == dot2(Gz, Pxv).sum() H[i, i] = mz - 2*count for g in Gx: v1 = (g+v)%2 v1 = dot2(Px, v1) j = lookup[v1.tobytes()] H[i, j] += 1 if argv.showham: s = lstr2(H, 0).replace(', ', ' ') s = s.replace(' 0', ' .') s = s.replace(', -', '-') print(s) if argv.symplectic: H1 = build_orbigraph(H, syndromes) else: H1 = build_orbigraph(H)
def build(name=""): if name: setattr(argv, name, True) # hack this _seed = argv.get("seed") if _seed is not None: numpy.random.seed(_seed) seed(_seed) size = argv.get("size", 1) l = argv.get('l', 4) li = argv.get('li', l) lj = argv.get('lj', l) lk = argv.get('lk', l) if argv.gcolor2 or (argv.gcolor and size == 1.5): Gx, Gz, Hx = build_gcolor2() Hz = Hx.copy() elif argv.gcolor: Gx, Gz, Hx = build_gcolor(size) Hz = Hx.copy() elif argv.compass: Gx, Gz, Hx, Hz = build_compass(li, lj) elif argv.compass3: Gx, Gz, Hx, Hz = build_compass3(li, lj, lk) elif argv.hex: Gx, Gz, Hx, Hz = build_hex(li, lj) elif argv.hex2: Gx, Gz, Hx, Hz = build_hex2(li, lj) elif argv.xy: Gx, Gz, Hx, Hz = build_xy(l) elif argv.xy2: Gx, Gz, Hx, Hz = build_xy2(li, lj) elif argv.xy21: Gx, Gz, Hx, Hz = build_xy21(li, lj) elif argv.xy3: Gx, Gz, Hx, Hz = build_xy3(li, lj, lk) elif argv.xy32: Gx, Gz, Hx, Hz = build_xy32(li, lj, lk) elif argv.ising: Gx, Gz, Hx, Hz = build_ising(l) elif argv.random: Gx, Gz, Hx, Hz = build_random(l) elif argv.random_nostabs: Gx, Gz, Hx, Hz = build_random_nostabs(l) elif argv.random_selfdual: Gx, Gz, Hx, Hz = build_random_selfdual(l) elif argv.pauli: Gx, Gz, Hx, Hz = build_pauli(l) elif argv.projective: n = argv.get('n', 3) dim = argv.get('dim', 2) Gx, Gz, Hx, Hz = build_projective(n, dim) elif argv.test: Gx, Gz, Hx, Hz = build_test() else: name = argv.next() try: fn = eval("build_%s" % name) except NameError: print("no model found") raise Gx, Gz, Hx, Hz = fn() if Hx is None: Hx = find_stabilizers(Gz, Gx) if Hz is None: Hz = find_stabilizers(Gx, Gz) if argv.flip: Gz, Gx = Gx, Gz Hz, Hx = Hx, Hz if argv.show: print("Gx Gz:") print(shortstrx(Gx, Gz)) if len(Hx): print("Hx Hz:") print(shortstrx(Hx, Hz)) return Gx, Gz, Hx, Hz
def build_model(Gx=None, Gz=None, Hx=None, Hz=None): if Gx is None: Gx, Gz, Hx, Hz = build() n = Gx.shape[1] if Hx is None: Hx = find_stabilizers(Gz, Gx) if Hz is None: Hz = find_stabilizers(Gx, Gz) check_commute(Hx, Hz) check_commute(Gx, Hz) check_commute(Hx, Gz) #Px = get_reductor(concatenate((Lx, Hx))) #Pz = get_reductor(concatenate((Lz, Hz))) Px = get_reductor(Hx) Pz = get_reductor(Hz) # Lz = find_logops( Hx , Hz ) # find_logops( ............. , ............. ) # ( commutes with , orthogonal to ) # ( ............. , ............. ) Lz = find_logops(Gx, Hz) assert Lz.shape[1] == n if 0: PGz = get_reductor(Gz) Lz = dot2(Lz, PGz.transpose()) Lz = row_reduce(Lz) print(shortstrx(Lz, Gz, Hz)) if len(Lz): #print Lz.shape, Hz.shape assert len(row_reduce(concatenate((Lz, Hz)))) == len(Lz) + len(Hz) assert len(row_reduce(concatenate( (Lz, Gz)))) == len(Lz) + len(row_reduce(Gz)) # Tz = find_errors( Hx , Lx ) # find_errors( ............. , ............. ) # ( conjugate to , commutes with ) # ( ............. , ............. ) Lx = find_errors(Lz, Gz) # invert Lz, commuting with Gz check_commute(Lx, Gz) check_commute(Lx, Hz) check_conjugate(Lx, Lz) check_commute(Lz, Gx) check_commute(Lz, Hx) # Lx | Lz # Hx | ? # ? | Hz # ? | ? #Rz = find_logops(concatenate((Lx, Hx)), Hz) Rz = dot2(Gz, Pz.transpose()) Rz = row_reduce(Rz) check_commute(Rz, Lx) check_commute(Rz, Hx) Rx = dot2(Gx, Px.transpose()) Rx = row_reduce(Rx) check_commute(Rx, Lz) check_commute(Rx, Hz) # Lx | Lz # Hx | ? # ? | Hz # Rx'| Rz' Tz = find_errors(Hx, concatenate((Lx, Rx))) Tx = find_errors(Hz, concatenate((Lz, Rz, Tz))) assert len((concatenate((Lx, Hx, Tx, Rx)))) == n assert len((concatenate((Lz, Hz, Tz, Rz)))) == n assert len(row_reduce(concatenate((Lx, Hx, Tx, Rx)))) == n assert len(row_reduce(concatenate((Lz, Hz, Tz, Rz)))) == n check_commute(Rz, Tx) Rx = find_errors(Rz, concatenate((Lz, Hz, Tz))) check_conjugate(Rx, Rz) check_commute(Rx, Hz) check_commute(Rx, Tz) check_commute(Rx, Lz) Rxt = Rx.transpose() Rzt = Rz.transpose() Pxt = Px.transpose() Pzt = Pz.transpose() check_sy(Lx, Hx, Tx, Rx, Lz, Hz, Tz, Rz) assert eq2(dot2(Gz, Rxt), dot2(Gz, Pzt, Rxt)) assert eq2(dot2(Gx, Rzt), dot2(Gx, Pxt, Rzt)) # print shortstrx(dot2(Rx, Pz), Rx) assert eq2(dot2(Rx, Pz), Rx) assert eq2(dot2(Rz, Px), Rz) assert len(find_kernel(dot2(Gz, Rx.transpose()))) == 0 model = Model(locals()) if argv.dual: model = model.get_dual() argv.dual = False # HACK !! return model
Hx[:mx, :n] = model.Hx Hz[:mz, :n] = model.Hz Hx[mx:, :n] = model.Lx Hz[mz:, :n] = model.Lz for i in range(k): Hx[mx + i, n + i] = 1 Hz[mz + i, n + i] = 1 model = build_model() # um.... print(model) if argv.show: print("Hx/Hz:") print(shortstrx(model.Hx, model.Hz)) print() print("Gx/Gz:") print(shortstrx(Gx, Gz)) print() print("Lx/Lz:") print(shortstrx(model.Lx, model.Lz)) if len(model.Lx) and argv.distance: w = min([v.sum() for v in span(model.Lx) if v.sum()]) print("distance:", w) if argv.do_lp: model.do_lp() if argv.do_slepc:
def test_code(Hxi, Hzi, Hx, Lx, Lz, Lx0, Lx1, LxiHx, **kw): code = CSSCode(Hx=Hxi, Hz=Hzi) print(code) assert rank(intersect(Lx, code.Lx)) == code.k assert rank(intersect(Lz, code.Lz)) == code.k verbose = argv.verbose decoder = get_decoder(argv, argv.decode, code) if decoder is None: return p = argv.get("p", 0.01) N = argv.get("N", 0) distance = code.n count = 0 failcount = 0 nonuniq = 0 logops = [] for i in range(N): err_op = ra.binomial(1, p, (code.n, )) err_op = err_op.astype(numpy.int32) op = decoder.decode(p, err_op, verbose=verbose, argv=argv) c = 'F' success = False if op is not None: op = (op + err_op) % 2 # Should be a codeword of Hz (kernel of Hz) assert dot2(code.Hz, op).sum() == 0 write("%d:" % op.sum()) # Are we in the image of Hx ? If so, then success. success = dot2(code.Lz, op).sum() == 0 if success and op.sum(): nonuniq += 1 c = '.' if success else 'x' if op.sum() and not success: distance = min(distance, op.sum()) write("L") logops.append(op.copy()) else: failcount += 1 write(c + ' ') count += success if N: print() print(argv) print("error rate = %.8f" % (1. - 1. * count / (i + 1))) print("fail rate = %.8f" % (1. * failcount / (i + 1))) print("nonuniq = %d" % nonuniq) print("distance <= %d" % distance) mx0, mx1 = len(Lx0), len(Lx1) LxHx = numpy.concatenate((Lx0, Lx1, Hx)) for op in logops: print(op.sum()) #print(shortstr(op)) #print(op.shape) #print(op) K = solve(LxHx.transpose(), op) K.shape = (1, len(K)) print(shortstrx(K[:, :mx0], K[:, mx0:mx0 + mx1], K[:, mx0 + mx1:]))
def main(l): lattice = Lattice(l) n = len(lattice.qubits) print(lattice) code = lattice.build_code(check=False) #Ex = lattice.Ex Gx, Gz = code.Gx, code.Gz Hx, Hz = code.Hx, code.Hz Lx = find_logops(Gz, Hx) #print Lx #print dot2(Lx, Gz.transpose()) print(code) print("Gx:") print(shortstrx(Gx)) print("Hx:") print(shortstrx(Hx)) print("Lx:") print(shortstrx(Lx)) print("0-simplices (bodies):", len(lattice.simplices[0])) print("1-simplices (faces):", len(lattice.simplices[1])) print("2-simplices (edges):", len(lattice.simplices[2])) corners = [] edges = [] faces = [] internal = [] for i in range(n): gw = Gx[:, i].sum() hw = Hx[:, i].sum() assert gw >= 3 assert hw in [1, 2, 3, 4] assert gw in [3, 5, 6] if gw == 3: corners.append(i) assert hw == 1 elif gw == 5: edges.append(i) assert hw == 2 elif gw == 6: if hw == 3: faces.append(i) else: assert hw == 4 internal.append(i) assert len(corners) + len(edges) + len(faces) + len(internal) == n #return # op = zeros2(n) # for i in corners: # op[i] = 1 # assert solve(Gx.transpose(), op) if 0: # ops spanned by gauge operators are all even weight for trial in range(100): m = len(Gx) op = zeros2(n) for i in range(m // 2): op += Gx[randint(0, m - 1)] op %= 2 w = op.sum() % 2 assert w % 2 == 0 print(op) #return desc = "stabs gauge strings qubits".split() for d in range(4): counts = {} print("%d:" % d, desc[d]) for p in lattice.simplices[d]: #print '\t', p #if not p.is_internal(): # continue cs = [colorof(v) for v in p.vs] cs.sort() cs = tuple(cs) + (len(lattice.get_qubits(p)), ) counts[cs] = counts.get(cs, 0) + 1 print(counts) R = [] for p in lattice.simplices[1]: a = lattice.make_op(p) a.shape = 1, n R.append(a) find_skip(Hx, Lx, R) return A = Hx[:, :] r = rank(A) source = [] for p in lattice.simplices[1]: if not p.is_internal(): continue vs = p.vs v0, v1 = vs key = (v1 - v0), p source.append(key) source.sort(key=lambda k_p: (k_p[0].color, k_p[0]), reverse=True) source = [(None, p) for p in lattice.simplices[1]] gauges = {} for key, p in source: if p.is_internal(): vs = p.vs v0, v1 = vs #write(str(v1-v0)) a = lattice.make_op(p) a.shape = 1, n A1 = numpy.concatenate((A, a)) if rank(A1) == r: #write("\n") continue #write(" OK\n") r = r + 1 A = A1 key = [colorof(v) for v in p.vs] key.sort() key = tuple(key) # + (len(lattice.get_qubits(p)),) gauges.setdefault(key, []).append(p) #print for key, value in list(gauges.items()): print(key, len(value)) print("rank:", r) print(rank(A)) #print shortstrx(A) return key = list(gauges.keys())[0] A = [] for op in gauges[key]: a = zeros2(n) for qubit in lattice.get_qubits(op): a[qubit.i] = 1 A.append(a) A = array2(A) #print shortstrx(A) print(A.shape) print(rank(A)) A = numpy.concatenate((Hx, A)) print(A.shape) print(rank(A)) #code.build_from_gauge() #A = dot2(code.Gx, code.Gz.transpose()) #print shortstrx(code.Gxr, code.Gzr) #print shortstr(A) assert rank(Hx) == Hx.shape[0] # L.I. #Hx = linear_independant(Hx) #Hz = linear_independant(Hz) n = code.n m = Hx.shape[0] + Hz.shape[0] r = n - m - 1 assert r % 2 == 0 return Rx = [] Rz = [] for gx, gz in pairs: Rx.append(gx) Rz.append(gz) Rx.append(gz) Rz.append(gx) Rx = array2(Rx) Rz = array2(Rz) print(shortstrx(Rx, Rz)) assert Rx.shape[0] == r assert rank(Rx) == r assert rank(numpy.concatenate((Rx, Hx))) == r + m // 2 A = dot2(Rx, Rz.transpose()) print(shortstrx(A)) return Rx = slow_remove(Gx, Hx) Rz = slow_remove(Gz, Hz) r = rank(Rx) assert r + m + 1 == n print("r =", r)
def test_puncture(A, B, ma, na, mb, nb, Ina, Ima, Inb, Imb, ka, kb, kat, kbt, k, KerA, KerB, CokerA, CokerB, Lzi, Lxi, Hzi, Hxi, **kw): I = identity2 assert ka - na + ma -kat == 0 assert kb - nb + mb -kbt == 0 #print("ka=%s, kat=%s, kb=%s, kbt=%s"%(ka, kat, kb, kbt)) assert k == ka*kbt + kat*kb == len(Lzi) == len(Lxi) kernel = lambda X : find_kernel(X).transpose() # use convention in paper KerA = KerA.transpose() # use convention in paper KerB = KerB.transpose() # use convention in paper #CokerA = CokerA.transpose() # use convention in paper #CokerB = CokerB.transpose() # use convention in paper assert CokerA.shape == (kat, ma) assert CokerB.shape == (kbt, mb) blocks = [ [kron(KerA, Imb), zeros2(na*mb, ma*kb), kron(Ina, B)], [zeros2(ma*nb, ka*mb), kron(Ima, KerB), kron(A,Inb)], ] print("blocks:", [[X.shape for X in row] for row in blocks]) #print(shortstrx(*blocks[0])) #print() #print(shortstrx(*blocks[1])) Mv = cat((blocks[0][0], blocks[0][2]), axis=1) Mh = cat((blocks[1][0], blocks[1][2]), axis=1) M = cat((Mv, Mh), axis=0) KM = kernel(M) Mv = cat(blocks[0], axis=1) Mh = cat(blocks[1], axis=1) M = cat((Mv, Mh), axis=0) x = kron(I(ka), B) dot2(blocks[0][0], x) y = zeros2(blocks[0][1].shape[1], x.shape[1]) dot2(blocks[0][1], y) z = kron(KerA, I(nb)) dot2(blocks[0][2], z) #print(shortstr(x)+'\n') #print(shortstr(y)+'\n') #print(shortstr(z)+'\n') xz = cat((x, z), axis=0) xyz = cat((x, y, z), axis=0) assert dot2(M, xyz).sum() == 0 #print(shortstr(xyz)) print("xyz:", xyz.shape) assert len(find_kernel(xyz))==0 assert rowspan_eq(KM.transpose(), xz.transpose()) print("kernel(M):", kernel(M).shape) Hzt = cat((blocks[0][2], blocks[1][2]), axis=0) #print("kernel(Hzt):", kernel(Hzt).shape) KHzt = kernel(Hzt) #assert KHzt.shape[1] == 0, (KHzt.shape,) print("kernel(Hzt):", KHzt.shape) Hx = cat((kron(A, I(mb)), kron(I(ma), B)), axis=1) #print("CokerB") #print(shortstr(CokerB)) #R = CokerB #R = rand2(CokerB.shape[0], CokerB.shape[1]) #R = rand2(mb, 1) #R = CokerB[:, 0:1] if argv.puncture and 1: idxs = get_puncture(B.transpose(), kbt) print("get_puncture:", idxs) R = zeros2(mb, len(idxs)) for i, idx in enumerate(idxs): R[idx, i] = 1 elif argv.puncture: idxs = get_puncture(B.transpose(), kbt) R = zeros2(mb, 1) R[idxs] = 1 elif argv.identity2: R = I(mb) else: R = B[:, :1] #R = rand2(mb, 100) print("R:") print(shortstrx(R)) lzt = cat((kron(KerA, R), zeros2(ma*nb, KerA.shape[1]*R.shape[1])), axis=0) print("lzt:", lzt.shape) print(shortstrx(lzt)) print("Hzt:", Hzt.shape) print(shortstrx(Hzt)) assert dot2(Hx, lzt).sum()==0 lz = lzt.transpose() Hz = Hzt.transpose() print(rank(lz), rank(Hz), rank(intersect(lz, Hz))) result = rowspan_le(lzt.transpose(), Hzt.transpose()) print("lzt <= Hzt:", result) if argv.puncture: assert not result assert not rank(intersect(lz, Hz)) print("OK")
def glue_classical_self(): from bruhat.triply_even import build from bruhat.triply_even import codes24 genus = argv.get("genus", 3) if argv.golay: H = codes24.get("g_{24}") else: m = argv.get("dim", 7) idx = argv.get("idx", 144) H = build.get(m, idx) H = shorten(H, 0) return H = H.astype(numpy.int32) count = argv.get("count", 1) if count == 0: print(H.shape) print(shortstrx(H)) print("distance:", classical_distance(H)) for ii in range(count): m, n = H.shape R = rand2(m, m) H = dot2(R, H) if ii == 0: print(H.shape) print(shortstrx(H)) assert dot2(H, H.transpose()).sum() == 0 # i0 = argv.get("i0", 0) # i1 = argv.get("i1", i0) # i2 = argv.get("i2", 1) # i3 = argv.get("i3", i2+1) items = list(range(n)) i0 = random.choice(items) items.remove(i0) i1 = i0 i2 = random.choice(items) items.remove(i2) i3 = random.choice(items) items.remove(i3) # glue i0<-->i2 and i1<-->i3 print("strong_morthogonal(%d) = %s" % (genus, strong_morthogonal(H, genus))) print() H3 = glue_self_classical(H, [(i0, i2), (i1, i3)]) print(H3.shape) print(shortstrx(H3)) print("strong_morthogonal(%d) = %s" % (genus, strong_morthogonal(H3, genus))) H = H3 print("distance:", classical_distance(H)) return H
def hpack(n, j=4, k=1, check=True, verbose=False): write("hpack...") U = identity2(n) # upper triangular L = identity2(n) # lower triangular I = identity2(n) for count in range(j*n): i = randint(0, n-1) j = randint(0, n-1) if i==j: continue U[i] = (U[i] + U[j])%2 L[j] = (L[j] - L[i])%2 assert solve.rank(U) == n assert solve.rank(L) == n assert eq2(dot2(U, L.transpose()), I) if verbose: print() print(shortstrx(U, L)) print() ws = [n] * n ws = stabweights(U, L) for i in range(n): w = min(U[i].sum(), L[i].sum()) ws[i] = min(ws[i], w) ws = list(enumerate(ws)) ws.sort(key = lambda item : -item[1]) idxs = [ws[i][0] for i in range(k)] idxs.sort() Lx, Lz = zeros2(0, n), zeros2(0, n) for idx in reversed(idxs): Lz = append2(Lz, U[idx:idx+1]) Lx = append2(Lx, L[idx:idx+1]) U = pop2(U, idx) L = pop2(L, idx) m = (n-k)//2 Hz, Tz = U[:m], U[m:] Tx, Hx = L[:m], L[m:] if verbose: print() print(shortstrx(Hx, Hz)) write("done.\n") code = CSSCode(Lx, Lz, Hx, Tz, Hz, Tx, check=check, verbose=verbose) return code