Ejemplo n.º 1
0
Archivo: expr.py Proyecto: punkdit/qupy
    def __init__(self, Hz, Hx, Lz=None, Lx=None, **kw):
        self.__dict__.update(kw)
        mz, n = Hz.shape
        mx, nx = Hx.shape
        assert n == nx
        assert rank(Hz) == mz
        assert rank(Hx) == mx
        xstabs = []
        zstabs = []
        space = Space(n)

        for i in range(mz):
            idxs = [j for j in range(n) if Hz[i, j]]
            op = space.make_zop(idxs)
            zstabs.append(op)

        for i in range(mx):
            idxs = [j for j in range(n) if Hx[i, j]]
            op = space.make_xop(idxs)
            xstabs.append(op)

        # code projector:
        P = None
        for op in zstabs + xstabs:
            A = (space.I + op)
            P = A if P is None else A * P
        print(P)
Ejemplo n.º 2
0
def rand_span(A):
    while 1:
        m, n = A.shape
        v = rand2(m, m)
        A1 = dot2(v, A)
        assert A1.shape == A.shape
        if rank(A) == rank(A1):
            break
    assert rank(intersect(A, A1)) == rank(A)
    return A1
Ejemplo n.º 3
0
Archivo: glue.py Proyecto: punkdit/qupy
def make_quantum(n, m, dist=0, weight=None):
    while 1:
        Hx, Hz = make_q(n, m, weight)
        if rank(Hx) < m or rank(Hz) < m:
            continue
        d = classical_distance(Hx, dist)
        if d < dist:
            continue
        d = classical_distance(Hz, dist)
        if d < dist:
            continue
        break
    return Hx, Hz
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
def skip_rank(Hx, R, skip):
    A = Hx.copy()
    r = rank(A)

    for a in R:
        if (a * skip).max():
            continue
        A1 = numpy.concatenate((A, a))
        if rank(A1) == r:
            #write("\n")
            continue
        r = r + 1
        A = A1

    return r
Ejemplo n.º 6
0
Archivo: glue.py Proyecto: punkdit/qupy
def test_ldpc():

    n = argv.get("n", 14)
    m = argv.get("m", n - 3)

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

    H1 = make_ldpc(m, n, p, weight, dist)
    #print(fstr(H1))

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

    H2 = make_ldpc(m, n, p, weight, dist)
    #print(fstr(H2))

    k = argv.get("k", 3)
    pairs = [(i, i) for i in range(k)]
    K = glue_pairs(H1, H2, pairs)
    #print(fstr(K))
    assert rank(K) == len(K)

    print(ldpc_str(H1), "+", ldpc_str(H2), "=", ldpc_str(K))

    if argv.show:
        print(shortstr(K))
Ejemplo n.º 7
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))
Ejemplo n.º 8
0
def rand_codes_slow(m, n, trials=10000):
    count = 0
    while count < trials:
        H = rand2(m, n)
        if rank(H) == m:
            yield H
            count += 1
Ejemplo n.º 9
0
def span(Hz):
    assert rank(Hz) == len(Hz)
    m, n = Hz.shape
    print("enum2: %d " % (2**m))
    for v in numpy.ndindex((2, ) * m):
        u = dot2(v, Hz)
        yield u
Ejemplo n.º 10
0
Archivo: glue.py Proyecto: punkdit/qupy
def make_morthogonal(m, n, genus):
    while 1:
        G = rand2(m, n)
        if strong_morthogonal(G, genus) and rank(G) == m and numpy.min(
                G.sum(0)):
            break
    return G
Ejemplo n.º 11
0
    def get_logops(idxs_C, idxs_Ct, idxs_D, idxs_Dt):

        # Lx --------------------------------------------------------------

        Ic1 = identity2(c1)[idxs_C, :]
        Lx_h = kron(Ic1,
                    CokerD), zeros2(len(idxs_C) * CokerD.shape[0], c0 * d1)
        Lx_h = numpy.concatenate(Lx_h, axis=1)
        assert dot2(Lx_h, Hz.transpose()).sum() == 0

        Id1 = identity2(d1)[idxs_D, :]
        Lx_v = zeros2(CokerC.shape[0] * len(idxs_D),
                      c1 * d0), kron(CokerC, Id1)
        Lx_v = numpy.concatenate(Lx_v, axis=1)
        Lxi = numpy.concatenate((Lx_h, Lx_v), axis=0)

        # Lz --------------------------------------------------------------

        KerCt = KerC.transpose()
        Id0 = identity2(d0)[:, idxs_Dt]
        Lzt_h = kron(KerCt, Id0), zeros2(c0 * d1,
                                         KerCt.shape[1] * len(idxs_Dt))
        Lzt_h = numpy.concatenate(Lzt_h, axis=0)
        assert dot2(Hx, Lzt_h).sum() == 0

        KerDt = KerD.transpose()
        assert KerDt.shape[0] == d1
        Ic0 = identity2(c0)[:, idxs_Ct]
        Lzt_v = zeros2(c1 * d0,
                       len(idxs_Ct) * KerDt.shape[1]), kron(Ic0, KerDt)
        Lzt_v = numpy.concatenate(Lzt_v, axis=0)
        assert dot2(Hx, Lzt_v).sum() == 0

        Lzti = numpy.concatenate((Lzt_h, Lzt_v), axis=1)
        Lzi = Lzti.transpose()

        # checking ---------------------------------------------------------

        assert dot2(Hx, Lzti).sum() == 0

        assert rank(Lxi) == len(Lxi)  # full rank
        assert rank(Lzi) == len(Lzi)  # full rank

        assert eq_span(numpy.concatenate((Lxi, Hx)), LxiHx)
        assert eq_span(numpy.concatenate((Lzi, Hz)), LziHz)

        return Lxi, Lzi
Ejemplo n.º 12
0
Archivo: glue.py Proyecto: punkdit/qupy
def rand_full_rank(m, n=None):
    if n is None:
        n = m
    assert n >= m
    while 1:
        f = rand2(m, n)
        if rank(f) == m:
            break
    return f
Ejemplo n.º 13
0
def random_code(n, k, kt, distance=1):
    "code length n, dimension k, transpose dimension kt"
    d = 0
    while d < distance:
        H = rand2(n - k, n)
        if rank(H) < n - k:
            continue
        d = classical_distance(H, distance)

    K = H
    dt = 0
    while dt < distance:
        R = rand2(kt, n - k)
        J = dot2(R, H)
        K = numpy.concatenate((H, J))
        if rank(K) < n - k:
            continue
        dt = classical_distance(K.transpose())

    return K
Ejemplo n.º 14
0
def get_codes(m, n):
    while 1:
        H = rand2(m, n)
        #H[0:2, :] = 0
        H[:, 0] = 0
        H[0, 0] = 1
        #H[0:2, 0:3] = A
        #print(shortstr(H))
        #print()
        if rank(H) < m:
            continue
        yield H
Ejemplo n.º 15
0
def independent_logops(L, H):
    m = len(H)
    LH = numpy.concatenate((L, H), axis=0)
    keep, remove = dependent_rows(LH)
    LH = LH[keep]

    assert rank(LH) == len(LH)
    assert len(LH) >= m
    assert eq2(LH[-len(H):], H)
    L = LH[:-m]

    return L
Ejemplo n.º 16
0
def random_code(n, k, kt, distance=1):
    "return parity check for code of length n, dimension k, transpose dimension kt"
    d = 0
    while d<distance:
        H = rand2(n-k, n)
        if rank(H) < n-k:
            continue
        d = classical_distance(H, distance)

    K = H
    dt = 0
    while dt<distance:
        R = rand2(kt, n-k)
        J = dot2(R, H)
        K = numpy.concatenate((H, J))
        if rank(K) < n-k:
            continue
        dt = classical_distance(K.transpose())

    m = len(K)
    assert k - n + m - kt == 0 

    return K
Ejemplo n.º 17
0
def independent_logops(L, H, verbose=False):
    m = len(H)
    LH = numpy.concatenate((L, H), axis=0)
    keep, remove = dependent_rows(LH)
    if verbose:
        print(keep, remove)
    LH = LH[keep]
    
    assert rank(LH) == len(LH)
    assert len(LH) >= m
    assert eq2(LH[-len(H):], H), "H not linearly independent ?"
    L = LH[:-m]

    return L
Ejemplo n.º 18
0
    def mk_disjoint_logops(L, H):
        m = len(H)
        #print("L:", len(L))

        L0 = L  # save this
        LH = numpy.concatenate((L, H), axis=0)

        #LH = remove_dependent(LH)
        keep, remove = dependent_rows(LH)
        #print("dependent_rows:", len(keep), len(remove))

        LH = LH[keep]

        assert rank(LH) == len(LH)
        assert len(LH) >= m
        assert eq2(LH[-len(H):], H)
        L = LH[:-m]
        #print("L:", len(L))

        # find disjoint set of L ops
        keep = set([idx for idx in keep if idx < len(L0)])
        assert len(keep) == len(L)

        idxs = list(range(len(L0)))
        idxs.sort(key=lambda idx: -int(idx in keep))
        assert idxs[0] in keep
        L1 = L0[idxs]
        assert L1.shape == L0.shape

        LH = numpy.concatenate((L1, H), axis=0)
        LH = remove_dependent(LH)
        L1 = LH[:-m]
        assert len(L) == len(L1), (L.shape, L1.shape)

        #print(shortstr(L))
        #print("--")
        #print(shortstr(L1))

        #print("--")
        A = numpy.dot(L, L1.transpose())
        #assert A.sum() == 0, "found overlap"
        if A.sum():
            print("*" * 79)
            print("WARNING: A.sum() =", A.sum())
            print("failed to find disjoint logops")
            print("*" * 79)
            return L, None

        return L, L1
Ejemplo n.º 19
0
def find_reduced_guage(Gx, Hx):

    #    print "find_reduced_guage"
    #    print shortstr(Hx)

    mg, n = Gx.shape
    mx, _ = Hx.shape

    m = mx
    A = Hx
    ra = rank(Hx)
    assert ra == mx
    for i in range(mg):
        assert A.shape == (m, n)
        B = zeros2(m + 1, n)
        B[:m] = A
        B[m] = Gx[i]
        r = rank(B)  # XX work with a row reduced A
        assert m + 1 >= r >= m, (m, r)
        if r == m + 1:
            m += 1
            A = B

    return A[mx:]
Ejemplo n.º 20
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()
Ejemplo n.º 21
0
def has_property(G, trials=1000):
    k, n = G.shape

    for trial in range(trials):
        pivots = []
        remain = list(range(n))
        shuffle(remain)
        G1 = G
        for row in range(k):
            for col in list(remain):
                if G1[row, col] == 0:
                    continue
                G1 = echelon1(G1, row, col)
                pivots.append(col)
                remain.remove(col)
                break
        if len(pivots) < k:
            continue
        J = G1[:, remain]
        if rank(J) == k:
            break
    else:
        return False
    return True
Ejemplo n.º 22
0
def process(G, H):

    m, n = G.shape
    row = 0
    while row < m:

        col = 0
        while G[row, col] == 0:
            col += 1
        assert col >= row
        swap_col(G, row, col)
        swap_col(H, row, col)
        echelon(G, row, row)

        row += 1

    col = row
    row = 0
    m, n = H.shape
    while row < m:
        j = col
        while H[row, j] == 0:
            j += 1
        swap_col(G, col, j)
        swap_col(H, col, j)
        echelon(H, row, col)

        row += 1
        col += 1

    k = n-m

    print("G =")
    print(shortstr(G))
    print("H =")
    print(shortstr(H))
    print()

    A = G[:, k:]
    B = H[:, :k]
    assert eq2(A.transpose(), B)

    if 0:
        for size in range(2, k):
            result = search(G, H, size=size, verbose=True)
            print("search(size=%d): %s"%(size, result))

    wd = weight_dist(H)
    print("H:", wd, sum(wd))
    wd = weight_dist(G)
    print("G:", wd, sum(wd))

    r = rank(A)
    print("rank deficit:", k-r)

    if r == k:

        idxs = list(range(k))
        jdxs = list(range(k, 2*k))

        C = cokernel(B)[0]
        C = row_reduce(C)
        rows, cols = C.shape
        assert rows == n-2*k
        assert cols == n-k

        jdxs = list(range(m))
        pivots = []
        for i in range(rows):
            for j in range(i, cols):
                if C[i, j] != 0:
                    pivots.append(j)
                    jdxs.remove(j)
                    break
        print("C:", pivots)
        print(shortstr(C))
        assert len(jdxs) == k

        jdxs = [k+i for i in jdxs]
        assert len( in_support(G, idxs) ) == 0
        assert len( in_support(G, jdxs) ) == 0
        assert len( in_support(H, idxs) ) == 0
        for row in in_support(H, jdxs):
            print("in_support:", row)
        assert len( in_support(H, jdxs) ) == 0
        print("OK")
Ejemplo n.º 23
0
def test_code(Hxi, Hzi, Hx, Lx, Lz, Lx0, Lx1, LxiHx, **kw):
    code = CSSCode(Hx=Hxi, Hz=Hzi)
    print(code)

    assert rank(intersect(Lx, code.Lx)) == code.k
    assert rank(intersect(Lz, code.Lz)) == code.k

    verbose = argv.verbose
    decoder = get_decoder(argv, argv.decode, code)

    if decoder is None:
        return

    p = argv.get("p", 0.01)
    N = argv.get("N", 0)

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

    logops = []

    for i in range(N):
        err_op = ra.binomial(1, p, (code.n, ))
        err_op = err_op.astype(numpy.int32)
        op = decoder.decode(p, err_op, verbose=verbose, argv=argv)

        c = 'F'
        success = False
        if op is not None:
            op = (op + err_op) % 2
            # Should be a codeword of Hz (kernel of Hz)
            assert dot2(code.Hz, op).sum() == 0
            write("%d:" % op.sum())

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

            if success and op.sum():
                nonuniq += 1

            c = '.' if success else 'x'

            if op.sum() and not success:
                distance = min(distance, op.sum())
                write("L")
                logops.append(op.copy())

        else:
            failcount += 1
        write(c + ' ')
        count += success

    if N:
        print()
        print(argv)
        print("error rate = %.8f" % (1. - 1. * count / (i + 1)))
        print("fail rate = %.8f" % (1. * failcount / (i + 1)))
        print("nonuniq = %d" % nonuniq)
        print("distance <= %d" % distance)

    mx0, mx1 = len(Lx0), len(Lx1)
    LxHx = numpy.concatenate((Lx0, Lx1, Hx))
    for op in logops:
        print(op.sum())
        #print(shortstr(op))
        #print(op.shape)
        #print(op)
        K = solve(LxHx.transpose(), op)
        K.shape = (1, len(K))
        print(shortstrx(K[:, :mx0], K[:, mx0:mx0 + mx1], K[:, mx0 + mx1:]))
Ejemplo n.º 24
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()
Ejemplo n.º 25
0
Archivo: glue.py Proyecto: punkdit/qupy
def ldpc_str(H):
    m, n = H.shape
    assert rank(H) == m
    k = n - m
    d = classical_distance(H)
    return "[%d, %d, %d]" % (n, k, d)
Ejemplo n.º 26
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()
Ejemplo n.º 27
0
    print(shortstr(Hz))
    print("Hx:")
    print(shortstr(Hx))

else:

    stem = argv.get("stem", "55_32_5")
    #stem = "55_360_8"
    #stem = "77_78_5"
    
    Hx = load(stem + "_Hx.npz")
    #Hx = linear_independent(Hx)
    print(Hx.shape)
    print(shortstr(Hx))
    #print(Hx.sum(0), Hx.sum(1))
    print(rank(Hx))
    
    Hz = load(stem + "_Hz.npz")
    #Hz = linear_independent(Hz)
    print(Hz.shape)
    #print(shortstr(Hz))

mx, n = Hx.shape
mz, _ = Hz.shape
print(mx, mz, n)

from qupy.condmat.isomorph import Tanner, search

lhs = Tanner.build2(Hx, Hz)
if argv.duality:
    print("searching for duality")
Ejemplo n.º 28
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")
Ejemplo n.º 29
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)
Ejemplo n.º 30
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))