Three CNOTs#
This notebook shows the construction and simulation results of three logical CNOT gates between three logical qubits with lattice surgery [Horsman et al.[1]].
Construction#
The three CNOT gates are applied in the following order:
tqec
provides builtin functions tqec.gallery.three_cnots
to construct three logical CNOT gates compressed in spacetime.
[1]:
from tqec.gallery import three_cnots
graph = three_cnots()
graph.view_as_html()
[1]:
The three logical CNOTs has six independent stabilizer flow generators: XXI -> XIX
, IXI -> IXX
, IIX -> IIX
, ZII -> ZII
, ZZI -> IZI
, IZZ -> IIZ
. Here we show the correlation surfaces for the generators.
[2]:
correlation_surfaces = graph.find_correlation_surfaces()
XXI -> XIX
#
[3]:
graph.view_as_html(
pop_faces_at_direction="-Y",
show_correlation_surface=correlation_surfaces[0],
)
[3]:
IXI -> IXX
#
[4]:
graph.view_as_html(
pop_faces_at_direction="-Y",
show_correlation_surface=correlation_surfaces[4],
)
[4]:
IIX -> IIX
#
[5]:
graph.view_as_html(
pop_faces_at_direction="-Y",
show_correlation_surface=correlation_surfaces[5],
)
[5]:
ZII -> ZII
#
[6]:
graph.view_as_html(
pop_faces_at_direction="+Z",
show_correlation_surface=correlation_surfaces[1],
)
[6]:
ZZI -> IZI
#
[7]:
graph.view_as_html(
pop_faces_at_direction="+X",
show_correlation_surface=correlation_surfaces[2],
)
[7]:
IZZ -> IIZ
#
[8]:
graph.view_as_html(
pop_faces_at_direction="+X",
show_correlation_surface=correlation_surfaces[3],
)
[8]:
Example Circuit#
Here we show an example circuit of three logical CNOTs with \(d=3\) surface code that is initialized and measured in X basis. You can download the circuit here or view it in Crumble.
[9]:
from tqec import Basis, NoiseModel, compile_block_graph
graph = three_cnots(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 six 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 import three_cnots
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 = three_cnots(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,
# note that save_resume_filepath and database_path can help reduce the time taken
# by the simulation after the database and result statistics have been saved to
# the chosen path
save_resume_filepath=Path(
f"../_examples_database/three_cnots_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"],
failure_units_per_shot_func=lambda stat: stat.json_metadata["d"],
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("Three CNOTs Error Rate")
ax.set_xlabel("Physical Error Rate")
ax.set_ylabel("Logical Error Rate(per round)")
fig.savefig(
SAVE_DIR
/ f"three_cnots_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#
[11]:
generate_graphs(Basis.Z)
X Basis#
[12]:
generate_graphs(Basis.X)