def __init__(self, Hz, Hx, Lz=None, Lx=None, **kw): self.__dict__.update(kw) mz, n = Hz.shape mx, nx = Hx.shape assert n == nx assert rank(Hz) == mz assert rank(Hx) == mx xstabs = [] zstabs = [] space = Space(n) for i in range(mz): idxs = [j for j in range(n) if Hz[i, j]] op = space.make_zop(idxs) zstabs.append(op) for i in range(mx): idxs = [j for j in range(n) if Hx[i, j]] op = space.make_xop(idxs) xstabs.append(op) # code projector: P = None for op in zstabs + xstabs: A = (space.I + op) P = A if P is None else A * P print(P)
def rand_span(A): while 1: m, n = A.shape v = rand2(m, m) A1 = dot2(v, A) assert A1.shape == A.shape if rank(A) == rank(A1): break assert rank(intersect(A, A1)) == rank(A) return A1
def make_quantum(n, m, dist=0, weight=None): while 1: Hx, Hz = make_q(n, m, weight) if rank(Hx) < m or rank(Hz) < m: continue d = classical_distance(Hx, dist) if d < dist: continue d = classical_distance(Hz, dist) if d < dist: continue break return Hx, Hz
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 skip_rank(Hx, R, skip): A = Hx.copy() r = rank(A) for a in R: if (a * skip).max(): continue A1 = numpy.concatenate((A, a)) if rank(A1) == r: #write("\n") continue r = r + 1 A = A1 return r
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_puncture(H): print("\ntest_puncture --------") n = H.shape[1] G = find_kernel(H) k = len(G) print("n = %d, k = %d" % (n, k)) print("G =") print(shortstr(G)) R = row_reduce(H) print("R =") print(shortstr(R)) pivots = get_pivots(R) rows = [i for (i, j) in pivots] cols = [j for (i, j) in pivots] print("pivots:", pivots) A = cols[:k] remain = [j for j in range(n) if j not in A] S = R[:, remain] print("S =") print(shortstr(S)) G1 = find_kernel(S) print("G1 =") G1 = row_reduce(G1) print(G1) S = row_reduce(S) print("S: rank = ", rank(S)) print(shortstr(S))
def rand_codes_slow(m, n, trials=10000): count = 0 while count < trials: H = rand2(m, n) if rank(H) == m: yield H count += 1
def span(Hz): assert rank(Hz) == len(Hz) m, n = Hz.shape print("enum2: %d " % (2**m)) for v in numpy.ndindex((2, ) * m): u = dot2(v, Hz) yield u
def make_morthogonal(m, n, genus): while 1: G = rand2(m, n) if strong_morthogonal(G, genus) and rank(G) == m and numpy.min( G.sum(0)): break return G
def get_logops(idxs_C, idxs_Ct, idxs_D, idxs_Dt): # Lx -------------------------------------------------------------- Ic1 = identity2(c1)[idxs_C, :] Lx_h = kron(Ic1, CokerD), zeros2(len(idxs_C) * CokerD.shape[0], c0 * d1) Lx_h = numpy.concatenate(Lx_h, axis=1) assert dot2(Lx_h, Hz.transpose()).sum() == 0 Id1 = identity2(d1)[idxs_D, :] Lx_v = zeros2(CokerC.shape[0] * len(idxs_D), c1 * d0), kron(CokerC, Id1) Lx_v = numpy.concatenate(Lx_v, axis=1) Lxi = numpy.concatenate((Lx_h, Lx_v), axis=0) # Lz -------------------------------------------------------------- KerCt = KerC.transpose() Id0 = identity2(d0)[:, idxs_Dt] Lzt_h = kron(KerCt, Id0), zeros2(c0 * d1, KerCt.shape[1] * len(idxs_Dt)) Lzt_h = numpy.concatenate(Lzt_h, axis=0) assert dot2(Hx, Lzt_h).sum() == 0 KerDt = KerD.transpose() assert KerDt.shape[0] == d1 Ic0 = identity2(c0)[:, idxs_Ct] Lzt_v = zeros2(c1 * d0, len(idxs_Ct) * KerDt.shape[1]), kron(Ic0, KerDt) Lzt_v = numpy.concatenate(Lzt_v, axis=0) assert dot2(Hx, Lzt_v).sum() == 0 Lzti = numpy.concatenate((Lzt_h, Lzt_v), axis=1) Lzi = Lzti.transpose() # checking --------------------------------------------------------- assert dot2(Hx, Lzti).sum() == 0 assert rank(Lxi) == len(Lxi) # full rank assert rank(Lzi) == len(Lzi) # full rank assert eq_span(numpy.concatenate((Lxi, Hx)), LxiHx) assert eq_span(numpy.concatenate((Lzi, Hz)), LziHz) return Lxi, Lzi
def rand_full_rank(m, n=None): if n is None: n = m assert n >= m while 1: f = rand2(m, n) if rank(f) == m: break return f
def random_code(n, k, kt, distance=1): "code length n, dimension k, transpose dimension kt" d = 0 while d < distance: H = rand2(n - k, n) if rank(H) < n - k: continue d = classical_distance(H, distance) K = H dt = 0 while dt < distance: R = rand2(kt, n - k) J = dot2(R, H) K = numpy.concatenate((H, J)) if rank(K) < n - k: continue dt = classical_distance(K.transpose()) return K
def get_codes(m, n): while 1: H = rand2(m, n) #H[0:2, :] = 0 H[:, 0] = 0 H[0, 0] = 1 #H[0:2, 0:3] = A #print(shortstr(H)) #print() if rank(H) < m: continue yield H
def independent_logops(L, H): m = len(H) LH = numpy.concatenate((L, H), axis=0) keep, remove = dependent_rows(LH) LH = LH[keep] assert rank(LH) == len(LH) assert len(LH) >= m assert eq2(LH[-len(H):], H) L = LH[:-m] return L
def random_code(n, k, kt, distance=1): "return parity check for code of length n, dimension k, transpose dimension kt" d = 0 while d<distance: H = rand2(n-k, n) if rank(H) < n-k: continue d = classical_distance(H, distance) K = H dt = 0 while dt<distance: R = rand2(kt, n-k) J = dot2(R, H) K = numpy.concatenate((H, J)) if rank(K) < n-k: continue dt = classical_distance(K.transpose()) m = len(K) assert k - n + m - kt == 0 return K
def independent_logops(L, H, verbose=False): m = len(H) LH = numpy.concatenate((L, H), axis=0) keep, remove = dependent_rows(LH) if verbose: print(keep, remove) LH = LH[keep] assert rank(LH) == len(LH) assert len(LH) >= m assert eq2(LH[-len(H):], H), "H not linearly independent ?" L = LH[:-m] return L
def mk_disjoint_logops(L, H): m = len(H) #print("L:", len(L)) L0 = L # save this LH = numpy.concatenate((L, H), axis=0) #LH = remove_dependent(LH) keep, remove = dependent_rows(LH) #print("dependent_rows:", len(keep), len(remove)) LH = LH[keep] assert rank(LH) == len(LH) assert len(LH) >= m assert eq2(LH[-len(H):], H) L = LH[:-m] #print("L:", len(L)) # find disjoint set of L ops keep = set([idx for idx in keep if idx < len(L0)]) assert len(keep) == len(L) idxs = list(range(len(L0))) idxs.sort(key=lambda idx: -int(idx in keep)) assert idxs[0] in keep L1 = L0[idxs] assert L1.shape == L0.shape LH = numpy.concatenate((L1, H), axis=0) LH = remove_dependent(LH) L1 = LH[:-m] assert len(L) == len(L1), (L.shape, L1.shape) #print(shortstr(L)) #print("--") #print(shortstr(L1)) #print("--") A = numpy.dot(L, L1.transpose()) #assert A.sum() == 0, "found overlap" if A.sum(): print("*" * 79) print("WARNING: A.sum() =", A.sum()) print("failed to find disjoint logops") print("*" * 79) return L, None return L, L1
def find_reduced_guage(Gx, Hx): # print "find_reduced_guage" # print shortstr(Hx) mg, n = Gx.shape mx, _ = Hx.shape m = mx A = Hx ra = rank(Hx) assert ra == mx for i in range(mg): assert A.shape == (m, n) B = zeros2(m + 1, n) B[:m] = A B[m] = Gx[i] r = rank(B) # XX work with a row reduced A assert m + 1 >= r >= m, (m, r) if r == m + 1: m += 1 A = B return A[mx:]
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 has_property(G, trials=1000): k, n = G.shape for trial in range(trials): pivots = [] remain = list(range(n)) shuffle(remain) G1 = G for row in range(k): for col in list(remain): if G1[row, col] == 0: continue G1 = echelon1(G1, row, col) pivots.append(col) remain.remove(col) break if len(pivots) < k: continue J = G1[:, remain] if rank(J) == k: break else: return False return True
def process(G, H): m, n = G.shape row = 0 while row < m: col = 0 while G[row, col] == 0: col += 1 assert col >= row swap_col(G, row, col) swap_col(H, row, col) echelon(G, row, row) row += 1 col = row row = 0 m, n = H.shape while row < m: j = col while H[row, j] == 0: j += 1 swap_col(G, col, j) swap_col(H, col, j) echelon(H, row, col) row += 1 col += 1 k = n-m print("G =") print(shortstr(G)) print("H =") print(shortstr(H)) print() A = G[:, k:] B = H[:, :k] assert eq2(A.transpose(), B) if 0: for size in range(2, k): result = search(G, H, size=size, verbose=True) print("search(size=%d): %s"%(size, result)) wd = weight_dist(H) print("H:", wd, sum(wd)) wd = weight_dist(G) print("G:", wd, sum(wd)) r = rank(A) print("rank deficit:", k-r) if r == k: idxs = list(range(k)) jdxs = list(range(k, 2*k)) C = cokernel(B)[0] C = row_reduce(C) rows, cols = C.shape assert rows == n-2*k assert cols == n-k jdxs = list(range(m)) pivots = [] for i in range(rows): for j in range(i, cols): if C[i, j] != 0: pivots.append(j) jdxs.remove(j) break print("C:", pivots) print(shortstr(C)) assert len(jdxs) == k jdxs = [k+i for i in jdxs] assert len( in_support(G, idxs) ) == 0 assert len( in_support(G, jdxs) ) == 0 assert len( in_support(H, idxs) ) == 0 for row in in_support(H, jdxs): print("in_support:", row) assert len( in_support(H, jdxs) ) == 0 print("OK")
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 hypergraph_product(C, D, check=False): print("hypergraph_product: C=%s, D=%s" % (C.shape, D.shape)) c0, c1 = C.shape d0, d1 = D.shape Ic0 = identity2(c0) Id0 = identity2(d0) Ic1 = identity2(c1) Id1 = identity2(d1) Hz0 = kron(Ic1, D.transpose()), kron(C.transpose(), Id1) Hz = numpy.concatenate(Hz0, axis=1) # horizontal concatenate Hx0 = kron(C, Id0), kron(Ic0, D) #print("Hx0:", Hx0[0].shape, Hx0[1].shape) Hx = numpy.concatenate(Hx0, axis=1) # horizontal concatenate assert dot2(Hx, Hz.transpose()).sum() == 0 n = Hz.shape[1] assert Hx.shape[1] == n # --------------------------------------------------- # Build Lz KerC = find_kernel(C) #KerC = min_span(KerC) # does not seem to matter... ?? KerC = rand_span(KerC) # ?? KerC = row_reduce(KerC) assert KerC.shape[1] == c1 K = KerC.transpose() #K = min_span(K) #K = rand_span(K) #E = identity2(d0) #print("c0,c1,d0,d1=", c0, c1, d0, d1) Lzt0 = kron(K, Id0), zeros2(c0 * d1, K.shape[1] * d0) Lzt0 = numpy.concatenate(Lzt0, axis=0) assert dot2(Hx, Lzt0).sum() == 0 KerD = find_kernel(D) K = KerD.transpose() assert K.shape[0] == d1 Lzt1 = zeros2(c1 * d0, K.shape[1] * c0), kron(Ic0, K) Lzt1 = numpy.concatenate(Lzt1, axis=0) assert dot2(Hx, Lzt1).sum() == 0 Lzt = numpy.concatenate((Lzt0, Lzt1), axis=1) # horizontal concatenate Lz = Lzt.transpose() assert dot2(Hx, Lzt).sum() == 0 # These are linearly independent among themselves, but # once we add stabilixers it will be reduced: assert rank(Lz) == len(Lz) # --------------------------------------------------- # Build Lx counit = lambda n: unit2(n).transpose() CokerD = find_cokernel(D) # matrix of row vectors #CokerD = min_span(CokerD) CokerD = rand_span(CokerD) Lx0 = kron(Ic1, CokerD), zeros2(CokerD.shape[0] * c1, c0 * d1) Lx0 = numpy.concatenate(Lx0, axis=1) # horizontal concatenate assert dot2(Lx0, Hz.transpose()).sum() == 0 CokerC = find_cokernel(C) Lx1 = zeros2(CokerC.shape[0] * d1, c1 * d0), kron(CokerC, Id1) Lx1 = numpy.concatenate(Lx1, axis=1) # horizontal concatenate Lx = numpy.concatenate((Lx0, Lx1), axis=0) assert dot2(Lx, Hz.transpose()).sum() == 0 # --------------------------------------------------- # overlap = 0 for lz in Lz: for lx in Lx: w = (lz * lx).sum() overlap = max(overlap, w) assert overlap <= 1, overlap #print("max overlap:", overlap) if 0: # here we assume that Hz/Hx are full rank Hzi = Hz Hxi = Hx assert rank(Hz) == len(Hz) assert rank(Hx) == len(Hx) mz = len(Hz) mx = len(Hx) else: Hzi = remove_dependent(Hz) Hxi = remove_dependent(Hx) mz = rank(Hz) mx = rank(Hx) assert len(Hzi) == mz assert len(Hxi) == mx # --------------------------------------------------- # Lz0, Lz1 = Lzt0.transpose(), Lzt1.transpose() Lzi = independent_logops(Lz, Hzi) Lxi = independent_logops(Lx, Hxi) print("Lzi:", len(Lzi)) print("Lxi:", len(Lxi)) k = len(Lzi) assert len(Lxi) == k assert mz + mx + k == n LziHz = numpy.concatenate((Lzi, Hzi)) assert rank(LziHz) == k + mz LxiHx = numpy.concatenate((Lxi, Hxi)) assert rank(LxiHx) == k + mx return locals()
def ldpc_str(H): m, n = H.shape assert rank(H) == m k = n - m d = classical_distance(H) return "[%d, %d, %d]" % (n, k, d)
def hypergraph_product(A, B, check=False): #print("hypergraph_product: A=%s, B=%s"%(A.shape, B.shape)) ma, na = A.shape mb, nb = B.shape Ima = identity2(ma) Imb = identity2(mb) Ina = identity2(na) Inb = identity2(nb) Hz0 = kron(Ina, B.transpose()), kron(A.transpose(), Inb) Hz = numpy.concatenate(Hz0, axis=1) # horizontal concatenate Hx0 = kron(A, Imb), kron(Ima, B) #print("Hx0:", Hx0[0].shape, Hx0[1].shape) Hx = numpy.concatenate(Hx0, axis=1) # horizontal concatenate assert dot2(Hx, Hz.transpose()).sum() == 0 n = Hz.shape[1] assert Hx.shape[1] == n # --------------------------------------------------- # Build Lz KerA = find_kernel(A) #KerA = rand_rowspan(KerA) # ?? KerA = row_reduce(KerA) ka = len(KerA) assert KerA.shape[1] == na K = KerA.transpose() #K = rand_rowspan(K) #E = identity2(mb) #print("ma,na,mb,nb=", ma, na, mb, nb) Lzt0 = kron(K, Imb), zeros2(ma*nb, K.shape[1]*mb) Lzt0 = numpy.concatenate(Lzt0, axis=0) assert dot2(Hx, Lzt0).sum() == 0 KerB = find_kernel(B) KerB = row_reduce(KerB) kb = len(KerB) K = KerB.transpose() assert K.shape[0] == nb Lzt1 = zeros2(na*mb, K.shape[1]*ma), kron(Ima, K) Lzt1 = numpy.concatenate(Lzt1, axis=0) assert dot2(Hx, Lzt1).sum() == 0 Lzt = numpy.concatenate((Lzt0, Lzt1), axis=1) # horizontal concatenate Lz = Lzt.transpose() assert dot2(Hx, Lzt).sum() == 0 # These are linearly independent among themselves, but # once we add stabilizers it will be reduced: assert rank(Lz) == len(Lz) # --------------------------------------------------- # Build Lx counit = lambda n : unit2(n).transpose() CokerB = find_cokernel(B) # matrix of row vectors #CokerB = rand_rowspan(CokerB) assert rank(CokerB)==len(CokerB) kbt = len(CokerB) Lx0 = kron(Ina, CokerB), zeros2(CokerB.shape[0]*na, ma*nb) Lx0 = numpy.concatenate(Lx0, axis=1) # horizontal concatenate assert dot2(Lx0, Hz.transpose()).sum() == 0 CokerA = find_cokernel(A) assert rank(CokerA)==len(CokerA) kat = len(CokerA) Lx1 = zeros2(CokerA.shape[0]*nb, na*mb), kron(CokerA, Inb) Lx1 = numpy.concatenate(Lx1, axis=1) # horizontal concatenate Lx = numpy.concatenate((Lx0, Lx1), axis=0) assert dot2(Lx, Hz.transpose()).sum() == 0 #print(ka, kat, kb, kbt) # --------------------------------------------------- # overlap = 0 for lz in Lz: for lx in Lx: w = (lz*lx).sum() overlap = max(overlap, w) assert overlap <= 1, overlap #print("max overlap:", overlap) if 0: # here we assume that Hz/Hx are full rank Hzi = Hz Hxi = Hx assert rank(Hz) == len(Hz) assert rank(Hx) == len(Hx) mz = len(Hz) mx = len(Hx) else: Hzi = remove_dependent(Hz) Hxi = remove_dependent(Hx) mz = rank(Hz) mx = rank(Hx) assert len(Hzi) == mz assert len(Hxi) == mx # --------------------------------------------------- # Lz0, Lz1 = Lzt0.transpose(), Lzt1.transpose() Lzi = independent_logops(Lz, Hzi) Lxi = independent_logops(Lx, Hxi) #print("Lzi:", len(Lzi)) #print("Lxi:", len(Lxi)) k = len(Lzi) assert len(Lxi) == k assert mz + mx + k == n LziHz = numpy.concatenate((Lzi, Hzi)) assert rank(LziHz) == k+mz LxiHx = numpy.concatenate((Lxi, Hxi)) assert rank(LxiHx) == k+mx return locals()
print(shortstr(Hz)) print("Hx:") print(shortstr(Hx)) else: stem = argv.get("stem", "55_32_5") #stem = "55_360_8" #stem = "77_78_5" Hx = load(stem + "_Hx.npz") #Hx = linear_independent(Hx) print(Hx.shape) print(shortstr(Hx)) #print(Hx.sum(0), Hx.sum(1)) print(rank(Hx)) Hz = load(stem + "_Hz.npz") #Hz = linear_independent(Hz) print(Hz.shape) #print(shortstr(Hz)) mx, n = Hx.shape mz, _ = Hz.shape print(mx, mz, n) from qupy.condmat.isomorph import Tanner, search lhs = Tanner.build2(Hx, Hz) if argv.duality: print("searching for duality")
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 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 print("make_gallagher%s" % ((r, n, l, m, d), )) C = make_gallagher(r, n, l, m, d) print(shortstr(C)) print() 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.hrand: #C = random_code(16, 8, 0, 3) C = random_code(8, 4, 0, 3) D = random_code(8, 4, 1, 3) elif argv.hvrand: #C = random_code(16, 8, 8, 3) C = random_code(8, 4, 4, 3) D = random_code(8, 4, 4, 3) elif argv.hvrandsmall: #C = random_code(16, 8, 8, 3) C = random_code(7, 1, 1, 2) # n, k, kt, d D = random_code(7, 1, 1, 2) elif argv.samerand: C = random_code(12, 6, 0, 4) D = C elif argv.smallrand: # make some vertical logops from rank degenerate parity check matrices C = random_code(8, 4, 0, 3) D = random_code(6, 3, 0, 2) elif argv.cookup: # [12,6,4] example that has no k-bipuncture C = parse(""" .1..1111.... 111.11111111 11.111...11. 1..11...1.11 .11...1...11 ..11.11.111. """) D = C R = row_reduce(C) print(shortstr(R)) elif argv.cookup2: # [12,6,4] example that has no k-bipuncture C = parse(""" .11..1.11..1 11...1111... 1....1.11111 ..1.1111..1. 111....1.11. 1111.11...11 .1.1.1....1. 1111111.1111 ....1..111.. .1..1.111.11 11.11......1 11..1111.1.. """) D = C elif argv.pair: #C = make_gallagher(9, 12, 3, 4, 4) # big C = make_gallagher(15, 20, 3, 4, 4) # big D = make_gallagher(6, 8, 3, 4, 1) # small 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 111.... """) D = C elif argv.surf or argv.surface: # Surface C = parse(""" 11.... .11... ..11.. ...11. ....11 """) D = parse(""" 11.. .11. ..11 """) elif argv.small: C = parse("""1111""") D = parse("""1111""") else: print("please specify a code") return print("C: shape=%s, rank=%d, dist=%d" % (C.shape, rank(C), classical_distance(C))) print("C.t: dist=%d" % (classical_distance(C.transpose()), )) print(shortstr(C)) print("D: shape=%s, rank=%d, dist=%d" % (D.shape, rank(D), classical_distance(D))) print("D.t: dist=%d" % (classical_distance(D.transpose()), )) print(shortstr(D)) Ct = C.transpose() Dt = D.transpose() if argv.dual: C, Ct = Ct, C D, Dt = Dt, D if argv.test_puncture: test_puncture(C) return # <--------- return if argv.test_indep: kw = hypergraph_product(C, Dt) test_indep(**kw) return # <--------- return if argv.test_code: kw = hypergraph_product(C, Dt) test_code(**kw) return # <--------- return if argv.test_overlap: #while 1: kw = hypergraph_product(C, Dt) success = test_overlap(**kw) print("success:", success) if argv.success: assert success #if success: # break #else: # sys.exit(0) C = shuff22(C) if argv.same: D = C Dt = D.transpose() else: Dt = shuff22(Dt)
def main(): n = argv.get("n", 8) k = argv.get("k", 4) assert 2*k<=n m = n-k dist = argv.get("dist", 2) Hdist = argv.get("Hdist", dist) max_tries = argv.get("max_tries", 1000) verbose = argv.verbose trials = argv.get("trials", 100000) count = 0 fails = 0 if argv.all_codes: gen = all_codes(m, n) elif argv.get_codes: gen = get_codes(m, n) elif argv.gallagher: cw = argv.get("cw", 3) # column weight rw = argv.get("rw", 4) # row weight m = argv.get("m", n*cw//rw) # rows n = argv.get("n", 12) # cols def gen(trials=1000, m=m, n=n, cw=cw, rw=rw, dist=dist): for _ in range(trials): H = make_gallagher(m, n, cw, rw, dist) yield H gen = gen(trials) elif argv.wedge: H = zeros2(m, n) H[0, :k+1] = 1 H[:, k-1] = 1 for i in range(m): H[i, i+k] = 1 gen = [H] #print(shortstr(H)) #print() elif argv.cookup: # fail gen = [parse(""" 1111........ ..1.1....... ..1..1...... ..1...1..... ..1....1.... ..1.....1... ..1......1.. ..1.......1. ..1........1 """)] gen = [parse(""" ....11...... ....1.1..... ....1..1.... ....1...1... 1.111....1.. .111......1. 11.11......1 """)] else: gen = rand_codes(m, n, trials) #assert Hdist == 2 for H in gen: m, n = H.shape assert rank(H) == m k = n-m dH = min_weight(H) if dH < Hdist: #print("[dH=%d]"%dH, end="", flush=True) continue G = find_kernel(H) #print(shortstr(G)) dG = min_weight(G) if dG < dist: #print("[dG=%d]"%dG, end="", flush=True) continue print("") result = search(G, H, max_tries) count += 1 print("result =", result) process(G, H) if result: if not argv.silent: print(".", end="", flush=True) continue if not argv.silent: print("|") if not result: if not argv.noassert: assert 0, "FAIL" fails += 1 print() print("codes found: %d, fails %d"%(count, fails))