CNOT#

This notebook shows the construction and simulation results of the logical CNOT gate between two logical qubits with lattice surgery.

Construction#

A logical CNOT between two logical qubits can be implemented with the help of an ancilla qubit. It can be accomplished by the following steps:

  1. \(M_{ZZ}\) parity measurement between \(Q_{control}\) and \(Q_{ancilla}\).

  2. \(M_{XX}\) parity measurement between \(Q_{target}\) and \(Q_{ancilla}\).

  3. \(M_{Z}\) measurement of \(Q_{ancilla}\).

tqec provides builtin functions tqec.gallery.cnot to construct the logical CNOT gate.

[1]:
from tqec.gallery import cnot

graph = cnot()
graph.view_as_html()
[1]:

The logical CNOT has four independent stabilizer flow generators: XI -> XX, IX -> IX, ZI -> ZI, IZ -> ZZ. Here we show the correlation surfaces for the generators.

[2]:
correlation_surfaces = graph.find_correlation_surfaces()

XI -> XX#

[3]:
graph.view_as_html(
    pop_faces_at_direction="-Y",
    show_correlation_surface=correlation_surfaces[0],
)
[3]:

IX -> IX#

[4]:
graph.view_as_html(
    pop_faces_at_direction="-Y",
    show_correlation_surface=correlation_surfaces[3],
)
[4]:

ZI -> ZI#

[5]:
graph.view_as_html(
    pop_faces_at_direction="-Y",
    show_correlation_surface=correlation_surfaces[1],
)
[5]:

IZ -> ZZ#

[6]:
graph.view_as_html(
    pop_faces_at_direction="-Y",
    show_correlation_surface=correlation_surfaces[2],
)
[6]:

Example Circuit#

Here we show an example circuit of logical CNOT with \(d=3\) surface code that is initialized and measured in X basis [Horsman et al.[1]]. You can download the circuit here or view it in Crumble.

[7]:
from tqec import Basis, NoiseModel, compile_block_graph

graph = cnot(Basis.X)
compiled_graph = compile_block_graph(graph)
circuit = compiled_graph.generate_stim_circuit(
    k=1, noise_model=NoiseModel.uniform_depolarizing(p=0.001)
)

Simulation#

Here we show the simulation results for all the four observables under uniform depolarizing noise model.

Click to show the full code used for simulation

from multiprocessing import cpu_count
from pathlib import Path

import matplotlib.pyplot as plt
import numpy
import sinter

from tqec.gallery.cnot import cnot
from tqec import NoiseModel
from tqec.simulation.plotting.inset import plot_observable_as_inset
from tqec.simulation.simulation import start_simulation_using_sinter
from tqec.utils.enums import Basis

SAVE_DIR = Path("results")


def generate_graphs(support_observable_basis: Basis) -> None:
    block_graph = cnot(support_observable_basis)
    zx_graph = block_graph.to_zx_graph()

    correlation_surfaces = block_graph.find_correlation_surfaces()

    stats = start_simulation_using_sinter(
        block_graph,
        range(1, 4),
        list(numpy.logspace(-4, -1, 10)),
        NoiseModel.uniform_depolarizing,
        manhattan_radius=2,
        observables=correlation_surfaces,
        num_workers=cpu_count(),
        max_shots=1_000_000,
        max_errors=5_000,
        decoders=["pymatching"],
        print_progress=True,
        save_resume_filepath=Path(
            f"../_examples_database/cnot_stats_{support_observable_basis.value}.csv"
        ),
        database_path=Path("../_examples_database/database.pkl"),
    )

    for i, stat in enumerate(stats):
        fig, ax = plt.subplots()
        sinter.plot_error_rate(
            ax=ax,
            stats=stat,
            x_func=lambda stat: stat.json_metadata["p"],
            group_func=lambda stat: stat.json_metadata["d"],
        )
        plot_observable_as_inset(ax, zx_graph, correlation_surfaces[i])
        ax.grid(axis="both")
        ax.legend()
        ax.loglog()
        ax.set_title("Logical CNOT Error Rate")
        ax.set_xlabel("Physical Error Rate")
        ax.set_ylabel("Logical Error Rate")
        fig.savefig(
            SAVE_DIR
            / f"logical_cnot_result_{support_observable_basis}_observable_{i}.png"
        )


def main():
    SAVE_DIR.mkdir(exist_ok=True)
    generate_graphs(Basis.Z)
    generate_graphs(Basis.X)


if __name__ == "__main__":
    main()

Z Basis#

[9]:
generate_graphs(Basis.Z)
../_images/gallery_cnot_18_0.svg
../_images/gallery_cnot_18_1.svg

X Basis#

[10]:
generate_graphs(Basis.X)
../_images/gallery_cnot_20_0.svg
../_images/gallery_cnot_20_1.svg

References#