def main_fail(): print() print("==" * 70) H = """ 012345678901234 0 YXZZ........... 1 X..X.XX.X...... 2 ZZ..ZZ.......Z. 3 .X..Y....XZ.... 4 .ZX....Y.Z..... 5 .....ZZZ.Z....Z 6 ..Z...ZZ....ZZ. 7 ...Z....Y.XX... 8 ..XX.......ZY.. 9 .........ZXX..Y 10 .....X.....XXXX 11 ....X.X.X.X..X. """ H = syparse(H) print() print(shortstr(H)) m = len(H) n = H.shape[1] // 2 assert n == 15 F = symplectic(n) C = dot2(H, dot2(F, H.transpose())) print(C.shape) for i in range(m): for j in range(i + 1, m): if C[i, j]: print("fail:", i, j) print(rank(H)) H = linear_independent(H) print("H=", H.shape) print(shortstr(H)) HF = dot2(H, F) K = array2(find_kernel(HF)) print("K=", K.shape) print(shortstr(K)) HK = numpy.concatenate((H, K)) L = linear_independent(HK) print() print(shortstr(L))
def classical_distance(H, max_dist=0): n = H.shape[1] dist = n K = find_kernel(H) K = numpy.array(K, dtype=numpy.int32) Kt = K.transpose() for u in numpy.ndindex((2, ) * K.shape[0]): v = dot2(Kt, u) if 0 < v.sum() < dist: dist = v.sum() #if dist<=max_dist: # break return dist
def find_homology_2(g, f, *dims): print("find_homology") print(dims[2], "--f-->", dims[1], "--g-->", dims[0]) F = numpy.zeros((dims[1], dims[2])) for row, col in list(f.keys()): v = f[row, col] F[row, col] = v % 2 #print shortstr(F.transpose()) #print G = numpy.zeros((dims[0], dims[1])) for row, col in list(g.keys()): v = g[row, col] G[row, col] = v % 2 #print shortstr(G) if argv.ldpc: from qupy.ldpc.css import CSSCode code = CSSCode(Hx=F.transpose(), Hz=G) code.build() code = code.prune_deadbits() print(code) name = argv.get("name") if name.endswith(".ldpc"): print("saving", name) code.save(name) if argv.logops: L = find_logops(G, F.transpose()) w = min([v.sum() for v in L]) print("logops weight:", w) L = find_logops(F, G.transpose()) w = min([v.sum() for v in L]) print("logops weight:", w) GF = numpy.dot(G, F) % 2 #print shortstr(GF) assert numpy.abs(GF).sum() == 0 F = F.astype(numpy.int32) G = G.astype(numpy.int32) print("rank(f)=%d, rank(g)=%d" % (rank(F), rank(G))) if g: kerg = find_kernel(G) print("ker(g):", len(kerg))
def __init__(self, G, H=None, d=None, desc="", check=True): assert len(G.shape)==2 self.G = G.copy() self.k, self.n = G.shape self.d = d self.desc = desc if H is None: H = list(find_kernel(G)) H = array2(H) if H.shape == (0,): H.shape = (0, self.n) self.H = H.copy() if check: self.check()
def main_torus(): n = 8 # ZZZZZZZZ|XXXXXXXX # 12345678|12345678 H = parse(""" 111..1..|........ 1..1....|1.1..... ........|11.11... .1..1...|.1...1.. ..1...1.|...1..1. ...11.11|........ .....1.1|....1..1 ........|..1..111 """.replace("|", "")) print() print("H=") print(shortstr(H)) F = symplectic(n) C = dot2(H, dot2(F, H.transpose())) for i in range(n): for j in range(i + 1, n): if C[i, j]: print("fail:", i + 1, j + 1) print(rank(H)) H = linear_independent(H) print("H=") print(shortstr(H)) HF = dot2(H, F) K = array2(find_kernel(HF)) print("K=") print(shortstr(K)) HK = numpy.concatenate((H, K)) L = linear_independent(HK) print() print(shortstr(L))
def intersect(G1, G2): G = numpy.concatenate((G1, G2)) #print("intersect") #print(G1, G2) #print(G) G = G.transpose() #print("find_kernel", G.shape) K = find_kernel(G) if not K: K = numpy.array(K) K.shape = 0, G.shape[1] else: K = numpy.array(K) #print("K:") #print(K, K.shape) G = dot2(K[:, :len(G1)], G1) #print("G:") #print(G, G.shape) #print() G = normal_form(G) return G
def search(): # Bravyi, Haah, 1209.2426v1 sec IX. # https://arxiv.org/pdf/1209.2426.pdf verbose = argv.get("verbose") m = argv.get("m", 6) # _number of rows k = argv.get("k", None) # _number of odd-weight rows # these are the variables N_x xs = list(cross([(0, 1)]*m)) maxweight = argv.maxweight minweight = argv.get("minweight", 1) xs = [x for x in xs if minweight <= sum(x)] if maxweight: xs = [x for x in xs if sum(x) <= maxweight] N = len(xs) lhs = [] rhs = [] # bi-orthogonality for a in range(m): for b in range(a+1, m): v = zeros2(N) for i, x in enumerate(xs): if x[a] == x[b] == 1: v[i] = 1 if v.sum(): lhs.append(v) rhs.append(0) # tri-orthogonality for a in range(m): for b in range(a+1, m): for c in range(b+1, m): v = zeros2(N) for i, x in enumerate(xs): if x[a] == x[b] == x[c] == 1: v[i] = 1 if v.sum(): lhs.append(v) rhs.append(0) # # dissallow columns with weight <= 1 # for i, x in enumerate(xs): # if sum(x)<=1: # v = zeros2(N) # v[i] = 1 # lhs.append(v) # rhs.append(0) if k is not None: # constrain to k _number of odd-weight rows assert 0<=k<m for a in range(m): v = zeros2(N) for i, x in enumerate(xs): if x[a] == 1: v[i] = 1 lhs.append(v) if a<k: rhs.append(1) else: rhs.append(0) A = array2(lhs) rhs = array2(rhs) #print(shortstr(A)) B = pseudo_inverse(A) soln = dot2(B, rhs) if not eq2(dot2(A, soln), rhs): print("no solution") return if verbose: print("soln:") print(shortstr(soln)) soln.shape = (N, 1) rhs.shape = A.shape[0], 1 K = array2(list(find_kernel(A))) #print(K) #print( dot2(A, K.transpose())) #sols = [] #for v in span(K): best = None density = 1.0 size = 99*N trials = argv.get("trials", 1024) count = 0 for trial in range(trials): u = rand2(len(K), 1) v = dot2(K.transpose(), u) #print(v) v = (v+soln)%2 assert eq2(dot2(A, v), rhs) if v.sum() > size: continue size = v.sum() Gt = [] for i, x in enumerate(xs): if v[i]: Gt.append(x) if not Gt: continue Gt = array2(Gt) G = Gt.transpose() assert is_morthogonal(G, 3) if G.shape[1]<m: continue if 0 in G.sum(1): continue if argv.strong_morthogonal and not strong_morthogonal(G, 3): continue #print(shortstr(G)) # for g in G: # print(shortstr(g), g.sum()) # print() _density = float(G.sum()) / (G.shape[0]*G.shape[1]) #if best is None or _density < density: if best is None or G.shape[1] <= size: best = G size = G.shape[1] density = _density if 0: #sols.append(G) Gx = even_rows(G) assert is_morthogonal(Gx, 3) if len(Gx)==0: continue GGx = array2(list(span(Gx))) assert is_morthogonal(GGx, 3) count += 1 print("found %d solutions" % count) if best is None: return G = best #print(shortstr(G)) for g in G: print(shortstr(g), g.sum()) print() print("density:", density) print("shape:", G.shape) G = linear_independent(G) A = list(span(G)) print(strong_morthogonal(A, 1)) print(strong_morthogonal(A, 2)) print(strong_morthogonal(A, 3)) #print(shortstr(dot2(G, G.transpose()))) if 0: B = pseudo_inverse(A) v = dot2(B, rhs) print("B:") print(shortstr(B)) print("v:") print(shortstr(v)) assert eq2(dot2(B, v), rhs)
def search_selfdual(): verbose = argv.get("verbose") m = argv.get("m", 6) # _number of rows k = argv.get("k", None) # _number of odd-weight rows maxweight = argv.get("maxweight", m) minweight = argv.get("minweight", 1) # these are the variables N_x print("building xs...") if 0: xs = cross([(0, 1)]*m) xs = [x for x in xs if minweight <= sum(x) <= maxweight] prune = argv.get("prune", 0.5) xs = [x for x in xs if random() < prune] xs = [] N = argv.get("N", m*100) colweight = argv.get("colweight", maxweight) assert colweight <= m for i in range(N): x = [0]*m total = 0 while total < colweight: idx = randint(0, m-1) if x[idx] == 0: x[idx] = 1 total += 1 xs.append(x) N = len(xs) lhs = [] rhs = [] # bi-orthogonality for a in range(m): for b in range(a+1, m): v = zeros2(N) for i, x in enumerate(xs): if x[a] == x[b] == 1: v[i] = 1 if v.sum(): lhs.append(v) rhs.append(0) k = 0 # all rows must have even weight # constrain to k _number of odd-weight rows assert 0<=k<m for a in range(m): v = zeros2(N) for i, x in enumerate(xs): if x[a] == 1: v[i] = 1 lhs.append(v) if a<k: rhs.append(1) else: rhs.append(0) logops = argv.logops A = array2(lhs) rhs = array2(rhs) #print(shortstr(A)) print("solve...") B = pseudo_inverse(A) soln = dot2(B, rhs) if not eq2(dot2(A, soln), rhs): print("no solution") return if verbose: print("soln:") print(shortstr(soln)) soln.shape = (N, 1) rhs.shape = A.shape[0], 1 K = array2(list(find_kernel(A))) print("kernel:", K.shape) if len(K)==0: return #print(K) #print( dot2(A, K.transpose())) #sols = [] #for v in span(K): best = None density = 1.0 size = 99*N trials = argv.get("trials", 1024) count = 0 print("trials...") for trial in range(trials): u = rand2(len(K), 1) v = dot2(K.transpose(), u) #print(v) v = (v+soln)%2 assert eq2(dot2(A, v), rhs) if v.sum() >= size: continue if v.sum() < m: continue if v.sum(): print(v.sum(), end=" ", flush=True) size = v.sum() if logops is not None and size != 2*m+logops: continue Gt = [] for i, x in enumerate(xs): if v[i]: Gt.append(x) Gt = array2(Gt) G = Gt.transpose() if dot2(G, Gt).sum() != 0: # not self-dual print(shortstr(dot2(G, Gt))) assert 0 return #if G.shape[1]<m: # continue if 0 in G.sum(1): print(".", end="", flush=True) continue #print(shortstr(G)) # for g in G: # print(shortstr(g), g.sum()) # print() _density = float(G.sum()) / (G.shape[0]*G.shape[1]) #if best is None or _density < density: if best is None or G.shape[1] <= size: best = G size = G.shape[1] density = _density if 0: #sols.append(G) Gx = even_rows(G) assert is_morthogonal(Gx, 3) if len(Gx)==0: continue GGx = array2(list(span(Gx))) assert is_morthogonal(GGx, 3) count += 1 print("found %d solutions" % count) if best is None: return G = best #print(shortstr(G)) f = open("selfdual.ldpc", "w") for spec in ["Hx =", "Hz ="]: print(spec, file=f) for g in G: print(shortstr(g), file=f) f.close() print() print("density:", density) print("shape:", G.shape) if 0: B = pseudo_inverse(A) v = dot2(B, rhs) print("B:") print(shortstr(B)) print("v:") print(shortstr(v)) assert eq2(dot2(B, v), rhs)
def search_extend(): # Extend the checks of a random code to make it triorthogonal. # Based on the search function above. verbose = argv.get("verbose") m = argv.get("m", 6) n = argv.get("n", m+2) k = argv.get("k") # odd _numbered rows ( logical operators) code = argv.get("code", "rand") if code == "rand": while 1: G0 = rand2(m, n) counts = G0.sum(0) if min(counts)==2 and rank(G0) == m: cols = set() for i in range(n): cols.add(tuple(G0[:, i])) if len(cols) == n: # no repeated cols break elif code == "toric": G0 = parse(""" 11.11... .111..1. 1...11.1 """) # l=2 toric code X logops + X stabs l = argv.get("l", 3) G0 = build_toric(l) m, n = G0.shape else: return code = Code(G0, check=False) print(shortstr(G0)) print("is_triorthogonal:", code.is_triorthogonal()) # these are the variables N_x xs = list(cross([(0, 1)]*m)) N = len(xs) lookup = {} for i, x in enumerate(xs): lookup[x] = i lhs = [] rhs = [] taken = set() for i in range(n): x = G0[:, i] idx = lookup[tuple(x)] assert idx not in taken taken.add(idx) if verbose: for idx in range(N): print(idx, xs[idx], "*" if idx in taken else "") for idx in taken: v = zeros2(N) v[idx] = 1 lhs.append(v) rhs.append(1) # bi-orthogonality for a in range(m): for b in range(a+1, m): v = zeros2(N) for i, x in enumerate(xs): if x[a] == x[b] == 1: v[i] += 1 assert v.sum() lhs.append(v) rhs.append(0) # tri-orthogonality for a in range(m): for b in range(a+1, m): for c in range(b+1, m): v = zeros2(N) for i, x in enumerate(xs): if x[a] == x[b] == x[c] == 1: v[i] += 1 assert v.sum() lhs.append(v) rhs.append(0) # dissallow columns with weight <= 1 for i, x in enumerate(xs): if sum(x)<=1: v = zeros2(N) v[i] = 1 lhs.append(v) rhs.append(0) if k is not None: # constrain to k _number of odd-weight rows assert 0<=k<m for a in range(m): v = zeros2(N) for i, x in enumerate(xs): if x[a] == 1: v[i] = 1 lhs.append(v) if a<k: rhs.append(1) else: rhs.append(0) A = array2(lhs) rhs = array2(rhs) if verbose: print("lhs:") print(shortstr(A)) print("rhs:") print(shortstr(rhs)) B = pseudo_inverse(A) soln = dot2(B, rhs) if not eq2(dot2(A, soln), rhs): print("no solution") return if verbose: print("soln:") print(shortstr(soln)) soln.shape = (N, 1) rhs.shape = A.shape[0], 1 K = array2(list(find_kernel(A))) best = None density = 1.0 size = 9999*n trials = argv.get("trials", 1024) count = 0 for trial in range(trials): u = rand2(len(K), 1) v = dot2(K.transpose(), u) #print(v) assert dot2(A, v).sum()==0 #if v.sum() != n: # continue assert v[0]==0 v = (v+soln)%2 assert eq2(dot2(A, v), rhs) Gt = list(G0.transpose()) for i, x in enumerate(xs): if v[i] and not i in taken: Gt.append(x) if not Gt: continue Gt = array2(Gt) G = Gt.transpose() if verbose: print("G0") print(shortstr(G0)) print("solution:") print(shortstr(G)) assert is_morthogonal(G, 3) if G.shape[1]<m: continue if 0 in G.sum(1): continue #print(shortstr(G)) # for g in G: # print(shortstr(g), g.sum()) # print() _density = float(G.sum()) / (G.shape[0]*G.shape[1]) #if best is None or _density < density: if best is None or G.shape[1] < size: best = G density = _density size = G.shape[1] if 0: #sols.append(G) Gx = even_rows(G) assert is_morthogonal(Gx, 3) if len(Gx)==0: continue GGx = array2(list(span(Gx))) assert is_morthogonal(GGx, 3) count += 1 print("found %d solutions" % count) G = best #print(shortstr(G)) for g in G: print(shortstr(g), g.sum()) print() print("density:", density)