Logical 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:
\(M_{ZZ}\) parity measurement between \(Q_{control}\) and \(Q_{ancilla}\).
\(M_{XX}\) parity measurement between \(Q_{target}\) and \(Q_{ancilla}\).
\(M_{Z}\) measurement of \(Q_{ancilla}\).
tqec
provides builtin functions tqec.gallery.logical_cnot_block_graph
to construct the logical CNOT gate.
[7]:
from tqec.gallery import logical_cnot_block_graph
graph = logical_cnot_block_graph(support_observable_basis="BOTH")
graph.view_as_html()
[7]:
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.
[8]:
from tqec import SignedDirection3D, Direction3D
correlation_surfaces = graph.to_zx_graph().find_correlation_surfaces()
XI -> XX
#
[9]:
graph.view_as_html(
pop_faces_at_direction=SignedDirection3D(Direction3D.Y, False),
show_correlation_surface=correlation_surfaces[1],
)
[9]:
IX -> IX
#
[10]:
graph.view_as_html(
pop_faces_at_direction=SignedDirection3D(Direction3D.Y, False),
show_correlation_surface=correlation_surfaces[5],
)
[10]:
ZI -> ZI
#
[11]:
graph.view_as_html(
pop_faces_at_direction=SignedDirection3D(Direction3D.Y, False),
show_correlation_surface=correlation_surfaces[2],
)
[11]:
IZ -> ZZ
#
[12]:
graph.view_as_html(
pop_faces_at_direction=SignedDirection3D(Direction3D.Y, False),
show_correlation_surface=correlation_surfaces[4],
)
[12]:
Example Circuit#
Here we show an example circuit of logical CNOT with \(d=3\) CSS-type surface code. The annotated logical observable corresponds to XI -> XX
stabilizer flow. You can download the circuit here or view it in
Crumble.
[17]:
from tqec import compile_block_graph, NoiseModel
graph = logical_cnot_block_graph(support_observable_basis="X")
correlation_surfaces = graph.find_correlation_surfaces()
compiled_graph = compile_block_graph(graph, observables=[correlation_surfaces[1]])
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 stabilizer flow generators as well as XX -> XI
and ZZ -> IZ
. The simulated surface code is CSS type and the noise model is uniform depolarizing.
Click to show the full code used for simulation
from pathlib import Path
from typing import Literal
import matplotlib.pyplot as plt
import numpy
import sinter
from tqec.gallery.logical_cnot import logical_cnot_block_graph
from tqec.noise_model import NoiseModel
from tqec.simulation.plotting.inset import plot_observable_as_inset
from tqec.simulation.simulation import start_simulation_using_sinter
SAVE_DIR = Path("results")
def generate_graphs(support_observable_basis: Literal["Z", "X"]) -> None:
block_graph = logical_cnot_block_graph(support_observable_basis)
zx_graph = block_graph.to_zx_graph()
correlation_surfaces = 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=20,
max_shots=10_000_000,
max_errors=5_000,
decoders=["pymatching"],
print_progress=True,
)
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("Z")
generate_graphs("X")
if __name__ == "__main__":
main()
XI -> XX
#
![XIXX](../_images/XIXX.png)
IX -> IX
#
![IXIX](../_images/IXIX.png)
XX -> XI
#
![XXXI](../_images/XXXI.png)
ZI -> ZI
#
![ZIZI](../_images/ZIZI.png)
IZ -> ZZ
#
![IZZZ](../_images/IZZZ.png)
ZZ -> IZ
#
![ZZIZ](../_images/ZZIZ.png)
References#
Horsman, D., Fowler, A. G., Devitt, S., & Van Meter, R. (2012). Surface code quantum computing by lattice surgery. New Journal of Physics, 14(12), 123011.