Ejemplo n.º 1
0
 def is_transversal(A, code):
     Lz = [Clifford.make_op(l, Clifford.z) for l in code.Lz]
     Lx = [Clifford.make_op(l, Clifford.x) for l in code.Lx]
     Hz = [Clifford.make_op(l, Clifford.z) for l in code.Hz]
     Hx = [Clifford.make_op(l, Clifford.x) for l in code.Hx]
     hz = [op.get_translation() for op in Hz]
     hx = [op.get_translation() for op in Hx]
     h = array2(hz + hx)
     ht = h.transpose()
     Ai = A.inverse()
     tgt = []
     for u in Hz + Hx:
         v = A * u * Ai
         assert v.is_translation()
         v = v.get_translation()
         tgt.append(v)
         #print(u.get_translation())
         #print("-->")
         #print(v)
         #print()
     tgt = array2(tgt)
     src = array2([u.get_translation() for u in Hz + Hx])
     tgt, src = tgt.transpose(), src.transpose()
     if solve(tgt, src) is None:
         return False
     if solve(src, tgt) is None:
         return False
     return True
Ejemplo n.º 2
0
 def solve(self, H, minimize=True, verbose=True):
     m, n = H.shape  # rows, cols
     u1 = self.u1
     assert u1.shape == (m, )
     rows = [i for i in range(m) if u1[i]]
     #print rows
     H = H[rows, :]
     u0 = self.u0[rows]
     v = self.v
     cols = [i for i in range(n) if v[i]]
     #print cols
     H = H[:, cols]
     assert cols, self.u0
     #print shortstr(H)
     #print "u0:", shortstr(u0)
     if verbose: print("Cluster.solve:", H.shape)
     v = solve.solve(H, u0)
     if v is None:
         return
     if minimize:
         kern = solve.find_kernel(H)
         if kern:
             kern = array2(kern)
             write("[w=%d, kern=%d, " % (v.sum(), len(list(kern))))
             graph = dynamic.Tanner(kern)
             #v = graph.minimize(v, target=30, verbose=True)
             v = graph.localmin(v, verbose=True)
             write("w=%d]" % v.sum())
     #u = dot(H, v)
     #assert numpy.abs(u-u0).sum() == 0
     v0 = numpy.zeros((n, ), dtype=numpy.int32)
     v0[cols] = v
     #print "v0:", shortstr(v0)
     #write("[%d]"%v0.sum())
     return v0
Ejemplo n.º 3
0
 def is_stab_cluster(self, v, str=shortstr, verbose=False):
     if v.max() == 0:
         if verbose:
             print("is_stab: zero")
         return True
     if verbose:
         print("is_stab: v")
         print(str(v))
     v0 = v
     v = v.copy()
     Hx_t = self.Hx.transpose()
     c = Cluster(v)
     c = c.grow(Hx_t,
                2)  # hmmm... doesn't work when the code has an empty colum
     u = c.solve(Hx_t, verbose=False)
     if u is None:
         write('S')
         u = solve.solve(Hx_t, v, debug=False)
     if u is None:
         if verbose:
             print("is_stab: no solution found")
         write('N')
         return None
     v1 = dot(Hx_t, u) % 2
     if verbose:
         print("is_stab: solved")
     assert ((v0 + v) % 2).max() == 0  # v0==v
     assert ((v1 + v) % 2).max() == 0  # !!!
     return ((v1 + v) % 2).max() == 0  # v1==v ie. solution found
Ejemplo n.º 4
0
 def show_stabx(self, sx):
     gxs = []
     for gx in self.Gx:
         if eq2(gx * sx, gx):
             gxs.append(gx)
     Gx = array2(gxs)
     #print "Gx:", Gx.shape
     #print shortstr(Gx)
     print("sx.sum() =", sx.sum(), end=' ')
     Gxt = Gx.transpose()
     K = find_kernel(Gxt)
     #print "kernel:", K
     K = array2(K)
     #print "kernel:", len(K)
     #print shortstr(K)
     #print
     best = None
     ubest = None
     u = solve(Gxt, sx)
     for w in enum2(len(K)):
         u2 = (u + dot2(w, K)) % 2
         if best is None or u2.sum() < best:
             best = u2.sum()
             ubest = u2
         print("u.sum() =", u2.sum(), end=' ')
     print()
Ejemplo n.º 5
0
 def is_stab_0(self, v):
     write('/')
     Hx_t = self.Hx.transpose()
     u = solve.solve(Hx_t, v)
     if u is not None:
         #print "[%s]"%u.sum(),
         v1 = dot2(Hx_t, u)
         assert ((v+v1)%2).max() == 0
     write('\\')
     return u is not None
Ejemplo n.º 6
0
 def is_stab_full(self, v, str=shortstr, verbose=False):
     Hx_t = self.Hx.transpose()
     #Hx_t = Hx_t.copy()
     #u = solve.search(Hx_t, v)
     #print "is_stab:", Hx_t.shape, v.shape,;sys.stdout.flush()
     u = solve.solve(Hx_t, v)
     #print u is not None
     if u is not None:
         #print "[%s]"%u.sum(),
         v1 = dot(Hx_t, u) % 2
         assert ((v + v1) % 2).max() == 0
     return u is not None
Ejemplo n.º 7
0
    def find_encoding(A, code):
        Lx = [Clifford.make_op(l, Clifford.x) for l in code.Lx]
        Lz = [Clifford.make_op(l, Clifford.z) for l in code.Lz]
        Hx = [Clifford.make_op(l, Clifford.x) for l in code.Hx]
        Hz = [Clifford.make_op(l, Clifford.z) for l in code.Hz]
        assert len(Lx) == len(Lz)
        Ai = A.inverse()
        rows = []
        for l in Lz + Lx:
            B = A * l * Ai
            assert B.is_translation()
            v = B.get_translation()
            rows.append(v)
        B = numpy.array(rows)
        #B = B[:8, :]
        #print(B.shape)
        #print(shortstr(B))
        U = numpy.array([l.get_translation() for l in Lz + Lx + Hz + Hx])
        #print(U.shape)
        #print(shortstr(U))
        Ut = U.transpose()
        V = solve(Ut, B.transpose())
        if V is None:
            return None
        V = V[:2 * code.k]
        #print(V.shape)
        #print(shortstr(V))

        # check that V is symplectic
        n = len(V) // 2
        F = symplectic_form(n)
        lhs = dot2(V.transpose(), dot2(F, V))
        assert eq2(lhs, F)

        #print(A.get_translation())
        u = solve(Ut, A.get_translation())
        u = u[:2 * code.k]
        #print(shortstr(u))

        return Clifford.from_symplectic_and_translation(V, u)
Ejemplo n.º 8
0
 def minsolve(self, H, verbose):
     m, n = H.shape  # rows, cols
     u1 = self.u1
     assert u1.shape == (m, )
     rows = [i for i in range(m) if u1[i]]
     #print rows
     H = H[rows, :]
     u0 = self.u0[rows]
     v = self.v
     cols = [i for i in range(n) if v[i]]
     #print cols
     H = H[:, cols]
     assert cols, self.u0
     #print shortstr(H)
     #print "u0:", shortstr(u0)
     if verbose: print("Cluster.solve:", H.shape)
     v = solve.solve(H, u0)
Ejemplo n.º 9
0
def eq_span(A, B):
    u = solve(A.transpose(), B.transpose())
    if u is None:
        return False
    u = solve(B.transpose(), A.transpose())
    return u is not None
Ejemplo n.º 10
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.º 11
0
def rowspan_le(A, B):
    u = solve(B.transpose(), A.transpose())
    if u is None:
        return False
    return True
Ejemplo n.º 12
0
def hypergraph_product(C, D, check=False):
    print("hypergraph_product:", C.shape, D.shape)
    print("distance:", classical_distance(C))

    c0, c1 = C.shape
    d0, d1 = D.shape

    E1 = identity2(c0)
    E2 = identity2(d0)
    M1 = identity2(c1)
    M2 = identity2(d1)

    Hx0 = kron(M1, D.transpose()), kron(C.transpose(), M2)
    Hx = numpy.concatenate(Hx0, axis=1)  # horizontal concatenate

    Hz0 = kron(C, E2), kron(E1, D)
    #print("Hz0:", Hz0[0].shape, Hz0[1].shape)
    Hz = numpy.concatenate(Hz0, axis=1)  # horizontal concatenate

    assert dot2(Hz, Hx.transpose()).sum() == 0

    n = Hx.shape[1]
    assert Hz.shape[1] == n

    # ---------------------------------------------------
    # Build Lx

    KerC = find_kernel(C)
    #KerC = min_span(KerC) # does not seem to matter... ??
    assert KerC.shape[1] == c1
    K = KerC.transpose()
    E = identity2(d0)

    print(shortstr(KerC))
    print()

    Lxt0 = kron(K, E), zeros2(c0 * d1, K.shape[1] * d0)
    Lxt0 = numpy.concatenate(Lxt0, axis=0)
    assert dot2(Hz, Lxt0).sum() == 0

    K = find_kernel(D).transpose()
    assert K.shape[0] == d1
    E = identity2(c0)

    Lxt1 = zeros2(c1 * d0, K.shape[1] * c0), kron(E, K)
    Lxt1 = numpy.concatenate(Lxt1, axis=0)
    assert dot2(Hz, Lxt1).sum() == 0

    Lxt = numpy.concatenate((Lxt0, Lxt1), axis=1)  # horizontal concatenate
    Lx = Lxt.transpose()

    assert dot2(Hz, Lxt).sum() == 0

    # These are linearly dependent, but
    # once we add stabilizers it will be reduced:
    assert rank(Lx) == len(Lx)

    if 0:
        # ---------------------------------------------------

        print(shortstr(Lx))
        k = get_k(Lx, Hx)
        print("k =", k)

        left, right = [], []

        draw = Draw(c0, c1, d0, d1)
        cols = []
        for j in range(d0):  # col
            col = []
            for i in range(len(KerC)):  # logical
                op = Lx[i * d0 + j]
                col.append(op)
                if j == i:
                    draw.mark_xop(op)
                if j < d0 / 2:
                    left.append(op)
                else:
                    right.append(op)
            cols.append(col)

        draw.save("output.2")

        left = array2(left)
        right = array2(right)

        print(get_k(left, Hx))
        print(get_k(right, Hx))

        return

    # ---------------------------------------------------
    # Build Lz

    counit = lambda n: unit2(n).transpose()

    K = find_cokernel(D)  # matrix of row vectors
    #E = counit(c1)
    E = identity2(c1)
    Lz0 = kron(E, K), zeros2(K.shape[0] * c1, c0 * d1)
    Lz0 = numpy.concatenate(Lz0, axis=1)  # horizontal concatenate

    assert dot2(Lz0, Hx.transpose()).sum() == 0

    K = find_cokernel(C)
    #E = counit(d1)
    E = identity2(d1)
    Lz1 = zeros2(K.shape[0] * d1, c1 * d0), kron(K, E)
    Lz1 = numpy.concatenate(Lz1, axis=1)  # horizontal concatenate

    Lz = numpy.concatenate((Lz0, Lz1), axis=0)

    assert dot2(Lz, Hx.transpose()).sum() == 0

    overlap = 0
    for lx in Lx:
        for lz in Lz:
            w = (lx * lz).sum()
            overlap = max(overlap, w)
    assert overlap <= 1, overlap
    #print("max overlap:", overlap)

    assert rank(Hx) == len(Hx)
    assert rank(Hz) == len(Hz)
    mx = len(Hx)
    mz = len(Hz)

    # ---------------------------------------------------

    Lxs = []
    for op in Lx:
        op = (op + Hx) % 2
        Lxs.append(op)
    LxHx = numpy.concatenate(Lxs)
    LxHx = row_reduce(LxHx)
    print("LxHx:", len(LxHx))
    assert LxHx.shape[1] == n
    print(len(intersect(LxHx, Hx)), mx)
    assert len(intersect(LxHx, Hx)) == mx

    Lzs = []
    for op in Lz:
        op = (op + Hz) % 2
        Lzs.append(op)
    LzHz = numpy.concatenate(Lzs)
    LzHz = row_reduce(LzHz)
    print("LzHz:", len(LzHz))
    assert LzHz.shape[1] == n

    # ---------------------------------------------------
    # Remove excess logops.

    #    print("remove_dependent")
    #
    #    # -------- Lx
    #
    #    Lx, Lx1 = mk_disjoint_logops(Lx, Hx)
    #
    #    # -------- Lz
    #
    #    Lz, Lz1 = mk_disjoint_logops(Lz, Hz)

    # --------------------------------
    # independent_logops for Lx

    k = get_k(Lx, Hx)

    idxs0, idxs1 = [], []

    for j in range(d0):  # col
        for i in range(c1):
            idx = j + i * d0
            if j < d0 // 2:
                idxs0.append(idx)
            else:
                idxs1.append(idx)

    Lx0 = in_support(LxHx, idxs0)
    Lx0 = independent_logops(Lx0, Hx)
    k0 = (len(Lx0))

    Lx1 = in_support(LxHx, idxs1)
    Lx1 = independent_logops(Lx1, Hx)
    k1 = (len(Lx1))
    assert k0 == k1 == k, (k0, k1, k)

    # --------------------------------
    # independent_logops for Lz

    idxs0, idxs1 = [], []

    for j in range(d0):  # col
        for i in range(c1):
            idx = j + i * d0
            if i < c1 // 2:
                idxs0.append(idx)
            else:
                idxs1.append(idx)

    Lz0 = in_support(LzHz, idxs0)
    Lz0 = independent_logops(Lz0, Hz)
    k0 = (len(Lz0))

    Lz1 = in_support(LzHz, idxs1)
    Lz1 = independent_logops(Lz1, Hz)
    k1 = (len(Lz1))
    assert k0 == k1 == k, (k0, k1, k)

    # ---------------------------------------------------
    #

    #assert eq2(dot2(Lz, Lxt), identity2(k))
    assert mx + mz + k == n

    print("mx = %d, mz = %d, k = %d : n = %d" % (mx, mz, k, n))

    # ---------------------------------------------------
    #

    #    if Lx1 is None:
    #        return
    #
    #    if Lz1 is None:
    #        return

    # ---------------------------------------------------
    #

    op = zeros2(n)
    for lx in Lx0:
        for lz in Lz0:
            lxz = lx * lz
            #print(lxz)
            #print(op.shape, lxz.shape)
            op += lxz

    for lx in Lx1:
        for lz in Lz1:
            lxz = lx * lz
            #print(lxz)
            #print(op.shape, lxz.shape)
            op += lxz

    idxs = numpy.where(op)[0]
    print("correctable region size = %d" % len(idxs))
    #print(op)
    #print(idxs)

    Lx, Lz = Lx0, Lz0

    Lxs = []
    for op in Lx:
        op = (op + Hx) % 2
        Lxs.append(op)
    LxHx = numpy.concatenate(Lxs)
    LxHx = row_reduce(LxHx)
    assert LxHx.shape[1] == n

    Lzs = []
    for op in Lz:
        op = (op + Hz) % 2
        Lzs.append(op)
    LzHz = numpy.concatenate(Lzs)
    LzHz = row_reduce(LzHz)
    assert LzHz.shape[1] == n

    if argv.draw:
        do_draw(**locals())

    good = is_correctable(n, idxs, LxHx, LzHz)
    assert good

    print("good")

    # ---------------------------------------------------
    #

    if argv.code:
        print("code = CSSCode()")
        code = CSSCode(Hx=Hx,
                       Hz=Hz,
                       Lx=Lx,
                       Lz=Lz,
                       check=True,
                       verbose=False,
                       build=True)
        print(code)
        #print(code.weightstr())

        if check:
            U = solve(Lx.transpose(), code.Lx.transpose())
            assert U is not None
            #print(U.shape)
            assert eq2(dot2(U.transpose(), Lx), code.Lx)
            #print(shortstr(U))

        if 0:
            Lx, Lz = code.Lx, code.Lz
            print("Lx:", Lx.shape)
            print(shortstr(Lx))
            print("Lz:", Lz.shape)
            print(shortstr(Lz))
Ejemplo n.º 13
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
Ejemplo n.º 14
0
Archivo: diag.py Proyecto: punkdit/qupy
def test_target():
    i = 1j
    fold = Diag([
        1,
        1,
        i,
        -i,
        i,
        -i,
        1,
        1,
        1,
        1,
        i,
        -i,
        i,
        -i,
        1,
        1,
        1,
        1,
        -i,
        i,
        i,
        -i,
        -1,
        -1,
        1,
        1,
        -i,
        i,
        i,
        -i,
        -1,
        -1,
        i,
        i,
        -1,
        1,
        -1,
        1,
        i,
        i,
        i,
        i,
        -1,
        1,
        -1,
        1,
        i,
        i,
        -i,
        -i,
        -1,
        1,
        1,
        -1,
        i,
        i,
        -i,
        -i,
        -1,
        1,
        1,
        -1,
        i,
        i,
        1,
        -1,
        i,
        i,
        i,
        i,
        1,
        -1,
        -1,
        1,
        -i,
        -i,
        -i,
        -i,
        -1,
        1,
        1,
        -1,
        -i,
        -i,
        i,
        i,
        -1,
        1,
        -1,
        1,
        i,
        i,
        -i,
        -i,
        1,
        -1,
        i,
        -i,
        -1,
        -1,
        -1,
        -1,
        i,
        -i,
        -i,
        i,
        1,
        1,
        1,
        1,
        -i,
        i,
        -i,
        i,
        -1,
        -1,
        1,
        1,
        i,
        -i,
        i,
        -i,
        1,
        1,
        -1,
        -1,
        -i,
        i,
        -i,
        -i,
        1,
        -1,
        -1,
        1,
        i,
        i,
        i,
        i,
        -1,
        1,
        1,
        -1,
        -i,
        -i,
        i,
        i,
        1,
        -1,
        1,
        -1,
        i,
        i,
        -i,
        -i,
        -1,
        1,
        -1,
        1,
        -i,
        -i,
        1,
        1,
        i,
        -i,
        -i,
        i,
        -1,
        -1,
        -1,
        -1,
        -i,
        i,
        i,
        -i,
        1,
        1,
        1,
        1,
        -i,
        i,
        -i,
        i,
        1,
        1,
        -1,
        -1,
        i,
        -i,
        i,
        -i,
        -1,
        -1,
        -i,
        i,
        1,
        1,
        -1,
        -1,
        i,
        -i,
        -i,
        i,
        1,
        1,
        -1,
        -1,
        i,
        -i,
        i,
        -i,
        1,
        1,
        1,
        1,
        i,
        -i,
        i,
        -i,
        1,
        1,
        1,
        1,
        i,
        -i,
        1,
        -1,
        i,
        i,
        -i,
        -i,
        -1,
        1,
        1,
        -1,
        i,
        i,
        -i,
        -i,
        -1,
        1,
        1,
        -1,
        -i,
        -i,
        -i,
        -i,
        1,
        -1,
        1,
        -1,
        -i,
        -i,
        -i,
        -i,
        1,
        -1,
    ])

    k = 8
    N = 2**k
    assert len(fold) == N

    #    print(fold)
    #    I = Diag([1.]*len(fold))
    #    op = fold
    #    count = 1
    #    while op != I:
    #        op = fold * op
    #        count += 1
    #    print(count)
    #    return

    # --------------- Diag ->>> Cliff ---------------------

    fold = fold.get_cliff()

    IN = Cliff([0] * N)
    I = Cliff([0, 0])
    phase = Cliff([1])
    Z = Cliff([0, 2])
    S = Cliff([0, 1])
    Si = Cliff([0, 3])
    CZ = Cliff([0, 0, 0, 2])
    II = Cliff([0, 0, 0, 0])

    s_gate = reduce(tensor, [S, I, S, I, I, S, S, I])
    s_gate_i = reduce(tensor, [Si, I, Si, I, I, Si, Si, I])

    target = s_gate * fold
    print(target)

    gens = []
    phase_gate = Cliff([1] * N)
    names = []

    #    # single qubit S gates
    #    for i in range(k):
    #        for s_gate in [S, Si]:
    #            ops = [I]*k
    #            ops[i] = s_gate
    #            op = reduce(tensor, ops)
    #            #gens.append(op)

    for i in range(k):
        diag = [0] * N
        for idx in range(N):
            if idx & (2**i):
                diag[idx] = 2
        Z = Cliff(diag)
        assert (Z * Z) == Cliff([0] * N)
        gens.append(Z)
        names.append("Z_{%d}" % i)

    for i in range(k):
        for j in range(i + 1, k):
            diag = [0] * N
            for idx in range(N):
                if idx & (2**i) and idx & (2**j):
                    diag[idx] = 2
            cz = Cliff(diag)
            assert (cz * cz) == Cliff([0] * N)
            gens.append(cz)
            names.append("CZ_{%d,%d}" % (i, j))

    print("gens:", len(gens))

    #for a in gens:
    #  for b in gens:
    #    print("%4s" % a.inner(b), end=" ")
    #  print()

    A = numpy.zeros((len(gens), N), dtype=int_scalar)
    for i, gen in enumerate(gens):
        A[i] = gen.diag
    A //= 2
    #A = row_reduce(A)
    #print(shortstr(A))
    print("rank:", rank(A))

    rhs = target.diag
    rhs = rhs.astype(int_scalar)
    rhs //= 2
    u = solve(A.transpose(), rhs)

    print(u)
    opnames = []
    op = s_gate_i
    for i, name in enumerate(names):
        if u[i]:
            opnames.append(names[i])
            op = gens[i] * op
    print("op =", "*".join(opnames))

    print(op)
    print(fold)
    assert op == fold
Ejemplo n.º 15
0
    def __init__(self, l):

        stars = []
        for i in range(l):
            for j in range(l):
                for k in range(l):
                    stars.append((2 * i, 2 * j, 2 * k))

        self.l = l
        self.keys = keys = []
        self.keymap = keymap = {}
        for i, j, k in stars:
            self.add_site(i + 1, j, k)
            self.add_site(i, j + 1, k)
            self.add_site(i, j, k + 1)
        #print keymap
        #print keys

        n = len(keys)
        #print "n =", n
        assert n == 3 * (l**3)
        assert keys[keymap[2 * l - 1, 0, 0]] == (2 * l - 1, 0, 0)
        assert keys[keymap[-1, 0, 0]] == (2 * l - 1, 0, 0)

        m = len(stars)
        Hz = zeros2(m - 1, n)

        for row, (i, j, k) in enumerate(stars):
            if row == len(stars) - 1:
                break
            #if row==4:
            #print shortstr(Hz[row]), (i, j, k)
            #for d in (-1, 1):
            #print keys[keymap[i+d, j, k]],
            #print keys[keymap[i, j+d, k]],
            #print keys[keymap[i, j, k+d]],
            #print

            for d in (-1, 1):
                Hz[row, keymap[i + d, j, k]] = 1
                Hz[row, keymap[i, j + d, k]] = 1
                Hz[row, keymap[i, j, k + d]] = 1

        #print shortstr(Hz)

        Hx = zeros2(3 * m, n)
        row = 0
        square = [(1, 0), (0, 1), (1, 2), (2, 1)]
        for i, j, k in stars:

            #print i, j, k

            if i + 2 < 2 * l or j + 2 < 2 * l:
                for d1, d2 in square:
                    #print (i+d1, j+d2, k),
                    #print keys[keymap[i+d1, j+d2, k]],
                    Hx[row, keymap[i + d1, j + d2, k]] = 1
                #print
                #print shortstr(Hx[row])
                #for q in range(m-1):
                #if dot2(Hx[row], Hz[q].transpose()).sum():
                #print shortstr(Hz[q]), "XXX"
                assert dot2(Hx[row], Hz.transpose()).sum() == 0
                assert dot2(Hx, Hz.transpose()).sum() == 0
                if not row or solve(Hx[:row].transpose(), Hx[row]) is None:
                    row += 1
                else:
                    Hx[row] = 0

            if i + 2 < 2 * l or k + 2 < 2 * l:
                for d1, d2 in square:
                    Hx[row, keymap[i + d1, j, k + d2]] = 1
                assert dot2(Hx, Hz.transpose()).sum() == 0
                if solve(Hx[:row].transpose(), Hx[row]) is None:
                    row += 1
                else:
                    Hx[row] = 0

            if i == 0 and (j + 2 < 2 * l or k + 2 < 2 * l):
                for (d1, d2) in square:
                    Hx[row, keymap[i, j + d1, k + d2]] = 1
                assert dot2(Hx, Hz.transpose()).sum() == 0
                if solve(Hx[:row].transpose(), Hx[row]) is None:
                    row += 1
                else:
                    Hx[row] = 0

        Hx = Hx[:row].copy()

        self.Hx = Hx
        self.Hz = Hz
Ejemplo n.º 16
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
Ejemplo n.º 17
0
def do_draw(c0, c1, d0, d1, Lx, Lz, Hx, Hz, idxs, LxHx, LzHz, **kw):

    draw = Draw(c0, c1, d0, d1)

    mark_xop = draw.mark_xop
    mark_zop = draw.mark_zop
    mark_idx = draw.mark_idx

    m, n = LxHx.shape

    assert rank(LxHx) == len(LxHx)
    assert rank(Hx) == len(Hx)
    assert rank(Lx) == len(Lx)
    #print(rank(LxHx))
    #print(rank(Hx))
    #print(rank(Lx))
    assert rank(Lx) + rank(Hx) == len(LxHx) + 1

    if 0:
        w = n
        best = None
        for i in range(10000):
            v = rand2(1, m)
            lop = dot2(v, LxHx)[0]
            #print(lop)
            if lop.sum() < w:
                best = lop
                w = lop.sum()
                print(w)

        mark_xop(best)

    all_idxs = list(range(c1 * d0 + c0 * d1))
    h_idxs, v_idxs = all_idxs[:c1 * d0], all_idxs[c1 * d0:]
    if 0:
        # find Hx stabilizers with horizontal support
        #for idx in h_idxs:
        #    mark_idx(idx)
        PHx = in_support(Hx, h_idxs)
        op = rand_span(PHx)
        mark_xop(op)
        # plenty...

    if 0:
        left = [draw.get_hidx(row, 0) for row in range(d0)]
        right = [draw.get_hidx(row, 5) for row in range(d0)]
        for idx in left + right:
            mark_idx(idx)
        PLx = in_support(LxHx, left + right)
        lop = rand_span(PLx)
        mark_xop(lop)

        PLx_left = in_support(LxHx, left)
        PLx_right = in_support(LxHx, right)

        PLx = numpy.concatenate((PLx_left, PLx_right))
        assert rank(PLx) == rank(PLx_left) + rank(PLx_right)

        U = solve(PLx.transpose(), lop)
        assert U is not None
        #print(U)

        draw.save("output.logop")

        return

    for op in Lx:
        #cl = color.rgb(0.2*random(), 0.2*random(), random(), 0.5)
        draw.mark_op(op, st_qubit=[blue] + st_thick, r=0.06, stroke=True)

    for op in Lz:
        #cl = color.rgb(0.2*random(), random(), 0.2*random(), 0.5)
        draw.mark_op(op, st_qubit=[green] + st_thick, r=0.12, stroke=True)

    for idx in idxs:
        draw.mark(idx, st_qubit=[red] + st_thick, r=0.16, stroke=True)

    correctable = draw.cvs
    #draw.save("output")

    rows = [[], []]

    margin = 0.2
    mkbox = lambda cvs: MarginBox(cvs, margin, 2 * margin)
    for op in Lx:
        draw = Draw(c0, c1, d0, d1)
        draw.mark_op(op, st_qubit=[blue] + st_thick, r=0.06, stroke=True)
        rows[0].append(mkbox(draw.cvs))

    for op in Lz:
        draw = Draw(c0, c1, d0, d1)
        draw.mark_op(op, st_qubit=[green] + st_thick, r=0.12, stroke=True)
        rows[1].append(mkbox(draw.cvs))

    row = [None] * len(Lx)
    row[0] = correctable
    rows.append(row)

    box = TableBox(rows)
    cvs = box.render()
    cvs.writePDFfile("output.pdf")