Exemplo n.º 1
0
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))
Exemplo n.º 2
0
Arquivo: glue.py Projeto: punkdit/qupy
def test_glue():

    m = argv.get("m", 9)
    n = argv.get("n", 10)

    d = argv.get("d", 0)
    p = argv.get("p", 0.5)
    weight = argv.weight

    H1 = rand2(m, n, p, weight)
    G1 = find_kernel(H1)
    G1t = G1.transpose()
    H1t = H1.transpose()
    A1 = Chain([G1, H1t])
    k1 = len(G1)

    print("H1")
    print(fstr(H1))
    print()
    print(fstr(G1))

    w = wenum(H1)
    print("wenum:", [len(wi) for wi in w])

    H2 = rand2(m, n, p, weight)
    H2t = H2.transpose()
    G2 = find_kernel(H2)
    G2t = G2.transpose()
    A2 = Chain([G2, H2t])
    k2 = len(G2)

    print("H2")
    print(fstr(H2))
    print()
    print(fstr(G2))

    w = wenum(H2)
    print("wenum:", [len(wi) for wi in w])

    if k1 != k2:
        return
    k = k1

    I = identity2(k)
    B = Chain([I, zeros2(k, 0)])

    a = zeros2(n, k)
    for i in range(k):
        a[i, i] = 1
    f1 = Morphism(B, A1, [dot2(G1, a), a, zeros2(m, 0)])
    f2 = Morphism(B, A2, [dot2(G2, a), a, zeros2(m, 0)])

    a, b, C, _ = chain.pushout(f1, f2)

    H = C[1].transpose()
    print("H:")
    print(fstr(H))

    w = wenum(H)
    print("wenum:", [len(wi) for wi in w])
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
 def solve(self, H, minimize=True, verbose=True):
     m, n = H.shape  # rows, cols
     u1 = self.u1
     assert u1.shape == (m, )
     rows = [i for i in range(m) if u1[i]]
     #print rows
     H = H[rows, :]
     u0 = self.u0[rows]
     v = self.v
     cols = [i for i in range(n) if v[i]]
     #print cols
     H = H[:, cols]
     assert cols, self.u0
     #print shortstr(H)
     #print "u0:", shortstr(u0)
     if verbose: print("Cluster.solve:", H.shape)
     v = solve.solve(H, u0)
     if v is None:
         return
     if minimize:
         kern = solve.find_kernel(H)
         if kern:
             kern = array2(kern)
             write("[w=%d, kern=%d, " % (v.sum(), len(list(kern))))
             graph = dynamic.Tanner(kern)
             #v = graph.minimize(v, target=30, verbose=True)
             v = graph.localmin(v, verbose=True)
             write("w=%d]" % v.sum())
     #u = dot(H, v)
     #assert numpy.abs(u-u0).sum() == 0
     v0 = numpy.zeros((n, ), dtype=numpy.int32)
     v0[cols] = v
     #print "v0:", shortstr(v0)
     #write("[%d]"%v0.sum())
     return v0
Exemplo n.º 5
0
 def show_stabx(self, sx):
     gxs = []
     for gx in self.Gx:
         if eq2(gx * sx, gx):
             gxs.append(gx)
     Gx = array2(gxs)
     #print "Gx:", Gx.shape
     #print shortstr(Gx)
     print("sx.sum() =", sx.sum(), end=' ')
     Gxt = Gx.transpose()
     K = find_kernel(Gxt)
     #print "kernel:", K
     K = array2(K)
     #print "kernel:", len(K)
     #print shortstr(K)
     #print
     best = None
     ubest = None
     u = solve(Gxt, sx)
     for w in enum2(len(K)):
         u2 = (u + dot2(w, K)) % 2
         if best is None or u2.sum() < best:
             best = u2.sum()
             ubest = u2
         print("u.sum() =", u2.sum(), end=' ')
     print()
Exemplo n.º 6
0
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()
Exemplo n.º 7
0
Arquivo: glue.py Projeto: punkdit/qupy
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))
Exemplo n.º 8
0
Arquivo: glue.py Projeto: punkdit/qupy
def wenum(H):
    m, n = H.shape
    K = find_kernel(H)
    #print(H)
    #print(K)
    w = dict((i, []) for i in range(n + 1))
    for v in image(K.transpose()):
        assert dot2(H, v).sum() == 0
        w[v.sum()].append(v)
    w = [w[i] for i in range(n + 1)]
    return w
Exemplo n.º 9
0
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
Exemplo n.º 10
0
def classical_distance(H, max_dist=0):
    if max_dist == 0:
        return max_dist
    n = H.shape[1]
    dist = n
    K = find_kernel(H)
    K = numpy.array(K)
    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
Exemplo n.º 11
0
    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()
Exemplo n.º 12
0
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
Exemplo n.º 13
0
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
Exemplo n.º 14
0
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))))
Exemplo n.º 15
0
def randcss(n, mx, mz, distance=None, **kw):
    """
    http://arxiv.org/abs/quant-ph/9512032
    Quantum error-correcting codes exist
    with asymptotic rate:
    k/n = 1 - 2H(2t/n) where 
    H(p) = -p log p - (1-p) log (1-p) and
    t = floor((d-1)/2).
    """

    while 1:
        k = n-mx-mz
        assert k>=0
    
        #print "rate:", 1.*k//n
        #H = lambda p: -p*log(p) - (1-p)*log(1-p)
        #d = 56 
        #print 1-2*H(1.*d//n) # works!
    
        Hz = rand2(mz, n)
    
        #print shortstrx(Hx)
    
        kern = numpy.array(solve.find_kernel(Hz))
    
        Hx = zeros2(mx, n)
        for i in range(mx):
            v = rand2(1, n-mx)
            Hx[i] = dot2(v, kern)
        C = CSSCode(Hx=Hx, Hz=Hz, **kw)

        if distance is None:
            break
        d = lookup_distance(C)
        if d < distance:
            continue
        d = lookup_distance(C.dual())
        if d < distance:
            continue
        break

    return C
Exemplo n.º 16
0
def dependent_rows(H):
    "find dependent rows of H, first to last"
    idxs = set(range(len(H)))
    #print(H)
    K = find_kernel(H.transpose())
    #print("K:")
    #print(K)
    K = row_reduce(K, truncate=True)
    #print("K:")
    #print(K)
    assert dot2(K, H).sum() == 0
    deps = []
    for row in K:
        #print(row)
        idx = numpy.where(row != 0)[0][0]
        deps.append(idx)
        idxs.remove(idx)
    assert len(set(deps)) == len(K)
    idxs = list(idxs)
    idxs.sort()
    deps.sort()
    return idxs, deps
Exemplo n.º 17
0
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)
Exemplo n.º 18
0
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))
Exemplo n.º 19
0
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
Exemplo n.º 20
0
    def build_from_gauge(self, check=True, verbose=False):

        write("build_from_gauge:")

        Gx, Gz = self.Gx, self.Gz
        Hx, Hz = self.Hx, self.Hz
        Lx, Lz = self.Lx, self.Lz

        #print "build_stab"
        #print shortstr(Gx)
        #vs = solve.find_kernel(Gx)
        #vs = list(vs)
        #print "kernel Gx:", len(vs)
    
        n = Gx.shape[1]
    
        if Hz is None:
            A = dot2(Gx, Gz.transpose())
            vs = solve.find_kernel(A)
            vs = list(vs)
            #print "kernel GxGz^T:", len(vs)
            Hz = zeros2(len(vs), n)
            for i, v in enumerate(vs):
                Hz[i] = dot2(v.transpose(), Gz) 
        Hz = solve.linear_independent(Hz)
    
        if Hx is None:
            A = dot2(Gz, Gx.transpose())
            vs = solve.find_kernel(A)
            vs = list(vs)
            Hx = zeros2(len(vs), n)
            for i, v in enumerate(vs):
                Hx[i] = dot2(v.transpose(), Gx)
        Hx = solve.linear_independent(Hx)

        if check:
            check_commute(Hz, Hx)
            check_commute(Hz, Gx)
            check_commute(Hx, Gz)

        #Gxr = numpy.concatenate((Hx, Gx))
        #Gxr = solve.linear_independent(Gxr)
        #print(Hx.shape)
        #assert rank(Hx) == len(Hx)
        #assert eq2(Gxr[:len(Hx)], Hx)
        #Gxr = Gxr[len(Hx):]

        Px = solve.get_reductor(Hx).transpose()
        Gxr = dot2(Gx, Px)
        Gxr = solve.linear_independent(Gxr)
    
        #Gzr = numpy.concatenate((Hz, Gz))
        #Gzr = solve.linear_independent(Gzr)
        #assert eq2(Gzr[:len(Hz)], Hz)
        #Gzr = Gzr[len(Hz):]

        Pz = solve.get_reductor(Hz).transpose()
        Gzr = dot2(Gz, Pz)
        Gzr = solve.linear_independent(Gzr)
    
        if Lx is None:
            Lx = solve.find_logops(Gz, Hx)
        if Lz is None:
            Lz = solve.find_logops(Gx, Hz)

        write('\n')

        print("Gxr", Gxr.shape)
        print("Gzr", Gzr.shape)
        assert len(Gxr)==len(Gzr)
        kr = len(Gxr)
        V = dot2(Gxr, Gzr.transpose())
        U = solve.solve(V, identity2(kr))
        assert U is not None
        Gzr = dot2(U.transpose(), Gzr)

        if check:
            check_conjugate(Gxr, Gzr)
            check_commute(Hz, Gxr)
            check_commute(Hx, Gzr)
            check_commute(Lz, Gxr)
            check_commute(Lx, Gzr)

        assert len(Lx)+len(Hx)+len(Hz)+len(Gxr)==n

        self.Lx, self.Lz = Lx, Lz
        self.Hx, self.Hz = Hx, Hz
        self.Gxr, self.Gzr = Gxr, Gzr
Exemplo n.º 21
0
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()
Exemplo n.º 22
0
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()
Exemplo n.º 23
0
def hypergraph_product(C, D, check=False):
    print("hypergraph_product:", C.shape, D.shape)
    print("distance:", classical_distance(C))

    c0, c1 = C.shape
    d0, d1 = D.shape

    E1 = identity2(c0)
    E2 = identity2(d0)
    M1 = identity2(c1)
    M2 = identity2(d1)

    Hx0 = kron(M1, D.transpose()), kron(C.transpose(), M2)
    Hx = numpy.concatenate(Hx0, axis=1)  # horizontal concatenate

    Hz0 = kron(C, E2), kron(E1, D)
    #print("Hz0:", Hz0[0].shape, Hz0[1].shape)
    Hz = numpy.concatenate(Hz0, axis=1)  # horizontal concatenate

    assert dot2(Hz, Hx.transpose()).sum() == 0

    n = Hx.shape[1]
    assert Hz.shape[1] == n

    # ---------------------------------------------------
    # Build Lx

    KerC = find_kernel(C)
    #KerC = min_span(KerC) # does not seem to matter... ??
    assert KerC.shape[1] == c1
    K = KerC.transpose()
    E = identity2(d0)

    print(shortstr(KerC))
    print()

    Lxt0 = kron(K, E), zeros2(c0 * d1, K.shape[1] * d0)
    Lxt0 = numpy.concatenate(Lxt0, axis=0)
    assert dot2(Hz, Lxt0).sum() == 0

    K = find_kernel(D).transpose()
    assert K.shape[0] == d1
    E = identity2(c0)

    Lxt1 = zeros2(c1 * d0, K.shape[1] * c0), kron(E, K)
    Lxt1 = numpy.concatenate(Lxt1, axis=0)
    assert dot2(Hz, Lxt1).sum() == 0

    Lxt = numpy.concatenate((Lxt0, Lxt1), axis=1)  # horizontal concatenate
    Lx = Lxt.transpose()

    assert dot2(Hz, Lxt).sum() == 0

    # These are linearly dependent, but
    # once we add stabilizers it will be reduced:
    assert rank(Lx) == len(Lx)

    if 0:
        # ---------------------------------------------------

        print(shortstr(Lx))
        k = get_k(Lx, Hx)
        print("k =", k)

        left, right = [], []

        draw = Draw(c0, c1, d0, d1)
        cols = []
        for j in range(d0):  # col
            col = []
            for i in range(len(KerC)):  # logical
                op = Lx[i * d0 + j]
                col.append(op)
                if j == i:
                    draw.mark_xop(op)
                if j < d0 / 2:
                    left.append(op)
                else:
                    right.append(op)
            cols.append(col)

        draw.save("output.2")

        left = array2(left)
        right = array2(right)

        print(get_k(left, Hx))
        print(get_k(right, Hx))

        return

    # ---------------------------------------------------
    # Build Lz

    counit = lambda n: unit2(n).transpose()

    K = find_cokernel(D)  # matrix of row vectors
    #E = counit(c1)
    E = identity2(c1)
    Lz0 = kron(E, K), zeros2(K.shape[0] * c1, c0 * d1)
    Lz0 = numpy.concatenate(Lz0, axis=1)  # horizontal concatenate

    assert dot2(Lz0, Hx.transpose()).sum() == 0

    K = find_cokernel(C)
    #E = counit(d1)
    E = identity2(d1)
    Lz1 = zeros2(K.shape[0] * d1, c1 * d0), kron(K, E)
    Lz1 = numpy.concatenate(Lz1, axis=1)  # horizontal concatenate

    Lz = numpy.concatenate((Lz0, Lz1), axis=0)

    assert dot2(Lz, Hx.transpose()).sum() == 0

    overlap = 0
    for lx in Lx:
        for lz in Lz:
            w = (lx * lz).sum()
            overlap = max(overlap, w)
    assert overlap <= 1, overlap
    #print("max overlap:", overlap)

    assert rank(Hx) == len(Hx)
    assert rank(Hz) == len(Hz)
    mx = len(Hx)
    mz = len(Hz)

    # ---------------------------------------------------

    Lxs = []
    for op in Lx:
        op = (op + Hx) % 2
        Lxs.append(op)
    LxHx = numpy.concatenate(Lxs)
    LxHx = row_reduce(LxHx)
    print("LxHx:", len(LxHx))
    assert LxHx.shape[1] == n
    print(len(intersect(LxHx, Hx)), mx)
    assert len(intersect(LxHx, Hx)) == mx

    Lzs = []
    for op in Lz:
        op = (op + Hz) % 2
        Lzs.append(op)
    LzHz = numpy.concatenate(Lzs)
    LzHz = row_reduce(LzHz)
    print("LzHz:", len(LzHz))
    assert LzHz.shape[1] == n

    # ---------------------------------------------------
    # Remove excess logops.

    #    print("remove_dependent")
    #
    #    # -------- Lx
    #
    #    Lx, Lx1 = mk_disjoint_logops(Lx, Hx)
    #
    #    # -------- Lz
    #
    #    Lz, Lz1 = mk_disjoint_logops(Lz, Hz)

    # --------------------------------
    # independent_logops for Lx

    k = get_k(Lx, Hx)

    idxs0, idxs1 = [], []

    for j in range(d0):  # col
        for i in range(c1):
            idx = j + i * d0
            if j < d0 // 2:
                idxs0.append(idx)
            else:
                idxs1.append(idx)

    Lx0 = in_support(LxHx, idxs0)
    Lx0 = independent_logops(Lx0, Hx)
    k0 = (len(Lx0))

    Lx1 = in_support(LxHx, idxs1)
    Lx1 = independent_logops(Lx1, Hx)
    k1 = (len(Lx1))
    assert k0 == k1 == k, (k0, k1, k)

    # --------------------------------
    # independent_logops for Lz

    idxs0, idxs1 = [], []

    for j in range(d0):  # col
        for i in range(c1):
            idx = j + i * d0
            if i < c1 // 2:
                idxs0.append(idx)
            else:
                idxs1.append(idx)

    Lz0 = in_support(LzHz, idxs0)
    Lz0 = independent_logops(Lz0, Hz)
    k0 = (len(Lz0))

    Lz1 = in_support(LzHz, idxs1)
    Lz1 = independent_logops(Lz1, Hz)
    k1 = (len(Lz1))
    assert k0 == k1 == k, (k0, k1, k)

    # ---------------------------------------------------
    #

    #assert eq2(dot2(Lz, Lxt), identity2(k))
    assert mx + mz + k == n

    print("mx = %d, mz = %d, k = %d : n = %d" % (mx, mz, k, n))

    # ---------------------------------------------------
    #

    #    if Lx1 is None:
    #        return
    #
    #    if Lz1 is None:
    #        return

    # ---------------------------------------------------
    #

    op = zeros2(n)
    for lx in Lx0:
        for lz in Lz0:
            lxz = lx * lz
            #print(lxz)
            #print(op.shape, lxz.shape)
            op += lxz

    for lx in Lx1:
        for lz in Lz1:
            lxz = lx * lz
            #print(lxz)
            #print(op.shape, lxz.shape)
            op += lxz

    idxs = numpy.where(op)[0]
    print("correctable region size = %d" % len(idxs))
    #print(op)
    #print(idxs)

    Lx, Lz = Lx0, Lz0

    Lxs = []
    for op in Lx:
        op = (op + Hx) % 2
        Lxs.append(op)
    LxHx = numpy.concatenate(Lxs)
    LxHx = row_reduce(LxHx)
    assert LxHx.shape[1] == n

    Lzs = []
    for op in Lz:
        op = (op + Hz) % 2
        Lzs.append(op)
    LzHz = numpy.concatenate(Lzs)
    LzHz = row_reduce(LzHz)
    assert LzHz.shape[1] == n

    if argv.draw:
        do_draw(**locals())

    good = is_correctable(n, idxs, LxHx, LzHz)
    assert good

    print("good")

    # ---------------------------------------------------
    #

    if argv.code:
        print("code = CSSCode()")
        code = CSSCode(Hx=Hx,
                       Hz=Hz,
                       Lx=Lx,
                       Lz=Lz,
                       check=True,
                       verbose=False,
                       build=True)
        print(code)
        #print(code.weightstr())

        if check:
            U = solve(Lx.transpose(), code.Lx.transpose())
            assert U is not None
            #print(U.shape)
            assert eq2(dot2(U.transpose(), Lx), code.Lx)
            #print(shortstr(U))

        if 0:
            Lx, Lz = code.Lx, code.Lz
            print("Lx:", Lx.shape)
            print(shortstr(Lx))
            print("Lz:", Lz.shape)
            print(shortstr(Lz))
Exemplo n.º 24
0
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")
Exemplo n.º 25
0
def test(A, B, ma, na, mb, nb, Ina, Ima, Inb, Imb, ka, kb, kat, kbt, k,
    KerA, KerB, CokerA, CokerB,
    Lzi, Lxi, Hzi, Hxi,
    **kw):

    #print("ka=%s, kat=%s, kb=%s, kbt=%s"%(ka, kat, kb, kbt))
    assert k == ka*kbt + kat*kb == len(Lzi) == len(Lxi)

    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

    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]))

    Hzt = cat((blocks[0][2], blocks[1][2]), axis=0)
    K = find_kernel(Hzt)
    assert len(K) == ka*kb # see proof of Lemma 3

    Lzv = cat((blocks[0][0], blocks[1][0])).transpose()
    Lzh = cat((blocks[0][1], blocks[1][1])).transpose()
    assert dot2(Hxi, Lzv.transpose()).sum() == 0

#    Hz = Hzt.transpose()
#    Hzi = linear_independent(Hz)
#    Lzhi = independent_logops(Lzh, Hzi, verbose=True)
#    print("Lzhi:", Lzhi.shape)

    # --------------------------------------------------------
    # basis for all logops, including stabilizers
    lz = find_kernel(Hxi) # returns transpose of kernel
    #lz = rand_rowspan(lz)
    #print("lz:", lz.shape)
    assert len(lz) == k+len(Hzi)

    # vertical qubits
    Iv = cat((identity2(na*mb), zeros2(ma*nb, na*mb)), axis=0).transpose()
    # horizontal qubits
    Ih = cat((zeros2(na*mb, ma*nb), identity2(ma*nb)), axis=0).transpose()
    assert len(intersect(Iv, Ih))==0 # sanity check

    # now restrict these logops to vertical qubits
    #print("Iv:", Iv.shape)
    lzv = intersect(Iv, lz)
    #print("lzv:", lzv.shape)

    J = intersect(lzv, Lzv)
    assert len(J) == len(lzv)

    # --------------------------------------------------------
    # now we manually build _lz supported on vertical qubits
    x = rand2(ka*mb, ka*nb)
    y = kron(KerA, Inb)
    assert eq2(dot2(blocks[0][2], y), kron(KerA, B))
    v = (dot2(blocks[0][0], x) + dot2(blocks[0][2], y)) % 2
    h = zeros2(ma*nb, v.shape[1])
    _lzt = cat((v, h))
    assert dot2(Hxi, _lzt).sum() == 0
    #print(shortstr(_lzt))
    _lz = _lzt.transpose()
    _lz = linear_independent(_lz)

    #print("*"*(na*mb))
    #print(shortstr(_lz))
    assert len(intersect(_lz, Ih)) == 0
    assert len(intersect(_lz, Iv)) == len(_lz)

    J = intersect(_lz, lz)
    assert len(J) == len(_lz)

    J = intersect(_lz, Lzv)
    #print(J.shape, _lz.shape, Lzv.shape)
    assert len(J) == len(_lz)

    if 0:
        V = cat(blocks[0][:2], axis=1)
        H = cat(blocks[1][:2], axis=1)
        X = cat((V, H), axis=0)
        K = find_kernel(X)
        print(K.shape)
    
        V = cat(blocks[0], axis=1)
        H = cat(blocks[1], axis=1)
        X = cat((V, H), axis=0)
        K = find_kernel(X)
        print(K.shape)
    
        #print("-"*(ka*mb+ma*kb))
        I = cat((identity2(ka*mb+ma*kb), zeros2(ka*mb+ma*kb, na*nb)), axis=1)
        J = intersect(K, I)
        print("J:", J.shape)
Exemplo n.º 26
0
def find_ideals():
    import networkx as nx
    from models import build_model

    model = build_model()
    if argv.verbose:
        print(model)
        print()
    #print(shortstrx(Hx, Hz))

    Gx, Gz = model.Gx, model.Gz
    Hx, Hz = model.Hx, model.Hz
    #print shortstrx(Gx, Gz)

    Rx, Rz = model.Rx, model.Rz
    Rxt = Rx.transpose()
    Rzt = Rz.transpose()

    Px, Pz = model.Px, model.Pz
    Pxt = Px.transpose()
    Pzt = Pz.transpose()

    r, n = Rx.shape

    assert eq2(dot2(Rx, Pxt), Rx)

#    print shortstrx(Gx, Gz)
#    print

    PGx = dot2(Gx, Pxt)
    PGz = dot2(Gz, Pzt)
    
#    print shortstrx(PGx, PGz)
#    print

    if 0:
        ng = len(PGx)

        graph = nx.Graph()
        for i in range(ng):
            graph.add_node(i)
    
        for i, gi in enumerate(PGx):
            for j, gj in enumerate(PGz):
                if (gi*gj).sum()%2:
                    graph.add_edge(i, j)

    mx = len(Gx)
    mz = len(Gz)
    graph = nx.Graph()
    for i in range(mx+mz):
        graph.add_node(i)

    for ix in range(mx):
        for iz in range(mz):
            if (Gx[ix]*Gz[iz]).sum()%2:
                graph.add_edge(ix, mx+iz)

#    excite = argv.excite
#    if type(excite) is int: 
#        _excite = [0]*len(model.Tx)
#        _excite[excite] = 1
#        excite = tuple(_excite)
#    #elif excite is None:
#    print("excite:", excite)

    equs = nx.connected_components(graph)
    equs = list(equs)

    print(model)
    print(("find_ideals:", len(equs)))

    models = []
    for equ in equs:
        equ = list(equ)
        equ.sort()
        #print(equ)
        gxs = []
        gzs = []
        for i in equ:
            if i<mx:
                gxs.append(Gx[i])
            else:
                gzs.append(Gz[i-mx])
        _model = build_model(array2(gxs), array2(gzs))
        print(_model)
        #print(shortstrx(_model.Gx))
        basis = find_kernel(_model.Gx.transpose())
        print(("kernel:", len(basis), [v.sum() for v in basis]))
        models.append(_model)

    idx = argv.dumpc
    if idx is not None:
        model = models[idx]
        #model = model.get_sector(compress=True)
        print(model)
        #print(shortstrx(model.Gx))
        basis = find_kernel(model.Gx.transpose())
        print(("kernel:", len(basis), [v.sum() for v in basis]))
        models.append(_model)
    
        model.dumpc()
        return

    if not argv.solve:
        return

    if argv.excite or argv.exciteall or argv.minweightall:
        if argv.minweightall:
            excites = minweightall(Hz)
            #print("excite", excite)
        elif argv.exciteall:
            excites = list(enum2(len(Hz)))[1:]
        else:
            assert len(Hz), Hz
            excites = []
            for i in range(len(Hz)):
                excite = array2([0]*len(Hz))
                excite[i] = 1
                excites.append(excite)
        print(("excites", len(excites)))
    else:
        excites = [None]

    if eq2(model.Hx, model.Hz):
        print("self dual stabilizers")

    _excite = None
    top = None
    for excite in excites:
        #if excite is not None:
        #    print "excite:", (excite)
        #    g = dot2(model.Hx.transpose(), excite)
        #    model.show_stabx(g)
        if excite is not None:
            tx = dot2(excite, model.Tx)

        total = 0.
        gaps = []

        for _model in models:
            #print(_model)
            if excite is not None:
                _tx = dot2(tx, _model.Hz.transpose(), _model.Tx)
                _excite = dot2(_tx, _model.Hz.transpose())
                #print(shortstrx(_excite))
                #print _excite
    
            r = len(_model.Rx)
            if r <= 12 and not argv.slepc and not argv.sparse:

                H = _model.build_ham(_excite) #weights=weights1)
                if argv.orbigraph:
                    H1 = build_orbigraph(H)
                
                vals, vecs = numpy.linalg.eigh(H)

            elif argv.sparse and r <= 19:

                vals = _model.sparse_ham_eigs(_excite) #weights=weights1)

            elif r <= 27:
                #for i in range(len(_excite)):
                #    _excite[i] = 1
                #print("excite:", tuple(_excite))
                #vals = slepc(excite=tuple(_excite), **_model.__dict__)
                if _excite is not None:
                    _excite = tuple(_excite)
                #vals = slepc(excite=_excite, **_model.__dict__)
                vals = _model.do_slepc(excite=_excite)
                #vals = [0, 0]

            else:
                assert 0, "r=%d too big"%r
            vals = list(vals)
            vals.sort(reverse=True)

            print(("total +=", vals[0]))
            total += vals[0]
            gaps.append(vals[0]-vals[1])
    
        if top is None or total > top:
            top = total
        print(("eval_1:", total))
        print(("eval_2:", total-min(gaps)))
    print(("top:", top))
Exemplo n.º 27
0
Arquivo: glue.py Projeto: punkdit/qupy
def find_triorth(m, k):
    # 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)

    if 0:
        A = list(span(G))
        print(strong_morthogonal(A, 1))
        print(strong_morthogonal(A, 2))
        print(strong_morthogonal(A, 3))

    G = [row for row in G if row.sum() % 2 == 0]
    return array2(G)

    #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)