Пример #1
0
    def build_code(self, build=False, check=False):

        qubits = self.qubits
        guage = self.guage

        n = len(qubits)
        m = len(guage)

        Gx, Gz = self.Gx, self.Gz
        #Hx, Hz, Lx, Lz = build_stab(Gx, Gz)
        Hx, Hz = self.Hx, self.Hz

        if build:
            Lx = find_logops(Gz, Hx)
            Lz = find_logops(Gx, Hz)
        else:
            Lx = Lz = None

        code = CSSCode(Lx,
                       Lz,
                       Hx,
                       None,
                       Hz,
                       None,
                       Gx,
                       Gz,
                       build=build,
                       check=check)

        return code
Пример #2
0
 def homology(self, i):
     "kern of Hs[i] mod image Hs[i+1]"
     H0, H1 = self[i], self[i + 1]
     #print "homology", i
     #print H0.shape, H1.shape
     L = solve.find_logops(H0, H1.transpose())
     return L
Пример #3
0
def main():

    import models

    assert not argv.orbiham, "it's called orbigraph now"

    if argv.find_ideals:
        find_ideals()
        return

    Gx, Gz, Hx, Hz = models.build()

    if argv.chainmap:
        do_chainmap(Gx, Gz)

    if argv.symmetry:
        do_symmetry(Gx, Gz, Hx, Hz)
        return
    
    #print shortstrx(Gx, Gz)
    if argv.report:
        print("Hz:")
        for i, h in enumerate(Hz):
            print(i, shortstr(h), h.sum())
    #print shortstr(find_stabilizers(Gx, Gz))

    Lz = find_logops(Gx, Hz)
    Lx = find_logops(Gz, Hx)
    #print "Lz:", shortstr(Lz)

    if Lz.shape[0]*Lz.shape[1]:
        print(Lz.shape, Gx.shape)
        check_commute(Lz, Gx)
        check_commute(Lz, Hx)

    Px = get_reductor(Hx) # projector onto complement of rowspan of Hx
    Pz = get_reductor(Hz) 

    Rz = [dot2(Pz, g) for g in Gz]
    Rz = array2(Rz)
    Rz = row_reduce(Rz, truncate=True)
    rz = len(Rz)

    n = Gx.shape[1]
    print("n =", n)
    if len(Lx):
        print("Lx Lz:")
        print(shortstrx(Lx, Lz))
    print("Hx:", len(Hx), "Hz:", len(Hz))
    print("Gx:", len(Gx), "Gz:", len(Gz))

    Rx = [dot2(Px, g) for g in Gx]
    Rx = array2(Rx)

    Rx = row_reduce(Rx, truncate=True)
    rx = len(Rx)
    print("Rx:", rx, "Rz:", rz)
    if argv.show:
        print(shortstrx(Rx, Rz))

    Qx = u_inverse(Rx)
    Pxt = Px.transpose()
    assert eq2(dot2(Rx, Qx), identity2(rx))
    assert eq2(dot2(Rx, Pxt), Rx)

    #print shortstr(dot2(Pxt, Qx))
    PxtQx = dot2(Pxt, Qx)
    lines = [shortstr(dot2(g, PxtQx)) for g in Gx]
    lines.sort()
    #print "PxtQx:"
    #for s in lines:
    #    print s
    #print "RzRxt"
    #print shortstr(dot2(Rz, Rx.transpose()))

    offset = argv.offset

    if len(Hz):
        Tx = find_errors(Hz, Lz, Rz)
    else:
        Tx = zeros2(0, n)

    if argv.dense:
        dense(**locals())
        return

    if argv.dense_full:
        dense_full(**locals())
        return

    if argv.show_delta:
        show_delta(**locals())
        return

    if argv.slepc:
        slepc(**locals())
        return

#    if argv.orbigraph:
#        from linear import orbigraph
#        orbigraph(**locals())
#        return

    v0 = None

#    excite = argv.excite
#    if excite is not None:
#        v0 = zeros2(n)
#        v0[excite] = 1

    verts = []
    lookup = {}
    for i, v in enumerate(span(Rx)): # XXX does not scale well
        if v0 is not None:
            v = (v+v0)%2
            v = dot2(Px, v)
        lookup[v.tobytes()] = i
        verts.append(v)
    print("span:", len(verts))
    assert len(lookup) == len(verts)

    mz = len(Gz)
    n = len(verts)

    if argv.lie:
        U = []
        for i, v in enumerate(verts):
            count = dot2(Gz, v).sum()
            Pxv = dot2(Px, v)
            assert count == dot2(Gz, Pxv).sum()
            U.append(mz - 2*count)
        uniq = list(set(U))
        uniq.sort(reverse=True)
        s = ', '.join("%d(%d)"%(val, U.count(val)) for val in uniq)
        print(s)
        print("sum:", sum(U))
        return
        

    if n <= 1024 and argv.solve:
        H = numpy.zeros((n, n))
        syndromes = []
        for i, v in enumerate(verts):
            syndromes.append(dot2(Gz, v))
            count = dot2(Gz, v).sum()
            Pxv = dot2(Px, v)
            assert count == dot2(Gz, Pxv).sum()
            H[i, i] = mz - 2*count
            for g in Gx:
                v1 = (g+v)%2
                v1 = dot2(Px, v1)
                j = lookup[v1.tobytes()]
                H[i, j] += 1
    
        if argv.showham:
            s = lstr2(H, 0).replace(',  ', ' ')
            s = s.replace(' 0', ' .')
            s = s.replace(', -', '-')
            print(s)
    
        vals, vecs = numpy.linalg.eigh(H)
        show_eigs(vals)

        if argv.show_partition:
            beta = argv.get("beta", 1.0)
            show_partition(vals, beta)

        if argv.orbigraph:
            if argv.symplectic:
                H1 = build_orbigraph(H, syndromes)
            else:
                H1 = build_orbigraph(H)
            print("orbigraph:")
            print(H1)
            vals, vecs = numpy.linalg.eig(H1)
            show_eigs(vals)

    elif argv.sparse:
        print("building H", end=' ')
        A = {} # adjacency
        U = [] # potential

        if offset is None:
            offset = mz + 1 # make H positive definite

        for i, v in enumerate(verts):
            if i%1000==0:
                write('.')
            count = dot2(Gz, v).sum()
            #H[i, i] = mz - 2*count
            U.append(offset + mz - 2*count)
            for g in Gx:
                v1 = (g+v)%2
                v1 = dot2(Px, v1)
                j = lookup[v1.tobytes()]
                A[i, j] = A.get((i, j), 0) + 1
    
        print("\nnnz:", len(A))

        if argv.lanczos:
            vals, vecs = do_lanczos(A, U)

        elif argv.orbigraph:
            vals, vecs = do_orbigraph(A, U)

        else:
            return

        vals -= offset # offset doesn't change vecs

        show_eigs(vals)

    elif argv.orbigraph:

        assert n<=1024

        H = numpy.zeros((n, n))
        syndromes = []
        for i, v in enumerate(verts):
            syndromes.append(dot2(Gz, v))
            count = dot2(Gz, v).sum()
            Pxv = dot2(Px, v)
            assert count == dot2(Gz, Pxv).sum()
            H[i, i] = mz - 2*count
            for g in Gx:
                v1 = (g+v)%2
                v1 = dot2(Px, v1)
                j = lookup[v1.tobytes()]
                H[i, j] += 1
    
        if argv.showham:
            s = lstr2(H, 0).replace(',  ', ' ')
            s = s.replace(' 0', ' .')
            s = s.replace(', -', '-')
            print(s)
    
        if argv.symplectic:
            H1 = build_orbigraph(H, syndromes)
        else:
            H1 = build_orbigraph(H)
Пример #4
0
def build_gcolor2():

    n = 39
    m = 10

    delta = 19

    top = n - 1  # top qubit

    # bottom faces: points must be adjacent in each face
    bfaces = [[0, 1, 2, 3], [1, 4, 5, 6, 7, 2], [3, 2, 7, 8], [4, 9, 10, 5],
              [8, 7, 6, 11, 12, 13], [9, 14, 15, 10], [5, 10, 15, 16, 11, 6],
              [11, 16, 17, 12], [13, 12, 17, 18]]

    faces = list(bfaces) + [[i + delta for i in face] for face in bfaces]

    def check_faces():
        items = [list(face) for face in faces]
        for face in items:
            assert len(face) % 2 == 0, face
            face.sort()
        assert len(set([tuple(face) for face in items])) == len(items)

    check_faces()

    # bottom edges
    bedges = []
    for face in bfaces:
        f = len(face)
        for i in range(f):
            bedges.append([face[i], face[(i + 1) % f]])

    # edges are not yet unique..
    for edge in bedges:
        edge.sort()
    bedges = list(set([tuple(e) for e in bedges]))

    # extrude bottom edges to make a face
    for edge in bedges:
        edge = list(edge)
        a, b = edge
        face = edge + [a + delta, b + delta]
        faces.append(face)
    check_faces()

    stabs = []
    for face in bfaces:
        stabs.append(face + [i + delta for i in face])

    # top faces
    for face in [[0, 1, 4, 9, 14], [0, 3, 8, 13, 18], [14, 15, 16, 17, 18]]:
        face = [i + delta for i in face] + [top]
        faces.append(face)
    check_faces()

    stabs.append([i + delta for i in range(19)] + [top])

    g = len(faces)
    #print "faces:", g

    for stab in stabs:
        assert len(stab) % 2 == 0, stab

    #faces.sort()
    #for face in faces:
    #    print face

    Gx = mkop(n, faces)
    Gz = Gx.copy()

    rows = [shortstr(g) for g in Gx]
    #rows.sort()
    #for i, row in enumerate(rows):
    #    print row, faces[i]
    assert len(set(rows)) == len(rows)

    Hz = mkop(n, stabs)
    Hx = Hz.copy()

    # bottom face
    Lx = mkop(n, [list(range(19))])
    Lz = Lx.copy()

    check_commute(Hx, Hz)
    check_commute(Hx, Gz)
    check_commute(Hz, Gx)
    check_commute(Gx, Lz)
    check_commute(Gz, Lx)
    check_commute(Hx, Lz)
    check_commute(Hz, Lx)

    #code = CSSCode(Hx=Hx, Gx=Gx, Hz=Hz, Gz=Gz, build=False)

    Lx = find_logops(Gz, Hx)

    #print "Lx:", shortstr(Lx)

    return Gx, Gz, Hx
Пример #5
0
def build_model(Gx=None, Gz=None, Hx=None, Hz=None):

    if Gx is None:
        Gx, Gz, Hx, Hz = build()

    n = Gx.shape[1]

    if Hx is None:
        Hx = find_stabilizers(Gz, Gx)
    if Hz is None:
        Hz = find_stabilizers(Gx, Gz)

    check_commute(Hx, Hz)
    check_commute(Gx, Hz)
    check_commute(Hx, Gz)

    #Px = get_reductor(concatenate((Lx, Hx)))
    #Pz = get_reductor(concatenate((Lz, Hz)))
    Px = get_reductor(Hx)
    Pz = get_reductor(Hz)

    # Lz = find_logops( Hx            , Hz            )
    #      find_logops( ............. , ............. )
    #                 ( commutes with , orthogonal to )
    #                 ( ............. , ............. )

    Lz = find_logops(Gx, Hz)
    assert Lz.shape[1] == n

    if 0:
        PGz = get_reductor(Gz)
        Lz = dot2(Lz, PGz.transpose())
        Lz = row_reduce(Lz)

        print(shortstrx(Lz, Gz, Hz))

    if len(Lz):
        #print Lz.shape, Hz.shape
        assert len(row_reduce(concatenate((Lz, Hz)))) == len(Lz) + len(Hz)
        assert len(row_reduce(concatenate(
            (Lz, Gz)))) == len(Lz) + len(row_reduce(Gz))

    # Tz = find_errors( Hx            , Lx            )
    #      find_errors( ............. , ............. )
    #                 ( conjugate to  , commutes with )
    #                 ( ............. , ............. )

    Lx = find_errors(Lz, Gz)  # invert Lz, commuting with Gz

    check_commute(Lx, Gz)
    check_commute(Lx, Hz)
    check_conjugate(Lx, Lz)
    check_commute(Lz, Gx)
    check_commute(Lz, Hx)

    # Lx | Lz
    # Hx | ?
    # ?  | Hz
    # ?  | ?
    #Rz = find_logops(concatenate((Lx, Hx)), Hz)
    Rz = dot2(Gz, Pz.transpose())
    Rz = row_reduce(Rz)

    check_commute(Rz, Lx)
    check_commute(Rz, Hx)

    Rx = dot2(Gx, Px.transpose())
    Rx = row_reduce(Rx)

    check_commute(Rx, Lz)
    check_commute(Rx, Hz)

    # Lx | Lz
    # Hx | ?
    # ?  | Hz
    # Rx'| Rz'

    Tz = find_errors(Hx, concatenate((Lx, Rx)))
    Tx = find_errors(Hz, concatenate((Lz, Rz, Tz)))

    assert len((concatenate((Lx, Hx, Tx, Rx)))) == n
    assert len((concatenate((Lz, Hz, Tz, Rz)))) == n
    assert len(row_reduce(concatenate((Lx, Hx, Tx, Rx)))) == n
    assert len(row_reduce(concatenate((Lz, Hz, Tz, Rz)))) == n

    check_commute(Rz, Tx)

    Rx = find_errors(Rz, concatenate((Lz, Hz, Tz)))

    check_conjugate(Rx, Rz)
    check_commute(Rx, Hz)
    check_commute(Rx, Tz)
    check_commute(Rx, Lz)

    Rxt = Rx.transpose()
    Rzt = Rz.transpose()

    Pxt = Px.transpose()
    Pzt = Pz.transpose()

    check_sy(Lx, Hx, Tx, Rx, Lz, Hz, Tz, Rz)

    assert eq2(dot2(Gz, Rxt), dot2(Gz, Pzt, Rxt))
    assert eq2(dot2(Gx, Rzt), dot2(Gx, Pxt, Rzt))

    #    print shortstrx(dot2(Rx, Pz), Rx)

    assert eq2(dot2(Rx, Pz), Rx)
    assert eq2(dot2(Rz, Px), Rz)

    assert len(find_kernel(dot2(Gz, Rx.transpose()))) == 0

    model = Model(locals())

    if argv.dual:
        model = model.get_dual()
        argv.dual = False  # HACK !!

    return model
Пример #6
0
def main(l):

    lattice = Lattice(l)
    n = len(lattice.qubits)
    print(lattice)

    code = lattice.build_code(check=False)
    #Ex = lattice.Ex
    Gx, Gz = code.Gx, code.Gz
    Hx, Hz = code.Hx, code.Hz
    Lx = find_logops(Gz, Hx)
    #print Lx
    #print dot2(Lx, Gz.transpose())
    print(code)
    print("Gx:")
    print(shortstrx(Gx))
    print("Hx:")
    print(shortstrx(Hx))
    print("Lx:")
    print(shortstrx(Lx))

    print("0-simplices (bodies):", len(lattice.simplices[0]))
    print("1-simplices (faces):", len(lattice.simplices[1]))
    print("2-simplices (edges):", len(lattice.simplices[2]))

    corners = []
    edges = []
    faces = []
    internal = []
    for i in range(n):
        gw = Gx[:, i].sum()
        hw = Hx[:, i].sum()
        assert gw >= 3
        assert hw in [1, 2, 3, 4]
        assert gw in [3, 5, 6]
        if gw == 3:
            corners.append(i)
            assert hw == 1
        elif gw == 5:
            edges.append(i)
            assert hw == 2
        elif gw == 6:
            if hw == 3:
                faces.append(i)
            else:
                assert hw == 4
                internal.append(i)

    assert len(corners) + len(edges) + len(faces) + len(internal) == n

    #return

    #    op = zeros2(n)
    #    for i in corners:
    #        op[i] = 1
    #    assert solve(Gx.transpose(), op)

    if 0:
        # ops spanned by gauge operators are all even weight
        for trial in range(100):

            m = len(Gx)
            op = zeros2(n)
            for i in range(m // 2):
                op += Gx[randint(0, m - 1)]
            op %= 2
            w = op.sum() % 2
            assert w % 2 == 0
            print(op)

    #return

    desc = "stabs gauge strings qubits".split()

    for d in range(4):
        counts = {}
        print("%d:" % d, desc[d])
        for p in lattice.simplices[d]:
            #print '\t', p
            #if not p.is_internal():
            #    continue
            cs = [colorof(v) for v in p.vs]
            cs.sort()
            cs = tuple(cs) + (len(lattice.get_qubits(p)), )
            counts[cs] = counts.get(cs, 0) + 1
        print(counts)

    R = []
    for p in lattice.simplices[1]:
        a = lattice.make_op(p)
        a.shape = 1, n
        R.append(a)

    find_skip(Hx, Lx, R)

    return

    A = Hx[:, :]
    r = rank(A)

    source = []
    for p in lattice.simplices[1]:
        if not p.is_internal():
            continue
        vs = p.vs
        v0, v1 = vs
        key = (v1 - v0), p
        source.append(key)
    source.sort(key=lambda k_p: (k_p[0].color, k_p[0]), reverse=True)

    source = [(None, p) for p in lattice.simplices[1]]
    gauges = {}
    for key, p in source:
        if p.is_internal():
            vs = p.vs
            v0, v1 = vs
            #write(str(v1-v0))
        a = lattice.make_op(p)
        a.shape = 1, n
        A1 = numpy.concatenate((A, a))
        if rank(A1) == r:
            #write("\n")
            continue
        #write(" OK\n")
        r = r + 1
        A = A1
        key = [colorof(v) for v in p.vs]
        key.sort()
        key = tuple(key)  # + (len(lattice.get_qubits(p)),)
        gauges.setdefault(key, []).append(p)

    #print

    for key, value in list(gauges.items()):
        print(key, len(value))

    print("rank:", r)
    print(rank(A))
    #print shortstrx(A)

    return

    key = list(gauges.keys())[0]
    A = []
    for op in gauges[key]:
        a = zeros2(n)
        for qubit in lattice.get_qubits(op):
            a[qubit.i] = 1
        A.append(a)
    A = array2(A)
    #print shortstrx(A)
    print(A.shape)
    print(rank(A))

    A = numpy.concatenate((Hx, A))
    print(A.shape)
    print(rank(A))

    #code.build_from_gauge()

    #A = dot2(code.Gx, code.Gz.transpose())
    #print shortstrx(code.Gxr, code.Gzr)
    #print shortstr(A)

    assert rank(Hx) == Hx.shape[0]  # L.I.
    #Hx = linear_independant(Hx)
    #Hz = linear_independant(Hz)

    n = code.n
    m = Hx.shape[0] + Hz.shape[0]

    r = n - m - 1
    assert r % 2 == 0

    return

    Rx = []
    Rz = []
    for gx, gz in pairs:
        Rx.append(gx)
        Rz.append(gz)
        Rx.append(gz)
        Rz.append(gx)

    Rx = array2(Rx)
    Rz = array2(Rz)

    print(shortstrx(Rx, Rz))
    assert Rx.shape[0] == r
    assert rank(Rx) == r
    assert rank(numpy.concatenate((Rx, Hx))) == r + m // 2

    A = dot2(Rx, Rz.transpose())
    print(shortstrx(A))

    return

    Rx = slow_remove(Gx, Hx)
    Rz = slow_remove(Gz, Hz)

    r = rank(Rx)
    assert r + m + 1 == n

    print("r =", r)
Пример #7
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
Пример #8
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