def build_tree(n): assert n%2 Hz = [] Hx = [] k0 = -1 k1 = 1 while k1+1<n: h = zeros2(n) h[max(0, k0)] = 1 h[k1] = 1 h[k1+1] = 1 Hz.append(h) if k0+2>=n//4: h = zeros2(n) h[k1] = 1 h[k1+1] = 1 Hx.append(h) k1 += 2 k0 += 1 Hz = array2(Hz) Hx = array2(Hx) print(shortstr(Hz)) print() print(shortstr(Hx)) code = CSSCode(Hz=Hz, Hx=Hx) return code
def __init__(self, Hxf, Hzf): Hx = remove_dependent(Hxf) Hz = remove_dependent(Hzf) mx, n = Hx.shape mz, n = Hz.shape xstabs = mk_xop(shortstr(Hx)) zstabs = mk_zop(shortstr(Hz)) for zop in zstabs: for xop in xstabs: assert zop*xop == xop*zop I = pauli.parse("I"*n) Pz = I for op in zstabs: Pz = (0.5)*Pz*(I + op) Px = I for op in xstabs: Px = (0.5)*Px*(I + op) self.Hxf = Hxf self.Hzf = Hzf self.Hx = Hx self.Hz = Hz self.Px = Px self.Pz = Pz self.n = n self.mx = mx self.mz = mz self.k = n-mx-mz
def dump(self): G, H = self.G, self.H print("G =") print(shortstr(G)) print("H =") print(shortstr(H))
def row_equal(A, B): assert A.shape[1] == B.shape[1] if A.shape[0] != B.shape[0]: return False A = shortstr(A).split() B = shortstr(B).split() A.sort() B.sort() return A==B
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 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 find_logops(): Hz = parse(""" 11111......................... 1....1111..................... .1.......1111................. ..1..1.......111.............. ...1..1..1......11............ ....1.....1..1....11.......... ...........1....1...111....... ............1.....1.1..11..... ..............1....1...1.11... .......1.......1.........1.11. ........1........1...1.....1.1 ......................1.1.1.11 """) Hx = parse(""" 11......1..1.........1........ .....11..11..1................ ...11...........1.1.1......... .........1..1....1......1....1 ....................11.1.1.1.. ..........11.......1..1...1... .............1.1..1.....1...1. ..11...........1.1.........1.. .....1..1.....1...........1..1 .11.........1.1........1...... 1...1..1...........1.....1.... ......11........1.....1.....1. """) Hz = remove_dependent(Hz) Hx = remove_dependent(Hx) mx, n = Hx.shape mz, n = Hz.shape print(n, mx, mz) Hz = parse("1.111... .111.1.. 1...1.11") Hx = parse("111...1. 11.1...1 ..1.111.") from qupy.ldpc.css import CSSCode code = CSSCode(Hx=Hx, Hz=Hz) print("Lx:") print(shortstr(code.Lx)) print("Lz:") print(shortstr(code.Lz))
def test_ldpc(): n = argv.get("n", 14) m = argv.get("m", n - 3) d = argv.get("d", 0) p = argv.get("p", 0.5) weight = argv.get("weight", 4) dist = argv.get("dist", 4) H1 = make_ldpc(m, n, p, weight, dist) #print(fstr(H1)) #Gt = find_kernel(H1) #w = wenum(H1) #print("wenum:", [len(wi) for wi in w]) H2 = make_ldpc(m, n, p, weight, dist) #print(fstr(H2)) k = argv.get("k", 3) pairs = [(i, i) for i in range(k)] K = glue_pairs(H1, H2, pairs) #print(fstr(K)) assert rank(K) == len(K) print(ldpc_str(H1), "+", ldpc_str(H2), "=", ldpc_str(K)) if argv.show: print(shortstr(K))
def test(n, k, dist=2, verbose=False): assert n > k if argv.rand: while 1: G = rand2(k, n) if rank(G) < k: continue dG = min_weight(G) if dG < dist: continue H = find_kernel(G) dH = min_weight(H) if dH < dist: continue break else: G = zeros2(k, n) jdx = 0 for idx in range(k): for kdx in range(dist): G[idx,jdx+kdx] = 1 jdx += dist-1 dG = min_weight(G) if n < 20 else None assert dG is None or dG == dist H = find_kernel(G) #print(".", flush=True, end="") H = row_reduce(H) search(G, H) if verbose: print("G =") print(shortstr(G)) print("weight =", dG) print() print("H =") print(shortstr(H)) print()
def build_ham(self, excite=None, weights=None, Jx=1., Jz=1.): Gx, Gz = self.Gx, self.Gz Rx, Rz = self.Rx, self.Rz Hx, Hz = self.Hx, self.Hz Tx, Tz = self.Tx, self.Tz gz = len(Gz) r = len(Rx) n = self.n if type(excite) is int: _excite = [0] * len(Tx) _excite[excite] = 1 excite = tuple(_excite) if excite is not None: 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) else: Gzt = 0 if weights is None: weights = [1.] * len(Gx) assert len(weights) == len(Gx), len(weights) H = numpy.zeros((2**r, 2**r)) 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 H[i, i] = Jz * value #U.append(value) Pxt = self.Px.transpose() Qx = Rz.transpose() #print dot2(Rx, Qx) PxtQx = dot2(Pxt, Qx) for i, v in enumerate(genidx((2, ) * r)): v = array2(v) #print shortstr(v), #for g in Gx: for j, g in enumerate(Gx): u = (v + dot2(g, PxtQx)) % 2 k = eval('0b' + shortstr(u, zero='0')) H[i, k] += Jx * weights[j] #A[i, k] = A.get((i, k), 0) + 1 return H
def wenum(): l = argv.get("l", 2) code = Toric2D(l) n = code.n Hz = code.Hz print(shortstr(Hz)) print() Lz = code.Lz print(shortstr(Lz)) Opz = numpy.concatenate((Hz, Lz)) x = Poly({(1, 0): 1}) y = Poly({(0, 1): 1}) zero = Poly({}, 2) polys = {} for v in numpy.ndindex((2, ) * len(Opz)): key = str(v) polys[key] = zero for v in numpy.ndindex((2, ) * n): w = sum(v) key = str(tuple(dot2(Opz, v))) g = x**w * y**(n - w) polys[key] = polys[key] + g for v in numpy.ndindex((2, ) * len(Opz)): key = str(v) print(v, polys[key]) f = reduce(add, polys.values()) print(f) p = 0.05 f = eval(str(f), {"x": (1. - p), "y": p}) print(f) print((x + y)**n)
def save(self, name=None, stem=None): assert name or stem if stem: s = hex(abs(hash(self)))[2:] name = "%s_%s_%d_%d_%d.ldpc"%(stem, s, self.n, self.k, self.d) print("save", name) f = open(name, 'w') for name in 'Lx Lz Hx Tz Hz Tx Gx Gz'.split(): value = getattr(self, name, None) if value is None: continue print("%s ="%name, file=f) print(shortstr(value), file=f) f.close()
def main(): if argv.ldpc: # LDPC l = argv.get("l", 3) # column weight m = argv.get("m", 4) # row weight n = argv.get("n", 8) # cols r = argv.get("r", n * l // m) # rows d = argv.get("d", 1) # distance C = make_gallagher(r, n, l, m, d) print(shortstr(C)) print("rank(C)", rank(C), "kernel(C)", len(find_kernel(C))) if argv.same: D = C else: D = make_gallagher(r, n, l, m, d) assert rank(C) == len(C) assert rank(D) == len(D) print("rank(D)", rank(D), "kernel(D)", len(find_kernel(D))) elif argv.torus: # Torus C = parse(""" 11.. .11. ..11 1..1 """) D = C elif argv.hamming: C = parse(""" ...1111 .11..11 1.1.1.1 """) D = C elif argv.surf or argv.surface: # Surface C = parse(""" 11.. .11. ..11 """) D = C else: return Ct = C.transpose() Dt = D.transpose() hypergraph_product(C, Dt)
def test_repitition(): H = parse(""" 111 11. .11 """) X = Chain([H]) X.check() XX = X.tensor(X.get_dual(), 1) print(XX) print(shortstr(XX[0]))
def opticycle(m, n): best_d = 0 for trial in range(4000): #row = '1101' row = [0] * n for i in range(18): row[randint(0, n-1)] = 1 print(shortstr(row)) Hz = build_cycle(m, n, row) Hz = solve.row_reduce(Hz, truncate=True) #print shortstr(Hz) code = CSSCode(Hz=Hz, build=True, check=True) Lx = code.Lx k = Lx.shape[0] ws = [Lx[i].sum() for i in range(k)] d = min(ws) print("\nd =", d) if d > best_d: d = code.find_distance(stopat=best_d) print("\n*d =", d) if d > best_d: best_d = d best = code print("distance <=", best_d) code = best print() print(code) #print code.weightstr() print(code.weightsummary()) print("distance <=", best_d) return code
def show_delta(Gx, Gz, Hx, Hz, Rx, Rz, Pxt, Qx, Pz, Tx, **kw): r, n = Rx.shape N = 2**r gz = len(Gz) GzTx = dot2(Gz, Tx.transpose()) RR = dot2(Gz, Rx.transpose()) PxtQx = dot2(Pxt, Qx) if argv.excite: excites = [argv.excite] else: excites = genidx((2,)*len(Tx)) 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) #for i in range(N): pos = neg = 0 for i, v in enumerate(genidx((2,)*r)): v = array2(v) syndrome0 = dot2(Gz, Rx.transpose(), v) syndrome = (dot2(Gz, Rx.transpose(), v) + Gzt)%2 delta = syndrome.sum() - syndrome0.sum() if delta > 0: pos += 1 elif delta < 0: neg += 1 if delta: print("%3d %3d" % (gz-2*syndrome0.sum(), gz-2*syndrome.sum())) print(pos, neg, "total:", i+1)
def do_symmetry(Gx, Gz, Hx, Hz): "find permutation symmetries of the code" bag0 = Tanner.build(Gx, Gz) bag1 = Tanner.build(Gx, Gz) #n = Gx.shape[1] #for i in range(n): # print Gx[:, i].sum(), #print rows = [shortstr(h) for h in Hx] bits = [p for p in bag0 if p.desc=='b'] #print bits count = 0 perms = [] #keys = range(m, len(bag0)) #print "keys:", keys for fn in search(bag0, bag1): write('.') perm = [bag1[fn[p.idx]].row for p in bits] #print perm # this is the action of graph automorphism on the stabilizers # rows1 = [rows.index(shortstr(h[perm])) for h in Hx] # print rows1 # perms.append(rows1) count += 1 print() print("isomorphisms:", count) print("stabilizer orbits:", end=' ') marked = {} for i in range(len(Hx)): if i in marked: continue print(i, end=' ') marked[i] = True for perm in perms: marked[perm[i]] = True print()
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 dense_full(Gx, Gz, Hx, Hz, Rx, Pxt, Qx, Pz, Tx, **kw): " find orbigraph for hamiltonian component Gamma " gz, n = Gz.shape if argv.excite: excites = [argv.excite] else: excites = genidx((2,)*len(Tx)) 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) # This is our basis Bx = array2([v+t for v in Rx] + [v+t for v in Hx]) Bx %= 2 r = len(Bx) N = 2**r Bx = row_reduce(Bx, truncate=True) assert len(Bx)==r # linearly independent rows Cx = u_inverse(Bx) 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, Bx.transpose(), v) 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) u0 = dot2(Bx.transpose(), v) #print shortstr(v), for g in Gx: u1 = (u0 + g) % 2 v1 = dot2(Cx.transpose(), u1) assert v1.shape == v.shape j = eval('0b'+shortstr(v1, zero='0')) if H is not None: H[i, j] += 1 A[i, j] = A.get((i, j), 0) + 1 #print H if argv.orbistab: hx = Hx[0] do_orbistab(Bx, Cx, H, hx) if argv.orbigraph: vals, vecs = do_orbigraph(A, U) show_eigs(vals) 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) #print vals vals = list(vals) vals.sort() val0 = vals[-1] # top one is last vec0 = vecs[:,-1] if vec0[0] < 0: vec0 = -vec0 assert vals[-2] < val0 - 1e-4 print("excite:", excite, end=' ') print("eigval:", val0)
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_gcolor2(): n = 39 m = 10 delta = 19 top = n - 1 # top qubit # bottom faces: points must be adjacent in each face bfaces = [[0, 1, 2, 3], [1, 4, 5, 6, 7, 2], [3, 2, 7, 8], [4, 9, 10, 5], [8, 7, 6, 11, 12, 13], [9, 14, 15, 10], [5, 10, 15, 16, 11, 6], [11, 16, 17, 12], [13, 12, 17, 18]] faces = list(bfaces) + [[i + delta for i in face] for face in bfaces] def check_faces(): items = [list(face) for face in faces] for face in items: assert len(face) % 2 == 0, face face.sort() assert len(set([tuple(face) for face in items])) == len(items) check_faces() # bottom edges bedges = [] for face in bfaces: f = len(face) for i in range(f): bedges.append([face[i], face[(i + 1) % f]]) # edges are not yet unique.. for edge in bedges: edge.sort() bedges = list(set([tuple(e) for e in bedges])) # extrude bottom edges to make a face for edge in bedges: edge = list(edge) a, b = edge face = edge + [a + delta, b + delta] faces.append(face) check_faces() stabs = [] for face in bfaces: stabs.append(face + [i + delta for i in face]) # top faces for face in [[0, 1, 4, 9, 14], [0, 3, 8, 13, 18], [14, 15, 16, 17, 18]]: face = [i + delta for i in face] + [top] faces.append(face) check_faces() stabs.append([i + delta for i in range(19)] + [top]) g = len(faces) #print "faces:", g for stab in stabs: assert len(stab) % 2 == 0, stab #faces.sort() #for face in faces: # print face Gx = mkop(n, faces) Gz = Gx.copy() rows = [shortstr(g) for g in Gx] #rows.sort() #for i, row in enumerate(rows): # print row, faces[i] assert len(set(rows)) == len(rows) Hz = mkop(n, stabs) Hx = Hz.copy() # bottom face Lx = mkop(n, [list(range(19))]) Lz = Lx.copy() check_commute(Hx, Hz) check_commute(Hx, Gz) check_commute(Hz, Gx) check_commute(Gx, Lz) check_commute(Gz, Lx) check_commute(Hx, Lz) check_commute(Hz, Lx) #code = CSSCode(Hx=Hx, Gx=Gx, Hz=Hz, Gz=Gz, build=False) Lx = find_logops(Gz, Hx) #print "Lx:", shortstr(Lx) return Gx, Gz, Hx
def check_commute(A, B): if A is None or B is None: return C = dot2(A, B.transpose()) assert C.sum() == 0, "\n%s" % shortstr(C)
def do_lp(self): # so far a failed experiment to apply LP... Gx, Gz = self.Gx, self.Gz Rx, Rz = self.Rx, self.Rz Hx, Hz = self.Hx, self.Hz Tx, Tz = self.Tx, self.Tz Px, Pz = self.Px, self.Pz gz = len(Gz) r = len(Rx) n = self.n assert len(Hz) import pulp prob = pulp.LpProblem("test1", pulp.LpMinimize) # Variables #x = pulp.LpVariable("x", 0, 4) #y = pulp.LpVariable("y", -1, 1) #z = pulp.LpVariable("z", 0) points = list(enum2(r)) lookup = {} #ps = [] for u in points: #name = "u"+shortstr(u) #var = pulp.LpVariable(name, 0., 1.) #lookup[u.tostring()] = var #ps.append(var) for v in points: name1 = "u%sv%s" % (shortstr(u), shortstr(v)) lookup[u.tostring(), v.tostring()] = pulp.LpVariable(name1, 0., 1.) # Objective #prob += x + 4*y + 9*z ps = [lookup[u.tostring(), u.tostring()] for u in points] prob += sum(ps) == 1. if 0: for t in enum2(len(Tx)): txt = dot2(Tx.transpose(), t) items = [] for u in points: Rxtu = dot2(Rx.transpose(), u) coeff = dot2(Gz, Rxtu + txt).sum() - dot2(Gz, Rxtu).sum() items.append(coeff * lookup[shortstr(u)]) prob += sum(items) > 0 ham = [] #pairs = [] for u in points: w = dot2(Gz, Rx.transpose(), u).sum() ham.append((len(Gz) - 2 * w) * lookup[u.tostring(), u.tostring()]) for gx in Gx: v = (u + dot2(gx, Rz.transpose())) % 2 key = u.tostring(), v.tostring() ham.append(lookup[key]) #pairs.append(key) #print w, shortstr(v) print("ham", len(ham)) #pairs = set(pairs) # uniq #for u, v in pairs: spoints = [u.tostring() for u in points] for u in spoints: for v in spoints: # 1/2(x**2 + y**2) >= xy prob += 0.5 * (lookup[u, u] + lookup[v, v]) >= lookup[u, v] for w in spoints: prob += 0.5*(lookup[u,u]+lookup[v,v]+lookup[w,w])>=\ lookup[u,v]+lookup[u,w]-lookup[v,w] prob += (lookup[u, v] == lookup[v, u]) # Objective prob += -sum(ham) print("solving...") pulp.GLPK().solve(prob) # Solution for v in prob.variables(): if v.varValue > 0.: print(v.name, "=", v.varValue) print("objective=", pulp.value(prob.objective))
print("distance:", w) if argv.do_lp: model.do_lp() if argv.do_slepc: model.do_slepc() if argv.solve: vals = model.sparse_ham_eigs() print(vals) if argv.minweight: v = minweight(model.Hz) print("minweight:") print(shortstr(v)) # for g in Gx: # print g.sum(), # print Rx = model.Rx HR = numpy.concatenate((Hx, Rx)) # print shortstr(Hx) # print # print shortstr(SR) # U = solve(Gx.transpose(), HR.transpose()) # print U.shape # h = len(Hx) # #GH = dot2(Gx.transpose(), U)
def strop(self, op): return shortstr(op)
def do_orbistab(Bx, Cx, H, sx): r, n = Bx.shape N = 2**r S = numpy.zeros((N, N)) for i, v in enumerate(genidx((2,)*r)): v = array2(v) u = dot2(Bx.transpose(), v) u1 = (u+sx)%2 v1 = dot2(Cx.transpose(), u1) j = eval('0b'+shortstr(v1, zero='0')) S[i, j] = 1.0 assert numpy.allclose(S, S.transpose()) P = 0.5*(numpy.eye(N) - S) H1 = numpy.dot(P, numpy.dot(H, P)) vals, vecs = numpy.linalg.eigh(H1) show_eigs(vals) idx = numpy.argmax(vals) evec = vecs[:, idx] print(idx) print(evec) #return pairs = [] for i, v in enumerate(genidx((2,)*r)): v = array2(v) u = dot2(Bx.transpose(), v) u1 = (u+sx)%2 v1 = dot2(Cx.transpose(), u1) j = eval('0b'+shortstr(v1, zero='0')) assert i!=j if evec[i]>evec[j] or (evec[i]==evec[j] and i<j): pairs.append((i, j)) # uniq print("pairs:", len(pairs)) print("N:", N) print(pairs) P = numpy.zeros((N, N/2)) Q = numpy.zeros((N/2, N)) for idx, pair in enumerate(pairs): i, j = pair P[i, idx] = 1 P[j, idx] = -1 Q[idx, i] = 1 H = numpy.dot(Q, numpy.dot(H, P)) #print lstr2(H, 0) evec = numpy.dot(Q, evec) print(evec) print("val:", (numpy.dot(evec, numpy.dot(H, evec))) / (numpy.dot(evec, evec))) vals, vecs = numpy.linalg.eig(H) show_eigs(vals.real) #idx = numpy.argmax(vals) print(vals.real)
def slepc(Gx, Gz, Hx, Hz, Rx, Rz, Pxt, Qx, Pz, Tx, **kw): name = argv.get("name", "ex3.tmp.c") print("slepc: name=%s"%name) r = len(Rx) n = 2**r assert (r<40), "ugh" #code = Code("body.h") code = Code() code.append("#define DIMS (%d)"%n) code.append("static void matmult(PetscScalar *py, const PetscScalar *px, long nx)") code.begin() code.append("assert(DIMS == %d);"%n) code.append("assert(nx == %d);"%n) code.append("memset(py, 0, sizeof(PetscScalar)*nx);") offset = argv.get("offset", None) mz = len(Gz) t = None #excite = argv.excite #if excite is None: excite = kw.get("excite") or argv.excite if excite is not None: print("excite:", excite) if type(excite) is tuple: t = Tx[excite[0]] for i in range(1, len(excite)): t = (t + Tx[excite[i]])%2 else: assert type(excite) in (int, int) t = Tx[excite] print("t:", shortstr(t)) Gzt = dot2(Gz, t) print("Gzt:", shortstr(Gzt)) weights = kw.get("weights") if weights is not None: assert len(weights)==len(Gx) RR = dot2(Gz, Rx.transpose()) PxtQx = dot2(Pxt, Qx) gxs = [getnum(dot2(gx, PxtQx)) for gx in Gx] gxs.sort() uniq_gxs = list(set(gxs)) uniq_gxs.sort() code.append("long v;") code.append("int k;") code.append("struct timeval t0, t1;") code.append("gettimeofday(&t0, NULL);") code.append("for(v=0; v<%d; v++)"%n) code.begin() code.append("double pxv = px[v];") if n >= 128: code.append(r'if((v+1) %% %d == 0)' % (n//128)) code.begin() code.append("gettimeofday(&t1, NULL);") code.append("long delta = t1.tv_sec-t0.tv_sec;") code.append("if(delta>1)") code.append('{printf("[%lds]", delta);fflush(stdout);}') code.append('t0 = t1;') code.end() code.append("k = 0;") for i, row in enumerate(RR): if t is not None and Gzt[i]==1: code.append("k += (countbits_fast(v&%s)+1) %% 2;" % getnum(row)) else: code.append("k += countbits_fast(v&%s) %% 2;" % getnum(row)) cutoff = argv.cutoff if cutoff is not None: code.append("if(k>%d) continue; // <-------- continue" % cutoff) else: code.append("if(k>cutoff) continue; // <-------- continue") code.append("py[v] += pxv * (%d - 2*k);" % mz) if weights is None: for gx in uniq_gxs: s = '+'.join(['pxv']*gxs.count(gx)) code.append("py[v^%s] += %s;" % (gx, s)) else: gxs = [getnum(dot2(gx, PxtQx)) for gx in Gx] for i, gx in enumerate(gxs): code.append("py[v^%s] += %s*pxv;" % (gx, weights[i])) code.end() code.end() if name is None: return s = code.output() src = open("ex3.c").read() match = '\n#include "body.h"\n' assert match in src src = src.replace(match, s) assert name and name.endswith(".c") f = open(name, 'w') tag = hash(src) print(("hash(src):", tag)) f.write(src) f.close() import socket host = socket.gethostname() if host == "bucket": cmd = "gcc MATCH.c -O3 -o MATCH -I/home/simon/local/petsc/arch-linux2-c-debug/include -I/home/simon/local/petsc/include/petsc/mpiuni -I/home/simon/local/petsc/include -I/home/simon/local/slepc-3.7.1/include -I/home/simon/local/slepc-3.7.1/arch-linux2-c-debug/include/ -L/home/simon/local/petsc/arch-linux2-c-debug/lib -L/home/simon/local/slepc-3.7.1/arch-linux2-c-debug/lib -lpetsc -lslepc" elif host == "hero": cmd = "gcc MATCH.c -O3 -o MATCH -I/usr/include/openmpi -I/usr/include/petsc -I/usr/include/slepc -lpetsc -lslepc -lmpi" else: cmd = "gcc -O3 MATCH.c -I/suphys/sburton/include/ -o MATCH -lpetsc -L$PETSC_DIR/$PETSC_ARCH/lib -L$SLEPC_DIR/$PETSC_ARCH/lib -lslepc" cmd = cmd.replace("MATCH.c", name) stem = name[:-2] cmd = cmd.replace("MATCH", stem) rval = os.system(cmd) assert rval == 0 #print("exec:", hash(open(stem).read())) nev = argv.get("nev", 1) cmd = "./%s -eps_nev %d -eps_ncv %d -eps_largest_real" if argv.plot: cmd += " -eps_view_vectors binary:evec.bin " cmd = cmd%(stem, nev, max(2*nev, 4)) eps_tol = argv.get("eps_tol", 1e-4) if eps_tol is not None: cmd += " -eps_tol %s "%eps_tol #cmd += " -eps_type arnoldi -info -eps_monitor -eps_tol 1e-3" print(cmd) #rval = os.system(cmd) #assert rval == 0 f = os.popen(cmd) s = f.read() #print(s) lines = s.split('\n') vals = [] for line in lines: line = line.strip() flds = line.split() #print("parse", flds) try: a, b = flds a = float(a) b = float(b) vals.append(a) except: pass if not argv.plot: print(("vals:", vals)) return vals assert argv.plot.endswith(".pdf") s = open("evec.bin").read() sz = 8*2**r if len(s)==sz+8: s = s[8:] elif len(s)==sz+16: s = s[16:] #elif len(s)==2*(sz+16): # got two vectors # s = s[16:16+sz] # pick the first vector elif len(s)%(sz+16) == 0: count = len(s)/(sz+16) # s = s[16:16+sz] # pick the first vector ev_idx = argv.get("ev_idx", 0) s = s[16+ev_idx*(16+sz):(ev_idx+1)*(16+sz)] else: assert 0, "sz=%d but s=%s"%(sz, len(s)) vec0 = numpy.fromstring(s, dtype=">d") assert len(vec0)==2**r assert excite is None print("graphing...") gz, n = Gz.shape xdata = [] lookup = {} GzRxt = dot2(Gz, Rx.transpose()) for i, v in enumerate(genidx((2,)*r)): v = array2(v) lookup[v.tobytes()] = i syndrome = dot2(GzRxt, v) value = gz - 2*syndrome.sum() xdata.append(value) pdata = {} ndata = {} my = 20. # mul y EPSILON = argv.get("EPSILON", 1e-6) def yfunc(y): y = log2(abs(y)) y = int(round(my*y)) return y for i in range(len(vec0)): x = xdata[i] # integer y = vec0[i] if abs(y) < EPSILON: continue if y > 0.: y = yfunc(y) pdata[x, y] = pdata.get((x, y), 0) + 1 else: y = yfunc(y) ndata[x, y] = ndata.get((x, y), 0) + 1 from pyx import graph, canvas, path, trafo, color, deco, text north = [text.halign.boxcenter, text.valign.top] northeast = [text.halign.boxright, text.valign.top] northwest = [text.halign.boxleft, text.valign.top] south = [text.halign.boxcenter, text.valign.bottom] southeast = [text.halign.boxright, text.valign.bottom] southwest = [text.halign.boxleft, text.valign.bottom] east = [text.halign.boxright, text.valign.middle] west = [text.halign.boxleft, text.valign.middle] center = [text.halign.boxcenter, text.valign.middle] c = canvas.canvas() sx = 0.4 sy = 1.4 tr = trafo.scale(sx, sy) green = color.rgb(0.2,0.6,0.2) brown = color.rgb(0.8,0.2,0.2) grey = color.rgb(0.4,0.4,0.4) lgrey = color.rgb(0.8,0.8,0.8) W = 2*gz H = log2(EPSILON) dy = 0.5 * 1.2/my X0 = -gz Y0 = 0. def showp(gx, radius): v = dot2(gx, PxtQx) syndrome = dot2(GzRxt, v) x = gz - 2*syndrome.sum() i = lookup[v.tobytes()] #print syndrome, syndrome.sum(), vec0[i] y = (1./my)*yfunc(vec0[i]) + 0.5*dy #y = 0.5*dy + log2(abs(vec0[i])) c.fill(path.circle(-x*sx, y*sy, radius), [lgrey]) showp(zeros2(n), 0.8) for gx in Gx: showp(gx, 0.4) for gx0 in Gx: for gx1 in Gx: gx = (gx0+gx1)%2 if gx.sum()==0: continue showp(gx, 0.2) for i in range(0, gz+1): x, y = X0+2*i, Y0 c.stroke(path.line(x, y, x, y+H), [tr, grey]) if i%2 == 0: c.text(x*sx, y*sy + 0.2, "%d"%i, south) c.stroke(path.line(X0, Y0, X0+1.0*W+3.5, Y0), [tr, deco.earrow(size=0.5)]) c.stroke(path.line(X0, Y0, X0, Y0+1.0*H-0.5), [tr, deco.earrow(size=0.5)]) y = 1.0 i = 0 while y > EPSILON: x = X0*sx y1 = sy*(1./my)*yfunc(y) c.stroke(path.line(x, y1, x-0.1, y1)) c.text(x-0.3, y1, "%d"%i, east) y /= 2. i -= 1 R = 0.15 for key, value in list(pdata.items()): x, y = key y = y/my x = -x value = 1 + math.log(value) r = R*value #c.stroke(path.circle(x, y, r)) #c.stroke(path.line(x, y, x+r, y), [brown, tr]) c.fill(path.rect(x, y, r, dy), [brown, tr]) for key, value in list(ndata.items()): x, y = key y = y/my x = -x value = 1 + math.log(value) r = R*value #c.stroke(path.circle(x, y, r)) #c.stroke(path.line(x-r, y, x, y), [green, tr]) c.fill(path.rect(x-r, y, r, dy), [green, tr]) c.writePDFfile(argv.plot) if 0: print("graph..") g = graph.graphxy( width=16, x=graph.axis.linear(reverse=True), y=graph.axis.linear()) #y=graph.axis.log(min=0.8*vec0.min(), max=1.2*vec0.max())) g.plot(graph.data.values(x=xdata, y=ydata)) g.writePDFfile(argv.plot)
def __str__(self): #s = str(self.A) #s = s.replace("0", ".") s = shortstr(self.A) return s