Ejemplo n.º 1
0
def reed_muller(r, m, puncture=False):
    "Build Reed-Muller code"

    assert 0<=r<=m, "r=%s, m=%d"%(r, m)

    n = 2**m # length

    one = array2([1]*n)
    basis = [one]

    vs = [[] for i in range(m)]
    for i in range(2**m):
        for j in range(m):
            vs[j].append(i%2)
            i >>= 1
        assert i==0

    vs = [array2(v) for v in vs]

    for k in range(r):
        for items in choose(vs, k+1):
            v = one
            #print(items)
            for u in items:
                v = v*u
            basis.append(v)
        
    G = numpy.array(basis)

    code = Code(G, d=2**(m-r), desc="reed_muller(%d, %d)"%(r, m))

    if puncture:
        code = code.puncture(0)

    return code
Ejemplo n.º 2
0
def check_toric():
    global toric  # arff !
    import qupy.ldpc.solve
    import bruhat.solve
    qupy.ldpc.solve.int_scalar = bruhat.solve.int_scalar
    from bruhat.solve import shortstr, zeros2, dot2, array2, solve
    from numpy import alltrue, zeros, dot
    l = argv.get("l", 2)
    from qupy.ldpc.toric import Toric2D
    toric = Toric2D(l)
    Hx, Hz = toric.Hx, toric.Hz
    assert alltrue(dot2(Hx, Hz.transpose()) == 0)

    from qupy.condmat.isomorph import Tanner, search
    src = Tanner.build2(Hx, Hz)
    #tgt = Tanner.build2(Hx, Hz)
    tgt = Tanner.build2(Hz, Hx)  # weak duality

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

    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]
        print("perm:", perm)
        print("fixed:", fixed)

        g = Perm(perm, list(range(n)))
        assert g.order() == 2

        perms.append(perm)

    for hx in Hx:
        print(toric.strop(hx))
        print("--->")
        hx = array2([hx[i] for i in perm])
        print(toric.strop(hx))
        print("--->")
        hx = array2([hx[i] for i in perm])
        print(toric.strop(hx))
        print()

    check_dualities(Hz, Hx.transpose(), perms)
Ejemplo n.º 3
0
def find_orbits():
    n = argv.get("n", 3)
    m = argv.get("m", 2)
    rows = list(range(m))
    cols = list(range(n))
    orbits = {}
    found = set()
    for H in numpy.ndindex((2,)*n*m):
        H = array2(H)
        H.shape = (m, n)
        s = H.tostring()
        if s in orbits:
            continue
        if rank(H)<m:
            continue
        found.add(s)
        for rperm in all_perms(rows):
          for cperm in all_perms(cols):
            #print(rperm, cperm)
            J = H[rperm, :]
            J = J[:, cperm]
            #print(J)
            J = J.copy()
            s = J.tostring()
            #assert s not in orbits
            orbits[s] = H
    for s in found:
        H = numpy.fromstring(s, dtype=H.dtype)
        print(H)
    print(len(found))
Ejemplo n.º 4
0
def test_triorth():
    code = reed_muller(1, 5)
    code = code.puncture(0)
    code.dump()

    print(code.is_triorthogonal())
    A = array2(list(span(code.G)))
    print(is_morthogonal(A, 2))
    #print(shortstr(A))

    k = len(A)

    for i in range(k):
      for j in range(i+1, k):
        u = A[i]
        v = A[j]
        x = (u*v).sum() % 2
        if x == 0:
            continue
        #print(shortstr(u))
        #print(shortstr(v))
        #print()

    for a in range(k):
      for b in range(a+1, k):
       for c in range(b+1, k):
        u = A[a]
        v = A[b]
        w = A[c]
        x = (u*v*w).sum() % 2
Ejemplo n.º 5
0
def even_rows(G):
    Gx = []
    for u in G:
        #print(shortstr(u), u.sum()%2)
        parity = u.sum()%2
        if parity==0:
            Gx.append(u)
    Gx = array2(Gx)
    return Gx
Ejemplo n.º 6
0
def main_fail():

    print()
    print("==" * 70)

    H = """
        012345678901234
     0  YXZZ...........
     1  X..X.XX.X......
     2  ZZ..ZZ.......Z.
     3  .X..Y....XZ....
     4  .ZX....Y.Z.....
     5  .....ZZZ.Z....Z
     6  ..Z...ZZ....ZZ.
     7  ...Z....Y.XX...
     8  ..XX.......ZY..
     9  .........ZXX..Y
    10  .....X.....XXXX
    11  ....X.X.X.X..X.
    """
    H = syparse(H)
    print()
    print(shortstr(H))

    m = len(H)
    n = H.shape[1] // 2
    assert n == 15
    F = symplectic(n)

    C = dot2(H, dot2(F, H.transpose()))

    print(C.shape)

    for i in range(m):
        for j in range(i + 1, m):
            if C[i, j]:
                print("fail:", i, j)

    print(rank(H))
    H = linear_independent(H)
    print("H=", H.shape)
    print(shortstr(H))

    HF = dot2(H, F)
    K = array2(find_kernel(HF))
    print("K=", K.shape)
    print(shortstr(K))

    HK = numpy.concatenate((H, K))
    L = linear_independent(HK)
    print()
    print(shortstr(L))
Ejemplo n.º 7
0
def gen():
    r = argv.get("r", None) # degree
    m = argv.get("m", None)

    if r is not None and m is not None:
        code = reed_muller(r, m)
    
        #print(code)
        #print("d =", code.get_distance())
        #code.dump()
    
        #code = code.puncture(3)
    
        #print(code)
        code = code.puncture(0)
        print(code)
        for g in code.G:
            print(shortstr(g), g.sum())
        print()
        #code.dump()
        #print("d =", code.get_distance())
    
        return

    for m in range(2, 8):
      for r in range(0, m+1):
        code = reed_muller(r, m)
        print(code, end=" ")
        if code.is_selfdual():
            print("is_selfdual", end=" ")
        if code.is_morthogonal(2):
            print("is_biorthogonal", end=" ")
        if code.is_morthogonal(3):
            print("is_triorthogonal", end=" ")
        if dot2(code.H, code.H.transpose()).sum()==0:
            print("***", end=" ")
        p = code.puncture(0)
        if p.is_morthogonal(3):
            print("puncture.is_triorthogonal", end=" ")
        if p.is_selfdual():
            print("puncture.is_selfdual", end=" ")
        if dot2(p.H, p.H.transpose()).sum()==0:
            print("***", end=" ")
        print()

        if p.is_triorthogonal() and p.k < 20:
            G = p.G
            #print(shortstr(G))
            A = list(span(G))
            A = array2(A)
            print(is_morthogonal(A, 3))
Ejemplo n.º 8
0
    def __init__(self, G, H=None, d=None, desc="", check=True):
        assert len(G.shape)==2
        self.G = G.copy()
        self.k, self.n = G.shape
        self.d = d
        self.desc = desc

        if H is None:
            H = list(find_kernel(G))
            H = array2(H)
        if H.shape == (0,):
            H.shape = (0, self.n)
        self.H = H.copy()

        if check:
            self.check()
Ejemplo n.º 9
0
def test_rm():
    params = [(r, m) for m in range(2, 8) for r in range(1, m)]
    r = argv.get("r", None) # degree
    m = argv.get("m", None)
    if r is not None and m is not None:
        params = [(r, m)]
    
    for (r, m) in params:
        #code = reed_muller(r, m)
#      for code in [ reed_muller(r, m), reed_muller(r, m).puncture(0) ]:
      for code in [reed_muller(r, m)]:
        if argv.puncture:
            print(code, end=" ", flush=True)
            code = code.puncture(0)
            code = code.get_even()
            if argv.puncture==2:
                code = code.puncture(0)
                code = code.get_even()
            G = code.G
            k, n = G.shape
            #code = Code(G)
            #d = code.get_distance()
            d = "."
            print("puncture [%d, %d, %s]" % (n, k, d), end=" ", flush=True)
        else:
            G = code.G
            print(code, end=" ", flush=True)
        i = 1
        while i<8:
            if (is_morthogonal(G, i)):
                print("(%d)"%i, end="", flush=True)
                i += 1
            else:
                break
            if i > code.k:
                print("*", end="")
                break
        print()
        if argv.show:
            print(G.shape)
            print(shortstr(G))
            print(dot2(G, G.transpose()).sum())
        if len(G) >= 14:
            continue
        A = array2(list(span(G)))
        for i in [1, 2, 3]:
            assert strong_morthogonal(G, i) == strong_morthogonal(A, i)
Ejemplo n.º 10
0
def main_torus():

    n = 8

    #   ZZZZZZZZ|XXXXXXXX
    #   12345678|12345678
    H = parse("""
    111..1..|........
    1..1....|1.1.....
    ........|11.11...
    .1..1...|.1...1..
    ..1...1.|...1..1.
    ...11.11|........
    .....1.1|....1..1
    ........|..1..111
    """.replace("|", ""))

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

    F = symplectic(n)
    C = dot2(H, dot2(F, H.transpose()))

    for i in range(n):
        for j in range(i + 1, n):
            if C[i, j]:
                print("fail:", i + 1, j + 1)

    print(rank(H))
    H = linear_independent(H)
    print("H=")
    print(shortstr(H))

    HF = dot2(H, F)
    K = array2(find_kernel(HF))
    print("K=")
    print(shortstr(K))

    HK = numpy.concatenate((H, K))
    L = linear_independent(HK)
    print()
    print(shortstr(L))
Ejemplo n.º 11
0
def test():
    for idx, H in enumerate(items):
        H = array2(H)
        #print(H.shape)

        print(names[idx])
        print(shortstr(H))
        assert (dot2(H, H.transpose()).sum()) == 0  # orthogonal code
        G = H
        for genus in range(1, 4):
            print(strong_morthogonal(G, genus), end=" ")
        print()

        keys = [0, 4, 8, 12, 16, 20, 24]
        counts = {0: 0, 4: 0, 8: 0, 12: 0, 16: 0, 20: 0, 24: 0}

        for v in span(G):
            counts[v.sum()] += 1
        print([counts[k] for k in keys])
        print()
Ejemplo n.º 12
0
def test_tri_rm():
    r = argv.get("r", 1) # degree
    m = argv.get("m", 4)
    puncture = argv.puncture
    code = reed_muller(r, m, puncture)
    G = code.G
    rows = [row for row in G if row.sum()%2==0]
    G = array2(rows)
    k = len(rows)
    print(G.shape)
    for i in range(1, 10):
        # statistical test for m-orthogonality
        for trials in range(10000):
            vecs = [rows[randint(0, k-1)] for j in range(i)]
            v = vecs[0].copy()
            for w in vecs[1:]:
                v = v*w
            if v.sum()%2 != 0:
                break
        else:
            print("(%d)"%i, end=" ", flush=True)
            continue
        break
    print()
Ejemplo n.º 13
0
def get_all():
    directory = path.dirname(__file__)
    name = path.join(directory, "matrixform.txt")
    f = open(name)

    line = f.readline()

    #items = []
    count = 0
    dim = None
    idx = None
    for line in f:
        line = line.strip()
        #print(line)

        if line in "[ ], ] ];".split():
            continue
        if line.startswith("<"):
            rows = []
            flds = line[1:].split(", ")
            dim = int(flds[0])
            idx = int(flds[1])
            count += 1
            continue

        assert line.startswith("["), repr(line)
        row = line[1:49]
        assert len(row) == 48
        rows.append([ord(c) - 48 for c in row])
        if ">" in line:
            G = array2(rows)
            #items.append(G)
            yield (dim, idx, G)
            rows = None
            dim = None
            idx = None
Ejemplo n.º 14
0
def check_dualities(Hz, Hxt, dualities):
    from bruhat.solve import shortstr, zeros2, dot2, array2, solve, span
    from numpy import alltrue, zeros, dot

    import qupy.ldpc.solve
    import bruhat.solve
    qupy.ldpc.solve.int_scalar = bruhat.solve.int_scalar
    from qupy.ldpc.css import CSSCode
    Hz = Hz % 2
    Hx = Hxt.transpose() % 2
    code = CSSCode(Hz=Hz, Hx=Hx)
    print(code)
    n = code.n

    Lx, Lz = code.Lx, code.Lz

    # check we really do have weak dualities here:
    for perm in dualities:
        Hz1 = Hz[:, perm]
        Hxt1 = Hxt[perm, :]
        assert solve(Hxt, Hz1.transpose()) is not None
        assert solve(Hz1.transpose(), Hxt) is not None

        Lz1 = Lz[:, perm]
        Lx1 = Lx[:, perm]
        find_xz = solve(concatenate((Lx, Hx)).transpose(),
                        Lz1.transpose()) is not None
        find_zx = solve(concatenate((Lz1, Hz1)).transpose(),
                        Lx.transpose()) is not None
        #print(find_xz, find_zx)
        assert find_xz
        assert find_zx

        # the fixed points live simultaneously in the homology & the cohomology
        fixed = [i for i in range(n) if perm[i] == i]
        if len(fixed) == 0:
            continue
        v = array2([0] * n)
        v[fixed] = 1
        v.shape = (n, 1)
        find_xz = solve(concatenate((Lx, Hx)).transpose(), v) is not None
        find_zx = solve(concatenate((Lz, Hz)).transpose(), v) is not None
        #print(find_xz, find_zx)
        assert find_xz
        assert find_zx

    from qupy.ldpc.asymplectic import Stim as Clifford
    s_gates = []
    h_gates = []
    s_names = []
    for idx, swap in enumerate(dualities):

        fixed = [i for i in range(n) if swap[i] == i]
        print(idx, fixed)
        for signs in cross([(-1, 1)] *
                           len(fixed)):  # <------- does not scale !!! XXX
            v = [0] * n
            for i, sign in enumerate(signs):
                v[fixed[i]] = sign
            ux = numpy.dot(Hx, v)
            uz = numpy.dot(Hz, v)
            if numpy.alltrue(ux == 0) and numpy.alltrue(uz == 0):
                #print("*", end=" ")
                break
        #else:
        #    assert 0
        #print(v)
        #print()

        # transversal S/CZ
        g = Clifford.identity(n)
        name = []
        for i in range(n):
            j = swap[i]
            if j < i:
                continue
            if j == i:
                assert v[i] in [1, -1]
                if v[i] == 1:
                    op = Clifford.s_gate(n, i)
                    name.append("S_%d" % (i, ))
                else:
                    op = Clifford.s_gate(n, i).inverse()
                    name.append("Si_%d" % (i, ))
            else:
                op = Clifford.cz_gate(n, i, j)
                name.append("CZ_%d_%d" % (i, j))
            g = op * g
        name = "*".join(reversed(name))
        s_names.append(name)
        #print(g)
        #print()
        #assert g.is_transversal(code)

        s_gates.append(g)

        h = Clifford.identity(n)
        for i in range(n):
            h = h * Clifford.h_gate(n, i)

        for i in range(n):
            j = swap[i]
            if j <= i:
                continue
            h = h * Clifford.swap_gate(n, i, j)
        #print(g)
        #print()
        #assert h.is_transversal(code)
        h_gates.append(h)

    if 0:
        print()
        print("CZ:")
        CZ = Clifford.cz_gate(2, 0, 1)
        op = (1., [0, 0], [1, 1])
        for i in range(4):
            print(op)
            op = CZ(*op)
        return

    for idx, sop in enumerate(s_gates):
        print("idx =", idx)
        #for hx in Hx:
        perm = dualities[idx]
        #for hx in span(Hx):
        for hx in Hx:
            #print("hx =", hx)
            #print(s_names[idx])
            phase, zop, xop = sop(1., None, hx)
            assert numpy.alltrue(xop == hx)  # fixes x component
            print(phase, zop, xop, dot2(zop, xop))
            for (i, j) in enumerate(perm):
                if xop[i] and xop[j] and i < j:
                    print("pair", (i, j))
            if toric is None:
                continue
            print("xop =")
            print(toric.strop(xop))
            print("zop =")
            print(toric.strop(zop))
            print()
Ejemplo n.º 15
0
 def get_even(self):
     G = self.G
     rows = [row for row in G if row.sum()%2==0]
     G = array2(rows)
     return Code(G)
Ejemplo n.º 16
0
def is_422_cat_selfdual(Hz, Hx, perm):
    "concatenate with the [[4,2,2]] code and see if we get a self-dual code"
    from numpy import alltrue, zeros, dot
    import qupy.ldpc.solve
    import bruhat.solve
    qupy.ldpc.solve.int_scalar = bruhat.solve.int_scalar
    from bruhat.solve import shortstrx, zeros2, dot2, array2, solve
    from qupy.ldpc.css import CSSCode
    Cout = CSSCode(Hz=Hz, Hx=Hx)
    #print(Cout)
    #Cin = CSSCode(Hz=array2([[1,1,1,1]]), Hx=array2([[1,1,1,1]]))
    #print(Cin)

    pairs = []
    singles = []
    for i in range(Cout.n):
        j = perm[i]
        if j < i:
            continue
        if i == j:
            singles.append(i)
        else:
            pairs.append((i, j))
    #print(singles, pairs)
    M = len(singles) + 4 * len(pairs)

    # encoding matrices
    enc_z = zeros2(M, Cout.n)
    enc_x = zeros2(M, Cout.n)

    row = 0
    for col in singles:
        enc_z[row, col] = 1
        enc_x[row, col] = 1
        row += 1
    H = []
    for (i, j) in pairs:
        enc_z[row, i] = 1  # 1010
        enc_z[row + 2, i] = 1
        enc_z[row, j] = 1  # 1100
        enc_z[row + 1, j] = 1

        enc_x[row, i] = 1  # 1100
        enc_x[row + 1, i] = 1
        enc_x[row, j] = 1  # 1010
        enc_x[row + 2, j] = 1
        h = array2([0] * M)
        h[row:row + 4] = 1
        H.append(h)

        row += 4
    assert row == M

    #print(shortstrx(enc_z, enc_x))

    Hz = dot2(enc_z, Cout.Hz.transpose()).transpose()
    Hx = dot2(enc_x, Cout.Hx.transpose()).transpose()
    assert alltrue(dot2(Hz, Hx.transpose()) == 0)

    Hz = numpy.concatenate((Hz, H))
    Hx = numpy.concatenate((Hx, H))
    assert alltrue(dot2(Hz, Hx.transpose()) == 0)

    C = CSSCode(Hz=Hz, Hx=Hx)
    assert C.k == Cout.k
    #print(C)

    lhs = (solve(Hz.transpose(), Hx.transpose()) is not None)
    rhs = (solve(Hx.transpose(), Hz.transpose()) is not None)
    return lhs and rhs
Ejemplo n.º 17
0
def search():
    # Bravyi, Haah, 1209.2426v1 sec IX.
    # https://arxiv.org/pdf/1209.2426.pdf

    verbose = argv.get("verbose")
    m = argv.get("m", 6) # _number of rows
    k = argv.get("k", None) # _number of odd-weight rows

    # these are the variables N_x
    xs = list(cross([(0, 1)]*m))

    maxweight = argv.maxweight
    minweight = argv.get("minweight", 1)

    xs = [x for x in xs if minweight <= sum(x)]
    if maxweight:
        xs = [x for x in xs if sum(x) <= maxweight]

    N = len(xs)

    lhs = []
    rhs = []

    # bi-orthogonality
    for a in range(m):
      for b in range(a+1, m):
        v = zeros2(N)
        for i, x in enumerate(xs):
            if x[a] == x[b] == 1:
                v[i] = 1
        if v.sum():
            lhs.append(v)
            rhs.append(0)

    # tri-orthogonality
    for a in range(m):
      for b in range(a+1, m):
       for c in range(b+1, m):
        v = zeros2(N)
        for i, x in enumerate(xs):
            if x[a] == x[b] == x[c] == 1:
                v[i] = 1
        if v.sum():
            lhs.append(v)
            rhs.append(0)

#    # dissallow columns with weight <= 1
#    for i, x in enumerate(xs):
#        if sum(x)<=1:
#            v = zeros2(N)
#            v[i] = 1
#            lhs.append(v)
#            rhs.append(0)

    if k is not None:
      # constrain to k _number of odd-weight rows
      assert 0<=k<m
      for a in range(m):
        v = zeros2(N)
        for i, x in enumerate(xs):
          if x[a] == 1:
            v[i] = 1
        lhs.append(v)
        if a<k:
            rhs.append(1)
        else:
            rhs.append(0)

    A = array2(lhs)
    rhs = array2(rhs)
    #print(shortstr(A))

    B = pseudo_inverse(A)
    soln = dot2(B, rhs)
    if not eq2(dot2(A, soln), rhs):
        print("no solution")
        return
    if verbose:
        print("soln:")
        print(shortstr(soln))

    soln.shape = (N, 1)
    rhs.shape = A.shape[0], 1

    K = array2(list(find_kernel(A)))
    #print(K)
    #print( dot2(A, K.transpose()))
    #sols = []
    #for v in span(K):
    best = None
    density = 1.0
    size = 99*N
    trials = argv.get("trials", 1024)
    count = 0
    for trial in range(trials):
        u = rand2(len(K), 1)
        v = dot2(K.transpose(), u)
        #print(v)
        v = (v+soln)%2
        assert eq2(dot2(A, v), rhs)

        if v.sum() > size:
            continue
        size = v.sum()

        Gt = []
        for i, x in enumerate(xs):
            if v[i]:
                Gt.append(x)
        if not Gt:
            continue
        Gt = array2(Gt)
        G = Gt.transpose()
        assert is_morthogonal(G, 3)
        if G.shape[1]<m:
            continue

        if 0 in G.sum(1):
            continue

        if argv.strong_morthogonal and not strong_morthogonal(G, 3):
            continue

        #print(shortstr(G))
#        for g in G:
#            print(shortstr(g), g.sum())
#        print()

        _density = float(G.sum()) / (G.shape[0]*G.shape[1])
        #if best is None or _density < density:
        if best is None or G.shape[1] <= size:
            best = G
            size = G.shape[1]
            density = _density

        if 0:
            #sols.append(G)
            Gx = even_rows(G)
            assert is_morthogonal(Gx, 3)
            if len(Gx)==0:
                continue
            GGx = array2(list(span(Gx)))
            assert is_morthogonal(GGx, 3)

        count += 1

    print("found %d solutions" % count)
    if best is None:
        return

    G = best
    #print(shortstr(G))
    for g in G:
        print(shortstr(g), g.sum())
    print()
    print("density:", density)
    print("shape:", G.shape)

    G = linear_independent(G)
    A = list(span(G))
    print(strong_morthogonal(A, 1))
    print(strong_morthogonal(A, 2))
    print(strong_morthogonal(A, 3))
    
    #print(shortstr(dot2(G, G.transpose())))

    if 0:
        B = pseudo_inverse(A)
        v = dot2(B, rhs)
        print("B:")
        print(shortstr(B))
        print("v:")
        print(shortstr(v))
        assert eq2(dot2(B, v), rhs) 
Ejemplo n.º 18
0
def search_extend():
    # Extend the checks of a random code to make it triorthogonal.
    # Based on the search function above.

    verbose = argv.get("verbose")

    m = argv.get("m", 6)
    n = argv.get("n", m+2)
    k = argv.get("k") # odd _numbered rows ( logical operators)
    code = argv.get("code", "rand")

    if code == "rand":
        while 1:
            G0 = rand2(m, n)
            counts = G0.sum(0)
            if min(counts)==2 and rank(G0) == m:
                cols = set()
                for i in range(n):
                    cols.add(tuple(G0[:, i]))
                if len(cols) == n: # no repeated cols
                    break

    elif code == "toric":
        G0 = parse("""
        11.11...
        .111..1.
        1...11.1
        """) # l=2 toric code X logops + X stabs 

        l = argv.get("l", 3)
        G0 = build_toric(l)

        m, n = G0.shape
    else:
        return

    code = Code(G0, check=False)
    print(shortstr(G0))
    print("is_triorthogonal:", code.is_triorthogonal())

    # these are the variables N_x
    xs = list(cross([(0, 1)]*m))
    N = len(xs)

    lookup = {}
    for i, x in enumerate(xs):
        lookup[x] = i

    lhs = []
    rhs = []

    taken = set()
    for i in range(n):
        x = G0[:, i]
        idx = lookup[tuple(x)]
        assert idx not in taken
        taken.add(idx)

    if verbose:
        for idx in range(N):
            print(idx, xs[idx], "*" if idx in taken else "")

    for idx in taken:
        v = zeros2(N)
        v[idx] = 1
        lhs.append(v)
        rhs.append(1)

    # bi-orthogonality
    for a in range(m):
      for b in range(a+1, m):
        v = zeros2(N)
        for i, x in enumerate(xs):
            if x[a] == x[b] == 1:
                v[i] += 1
        assert v.sum()
        lhs.append(v)
        rhs.append(0)

    # tri-orthogonality
    for a in range(m):
      for b in range(a+1, m):
       for c in range(b+1, m):
        v = zeros2(N)
        for i, x in enumerate(xs):
            if x[a] == x[b] == x[c] == 1:
                v[i] += 1
        assert v.sum()
        lhs.append(v)
        rhs.append(0)

    # dissallow columns with weight <= 1
    for i, x in enumerate(xs):
        if sum(x)<=1:
            v = zeros2(N)
            v[i] = 1
            lhs.append(v)
            rhs.append(0)

    if k is not None:
      # constrain to k _number of odd-weight rows
      assert 0<=k<m
      for a in range(m):
        v = zeros2(N)
        for i, x in enumerate(xs):
          if x[a] == 1:
            v[i] = 1
        lhs.append(v)
        if a<k:
            rhs.append(1)
        else:
            rhs.append(0)

    A = array2(lhs)
    rhs = array2(rhs)

    if verbose:
        print("lhs:")
        print(shortstr(A))
    
        print("rhs:")
        print(shortstr(rhs))

    B = pseudo_inverse(A)
    soln = dot2(B, rhs)
    if not eq2(dot2(A, soln), rhs):
        print("no solution")
        return
    if verbose:
        print("soln:")
        print(shortstr(soln))

    soln.shape = (N, 1)
    rhs.shape = A.shape[0], 1

    K = array2(list(find_kernel(A)))

    best = None
    density = 1.0
    size = 9999*n
    trials = argv.get("trials", 1024)
    count = 0
    for trial in range(trials):
        u = rand2(len(K), 1)
        v = dot2(K.transpose(), u)
        #print(v)
        assert dot2(A, v).sum()==0
        #if v.sum() != n:
        #    continue
        assert v[0]==0
        v = (v+soln)%2
        assert eq2(dot2(A, v), rhs)

        Gt = list(G0.transpose())
        for i, x in enumerate(xs):
            if v[i] and not i in taken:
                Gt.append(x)
        if not Gt:
            continue
        Gt = array2(Gt)
        G = Gt.transpose()
        if verbose:
            print("G0")
            print(shortstr(G0))
            print("solution:")
            print(shortstr(G))
        assert is_morthogonal(G, 3)
        if G.shape[1]<m:
            continue

        if 0 in G.sum(1):
            continue

        #print(shortstr(G))
#        for g in G:
#            print(shortstr(g), g.sum())
#        print()

        _density = float(G.sum()) / (G.shape[0]*G.shape[1])
        #if best is None or _density < density:
        if best is None or G.shape[1] < size:
            best = G
            density = _density
            size = G.shape[1]

        if 0:
            #sols.append(G)
            Gx = even_rows(G)
            assert is_morthogonal(Gx, 3)
            if len(Gx)==0:
                continue
            GGx = array2(list(span(Gx)))
            assert is_morthogonal(GGx, 3)

        count += 1

    print("found %d solutions" % count)

    G = best
    #print(shortstr(G))
    for g in G:
        print(shortstr(g), g.sum())
    print()
    print("density:", density)
Ejemplo n.º 19
0
def search_selfdual():

    verbose = argv.get("verbose")
    m = argv.get("m", 6) # _number of rows
    k = argv.get("k", None) # _number of odd-weight rows


    maxweight = argv.get("maxweight", m)
    minweight = argv.get("minweight", 1)

    # these are the variables N_x
    print("building xs...")

    if 0:
        xs = cross([(0, 1)]*m)
        xs = [x for x in xs if minweight <= sum(x) <= maxweight]
    
        prune = argv.get("prune", 0.5)
        xs = [x for x in xs if random() < prune]

    xs = []
    N = argv.get("N", m*100)
    colweight = argv.get("colweight", maxweight)
    assert colweight <= m
    for i in range(N):
        x = [0]*m
        total = 0
        while total < colweight:
            idx = randint(0, m-1)
            if x[idx] == 0:
                x[idx] = 1
                total += 1
        xs.append(x)

    N = len(xs)

    lhs = []
    rhs = []

    # bi-orthogonality
    for a in range(m):
      for b in range(a+1, m):
        v = zeros2(N)
        for i, x in enumerate(xs):
            if x[a] == x[b] == 1:
                v[i] = 1
        if v.sum():
            lhs.append(v)
            rhs.append(0)

    k = 0 # all rows must have even weight
    # constrain to k _number of odd-weight rows
    assert 0<=k<m
    for a in range(m):
      v = zeros2(N)
      for i, x in enumerate(xs):
        if x[a] == 1:
          v[i] = 1
      lhs.append(v)
      if a<k:
          rhs.append(1)
      else:
          rhs.append(0)

    logops = argv.logops

    A = array2(lhs)
    rhs = array2(rhs)
    #print(shortstr(A))

    print("solve...")
    B = pseudo_inverse(A)
    soln = dot2(B, rhs)
    if not eq2(dot2(A, soln), rhs):
        print("no solution")
        return

    if verbose:
        print("soln:")
        print(shortstr(soln))

    soln.shape = (N, 1)
    rhs.shape = A.shape[0], 1

    K = array2(list(find_kernel(A)))
    print("kernel:", K.shape)
    if len(K)==0:
        return
    #print(K)
    #print( dot2(A, K.transpose()))
    #sols = []
    #for v in span(K):
    best = None
    density = 1.0
    size = 99*N
    trials = argv.get("trials", 1024)
    count = 0
    print("trials...")
    for trial in range(trials):
        u = rand2(len(K), 1)
        v = dot2(K.transpose(), u)
        #print(v)
        v = (v+soln)%2
        assert eq2(dot2(A, v), rhs)

        if v.sum() >= size:
            continue

        if v.sum() < m:
            continue

        if v.sum():
            print(v.sum(), end=" ", flush=True)

        size = v.sum()

        if logops is not None and size != 2*m+logops:
            continue

        Gt = []
        for i, x in enumerate(xs):
            if v[i]:
                Gt.append(x)

        Gt = array2(Gt)
        G = Gt.transpose()
        if dot2(G, Gt).sum() != 0:
            # not self-dual
            print(shortstr(dot2(G, Gt)))
            assert 0
            return

        #if G.shape[1]<m:
        #    continue

        if 0 in G.sum(1):
            print(".", end="", flush=True)
            continue

        #print(shortstr(G))
#        for g in G:
#            print(shortstr(g), g.sum())
#        print()

        _density = float(G.sum()) / (G.shape[0]*G.shape[1])
        #if best is None or _density < density:
        if best is None or G.shape[1] <= size:
            best = G
            size = G.shape[1]
            density = _density

        if 0:
            #sols.append(G)
            Gx = even_rows(G)
            assert is_morthogonal(Gx, 3)
            if len(Gx)==0:
                continue
            GGx = array2(list(span(Gx)))
            assert is_morthogonal(GGx, 3)

        count += 1

    print("found %d solutions" % count)
    if best is None:
        return

    G = best
    #print(shortstr(G))
    f = open("selfdual.ldpc", "w")
    for spec in ["Hx =", "Hz ="]:
        print(spec, file=f)
        for g in G:
            print(shortstr(g), file=f)
    f.close()

    print()
    print("density:", density)
    print("shape:", G.shape)
    

    if 0:
        B = pseudo_inverse(A)
        v = dot2(B, rhs)
        print("B:")
        print(shortstr(B))
        print("v:")
        print(shortstr(v))
        assert eq2(dot2(B, v), rhs) 
Ejemplo n.º 20
0
def triortho():
    code = get_code()

    code.dump()
    print(code)

    Gx = []
    for u in code.G:
        print(shortstr(u), u.sum()%2)
        parity = u.sum()%2
        if parity==0:
            Gx.append(u)
    Gx = array2(Gx)

    print("is_triorthogonal:", code.is_triorthogonal())

    A = array2(list(span(Gx)))
    print("span(Gx) is_morthogonal(2):", is_morthogonal(A, 2))
    print("span(Gx) is_morthogonal(3):", is_morthogonal(A, 3))

    return

    G = code.G

#    A = array2(list(span(G)))
#    poly = {}
#    for v in A:
#        w = v.sum()
#        poly[w] = poly.get(w, 0) + 1
#    print(poly)

    k, n = G.shape

    if 0:
        from comm import Poly
        a = Poly({(1,0):1})
        b = Poly({(0,1):1})
        poly = Poly.zero(2)
        for v in span(G):
            w = v.sum()
            term = Poly({(n-w,0) : 1}) * Poly({(0,w) : 1})
            poly = poly + term
        print(poly)

    # print higher genus weight enumerator
    genus = argv.get("genus", 1)
    assert 1<=genus<=4
    N = 2**genus
    idxs = list(cross([(0,1)]*genus))

    cs = {} # _coefficients : map exponent to coeff
    for vs in cross([list(span(G)) for _ in range(genus)]):
        key = [0]*N
        for i in range(n):
            ii = tuple(v[i] for v in vs)
            idx = idxs.index(ii)
            key[idx] += 1
        key = tuple(key)
        cs[key] = cs.get(key, 0) + 1
    #print(cs)
    keys = list(cs.keys())
    keys.sort()
    print(idxs)
    for key in keys:
        print(key, cs[key])
Ejemplo n.º 21
0
def get(name):
    assert name in names, "%r not found in %s" % (name, names)
    idx = names.index(name)
    H = items[idx]
    H = array2(H)
    return H
Ejemplo n.º 22
0
def projective(n, dim=2):
    # Take n-dim F_2-vector space
    # points are subspaces of dimension 1
    # lines are subspaces of dimension 2
    # etc.

    def get_key(L):
        vs = [str(v) for v in span(L) if v.sum()]
        vs.sort()
        key = ''.join(vs)
        return key

    assert n > 1

    points = []
    for P in enum2(n):
        P = array2(P)
        if P.sum() == 0:
            continue
        points.append(P)
    #print "points:", len(points)

    lines = []
    lookup = {}
    for L in enum2(2 * n):
        L = array2(L)
        L.shape = (2, n)
        L = row_reduce(L)
        if len(L) != 2:
            continue
        key = get_key(L)
        if key in lookup:
            continue
        lines.append(L)
        lookup[key] = L
    #print "lines:", len(lines)

    spaces = []
    if n > 3 and dim > 2:
        m = 3
        lookup = {}
        for A in enum2(m * n):
            A.shape = (m, n)
            A = row_reduce(A)
            if len(A) != m:
                continue
            key = get_key(A)
            if key in lookup:
                continue
            spaces.append(A)
            lookup[key] = A
        #print "spaces:", len(spaces)

    incidence = []
    tpmap = {}
    for point in points:
        point = str(point)
        tpmap[point] = 0
        #print point

    for L in lines:
        line = str(tuple(tuple(row) for row in L))
        tpmap[line] = 1
        for P in span(L):
            if P.sum():
                incidence.append((str(P), line))

    for A in spaces:
        space = freeze(A)
        tpmap[space] = 2
        for P in span(A):
            if P.sum() == 0:
                continue
            incidence.append((str(P), space))
        for L in lines:
            B = solve(A.transpose(), L.transpose())
            if B is not None:
                line = str(tuple(tuple(row) for row in L))
                incidence.append((space, line))

    g = Geometry(incidence, tpmap)
    if dim == 2:
        assert g.get_diagram() == [(0, 1)]
    elif dim == 3:
        assert n > 3
        assert g.get_diagram() == [(0, 1), (1, 2)]
    return g