Example #1
0
def build_random(n):

    weight = argv.get("weight", 3)
    coweight = argv.get("coweight")

    p = argv.get("p", 0.3)
    m = argv.get("m", n)
    mx = argv.get("mx", m)
    mz = argv.get("mz", m)

    if coweight is not None:
        Gx = rand2(n, mx, weight=coweight).transpose()
        Gz = rand2(n, mz, weight=coweight).transpose()

    else:
        Gx = rand2(mx, n, p=p, weight=weight)
        Gz = rand2(mz, n, p=p, weight=weight)

    Hx = Hz = None

    Gx = Gx[[i for i in range(m) if Gx[i].sum()], :]
    Gz = Gz[[i for i in range(m) if Gz[i].sum()], :]

    li = argv.get("li", True)

    if li:
        Gx = linear_independent(Gx)
        Gz = linear_independent(Gz)

    return Gx, Gz, Hx, Hz
Example #2
0
def build_random_selfdual(n):

    weight = argv.get("weight", 3)
    m = argv.get("m", n)
    h = argv.get("h", 0)

    while 1:
        Gx = rand2(m, n, weight=weight)
        Gz = Gx.copy()

        Hx = Hz = None

        Gx = Gx[[i for i in range(m) if Gx[i].sum()], :]
        Gx = linear_independent(Gx)

        if len(Gx) < m:
            write("m")
            continue

        Gz = Gx.copy()

        Hx = find_stabilizers(Gz, Gx)
        Hz = find_stabilizers(Gx, Gz)

        if len(Hx) == h and len(Hz) == h:
            break

        write("H(%d,%d)" % (len(Hx), len(Hz)))

    print()
    return Gx, Gz, Hx, Hz
Example #3
0
 def puncture(self, i):
     assert 0 <= i < self.n
     G = self.G
     A = G[:, :i]
     B = G[:, i + 1:]
     G = numpy.concatenate((A, B), axis=1)
     G = linear_independent(G, check=True)
     return Code(G)
Example #4
0
 def get_code(self, idx=0, build=True, check=True):
     #print "get_code"
     Hs = self.Hs
     Hx = Hs[idx]
     write("li:")
     Hx = solve.linear_independent(Hx)
     Hz = Hs[idx + 1].transpose()
     write("li:")
     Hz = solve.linear_independent(Hz)
     #print(Hx.shape, Hz.shape)
     if self.Ls:
         Lz = self.Ls[idx]
         #print "get_code:", Lz.shape
     else:
         Lz = None
     #print shortstr(dot(Hx, Hz.transpose()))
     #print "Hz:"
     #print shortstr(Hz)
     #print "Hx:"
     #print shortstr(Hx)
     from qupy.ldpc.css import CSSCode
     code = CSSCode(Hx=Hx, Hz=Hz, Lz=Lz, build=build, check=check)
     return code
Example #5
0
def make_gallagher(r, n, l, m, distance=0, verbose=False):
    assert r % l == 0
    assert n % m == 0
    assert r * m == n * l
    if verbose:
        print("make_gallagher", r, n, l, m, distance)
    H = zeros2(r, n)
    H1 = zeros2(r // l, n)
    H11 = identity2(r // l)
    #print(H1)
    #print(H11)
    for i in range(m):
        H1[:, (n // m) * i:(n // m) * (i + 1)] = H11
    #print(shortstrx(H1))

    while 1:
        H2 = H1.copy()
        idxs = list(range(n))
        for i in range(l):
            H[(r // l) * i:(r // l) * (i + 1), :] = H2
            shuffle(idxs)
            H2 = H2[:, idxs]
        #print(H.shape)
        Hli = linear_independent(H)
        k = Hli.shape[0] - Hli.shape[1]
        assert k <= 24, "ummm, too big? k = %d" % k
        if distance is None:
            break
        if verbose:
            write("/")
        dist = classical_distance(Hli, distance)
        if dist >= distance:
            break
        if verbose:
            write(".")
    if verbose:
        write("\n")
    return Hli
Example #6
0
def test(A, B, ma, na, mb, nb, Ina, Ima, Inb, Imb, ka, kb, kat, kbt, k,
    KerA, KerB, CokerA, CokerB,
    Lzi, Lxi, Hzi, Hxi,
    **kw):

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

    KerA = KerA.transpose() # use convention in paper
    KerB = KerB.transpose() # use convention in paper
    CokerA = CokerA.transpose() # use convention in paper
    CokerB = CokerB.transpose() # use convention in paper

    blocks = [
        [kron(KerA, Imb), zeros2(na*mb, ma*kb), kron(Ina, B)],
        [zeros2(ma*nb, ka*mb), kron(Ima, KerB), kron(A,Inb)],
    ]
    print("blocks:", [[X.shape for X in row] for row in blocks])

    #print(shortstrx(*blocks[0]))
    #print()
    #print(shortstrx(*blocks[1]))

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

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

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

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

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

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

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

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

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

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

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

    if 0:
        V = cat(blocks[0][:2], axis=1)
        H = cat(blocks[1][:2], axis=1)
        X = cat((V, H), axis=0)
        K = find_kernel(X)
        print(K.shape)
    
        V = cat(blocks[0], axis=1)
        H = cat(blocks[1], axis=1)
        X = cat((V, H), axis=0)
        K = find_kernel(X)
        print(K.shape)
    
        #print("-"*(ka*mb+ma*kb))
        I = cat((identity2(ka*mb+ma*kb), zeros2(ka*mb+ma*kb, na*nb)), axis=1)
        J = intersect(K, I)
        print("J:", J.shape)
Example #7
0
File: glue.py Project: punkdit/qupy
def find_triorth(m, k):
    # Bravyi, Haah, 1209.2426v1 sec IX.
    # https://arxiv.org/pdf/1209.2426.pdf

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

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

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

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

    N = len(xs)

    lhs = []
    rhs = []

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

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

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

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

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

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

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

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

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

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

        if 0 in G.sum(1):
            continue

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

        #print(shortstr(G))


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

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

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

        count += 1

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

    G = best
    #print(shortstr(G))

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

    G = linear_independent(G)

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

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

    #print(shortstr(dot2(G, G.transpose())))

    if 0:
        B = pseudo_inverse(A)
        v = dot2(B, rhs)
        print("B:")
        print(shortstr(B))
        print("v:")
        print(shortstr(v))
        assert eq2(dot2(B, v), rhs)
Example #8
0
    def build(self, logops_only=False, check=True, verbose=False):
    
        Hx, Hz = self.Hx, self.Hz
        Lx, Lz = self.Lx, self.Lz
        Tx, Tz = self.Tx, self.Tz

        if verbose:
            _write = write
        else:
            _write = lambda *args : None
    
        _write('li:')
        self.Hx = Hx = solve.linear_independent(Hx)
        self.Hz = Hz = solve.linear_independent(Hz)
    
        mz, n = Hz.shape
        mx, nx = Hx.shape
        assert n==nx
        assert mz+mx<=n, (mz, mx, n)
    
        _write('build:')
    
        if check:
            # check kernel of Hx contains image of Hz^t
            check_commute(Hx, Hz)
    
        if Lz is None:
            _write('find_logops(Lz):')
            Lz = solve.find_logops(Hx, Hz, verbose=verbose)
            #print shortstr(Lz)
            #_write(len(Lz))

        k = len(Lz)
        assert n-mz-mx==k, "_should be %d logops, found %d. Is Hx/z degenerate?"%(
            n-mx-mz, k)

        _write("n=%d, mx=%d, mz=%d, k=%d\n" % (n, mx, mz, k))
    
        # Find Lx --------------------------
        if Lx is None:
            _write('find_logops(Lx):')
            Lx = solve.find_logops(Hz, Hx, verbose=verbose)

        assert len(Lx)==k

        if check:
            check_commute(Lx, Hz)
            check_commute(Lz, Hx)


        U = dot2(Lz, Lx.transpose())
        I = identity2(k)
        A = solve.solve(U, I)
        assert A is not None, "problem with logops: %s"%(U,)
        #assert eq2(dot2(U, A), I)
        #assert eq2(dot2(Lz, Lx.transpose(), A), I)

        Lx = dot2(A.transpose(), Lx)

        if check:
            check_conjugate(Lz, Lx)

        if not logops_only:

            # Find Tz --------------------------
            _write('Find(Tz):')
            U = zeros2(mx+k, n)
            U[:mx] = Hx
            U[mx:] = Lx
            B = zeros2(mx+k, mx)
            B[:mx] = identity2(mx)
    
            Tz_t = solve.solve(U, B)
            Tz = Tz_t.transpose()
            assert len(Tz) == mx
    
            check_conjugate(Hx, Tz)
            check_commute(Lx, Tz)
    
            # Find Tx --------------------------
            _write('Find(Tx):')
            U = zeros2(n, n)
            U[:mz] = Hz
            U[mz:mz+k] = Lz
            U[mz+k:] = Tz
    
            B = zeros2(n, mz)
            B[:mz] = identity2(mz)
            Tx_t = solve.solve(U, B)
            Tx = Tx_t.transpose()
    
            _write('\n')
        
            if check:
                check_conjugate(Hz, Tx)
                check_commute(Lz, Tx)
                check_commute(Tz, Tx)

        self.k = k
        self.Lx = Lx
        self.Lz = Lz
        self.Tz = Tz
        self.Tx = Tx
Example #9
0
    def build_from_gauge(self, check=True, verbose=False):

        write("build_from_gauge:")

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

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

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

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

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

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

        write('\n')

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

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

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

        self.Lx, self.Lz = Lx, Lz
        self.Hx, self.Hz = Hx, Hz
        self.Gxr, self.Gzr = Gxr, Gzr