Beispiel #1
0
def test():

    Hx = parse("1.11. .11.1")
    Hz = parse("111.. ..111")

    code = CSSCode(Hx=Hx, Hz=Hz)

    print(code)

    z_weld(code, code, [(3, 0), (4, 1)])
Beispiel #2
0
def main_8T():
    """
    _Transversal T gate on the [[8,3,2]] colour code.
    https://earltcampbell.com/2016/09/26/the-smallest-interesting-colour-code
    https://arxiv.org/abs/1706.02717
    """

    Hz = parse("1111.... 11..11.. 1.1.1.1. 11111111")
    Hx = parse("11111111")
    Lz = parse("1...1... 1.1..... 11......")
    Lx = parse("1111.... 11..11.. 1.1.1.1.")

    code = Code(Hz, Hx, Lz, Lx)
    code.check()
Beispiel #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)
Beispiel #4
0
def test():
    H = parse("""
     1001011
     0101110
     0010111
    """)
    print(latex(H))
    G = parse("""
     1101000
     0110100
     1110010
     1010001
    """)
    print(latex(G))
    print(dot2(G, H.transpose()))
Beispiel #5
0
def find_logops():

    Hz = parse("""
    11111.........................
    1....1111.....................
    .1.......1111.................
    ..1..1.......111..............
    ...1..1..1......11............
    ....1.....1..1....11..........
    ...........1....1...111.......
    ............1.....1.1..11.....
    ..............1....1...1.11...
    .......1.......1.........1.11.
    ........1........1...1.....1.1
    ......................1.1.1.11
    """)

    Hx = parse("""
    11......1..1.........1........
    .....11..11..1................
    ...11...........1.1.1.........
    .........1..1....1......1....1
    ....................11.1.1.1..
    ..........11.......1..1...1...
    .............1.1..1.....1...1.
    ..11...........1.1.........1..
    .....1..1.....1...........1..1
    .11.........1.1........1......
    1...1..1...........1.....1....
    ......11........1.....1.....1.
    """)
    Hz = remove_dependent(Hz)
    Hx = remove_dependent(Hx)

    mx, n = Hx.shape
    mz, n = Hz.shape

    print(n, mx, mz)

    Hz = parse("1.111... .111.1.. 1...1.11")
    Hx = parse("111...1. 11.1...1 ..1.111.")

    from qupy.ldpc.css import CSSCode
    code = CSSCode(Hx=Hx, Hz=Hz)
    print("Lx:")
    print(shortstr(code.Lx))
    print("Lz:")
    print(shortstr(code.Lz))
Beispiel #6
0
def test_toric4():

    d = 2

    H = parse("""
    1100
    0110
    0011
    1001
    """)

    T1 = Chain([H])
    T1t = T1.get_dual()

    T2 = T1.tensor(T1t)
    assert len(T2) == 2
    T2.check()

    #T3 = T2.tensor(T1)
    T4 = T2.tensor(T2)

    code = T4.get_code(1)
    print(code)

    code.save("toric4_%d_%d.ldpc" % (code.n, len(code.Lx)))
Beispiel #7
0
def test_repitition():

    H = parse("""
        111
        11.
        .11
    """)

    X = Chain([H])
    X.check()

    XX = X.tensor(X.get_dual(), 1)
    print(XX)
    print(shortstr(XX[0]))
Beispiel #8
0
        syndrome[i, j+1] += 1
    
    for i in range(l):
      for j in range(l):
        if syndrome[i,j]>1:
          if random()<0.5:
            syndrome[i,j]=0
          else:
            syndrome[i,j]=1

else:
    syndrome = parse("""
........
........
...1....
...1....
..1.....
........
.11.....
........
""")

#print syndrome

syndrome = syndrome[1:, :7]
l = 7

sites = [(i, j) for i in range(l) for j in range(l)]
nbd = dict(((i, j), []) for (i, j) in sites)
for i in range(l):
  for j in range(l):
    items = nbd[i, j]
Beispiel #9
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)
Beispiel #10
0
def test_symplectic():

    n = 3
    I = Matrix.identity(n)
    for idx in range(n):
        for jdx in range(n):
            if idx == jdx:
                continue
            CN_01 = Matrix.cnot(n, idx, jdx)
            CN_10 = Matrix.cnot(n, jdx, idx)
            assert CN_01 * CN_01 == I
            assert CN_10 * CN_10 == I
            lhs = CN_10 * CN_01 * CN_10
            rhs = Matrix.swap(n, idx, jdx)
            assert lhs == rhs
            lhs = CN_01 * CN_10 * CN_01
            assert lhs == rhs

    #print(Matrix.cnot(3, 0, 2))

    #if 0:
    cnot = Matrix.cnot
    hadamard = Matrix.hadamard
    n = 2
    gen = [cnot(n, 0, 1), cnot(n, 1, 0), hadamard(n, 0), hadamard(n, 1)]
    for A in gen:
        assert A.is_symplectic()
    Cliff2 = mulclose_fast(gen)
    assert len(Cliff2) == 72  # index 10 in Sp(2, 4)

    CZ = array2([[1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 1, 0], [1, 0, 0, 1]])
    CZ = Matrix(CZ)
    assert CZ.is_symplectic()
    assert CZ in Cliff2

    n = 3
    gen = [
        cnot(n, 0, 1),
        cnot(n, 1, 0),
        cnot(n, 0, 2),
        cnot(n, 2, 0),
        cnot(n, 1, 2),
        cnot(n, 2, 1),
        hadamard(n, 0),
        hadamard(n, 1),
        hadamard(n, 2),
    ]
    for A in gen:
        assert A.is_symplectic()
    assert len(mulclose_fast(gen)) == 40320  # index 36 in Sp(2,4)

    if 0:
        # cnot's generate GL(2, n)
        n = 4
        gen = []
        for i in range(n):
            for j in range(n):
                if i != j:
                    gen.append(cnot(n, i, j))
        assert len(mulclose_fast(gen)) == 20160

    if 0:
        n = 2
        count = 0
        for A in enum2(4 * n * n):
            A.shape = (2 * n, 2 * n)
            A = Matrix(A)
            try:
                assert A.is_symplectic()
                count += 1
            except:
                pass
        print(count)  # 720 = |Sp(2, 4)|
        return

    for n in [1, 2]:
        gen = []
        for x in enum2(2 * n):
            A = Matrix.transvect(x)
            assert A.is_symplectic()
            gen.append(A)
        G = mulclose_fast(gen)
        assert len(G) == [6, 720][n - 1]

    n = 2
    Sp = G
    #print(len(Sp))
    found = set()
    for g in Sp:
        A = g.A.copy()
        A[:n, n:] = 0
        A[n:, :n] = 0
        found.add(str(A))
    #print(len(A))

    #return

    n = 4
    I = Matrix.identity(n)
    H = Matrix.hadamard(n, 0)
    assert H * H == I

    CN_01 = Matrix.cnot(n, 0, 1)
    assert CN_01 * CN_01 == I

    n = 3
    trivial = CSSCode(Lx=parse("1.."),
                      Lz=parse("1.."),
                      Hx=zeros2(0, n),
                      Hz=parse(".1. ..1"))

    assert trivial.row_equal(CSSCode.get_trivial(3, 0))

    repitition = CSSCode(Lx=parse("111"),
                         Lz=parse("1.."),
                         Hx=zeros2(0, n),
                         Hz=parse("11. .11"))

    assert not trivial.row_equal(repitition)

    CN_01 = Matrix.cnot(n, 0, 1)
    CN_12 = Matrix.cnot(n, 1, 2)
    CN_21 = Matrix.cnot(n, 2, 1)
    CN_10 = Matrix.cnot(n, 1, 0)
    encode = CN_12 * CN_01

    code = CN_01(trivial)
    assert not code.row_equal(repitition)
    code = CN_12(code)
    assert code.row_equal(repitition)

    A = get_encoder(trivial, repitition)

    gen, names = get_gen(3)
    word = mulclose_find(gen, names, A)

    if 1:
        assert type(word) is tuple
        #print("word:")
        #print(repr(word))

        items = [gen[names.index(op)] for op in word]
        op = reduce(mul, items)

        #print(op)
        #assert op*(src) == (tgt)

        #print(op(trivial).longstr())
        assert op(trivial).row_equal(repitition)
Beispiel #11
0
        data[i, j+1] += 1
    
    for i in range(l):
      for j in range(l):
        if data[i,j]>1:
          if random()<0.5:
            data[i,j]=0
          else:
            data[i,j]=1

else:
    data = parse("""
........
........
...1....
...1....
..1.....
........
.11.....
........
""")

#print data

data = data[1:, :7]
l = 7

sites = [(i, j) for i in range(l) for j in range(l)]
nbd = dict(((i, j), []) for (i, j) in sites)
for i in range(l):
  for j in range(l):
    items = nbd[i, j]
Beispiel #12
0
def main():

    l = argv.get("l", 4)
    m = argv.get("m", l * l - 1)
    n = argv.get("n", 2 * l * l)

    weight = argv.get("weight", 4)

    if argv.e8:
        Hz = parse("""
        1....111
        .1..1.11
        ..1.11.1
        ...1111.
        """)
    elif argv.toric:
        code = Toric2D(l)
        Hz = code.Hz
    elif argv.toric3:
        code = Toric3D(l)
        Hz = code.Hx
        print("row weight:", Hz[0].sum())
    elif argv.rand_sparse:
        Hz = get_rand_sparse(m, n, weight)
    elif argv.rand_dense:
        Hz = get_rand_dense(m, n)
    else:
        return

    m, n = Hz.shape

    print("Hz.shape:", (m, n))

    logop = argv.logop
    if logop == "dense":
        logop = get_rand_dense(1, n)
        logop.shape = (n, )
    elif logop == "sparse":
        logop = get_rand_sparse(1, n, weight)
        logop.shape = (n, )

    if argv.spin:
        counts = sample_spin(Hz)
        print(counts)
        return

    if argv.spin_2:
        counts = sample_spin_2(Hz)
        print(counts)
        return

    genus = argv.get("genus", 1)

    if genus == 1:
        if argv.exact:
            counts = get_counts(Hz)
        else:
            counts = sample_counts(Hz, logop=logop)
    elif genus == 2:

        trials = argv.get("trials", 100)
        counts = sample_counts_2(Hz, trials)

        counts = list(counts.items())
        #counts.sort()
        counts.sort(key=lambda item: -item[1])
        for (k, v) in counts[:40]:
            print(k, v)
        return

    else:
        return

    if argv.show:
        print(list(counts))
    if argv.showpoly:
        cs = list(int(round(x)) for x in counts)
        n = len(cs)
        s = ' + '.join("%d*x**%d*y**%d" % (v, i, n - i - 1)
                       for i, v in enumerate(cs) if v)
        print(s)

    avg = get_avg(counts)
    print("get_avg:", avg)

    dev = get_dev(counts)
    print("get_dev:", dev)

    gauss = []
    for i in range(len(counts)):
        x = exp(-(i - avg)**2 / (2 * dev**2)) / ((2 * pi)**0.5 * dev)
        gauss.append(x)

    if argv.plot:
        pyplot.plot(counts, 'b')
        pyplot.plot(gauss, 'g')
        pyplot.show()

    return

    m, n = Hz.shape

    for i in range(10):
        Hz = get_rand(m, n)
        #print(shortstr(Hz))
        #counts = get_counts(Hz)
        counts = sample_counts(Hz)
        print(repr(counts))

        if argv.plot:
            pyplot.plot(counts, 'g')

    if argv.plot:
        pyplot.show()
Beispiel #13
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))
Beispiel #14
0
def main():

    m = argv.get('m', 6)  # constraints (rows)
    n = argv.get('n', 16)  # bits (cols)
    j = argv.get('j', 3)  # column weight (left degree)
    k = argv.get('k', 8)  # row weight (constraint weight; right degree)

    #assert 2*m<=n, "um?"

    max_iter = argv.get('max_iter', 200)
    verbose = argv.verbose
    check = argv.get('check', False)

    strop = shortstr

    Lx = None
    Lz = None
    Hx = None
    Tz = None
    Hz = None
    Tx = None
    build = argv.get('build', False)
    logops_only = argv.get("logops_only", True)

    code = None

    if argv.code == 'ldpc':

        H = ldpc(m, n, j, k)
        code = CSSCode(Hz=H, Hx=zeros2(0, n))

    elif argv.code == 'cycle':

        #n = argv.get('n', 20)
        #m = argv.get('m', 18)

        row = str(argv.get('H', '1101'))

        H = []

        for i in range(n):
            h = [0] * n
            for j, c in enumerate(row):
                h[(i + j) % n] = int(c)
            H.append(h)

        delta = n - m
        for i in range(delta):
            H.pop(i * n // delta - i)

#        while len(H) > m:
#            idx = randint(0, len(H)-1)
#            H.pop(idx)

        Hz = array2(H)

        print(shortstr(Hz))

        #print shortstr(solve.row_reduce(Hz))

#        code = CSSCode(Hz=Hz)
#        print
#        print code
#        print code.weightstr()
#
#        decoder = StarDynamicDistance(code)
#        L = decoder.find(verbose=verbose)
#        print shortstr(L)
#        print "distance:", L.sum()
#        return

    elif argv.code == "opticycle":

        code = opticycle(m, n)

        H = Hz = code.Hz

        #return

    elif argv.code == 'tree':

        k = argv.get('k', 5)
        n = 2**k + 1

        code = build_tree(45)
        print(code)

#        graph = Graph()
#        for i in range(H.shape[0]):
#            edge = list(numpy.where(H[i])[0])
#            #print edge,
#            for i0 in edge:
#              for i1 in edge:
#                if i0!=i1:
#                    graph.add_edge(i0, i1)
#
#        leaves = [idx for idx in range(n) if H[:, idx].sum()<=1]
#        print leaves
#
#
#        k = len(leaves)//2
#        print graph.metric(leaves[1], leaves[k])
#        return
#        for i in range(k-1):
#            #i0 = poprand(leaves)
#            #i1 = poprand(leaves)
#            u = zeros2(1, n)
#            u[0, leaves[i]] = 1
#            u[0, leaves[i+k]] = 1
#            # what about picking three leaves?
#            print (leaves[i], leaves[i+k]),
#            H = append2(H, u)
#        print
#
#        # if we take all the leaves we get degenerate...
#        leaves = [idx for idx in range(n) if H[:, idx].sum()<=1]
#        print "leaves:", leaves
#
#        #print shortstr(H)
#        #print
#        #print shortstr(solve.row_reduce(H))

#        code = CSSCode(Hz=H)
#        print code
#        print code.weightstr()

#        print numpy.where(code.Lx[3])
#
#        return

    elif argv.code == 'bicycle':

        from qupy.ldpc.bicycle import Bicycle_LDPC
        print("Bicycle_LDPC(%s, %s, %s, %s)" % (m, n, j, k))
        b = Bicycle_LDPC(m, n, j, k)
        Hx = Hz = b.H

    elif argv.code == 'toric':

        from qupy.ldpc.toric import Toric2D

        l = argv.get('l', 8)
        li = argv.get('li', l)
        lj = argv.get('lj', l)
        si = argv.get('si', 0)
        sj = argv.get('sj', 0)

        toric = Toric2D(li, lj, si, sj)
        Hx, Hz = toric.Hx, toric.Hz
        strop = toric.strop
        #print("Hx:")
        #print(shortstr(Hx))
        #print("Lx:")
        #print(shortstr(toric.Lx))
        code = CSSCode(Hx=Hx, Hz=Hz, Lx=toric.Lx, Lz=toric.Lz)

    elif argv.code == 'cylinder':

        from qupy.ldpc.toric import Cylinder

        l = argv.get('l', 8)
        li = argv.get('li', l)
        lj = argv.get('lj', l)
        si = argv.get('si', 0)
        sj = argv.get('sj', 0)
        assert si == 0

        surface = Cylinder(li, lj, sj)
        Hx, Hz = surface.Hx, surface.Hz
        strop = surface.strop
        #print("Hx:")
        #print(shortstr(Hx))
        #print("Lx:")
        #print(shortstr(surface.Lx))
        code = CSSCode(Hx=Hx, Hz=Hz)

    elif argv.code == 'torichie':

        from qupy.ldpc.toric import Toric2DHie
        l = argv.get('l', 8)

        toric = Toric2DHie(l)
        Hx, Hz = toric.Hx, toric.Hz

    elif argv.code == 'surface':

        from qupy.ldpc.toric import Surface
        l = argv.get('l', 8)
        si = argv.get('si', 0)  # todo
        sj = argv.get('sj', 0)

        surface = Surface(l)
        #Hx, Hz = surface.Hx, surface.Hz
        #strop = surface.strop
        #print shortstr(Hx)
        code = surface.get_code()

    elif argv.code == 'toric3':

        from qupy.ldpc.toric import Toric3D
        l = argv.get('l', 8)

        toric = Toric3D(l)
        Hx, Hz = toric.Hx, toric.Hz
        strop = toric.strop
        #print shortstr(Hx)

    elif argv.code == 'gcolor':

        from qupy.ldpc.gcolor import Lattice
        l = argv.get('l', 1)
        lattice = Lattice(l)
        #code = lattice.build_code()
        G = lattice.Hx
        print(shortstr(G))
        m, n = G.shape
        G1 = zeros2(m + 1, n + 1)
        G1[1:, 1:] = G
        G1[0, :] = 1
        print()
        print(shortstr(G1))
        for genus in range(1, 5):
            print(genus, strong_morthogonal(G1, genus))
        code = CSSCode(Hx=G1, Hz=G1)

    elif argv.code == 'self_ldpc':

        from qupy.ldpc.search import SelfContainingLDPC_Code
        ldpc_code = SelfContainingLDPC_Code(m, n, j, k)
        ldpc_code.search(max_step=argv.get('max_step', None), verbose=verbose)
        #print ldpc_code

        H = ldpc_code.H
        print("H:")
        print(shortstr(H))
        H = solve.linear_independent(H)
        Hx = Hz = H

        code = CSSCode(Hx=Hx, Hz=Hz)

    elif argv.code == 'cssldpc':

        from qupy.ldpc.search import CSS_LDPC_Code
        ldpc_code = CSS_LDPC_Code(m, n, j, k)
        ldpc_code.search(max_step=argv.get('max_step', None), verbose=verbose)
        #print ldpc_code

        Hx, Hz = ldpc_code.Hx, ldpc_code.Hz
        #print "Hx:"
        #print shortstr(Hx)
        Hx = solve.linear_independent(Hx)
        Hz = solve.linear_independent(Hz)
        #Hx = Hz = H

        code = CSSCode(Hx=Hx, Hz=Hz)

    elif argv.code == "hpack":

        code = hpack(n, j=j, k=k, check=check, verbose=verbose)

    elif argv.code == 'randldpc':

        mz = argv.get('mz', n // 3)
        rw = argv.get('rw', 12)  # row weight
        code = randldpc(n, mz, rw, check=check, verbose=verbose)

    elif argv.code == 'randcss':

        mx = argv.get('mx', n // 3)
        mz = argv.get('mz', n // 3)
        distance = argv.get("code_distance")
        code = randcss(n,
                       mx,
                       mz,
                       distance=distance,
                       check=check,
                       verbose=verbose)

    elif argv.code == 'sparsecss':

        mx = argv.get('mx', n // 3)
        mz = argv.get('mz', n // 3)
        weight = argv.get('weight', 4)
        code = sparsecss(n, mx, mz, weight, check=check, verbose=verbose)

    elif argv.code == 'ensemble':

        mx = argv.get('mx', n // 3)
        mz = argv.get('mz', mx)
        rw = argv.get('rw', 12)  # row weight
        maxw = argv.get('maxw', 4 * rw)
        C = argv.get("C", 100)
        code = ensemble.build(n,
                              mx,
                              mz,
                              rw,
                              maxw,
                              C,
                              check=check,
                              verbose=verbose)

    elif argv.code == "rm" or argv.code == "reed_muller":
        from qupy.ldpc import reed_muller
        r = argv.get("r", 1)
        m = argv.get("m", 4)
        puncture = argv.puncture
        cl_code = reed_muller.build(r, m, puncture)
        G = cl_code.G
        G = array2([row for row in G if row.sum() % 2 == 0])
        code = CSSCode(Hx=G, Hz=G)

    elif argv.code == "qrm":
        from qupy.ldpc.gallagher import get_code, hypergraph_product
        from qupy.ldpc import reed_muller
        r = argv.get("r", 1)
        m = argv.get("m", 4)
        puncture = argv.puncture
        cl_code = reed_muller.build(r, m, puncture)
        H = cl_code.G
        H = array2([row for row in H if row.sum() % 2 == 0])
        print(shortstr(H))
        m, n = 4, 4
        J = zeros2(m, n)
        for i in range(m):
            J[i, i] = 1
            J[i, (i + 1) % n] = 1
        print()
        print(shortstr(J))
        Hx, Hz, Lx, Lz = hypergraph_product(J, H)
        code = CSSCode(Hx=Hx, Hz=Hz, Lx=Lx, Lz=Lz)
        #print(code.weightstr())
        #print("Hz:")
        #print(shortstr(code.Hz))
        #print("Hx:")
        #print(shortstr(code.Hx))

    elif argv.code == "qgall":
        from qupy.ldpc.gallagher import make_gallagher, hypergraph_product
        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
        dist = argv.get("dist", 4)  # distance
        H = make_gallagher(r, n, l, m, dist)
        #print(H)
        rm = argv.get("rm", dist)
        J = zeros2(rm, rm)
        for i in range(rm):
            J[i, i] = 1
            J[i, (i + 1) % rm] = 1
        #print(J)
        Hx, Hz, Lx, Lz = hypergraph_product(J, H)
        code = CSSCode(Hx=Hx, Hz=Hz, Lx=Lx, Lz=Lz)
        #print(code.weightstr())
        #print("Hz:")
        #print(shortstr(code.Hz))
        #print("Hx:")
        #print(shortstr(code.Hx))

    elif argv.code == "qr7":
        H = parse("""
        ...1111
        .11..11
        1.1.1.1
        """)
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "golay" or argv.code == "qr23":
        H = parse("""
        1.1..1..11111..........
        1111.11.1....1.........
        .1111.11.1....1........
        ..1111.11.1....1.......
        ...1111.11.1....1......
        1.1.1.111..1.....1.....
        1111...1..11......1....
        11.111...11........1...
        .11.111...11........1..
        1..1..11111..........1.
        .1..1..11111..........1
        """)
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "dgolay":  # double golay code (tri-orthogonal)
        H = parse("""
        111111111111111111111111........................
        .1111.1.11..11..1.1....1.1111.1.11..11..1.1....1
        ..1111.1.11..11..1.1...1..1111.1.11..11..1.1...1
        ...1111.1.11..11..1.1..1...1111.1.11..11..1.1..1
        ....1111.1.11..11..1.1.1....1111.1.11..11..1.1.1
        .....1111.1.11..11..1.11.....1111.1.11..11..1.11
        1.....1111.1.11..11..1.11.....1111.1.11..11..1.1
        .1.....1111.1.11..11..11.1.....1111.1.11..11..11
        1.1.....1111.1.11..11..11.1.....1111.1.11..11..1
        .1.1.....1111.1.11..11.1.1.1.....1111.1.11..11.1
        ..1.1.....1111.1.11..111..1.1.....1111.1.11..111
        1..1.1.....1111.1.11..111..1.1.....1111.1.11..11
        11..1.1.....1111.1.11..111..1.1.....1111.1.11..1
        """)
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "dham":  # double hamming code (tri-orthogonal)
        H = parse("""
        11111111........
        .11.1..1.11.1..1
        ..11.1.1..11.1.1
        ...11.11...11.11
        1...11.11...11.1
        """)
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "ddham":  # double double hamming code
        H = parse("""
        1111111111111111................
        11111111........11111111........
        .11.1..1.11.1..1.11.1..1.11.1..1
        ..11.1.1..11.1.1..11.1.1..11.1.1
        ...11.11...11.11...11.11...11.11
        1...11.11...11.11...11.11...11.1
        """)
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "qr31":
        H = parse("""
        1..1..1.1...11.11..............
        11.11.1111..1.11.1.............
        11111111.11.1.....1............
        .11111111.11.1.....1...........
        ..11111111.11.1.....1..........
        ...11111111.11.1.....1.........
        1..111.1.1111.11......1........
        11.111....11...........1.......
        .11.111....11...........1......
        ..11.111....11...........1.....
        ...11.111....11...........1....
        ....11.111....11...........1...
        1..1.1...11.11..............1..
        .1..1.1...11.11..............1.
        ..1..1.1...11.11..............1
        """)
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "qr17":
        # not self-dual
        Hz = parse("""
        .11.1...11...1.11
        1.11.1...11...1.1
        11.11.1...11...1.
        .11.11.1...11...1
        1.11.11.1...11...
        .1.11.11.1...11..
        ..1.11.11.1...11.
        ...1.11.11.1...11
        1...1.11.11.1...1
        11...1.11.11.1...
        .11...1.11.11.1..
        ..11...1.11.11.1.
        ...11...1.11.11.1
        1...11...1.11.11.
        .1...11...1.11.11
        1.1...11...1.11.1
        11.1...11...1.11.
        """)
        Hx = parse("""
        ...1.111..111.1..
        11.1.....1.111..1
        111..111.1.....1.
        ....1.111..111.1.
        111.1.....1.111..
        .111..111.1.....1
        .....1.111..111.1
        .111.1.....1.111.
        1.111..111.1.....
        1.....1.111..111.
        ..111.1.....1.111
        .1.111..111.1....
        .1.....1.111..111
        1..111.1.....1.11
        ..1.111..111.1...
        1.1.....1.111..11
        11..111.1.....1.1
        """)
        Hz = solve.linear_independent(Hz)
        Hx = solve.linear_independent(Hx)
        code = CSSCode(Hx=Hx, Hz=Hz)

    elif argv.code == "qr41":
        # not self-dual
        Hz = parse("""
        .11.11..111.....1.1.11.1.1.....111..11.11
        1.11.11..111.....1.1.11.1.1.....111..11.1
        11.11.11..111.....1.1.11.1.1.....111..11.
        .11.11.11..111.....1.1.11.1.1.....111..11
        1.11.11.11..111.....1.1.11.1.1.....111..1
        11.11.11.11..111.....1.1.11.1.1.....111..
        .11.11.11.11..111.....1.1.11.1.1.....111.
        ..11.11.11.11..111.....1.1.11.1.1.....111
        1..11.11.11.11..111.....1.1.11.1.1.....11
        11..11.11.11.11..111.....1.1.11.1.1.....1
        111..11.11.11.11..111.....1.1.11.1.1.....
        .111..11.11.11.11..111.....1.1.11.1.1....
        ..111..11.11.11.11..111.....1.1.11.1.1...
        ...111..11.11.11.11..111.....1.1.11.1.1..
        ....111..11.11.11.11..111.....1.1.11.1.1.
        .....111..11.11.11.11..111.....1.1.11.1.1
        1.....111..11.11.11.11..111.....1.1.11.1.
        .1.....111..11.11.11.11..111.....1.1.11.1
        1.1.....111..11.11.11.11..111.....1.1.11.
        .1.1.....111..11.11.11.11..111.....1.1.11
        """)
        Hx = parse("""
        ...1..11...11111.1.1..1.1.11111...11..1..
        1111...11..1.....1..11...11111.1.1..1.1.1
        111.1.1..1.1.11111...11..1.....1..11...11
        ....1..11...11111.1.1..1.1.11111...11..1.
        11111...11..1.....1..11...11111.1.1..1.1.
        1111.1.1..1.1.11111...11..1.....1..11...1
        .....1..11...11111.1.1..1.1.11111...11..1
        .11111...11..1.....1..11...11111.1.1..1.1
        11111.1.1..1.1.11111...11..1.....1..11...
        1.....1..11...11111.1.1..1.1.11111...11..
        1.11111...11..1.....1..11...11111.1.1..1.
        .11111.1.1..1.1.11111...11..1.....1..11..
        .1.....1..11...11111.1.1..1.1.11111...11.
        .1.11111...11..1.....1..11...11111.1.1..1
        ..11111.1.1..1.1.11111...11..1.....1..11.
        ..1.....1..11...11111.1.1..1.1.11111...11
        1.1.11111...11..1.....1..11...11111.1.1..
        ...11111.1.1..1.1.11111...11..1.....1..11
        1..1.....1..11...11111.1.1..1.1.11111...1
        .1.1.11111...11..1.....1..11...11111.1.1.
        """)
        code = CSSCode(Hz=Hz, Hx=Hx)

    elif argv.code == "qr47":
        H = parse("""
        1...11..11.11..1..1.1..11......................
        11..1.1.1.11.1.11.1111.1.1.....................
        111.1..11.....111111.111..1....................
        11111......11...11.1..1....1...................
        .11111......11...11.1..1....1..................
        1.11..1.11.11111...111.1.....1.................
        11.1.1.11.11.11.1.1..111......1................
        111..11.......1..1111.1........1...............
        .111..11.......1..1111.1........1..............
        1.11.1.1.1.11..11.11.111.........1.............
        11.1.11..111.1.11111..1...........1............
        .11.1.11..111.1.11111..1...........1...........
        1.111..1.1...1...1.1.1.1............1..........
        11.1.....1111.11......11.............1.........
        111..1..111..1..1.1.1.................1........
        .111..1..111..1..1.1.1.................1.......
        ..111..1..111..1..1.1.1.................1......
        ...111..1..111..1..1.1.1.................1.....
        1.....1.1..1.111.11...11..................1....
        11..11.11..1..1.1..11......................1...
        .11..11.11..1..1.1..11......................1..
        ..11..11.11..1..1.1..11......................1.
        ...11..11.11..1..1.1..11......................1
        """)
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "qr71":
        H = parse("""
        1.1.1.11.1...11..11.....1....1...1111..................................
        1111111.111..1.1.1.1....11...11..1...1.................................
        .1111111.111..1.1.1.1....11...11..1...1................................
        ..1111111.111..1.1.1.1....11...11..1...1...............................
        1.11.1..1..11.1.11..1.1.1..111..1.11....1..............................
        1111...1....1.11.....1.111..1.1...1......1.............................
        .1111...1....1.11.....1.111..1.1...1......1............................
        1..1.111.....1..1.1....11111.11.1111.......1...........................
        111.....11...1....11.....1111111............1..........................
        .111.....11...1....11.....1111111............1.........................
        ..111.....11...1....11.....1111111............1........................
        ...111.....11...1....11.....1111111............1.......................
        ....111.....11...1....11.....1111111............1......................
        1.1.11...1.......1.....1.....1111................1.....................
        .1.1.11...1.......1.....1.....1111................1....................
        ..1.1.11...1.......1.....1.....1111................1...................
        ...1.1.11...1.......1.....1.....1111................1..................
        1.1....11.....1..11..1..1..1.1.......................1.................
        .1.1....11.....1..11..1..1..1.1.......................1................
        ..1.1....11.....1..11..1..1..1.1.......................1...............
        ...1.1....11.....1..11..1..1..1.1.......................1..............
        ....1.1....11.....1..11..1..1..1.1.......................1.............
        .....1.1....11.....1..11..1..1..1.1.......................1............
        ......1.1....11.....1..11..1..1..1.1.......................1...........
        1.1.1.1......1.1.11..1...1..11.1.1.1........................1..........
        1111111..1...1..11.1..1.1.1...1.11.1.........................1.........
        11.1.1...11..1......1..111.1.1.1...1..........................1........
        11.....1.111.1...11..1...11.111.1111...........................1.......
        11..1.11111111...1.1..1.1.11..11................................1......
        .11..1.11111111...1.1..1.1.11..11................................1.....
        ..11..1.11111111...1.1..1.1.11..11................................1....
        ...11..1.11111111...1.1..1.1.11..11................................1...
        ....11..1.11111111...1.1..1.1.11..11................................1..
        1.1.11.1...11..11.....1....1...1111..................................1.
        .1.1.11.1...11..11.....1....1...1111..................................1
        """)
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "rm_2_5_p":
        H = parse("""
        ...11111111....................
        .11..1111..11..................
        1.1.1.11.1.1.1.................
        11.1..1.11.1..1................
        ...1111........1111............
        .11..11........11..11..........
        1.1.1.1........1.1.1.1.........
        11.1..1.........11.1..1........
        .11111111......11......11......
        1.111111.1.....1.1.....1.1.....
        11.1111.11......11.....1..1....
        111.1111...1...1...1...1...1...
        1111.11.1..1....1..1...1....1..
        11111.1..1.1.....1.1...1.....1.
        111111.111.1...111.1...1......1
        """)
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "to_16_6":  # triorthogonal
        H = parse("""
        ........11111111
        ....1111....1111
        11111111........
        ..11..11..11..11
        .1.1.1.1.1.1.1.1
        1..1.11..11.1..1
        """)  # distance = 4
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "B11":  # Pless 1971, punctured B12
        H = parse("""
        .1111......
        ...1111....
        .....1111..
        .......1111
        1.1.1.1.1.1
        """)
        from qupy.ldpc.gallagher import classical_distance
        print(classical_distance(H))
        code = CSSCode(Hx=H, Hz=H)

    elif argv.code == "glue_classical_self":
        from qupy.ldpc.glue import glue_classical, glue_classical_self
        H = glue_classical_self()
        H = H.copy()
        code = CSSCode(Hx=H, Hz=H)
        #if argv.classical_distance:
        #    from qupy.ldpc.gallagher import classical_distance
        #    print("distance:", classical_distance(H))

    elif argv.code == "randselfdual":
        m = argv.get("m", 4)
        n = argv.get("n", 8)
        rw = argv.get("rw", 4)
        code = randselfdual(m, n, rw)

    else:
        from qupy.ldpc.gallagher import get_code
        code = get_code(argv.code)

    if argv.truncate:
        idx = argv.truncate
        Hx = Hx[:idx]
        Hz = Hz[:idx]

    for arg in argv:
        if arg.endswith('.ldpc'):
            code = CSSCode.load(arg,
                                build=build,
                                check=check,
                                rebuild=argv.rebuild)

            if argv.rebuild:
                code.save(arg)

            break

    if code is None:
        code = CSSCode(Lx,
                       Lz,
                       Hx,
                       Tz,
                       Hz,
                       Tx,
                       build=build,
                       check=check,
                       verbose=verbose,
                       logops_only=logops_only)

    if argv.dual:
        print("dual code...")
        code = code.dual(build=build)

    # take several copies of the code..
    mul = argv.get("mul", 1)
    code = mul * code

    if argv.classical_product:
        H1 = code.Hx
        H2 = H1.transpose()
        Hx, Hz = hypergraph_product(H1, H2)
        code = CSSCode(Hx=Hx, Hz=Hz)

    if argv.product:

        codes = code.product(code.dual())

        for _code in codes:
            print(_code)
            if _code.k:
                _code.save(stem="prod")

    if argv.verbose != 0:
        print(code)
        #print code.longstr()
        #print code.weightstr()
        print(code.weightsummary())

    if argv.shorten:
        code.shorten()
        print(code)
        print(code.weightsummary())

    if argv.prune:
        print("pruning:", argv.prune)
        code.prune_xlogops(argv.prune)
        print(code)
        print(code.weightsummary())

    if argv.split:

        for i in range(4):
            code = x_split(code, build=False)
            print(code)
            print(code.weightsummary())
            code = code.dual()
            code = x_split(code, build=False)
            code = code.dual()
            print(code)
            print(code.weightsummary())
            code.save(stem="split")

    if argv.save:
        code.save(argv.save)

    if argv.symplectic:
        i = randint(0, code.mz - 1)
        j = randint(0, code.k - 1)
        code.Lz[j] += code.Hz[i]
        code.Lz[j] %= 2
        code.Tx[i] -= code.Lx[j]
        code.Tx[i] %= 2
        code.do_check()

        return

    if argv.showcode:
        print(code.longstr())

    if argv.todot:
        todot(code.Hz)
        return

    if argv.tanner:
        Hx = code.Hx
        graph = Tanner(Hx)
        #graph.add_dependent()

        depth = 3

        graphs = [graph]
        for i in range(depth):
            _graphs = []
            for g in graphs:
                left, right = g.split()
                _graphs.append(left)
                _graphs.append(right)
            graphs = _graphs
        print("split", graphs)

        k = code.Lx.shape[0]
        op = code.Lx[1]
        #op = (op + code.Tx[20])%2
        print(strop(op), op.sum())
        print()
        for i in range(Hx.shape[0]):
            if random() <= 0.5:
                op = (op + Hx[i]) % 2
        #print shortstr(op), op.sum()

        print(strop(op), op.sum())
        print()

        #for graph in [left, right]:
        for graph in graphs * 2:

            #op = graph.minimize(op, verbose=True)
            op = graph.localmin(op, verbose=True)
            print(strop(op), op.sum())
            print()

        #op = graph.localmin(op)
        #print strop(op), op.sum()
        #print
        #print shortstr(op), op.sum()

        return

    if argv.distance == 'star':
        decoder = StarDynamicDistance(code)
        L = decoder.find(verbose=verbose)
        print(shortstr(L))
        print("distance <=", L.sum())
    elif argv.distance == 'stab':
        d = random_distance_stab(code)
        print("distance <=", d)
    elif argv.distance == 'pair':
        d = pair_distance(code)
        print("distance <=", d)
    elif argv.distance == 'free':
        d = free_distance(code)
        print("distance <=", d)
    elif argv.distance == 'lookup':
        d = lookup_distance(code)
        if d <= 4:
            print("distance =", d)
        else:
            print("distance <=", d)

    if type(argv.distance) == str:
        return

    if argv.get('exec'):

        exec(argv.get('exec'))

    N = argv.get('N', 0)
    p = argv.get('p', 0.01)
    weight = argv.weight

    #assert code.Tx is not None, "use code.build ?"

    decoder = get_decoder(argv, argv.decode, code)
    if decoder is None:
        return

    if argv.whack:
        whack(code, decoder, p, N, argv.get("C0", 10),
              argv.get("error_rate", 0.05), argv.get("mC", 1.2), verbose, argv)
        return

    if argv.noerr:
        print("redirecting stderr to stderr.out")
        fd = os.open("stderr.out", os.O_CREAT | os.O_WRONLY)
        os.dup2(fd, 2)

    decoder.strop = strop
    print("decoder:", decoder.__class__.__name__)

    n_ranks = numpy.zeros((code.n, ), dtype=numpy.float64)
    n_record = []
    k_ranks = numpy.zeros((code.k, ), dtype=numpy.float64)
    k_record = []

    failures = open(argv.savefail, 'w') if argv.savefail else None

    if argv.loadfail:
        loadfail = open(argv.loadfail)
        errs = loadfail.readlines()
        N = len(errs)

    newHx = []
    newHz = []

    distance = code.n
    count = 0
    failcount = 0
    nonuniq = 0

    if argv.weight1:
        # run through all weight=1 errors
        N = code.n

    if argv.weight2:
        # run through all weight=1 errors
        N = code.n**2

    for i in range(N):

        # We use Hz to look at X type errors (bitflip errors)

        if argv.loadfail:
            err_op = parse(errs[i])
            err_op.shape = (code.n, )
        elif argv.weight1:
            err_op = zeros2(code.n)
            err_op[i % code.n] = 1
        elif argv.weight2:
            err_op = zeros2(code.n)
            ai = i % code.n
            bi = (i // code.n)
            err_op[ai] = 1
            err_op[bi] = 1

        elif weight is not None:
            err_op = zeros2(code.n)
            r = 0
            while r < weight:
                idx = randint(0, code.n - 1)
                if err_op[idx] == 0:
                    err_op[idx] = 1
                    r += 1
            #print err_op
        else:
            err_op = ra.binomial(1, p, (code.n, ))
            err_op = err_op.astype(numpy.int32)

#        err_op = parse("..............................")
#        err_op.shape = (err_op.shape[1],)
        write(str(err_op.sum()))
        #print err_op.shape

        s = dot2(code.Hz, err_op)
        write(":s%d:" % s.sum())

        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)
            if dot2(code.Hz, op).sum() != 0:
                print(dot2(code.Hz, op))
                print("\n!!!!!  BUGBUG  !!!!!", sparsestr(err_op))
                continue
            write("%d:" % op.sum())

            #print "is_stab:"
            #print strop(op)
            # Are we in the image of Hx ? If so, then success.
            #success = code.is_stab(op)
            success = dot2(code.Lz, op).sum() == 0

            if success and op.sum():
                nonuniq += 1
            #    print "\n", shortstr(err_op)
            #    return

            c = '.' if success else 'x'

            if argv.k_rank:

                # XX this does not work very well...

                a = dot2(code.Lz, op)
                assert (a.sum() == 0) == success

                if not success:
                    #r = -1. // (a.sum()**0.5) # sqrt ??
                    r = -1. / a.sum()
                    k_ranks += r * a
                else:
                    #r = 1. / (code.k**0.5)
                    r = 1. / code.k
                    k_ranks += r * a

                k_record.append((a, success))

            if op.sum() and not success:
                distance = min(distance, op.sum())
                #if op.sum() == 2:
                #    print()
                #    print("main:")
                #    print(shortstr(op))
                #    print()
                #    print(strop(op))

                if argv.minop and argv.minop >= op.sum():
                    a = dot2(code.Lz, op)
                    print()
                    print(sparsestr(a))

            if not success and argv.addstabs and op.sum() <= argv.addstabs:
                #write("%d"%op.sum())
                print((sparsestr(op)))
                newHx.append(op)

                A = numpy.concatenate((code.Lx, code.Hx))
                c = solve.solve(A.transpose(), op.transpose()).transpose()
                cL = c[:code.k]
                zstab = dot2(cL, code.Lz)
                print(shortstr(zstab))
                graph = Tanner(code.Hz)
                zstab = graph.minimize(zstab, target=8, verbose=True)
                print(shortstr(zstab))
                newHz.append(zstab)
                break


#                Hz, Hx = code.Hz, append2(code.Hx, op)
#                #if len(Hz) < len(Hx):
#                #    Hx, Hz = Hz, Hx
#                print Hx.shape, Hz.shape
#                code = CSSCode(Hx=Hx, Hz=Hz)
#                if len(Hz) < len(Hx):
#                    code = code.dual()
#                    decoder = get_decoder(argv, argv.decode, code)
#                print
#                print code
#                print code.weightsummary()
#                code.save("addstabs_%d_%d_%d.ldpc"%(code.n, code.k, code.distance))

            if not success and argv.showfail:
                print()
                print("FAIL:")
                print(shortstr(err_op))

        else:
            failcount += 1

            if failures:
                print(shortstr(err_op), file=failures)
                failures.flush()

        if argv.n_rank:
            r = 2. * int(success) - 1
            #print "r =", r
            if err_op.sum():
                r /= err_op.sum()
                #print r
                #print r*err_op
                n_ranks += r * err_op
                n_record.append((err_op, success))

        write(c + ' ')
        count += success

    if hasattr(decoder, 'fini'):
        decoder.fini()

    if N:
        print()
        print(datestr)
        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)

    if argv.n_rank:
        #n_ranks //= N
        n_ranks = list(enumerate(n_ranks))
        n_ranks.sort(key=lambda item: -item[1])
        #print [r[0] for r in n_ranks]
        print(' '.join('%d:%.2f' % r for r in n_ranks))
        #print min(r[1] for r in n_ranks)
        #print max(r[1] for r in n_ranks)
        A = numpy.array([rec[0] for rec in n_record])
        b = numpy.array([rec[1] for rec in n_record])
        print(A.shape, b.shape)
        sol = lstsq(A, b)
        x, res, rk, s = sol
        #print x
        for i, val in enumerate(x):
            if val < 0:
                print(i, end=' ')
        print()

    if argv.k_rank:
        #k_ranks //= N
        k_ranks = list(enumerate(k_ranks))
        k_ranks.sort(key=lambda item: -item[1])
        #print [r[0] for r in k_ranks]
        print(' '.join('%d:%.2f' % r for r in k_ranks))
        #print ' '.join(str(r) for r in k_ranks)
        #print min(r[1] for r in k_ranks)
        #print max(r[1] for r in k_ranks)
        A = numpy.array([rec[0] for rec in k_record])
        b = numpy.array([rec[1] for rec in k_record])
        #print A.shape, b.shape
        sol = lstsq(A, b)
        x, res, rk, s = sol
        #print x
        xs = list(enumerate(x))
        xs.sort(key=lambda item: item[1])
        print(' '.join('%d:%.2f' % item for item in xs))

    if argv.addstabs and newHz:
        Hz = append2(code.Hz, newHz[0])
        code = CSSCode(Hx=code.Hx, Hz=Hz)
        code.save(stem="addstabs")
        print(code)
        print(code.weightsummary())

    elif argv.addstabs and newHx:  # and newHx.shape[0]>code.Hx.shape[0]:
        newHx = array2(newHx)
        newHx = numpy.concatenate((code.Hx, newHx))
        #print shortstr(newHx)
        #print
        Hx = solve.linear_independent(newHx)
        #print shortstr(Hx)
        #print
        code = CSSCode(Hx=Hx, Hz=code.Hz)
        code.save(stem="addstabs")
        print(code)
        print(code.weightsummary())
Beispiel #15
0
def main():

    Hz = parse("""
    11111.........................
    1....1111.....................
    .1.......1111.................
    ..1..1.......111..............
    ...1..1..1......11............
    ....1.....1..1....11..........
    ...........1....1...111.......
    ............1.....1.1..11.....
    ..............1....1...1.11...
    .......1.......1.........1.11.
    ........1........1...1.....1.1
    ......................1.1.1.11
    """)

    Hx = parse("""
    11......1..1.........1........
    .....11..11..1................
    ...11...........1.1.1.........
    .........1..1....1......1....1
    ....................11.1.1.1..
    ..........11.......1..1...1...
    .............1.1..1.....1...1.
    ..11...........1.1.........1..
    .....1..1.....1...........1..1
    .11.........1.1........1......
    1...1..1...........1.....1....
    ......11........1.....1.....1.
    """)

    mx, n = Hx.shape
    mz, n = Hz.shape

    from qupy.condmat.isomorph import Tanner, search

    src = Tanner.build2(Hx, Hz)

    #tgt = Tanner.build2(Hx, Hz)
    tgt = Tanner.build2(Hz, Hx) # weak duality

    # from bruhat.psl2:
    edges = [
        (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 4), (2, 5),
        (2, 10), (2, 11), (3, 5), (3, 6), (3, 7), (3, 8), (4,
        6), (4, 9), (4, 10), (5, 7), (5, 11), (6, 8), (6, 9),
        (7, 8), (7, 11), (7, 12), (8, 9), (8, 12), (9, 10), (9,
        12), (10, 11), (10, 12), (11, 12)]

    fns = []
    perms = []
    for fn in search(src, tgt):
        assert len(fn) == mx+mz+n
        bitmap = []
        for i in range(n):
            bitmap.append( fn[i+mx+mz]-mx-mz )
        perm = tuple(bitmap)
        #print(bitmap)
        fixed = [i for i in range(n) if bitmap[i]==i]
        if len(fixed)==6:
            perms.append(perm)
            #print(len(fixed), end=" ")
            #break
        else:
            print("fixed:", fixed)
            for i, ii in enumerate(fixed):
                print('\t', edges[ii])
    return

    perm = perms[1]
    idxs = (0,1,1,0,1,0)
    print(perm)
    fixed = []
    for i, ii in enumerate(perm):
        if i==ii:
            fixed.append(i)
    print("fixed:", fixed)
    for i, ii in enumerate(fixed):
        print(edges[ii], idxs[i])

    return

    perm = tuple(bitmap)
    print(perm)

    # XX too big...
#    fold = I
#    for i, j in enumerate(perm):
#        if i < j:
#            print("swap", i, j)
#            op = make_swap(i, j, n)
#            fold = op*fold

    code = Code(Hx, Hz)
    print(code)

    code1 = code.get_perm(perm)
    print(code1)
    assert not code==code1

    In = pauli.parse("I"*n)
    fold = In
    for i, j in enumerate(perm):
        if i < j:
            fold *= make_cz(i, j, code.n)
        elif i==j:
            fold *= make_op(S, i, code.n)

    print("fold")

    #lhs = fold * code.get_projector()
    lhs = fold * code.Pz * code.Px
    print("lhs")
    rhs = code1.Pz * (code1.Px * fold)
    print("rhs")
    print(lhs == rhs)

    if argv.pause:
        print("done...")
        while 1:
            sleep(1)
Beispiel #16
0
def test_encode():

    n = 5

    target = parse("""
    1.11......
    .11.1.....
    .....111..
    .......111
    1.1.1.....
    ........1.
    ......1...
    1.........
    1.1.......
    ......1..1
    """)
    target = Matrix(target)
    assert target.is_symplectic()

    source = parse("""
    ...1......
    .1........
    .....1....
    .......1..
    ....1.....
    ........1.
    ......1...
    1.........
    ..1.......
    .........1
    """)
    source = Matrix(source)
    assert source.is_symplectic()

    def get_encoder(source, target):
        assert isinstance(source, CSSCode)
        assert isinstance(target, CSSCode)
        src = Matrix(source.to_symplectic())
        src_inv = src.inverse()
        tgt = Matrix(target.to_symplectic())
        A = (src_inv * tgt).transpose()
        return A

    #print(Matrix.cnot(2, 0, 1))
    #return

    #source = source.transpose()
    #target = target.transpose()

    def cnot(i, j):
        g = Matrix.cnot(n, i - 1, j - 1)
        g.name = "cnot(%d,%d)" % (i, j)
        return g

    assert cnot(3, 1) == cnot(1, 3).transpose()
    #gen = [cnot(3,1), cnot(2,3), cnot(2,5), cnot(4,3), cnot(5,3)]
    gen = [
        cnot(3, 1),
        cnot(2, 3),
        cnot(2, 5),
        cnot(4, 3),
        cnot(4, 1),
        cnot(5, 3),
        cnot(5, 4),
        cnot(2, 1),
    ]
    #gen = [cnot(i,j) for i in range(1,n+1) for j in range(1,n+1) if i!=j]
    names = [g.name for g in gen]

    gen = [g.transpose() for g in gen]

    #A = (source.inverse() * target).transpose()
    #A = source.inverse() * target
    A = target * source.inverse()
    assert A.is_symplectic()
    #print(A)

    words = set()
    for trial in range(100):
        word = mulclose_find(gen, names, A)
        if word is None:
            break
        if word not in words:
            print(word)
            words.add(word)

    if word is None:
        print("not found")
        return
    ops = [gen[names.index(c)] for c in word]
    op = reduce(mul, ops)
    assert op * source == target
Beispiel #17
0
def test_stean():

    Hx = parse("""
        ...1111
        .11..11
        1.1.1.1
        1.11.1.
        .1111..
    """)

    Hx = parse("""
        ...1111
        .11..11
        1.1.1.1
    """)

    Hz = parse("""
        ...1111
        .11..11
        1.1.1.1
    """)

    A = list(a for a in solve.span(Hz) if a.sum())
    A = array2(A)
    print(shortstr(A))
    Hx = A

    Hz = Hx.copy()

    X = Chain([Hx, Hz.transpose()])

    X.check()

    #    for i in range(-1, 3):
    #        print "homology", i
    #        print shortstr(X.homology(i))

    #    X.dumpcodes()
    #    print
    #    print "=========="*10
    #    print

    XX = X.tensor(X)

    XX.dumpcodes()
    return

    for L in XX.Ls:
        print(L.shape)

    code = XX.get_code(1)
    print(code)
    print(code.weightsummary())
    #code.save("stean2_147_33.ldpc")
    return

    #XX = XX.tensor(X)

    XX.dumpcodes()

    return

    #code = XX.get_code(1)

    #code.save('stean2.ldpc')

    X4 = XX.tensor(XX)

    X4.dumpcodes()
Beispiel #18
0
def main():

    n = 5
    Tx = parse("""
    1....
    1.1..
    1.1.1
    """)

    Tz = parse("""
    .1...
    ...1.
    """)


    code = CSSCode(Hx=Tx, Hz=Tz)

    #print(code)
    #print(code.longstr())

    S = parse("""
    1.1..1
    11.1..
    .11.1.
    ...111
    """)

    I = parse("""
    1...
    .1..
    ..1.
    ...1
    """)

    A = parse("""
    1...
    11..
    ..1.
    ...1
    """)

    B = parse("""
    1...
    .1..
    .11.
    ...1
    """)

    C = parse("""
    1...
    .1..
    ..1.
    ..11
    """)

    #print(I)
    #print(dot2(A))
    #print(dot2(B, A))
    L = dot2(C, B, A)
    #print(dot2(L, S)) # row reduced S

    L = L[:3, :3]

    S = S[:3, :]
    print("S =")
    print(S)

    print("LS =")
    print(dot2(L, S))

    J = parse("""
    1..
    11.
    ...
    ...
    111
    ...
    """)

    U = parse("""
    1..
    .11
    ..1
    """)

    print(dot2(U, L, S))