Note
Go to the end to download the full example code.
Move and Rotation#
This example demonstrates moving and rotating the spatial boundary of a logical qubit.
# ruff: noqa: E402
#!/usr/bin/env python
# coding: utf-8
# # Move Rotation
#
# This notebook demonstrates moving and rotating the spatial boundary of a logical
# qubit. Rotating the boundary types of a logical qubit is a crucial operation in
# lattice surgery. For instance, merging two logical qubits requires their boundary
# types to be aligned. Therefore, performing such boundary-type rotations is often
# essential to facilitate seamless lattice merging.
# ### Construction
#
# `tqec` provides the builtin function `tqec.gallery.move_rotation` to construct it.
from tqec import Basis
from tqec.gallery import move_rotation
graph = move_rotation()
graph.view_as_html()
# This operation rotates the orientation of the logical observable through a
# spatial L-shape junction. As shown below, the correlation surface initially
# aligns with the Y-axis and finally aligns with the X-axis.
correlation_surfaces = graph.find_correlation_surfaces()
graph.view_as_html(
pop_faces_at_directions=("-Y",),
show_correlation_surface=correlation_surfaces[0],
)
# ### Example Circuit
#
# Here we show an example circuit of move rotation with $d=3$ surface code that is initialized and measured in the $X$ basis. You can download the circuit :download:`here <../media/gallery/move_rotation/circuit.stim>` or view it in `Crumble <https://algassert.com/crumble#circuit=Q(0,4>`_0;Q(0,8)1;Q(0,12)2;Q(1,1)3;Q(1,3)4;Q(1,5)5;Q(1,7)6;Q(1,9)7;Q(1,11)8;Q(1,13)9;Q(2,0)10;Q(2,2)11;Q(2,4)12;Q(2,6)13;Q(2,8)14;Q(2,10)15;Q(2,12)16;Q(2,14)17;Q(3,1)18;Q(3,3)19;Q(3,5)20;Q(3,7)21;Q(3,9)22;Q(3,11)23;Q(3,13)24;Q(4,2)25;Q(4,4)26;Q(4,6)27;Q(4,8)28;Q(4,10)29;Q(4,12)30;Q(5,1)31;Q(5,3)32;Q(5,5)33;Q(5,7)34;Q(5,9)35;Q(5,11)36;Q(5,13)37;Q(6,2)38;Q(6,6)39;Q(6,10)40;Q(6,12)41;Q(6,14)42;Q(7,9)43;Q(7,11)44;Q(7,13)45;Q(8,8)46;Q(8,10)47;Q(8,12)48;Q(9,9)49;Q(9,11)50;Q(9,13)51;Q(10,10)52;Q(10,12)53;Q(10,14)54;Q(11,9)55;Q(11,11)56;Q(11,13)57;Q(12,8)58;Q(12,10)59;Q(12,12)60;Q(13,9)61;Q(13,11)62;Q(13,13)63;Q(14,12)64;RX_0_3_4_5_10_11_12_18_19_20_25_26_27_31_32_33_38;TICK;CX_12_4_25_18_27_20;CZ_11_3_26_19_38_31;TICK;CX_12_19_25_31_27_33;CZ_0_4;TICK;CX_10_3_12_5_25_19;CZ_11_4_26_20_38_32;TICK;CZ_11_18_26_32;TICK;CX_10_18_12_20_25_32;CZ_0_5_11_19_26_33;TICK;MX_0_10_11_12_25_26_27_38;DT(2,0,0)rec[-7];DT(2,4,0)rec[-5];DT(4,2,0)rec[-4];DT(4,6,0)rec[-2];TICK;RX_0_10_11_12_25_26_27_38;TICK;CX_12_4_25_18_27_20;CZ_11_3_26_19_38_31;TICK;CX_12_19_25_31_27_33;CZ_0_4;TICK;CX_10_3_12_5_25_19;CZ_11_4_26_20_38_32;TICK;CZ_11_18_26_32;TICK;CX_10_18_12_20_25_32;CZ_0_5_11_19_26_33;TICK;MX_0_10_11_12_25_26_27_38;DT(0,4,1)rec[-8]_rec[-16];DT(2,0,1)rec[-7]_rec[-15];DT(2,2,1)rec[-6]_rec[-14];DT(2,4,1)rec[-5]_rec[-13];DT(4,2,1)rec[-4]_rec[-12];DT(4,4,1)rec[-3]_rec[-11];DT(4,6,1)rec[-2]_rec[-10];DT(6,2,1)rec[-1]_rec[-9];TICK;RX_0_10_11_12_25_26_27_38;TICK;CX_12_4_25_18_27_20;CZ_11_3_26_19_38_31;TICK;CX_12_19_25_31_27_33;CZ_0_4;TICK;CX_10_3_12_5_25_19;CZ_11_4_26_20_38_32;TICK;CZ_11_18_26_32;TICK;CX_10_18_12_20_25_32;CZ_0_5_11_19_26_33;TICK;MX_0_10_11_12_25_26_27_38;DT(0,4,2)rec[-8]_rec[-16];DT(2,0,2)rec[-7]_rec[-15];DT(2,2,2)rec[-6]_rec[-14];DT(2,4,2)rec[-5]_rec[-13];DT(4,2,2)rec[-4]_rec[-12];DT(4,4,2)rec[-3]_rec[-11];DT(4,6,2)rec[-2]_rec[-10];DT(6,2,2)rec[-1]_rec[-9];TICK;RX_0_1_2_6_7_8_9_10_11_12_13_14_15_16_17_21_22_23_24_25_26_27_28_29_30_34_35_36_37_38_39_40_41_42_43_44_45_46_47_48_49_50_51_52_53_54_55_56_57_58_59_60_61_62_63_64;TICK;CX_12_4_14_6_16_8_25_18_27_20_29_22_41_36_47_43_53_50_59_55_64_62;CZ_11_3_13_5_15_7_17_9_26_19_28_21_30_23_38_31_39_33_40_35_42_37_48_44_52_49_54_51_60_56;TICK;CX_12_19_14_21_25_31_27_33_29_35;CZ_0_4_1_6_2_8_17_24_30_36_40_43_42_45_48_50_52_55_54_57_60_62;TICK;CX_10_3_12_5_14_7_16_9_25_19_27_21_29_23_41_37_47_44_53_51_59_56_64_63;CZ_11_4_13_6_15_8_26_20_28_22_30_24_38_32_39_34_40_36_46_43_48_45_52_50_58_55_60_57;TICK;CX_16_23_41_44_47_49_53_56_59_61;CZ_11_18_13_20_15_22_26_32_28_34;TICK;CX_10_18_12_20_14_22_16_24_25_32_27_34_29_36_41_45_47_50_53_57_59_62;CZ_0_5_1_7_2_9_11_19_13_21_15_23_26_33_28_35_30_37_40_44_46_49_48_51_52_56_58_61_60_63;TICK;MX_0_1_2_10_11_12_13_14_15_16_17_25_26_27_28_29_30_38_39_40_41_42_46_47_48_52_53_54_58_59_60_64;DT(0,4,3)rec[-32]_rec[-40];DT(2,0,3)rec[-29]_rec[-39];DT(2,2,3)rec[-28]_rec[-38];DT(2,4,3)rec[-27]_rec[-37];DT(2,8,3)rec[-25];DT(2,12,3)rec[-23];DT(4,2,3)rec[-21]_rec[-36];DT(4,4,3)rec[-20]_rec[-35];DT(4,6,3)rec[-19]_rec[-34];DT(4,10,3)rec[-17];DT(6,2,3)rec[-15]_rec[-33];DT(6,12,3)rec[-12];DT(8,10,3)rec[-9];DT(10,12,3)rec[-6];DT(12,10,3)rec[-3];DT(14,12,3)rec[-1];TICK;RX_0_1_2_10_11_12_13_14_15_16_17_25_26_27_28_29_30_38_39_40_41_42_46_47_48_52_53_54_58_59_60_64;TICK;CX_12_4_14_6_16_8_25_18_27_20_29_22_41_36_47_43_53_50_59_55_64_62;CZ_11_3_13_5_15_7_17_9_26_19_28_21_30_23_38_31_39_33_40_35_42_37_48_44_52_49_54_51_60_56;TICK;CX_12_19_14_21_25_31_27_33_29_35;CZ_0_4_1_6_2_8_17_24_30_36_40_43_42_45_48_50_52_55_54_57_60_62;TICK;CX_10_3_12_5_14_7_16_9_25_19_27_21_29_23_41_37_47_44_53_51_59_56_64_63;CZ_11_4_13_6_15_8_26_20_28_22_30_24_38_32_39_34_40_36_46_43_48_45_52_50_58_55_60_57;TICK;CX_16_23_41_44_47_49_53_56_59_61;CZ_11_18_13_20_15_22_26_32_28_34;TICK;CX_10_18_12_20_14_22_16_24_25_32_27_34_29_36_41_45_47_50_53_57_59_62;CZ_0_5_1_7_2_9_11_19_13_21_15_23_26_33_28_35_30_37_40_44_46_49_48_51_52_56_58_61_60_63;TICK;MX_0_1_2_10_11_12_13_14_15_16_17_25_26_27_28_29_30_38_39_40_41_42_46_47_48_52_53_54_58_59_60_64;DT(0,4,4)rec[-32]_rec[-64];DT(0,8,4)rec[-31]_rec[-63];DT(0,12,4)rec[-30]_rec[-62];DT(2,0,4)rec[-29]_rec[-61];DT(2,2,4)rec[-28]_rec[-60];DT(2,4,4)rec[-27]_rec[-59];DT(2,6,4)rec[-26]_rec[-58];DT(2,8,4)rec[-25]_rec[-57];DT(2,10,4)rec[-24]_rec[-56];DT(2,12,4)rec[-23]_rec[-55];DT(2,14,4)rec[-22]_rec[-54];DT(4,2,4)rec[-21]_rec[-53];DT(4,4,4)rec[-20]_rec[-52];DT(4,6,4)rec[-19]_rec[-51];DT(4,8,4)rec[-18]_rec[-50];DT(4,10,4)rec[-17]_rec[-49];DT(4,12,4)rec[-16]_rec[-48];DT(6,2,4)rec[-15]_rec[-47];DT(6,6,4)rec[-14]_rec[-46];DT(6,10,4)rec[-13]_rec[-45];DT(6,12,4)rec[-12]_rec[-44];DT(6,14,4)rec[-11]_rec[-43];DT(8,8,4)rec[-10]_rec[-42];DT(8,10,4)rec[-9]_rec[-41];DT(8,12,4)rec[-8]_rec[-40];DT(10,10,4)rec[-7]_rec[-39];DT(10,12,4)rec[-6]_rec[-38];DT(10,14,4)rec[-5]_rec[-37];DT(12,8,4)rec[-4]_rec[-36];DT(12,10,4)rec[-3]_rec[-35];DT(12,12,4)rec[-2]_rec[-34];DT(14,12,4)rec[-1]_rec[-33];TICK;RX_0_1_2_10_11_12_13_14_15_16_17_25_26_27_28_29_30_38_39_40_41_42_46_47_48_52_53_54_58_59_60_64;TICK;CX_12_4_14_6_16_8_25_18_27_20_29_22_41_36_47_43_53_50_59_55_64_62;CZ_11_3_13_5_15_7_17_9_26_19_28_21_30_23_38_31_39_33_40_35_42_37_48_44_52_49_54_51_60_56;TICK;CX_12_19_14_21_25_31_27_33_29_35;CZ_0_4_1_6_2_8_17_24_30_36_40_43_42_45_48_50_52_55_54_57_60_62;TICK;CX_10_3_12_5_14_7_16_9_25_19_27_21_29_23_41_37_47_44_53_51_59_56_64_63;CZ_11_4_13_6_15_8_26_20_28_22_30_24_38_32_39_34_40_36_46_43_48_45_52_50_58_55_60_57;TICK;CX_16_23_41_44_47_49_53_56_59_61;CZ_11_18_13_20_15_22_26_32_28_34;TICK;CX_10_18_12_20_14_22_16_24_25_32_27_34_29_36_41_45_47_50_53_57_59_62;CZ_0_5_1_7_2_9_11_19_13_21_15_23_26_33_28_35_30_37_40_44_46_49_48_51_52_56_58_61_60_63;TICK;MX_0_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39_40_41_42_43_44_45_46_47_48_52_53_54_58_59_60_64;DT(0,4,5)rec[-56]_rec[-88];DT(0,8,5)rec[-55]_rec[-87];DT(0,12,5)rec[-54]_rec[-86];DT(2,0,5)rec[-46]_rec[-85];DT(2,2,5)rec[-45]_rec[-84];DT(2,4,5)rec[-44]_rec[-83];DT(2,6,5)rec[-43]_rec[-82];DT(2,8,5)rec[-42]_rec[-81];DT(2,10,5)rec[-41]_rec[-80];DT(2,12,5)rec[-40]_rec[-79];DT(2,14,5)rec[-39]_rec[-78];DT(3,1,5)rec[-38]_rec[-46]_rec[-53];DT(3,5,5)rec[-36]_rec[-37]_rec[-44]_rec[-51]_rec[-52];DT(3,9,5)rec[-34]_rec[-35]_rec[-42]_rec[-49]_rec[-50];DT(1,11,5)rec[-32]_rec[-33]_rec[-40]_rec[-47]_rec[-48];DT(4,2,5)rec[-31]_rec[-77];DT(4,4,5)rec[-30]_rec[-76];DT(4,6,5)rec[-29]_rec[-75];DT(4,8,5)rec[-28]_rec[-74];DT(4,10,5)rec[-27]_rec[-73];DT(4,12,5)rec[-26]_rec[-72];DT(5,3,5)rec[-24]_rec[-25]_rec[-31]_rec[-37]_rec[-38];DT(5,5,5)rec[-22]_rec[-23]_rec[-29]_rec[-35]_rec[-36];DT(3,11,5)rec[-20]_rec[-21]_rec[-27]_rec[-33]_rec[-34];DT(6,2,5)rec[-18]_rec[-71];DT(6,6,5)rec[-17]_rec[-70];DT(6,10,5)rec[-16]_rec[-69];DT(6,12,5)rec[-15]_rec[-68];DT(6,14,5)rec[-14]_rec[-67];DT(5,11,5)rec[-11]_rec[-12]_rec[-15]_rec[-19]_rec[-20];DT(8,8,5)rec[-10]_rec[-66];DT(8,10,5)rec[-9]_rec[-65];DT(8,12,5)rec[-8]_rec[-64];DT(10,10,5)rec[-7]_rec[-63];DT(10,12,5)rec[-6]_rec[-62];DT(10,14,5)rec[-5]_rec[-61];DT(12,8,5)rec[-4]_rec[-60];DT(12,10,5)rec[-3]_rec[-59];DT(12,12,5)rec[-2]_rec[-58];DT(14,12,5)rec[-1]_rec[-57];TICK;RX_47_52_53_54_58_59_60_64;TICK;CX_53_50_59_55_64_62;CZ_52_49_54_51_60_56;TICK;CX_47_49;CZ_52_55_54_57_60_62;TICK;CX_53_51_59_56_64_63;CZ_52_50_58_55_60_57;TICK;CX_53_56_59_61;TICK;CX_47_50_53_57_59_62;CZ_52_56_58_61_60_63;TICK;MX_47_52_53_54_58_59_60_64;DT(8,10,6)rec[-8]_rec[-17]_rec[-20]_rec[-21];DT(10,10,6)rec[-7]_rec[-15];DT(10,12,6)rec[-6]_rec[-14];DT(10,14,6)rec[-5]_rec[-13];DT(12,8,6)rec[-4]_rec[-12];DT(12,10,6)rec[-3]_rec[-11];DT(12,12,6)rec[-2]_rec[-10];DT(14,12,6)rec[-1]_rec[-9];TICK;RX_47_52_53_54_58_59_60_64;TICK;CX_53_50_59_55_64_62;CZ_52_49_54_51_60_56;TICK;CX_47_49;CZ_52_55_54_57_60_62;TICK;CX_53_51_59_56_64_63;CZ_52_50_58_55_60_57;TICK;CX_53_56_59_61;TICK;CX_47_50_53_57_59_62;CZ_52_56_58_61_60_63;TICK;MX_47_52_53_54_58_59_60_64;DT(8,10,7)rec[-8]_rec[-16];DT(10,10,7)rec[-7]_rec[-15];DT(10,12,7)rec[-6]_rec[-14];DT(10,14,7)rec[-5]_rec[-13];DT(12,8,7)rec[-4]_rec[-12];DT(12,10,7)rec[-3]_rec[-11];DT(12,12,7)rec[-2]_rec[-10];DT(14,12,7)rec[-1]_rec[-9];TICK;RX_47_52_53_54_58_59_60_64;TICK;CX_53_50_59_55_64_62;CZ_52_49_54_51_60_56;TICK;CX_47_49;CZ_52_55_54_57_60_62;TICK;CX_53_51_59_56_64_63;CZ_52_50_58_55_60_57;TICK;CX_53_56_59_61;TICK;CX_47_50_53_57_59_62;CZ_52_56_58_61_60_63;TICK;MX_47_49_50_51_52_53_54_55_56_57_58_59_60_61_62_63_64;DT(8,10,8)rec[-17]_rec[-25];DT(9,9,8)rec[-15]_rec[-16]_rec[-17];DT(10,10,8)rec[-13]_rec[-24];DT(10,12,8)rec[-12]_rec[-23];DT(10,14,8)rec[-11]_rec[-22];DT(11,13,8)rec[-8]_rec[-9]_rec[-12]_rec[-14]_rec[-15];DT(12,8,8)rec[-7]_rec[-21];DT(12,10,8)rec[-6]_rec[-20];DT(12,12,8)rec[-5]_rec[-19];DT(13,9,8)rec[-3]_rec[-4]_rec[-6]_rec[-9]_rec[-10];DT(13,11,8)rec[-1]_rec[-2]_rec[-3];DT(14,12,8)rec[-1]_rec[-18];OI(0)rec[-3]_rec[-9]_rec[-15]_rec[-45]_rec[-53]_rec[-66]_rec[-67]_rec[-68]_rec[-69]_rec[-70]_rec[-71]). # noqa: E501
from tqec import NoiseModel, compile_block_graph
graph = move_rotation(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 of both $X$-basis and $Z$-basis
# experiments under a **uniform depolarizing** noise model.
#
# <details><summary>Click to show the full code used for simulation</summary>
#
# ```py
# from multiprocessing import cpu_count
# from pathlib import Path
#
# import matplotlib.pyplot as plt
# import numpy
# import sinter
#
# from tqec.gallery.memory import memory
# from tqec.gallery.move_rotation import move_rotation
# 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 = move_rotation(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/move_rotation_stats_{support_observable_basis.value}.csv"
# ),
# database_path=Path("../_examples_database/database.pkl"),
# )
#
# for i, stat in enumerate(stats):
# _, 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("Move Rotation Error Rate")
# ax.set_xlabel("Physical Error Rate")
# ax.set_ylabel("Logical Error Rate(per round)")
# fig.savefig(
# SAVE_DIR
# / f"move_rotation_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()
#
#
# ```
#
# </details>
#
from multiprocessing import cpu_count
from pathlib import Path
import matplotlib.pyplot as plt
import numpy
import sinter
from tqec import NoiseModel
from tqec.gallery.move_rotation import move_rotation
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
def generate_graphs(support_observable_basis: Basis) -> None:
"""Generate the logical error-rate graphs corresponding to the provided basis."""
block_graph = move_rotation(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"],
# 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/move_rotation_stats_{support_observable_basis.value}.csv"
),
database_path=Path("../_examples_database/database.pkl"),
)
for i, stat in enumerate(stats):
_, 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("Move Rotation Error Rate")
ax.set_xlabel("Physical Error Rate")
ax.set_ylabel("Logical Error Rate(per round)")
# #### Z Basis
generate_graphs(Basis.Z)
# #### X Basis

generate_graphs(Basis.X)

Total running time of the script: (1 minutes 45.910 seconds)