Esempio n. 1
0
 def get_adj(left, right):
     A = zeros2((len(left), len(right)))
     for i, l in enumerate(left):
         for j, r in enumerate(right):
             lr = l.intersect(r)
             A[i, j] = len(lr)
     return A
Esempio n. 2
0
 def rel(self, a, b):
     incidence = self.incidence
     A = zeros2(len(a), len(b))
     for i, aa in enumerate(a):
         for j, bb in enumerate(b):
             A[i, j] = (aa, bb) in incidence
     return A
Esempio n. 3
0
def syparse(decl):
    for c in '0123456789':
        decl = decl.replace(c, ' ')
    decl = decl.strip().split()
    n = len(decl[0])
    m = len(decl)
    H = zeros2(m, 2 * n)
    for i, row in enumerate(decl):
        for j, c in enumerate(row):
            if c == 'X' or c == 'Y':
                H[i, j] = 1
            if c == 'Z' or c == 'Y':
                H[i, n + j] = 1
    return H
Esempio n. 4
0
def symplectic(n):
    F = zeros2(2 * n, 2 * n)
    for i in range(n):
        F[i, n + i] = 1
        F[n + i, i] = 1
    return F
Esempio n. 5
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
Esempio n. 6
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) 
Esempio n. 7
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) 
Esempio n. 8
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)
Esempio n. 9
0
def build_toric(l=3, allgen=True):
    keys = []
    keymap = {}
    for i in range(l):
      for j in range(l):
        for k in (0, 1):
            m = len(keys)
            keys.append((i, j, k))
            for di in (-l, 0, l):
              for dj in (-l, 0, l):
                keymap[i+di, j+dj, k] = m

    if l>2:
        assert keys[keymap[2, 1, 0]] == (2, 1, 0)

    if allgen:
        m = l**2 # rows (constraints)
    else:
        m = l**2-1 # rows (constraints)
    n = len(keys) # cols (bits)
    assert n == 2*(l**2)

    Lx = zeros2(2, n)
    Lz = zeros2(2, n)
    Hx = zeros2(m, n)
    Tz = zeros2(m, n)
    Hz = zeros2(m, n)
    Tx = zeros2(m, n)

    for i in range(l):
        Lx[0, keymap[i, l-1, 1]] = 1
        Lx[1, keymap[l-1, i, 0]] = 1
        Lz[0, keymap[0, i, 1]] = 1
        Lz[1, keymap[i, 0, 0]] = 1

    row = 0
    xmap = {}
    for i in range(l):
      for j in range(l):
        if (i, j)==(0, 0) and not allgen:
            continue
        Hx[row, keymap[i, j, 0]] = 1
        Hx[row, keymap[i, j, 1]] = 1
        Hx[row, keymap[i-1, j, 0]] = 1
        Hx[row, keymap[i, j-1, 1]] = 1
        xmap[i, j] = row
        i1 = i
        while i1>0:
            Tz[row, keymap[i1-1, j, 0]] = 1
            i1 -= 1
        j1 = j
        while j1>0:
            Tz[row, keymap[i1, j1-1, 1]] = 1
            j1 -= 1
        row += 1

    row = 0
    zmap = {}
    for i in range(l):
      for j in range(l):
        if i==l-1 and j==l-1 and not allgen:
            continue
        Hz[row, keymap[i, j, 0]] = 1
        Hz[row, keymap[i, j, 1]] = 1
        Hz[row, keymap[i+1, j, 1]] = 1
        Hz[row, keymap[i, j+1, 0]] = 1
        zmap[i, j] = row
        i1 = i
        while i1<l-1:
            Tx[row, keymap[i1+1, j, 1]] = 1
            i1 += 1
        j1 = j
        while j1<l-1:
            Tx[row, keymap[i1, j1+1, 0]] = 1
            j1 += 1
        row += 1

    return Hx
Esempio n. 10
0
def hecke(self):

    bag0 = self.get_bag()
    bag1 = self.get_bag()

    points = [p for p in bag0 if p.desc == '0']
    lines = [p for p in bag0 if p.desc == '1']
    print(points)
    print(lines)
    flags = []
    for p in points:
        ls = [l for l in p.nbd if l != p]
        print(p, ls)
        for l in ls:
            flags.append((p, l))

    print("flags:", len(flags))

    #    for point in bag0:
    #        print point, repr(point.desc)

    #items = [(point.idx, line.idx) for point in points for line in lines]
    #items = [(a.idx, b.idx) for a in points for b in points]
    items = [(a, b) for a in flags for b in flags]

    # fixing two points gives the Klein four group, Z_2 x Z_2:
    #for f in isomorph.search(bag0, bag1):
    #    if f[0]==0 and f[1]==1:
    #        print f

    perms = []
    for f in isomorph.search(bag0, bag1):
        #print f
        g = dict((bag0[idx], bag0[f[idx]]) for idx in list(f.keys()))
        perm = {}
        for a, b in items:
            a1 = (g[a[0]], g[a[1]])
            b1 = (g[b[0]], g[b[1]])
            assert (a1, b1) in items
            perm[a, b] = a1, b1
        perm = Perm(perm, items)
        perms.append(perm)
        write('.')
    print()

    g = Group(perms, items)
    print("group:", len(g))

    orbits = g.orbits()
    #print orbits
    print("orbits:", len(orbits))

    eq = numpy.allclose
    dot = numpy.dot

    n = len(flags)
    basis = []
    gen = []
    I = identity2(n)
    for orbit in orbits:
        A = zeros2(n, n)
        #print orbits
        for a, b in orbit:
            A[flags.index(a), flags.index(b)] = 1
        print(shortstr(A))
        print(A.sum())
        #print

        basis.append(A)
        if A.sum() == 42:
            gen.append(A)

    assert len(gen) == 2
    L = gen[0]
    P = gen[1]
    q = 2

    assert eq(dot(L, L), L + q * I)
    assert eq(dot(P, P), P + q * I)
    assert eq(dot(L, dot(P, L)), dot(P, dot(L, P)))