Source code for surface_sim.log_gates.util

from ..layouts.layout import Layout
from ..layouts.operations import check_overlap_layouts


[docs] def set_x(layout: Layout) -> None: """Adds the required attributes (in place) for the layout to run the Pauli X gate for the unrotated surface code. Parameters ---------- layout The layout in which to add the attributes. """ if len(layout.logical_qubits) != 1: raise ValueError( "The given surface code does not have a logical qubit, " f"it has {len(layout.logical_qubits)}." ) data_qubits = layout.data_qubits anc_qubits = layout.anc_qubits log_qubit_label = layout.logical_qubits[0] gate_label = f"log_x_{log_qubit_label}" x_gates = {q: "I" for q in data_qubits} for q in layout.logical_param("log_x", log_qubit_label): x_gates[q] = "X" # Store logical gate information to the data qubits for qubit in data_qubits: layout.set_param(gate_label, qubit, {"local": x_gates[qubit]}) # Store new stabilizer generators to the ancilla qubits for anc_qubit in anc_qubits: layout.set_param( gate_label, anc_qubit, {"new_stab_gen": [anc_qubit], "new_stab_gen_inv": [anc_qubit]}, ) return
[docs] def set_z(layout: Layout) -> None: """Adds the required attributes (in place) for the layout to run the Pauli Z gate for the unrotated surface code. Parameters ---------- layout The layout in which to add the attributes. """ if len(layout.logical_qubits) != 1: raise ValueError( "The given surface code does not have a logical qubit, " f"it has {len(layout.logical_qubits)}." ) data_qubits = layout.data_qubits anc_qubits = layout.anc_qubits log_qubit_label = layout.logical_qubits[0] gate_label = f"log_z_{log_qubit_label}" z_gates = {q: "I" for q in data_qubits} for q in layout.logical_param("log_z", log_qubit_label): z_gates[q] = "Z" # Store logical gate information to the data qubits for qubit in data_qubits: layout.set_param(gate_label, qubit, {"local": z_gates[qubit]}) # Store new stabilizer generators to the ancilla qubits for anc_qubit in anc_qubits: layout.set_param( gate_label, anc_qubit, {"new_stab_gen": [anc_qubit], "new_stab_gen_inv": [anc_qubit]}, ) return
[docs] def set_idle(layout: Layout) -> None: """Adds the required attributes (in place) for the layout to run the Pauli I gate for codes with just one logical qubit. Parameters ---------- layout The layout in which to add the attributes. """ if len(layout.logical_qubits) != 1: raise ValueError( "The given surface code does not have a logical qubit, " f"it has {len(layout.logical_qubits)}." ) data_qubits = layout.data_qubits anc_qubits = layout.anc_qubits log_qubit_label = layout.logical_qubits[0] gate_label = f"idle_{log_qubit_label}" # Store logical gate information to the data qubits for qubit in data_qubits: layout.set_param(gate_label, qubit, {"local": "I"}) # Store new stabilizer generators to the ancilla qubits for anc_qubit in anc_qubits: layout.set_param( gate_label, anc_qubit, {"new_stab_gen": [anc_qubit], "new_stab_gen_inv": [anc_qubit]}, ) return
[docs] def set_trans_cnot(layout_c: Layout, layout_t: Layout) -> None: """Adds the required attributes (in place) for the layout to run the transversal CNOT gate for the unrotated surface code. Parameters ---------- layout_c The layout for the control of the CNOT for which to add the attributes. layout_t The layout for the target of the CNOT for which to add the attributes. """ if (layout_c.code not in ["unrotated_surface_code", "rotated_surface_code"]) or ( layout_t.code not in ["unrotated_surface_code", "rotated_surface_code"] ): raise ValueError( "This function is for unrotated and rotated surface codes, " f"but layouts for {layout_t.code} and {layout_c.code} were given." ) if (layout_c.distance_x != layout_t.distance_x) or ( layout_c.distance_z != layout_t.distance_z ): raise ValueError("This function requires two surface codes of the same size.") check_overlap_layouts(layout_c, layout_t) gate_label = ( f"log_trans_cnot_{layout_c.logical_qubits[0]}_{layout_t.logical_qubits[0]}" ) qubit_coords_c = layout_c.qubit_coords qubit_coords_t = layout_t.qubit_coords bottom_left_qubit_c = sorted( qubit_coords_c.items(), key=lambda x: 999_999_999 * x[1][0] + x[1][1] ) bottom_left_qubit_t = sorted( qubit_coords_t.items(), key=lambda x: 999_999_999 * x[1][0] + x[1][1] ) mapping_t_to_c = {} mapping_c_to_t = {} for (qc, _), (qt, _) in zip(bottom_left_qubit_c, bottom_left_qubit_t): mapping_t_to_c[qt] = qc mapping_c_to_t[qc] = qt # Store the logical information for the data qubits data_qubits_c = set(layout_c.data_qubits) data_qubits_t = set(layout_t.data_qubits) for qubit in data_qubits_c: layout_c.set_param( gate_label, qubit, {"cz": mapping_c_to_t[qubit], "local": "I"} ) for qubit in data_qubits_t: layout_t.set_param( gate_label, qubit, {"cz": mapping_t_to_c[qubit], "local": "H"} ) # Compute the new stabilizer generators based on the CNOT connections anc_to_new_stab = {} for anc in layout_c.get_qubits(role="anc", stab_type="z_type"): anc_to_new_stab[anc] = [anc] for anc in layout_c.get_qubits(role="anc", stab_type="x_type"): anc_to_new_stab[anc] = [anc, mapping_c_to_t[anc]] for anc in layout_t.get_qubits(role="anc", stab_type="z_type"): anc_to_new_stab[anc] = [anc, mapping_t_to_c[anc]] for anc in layout_t.get_qubits(role="anc", stab_type="x_type"): anc_to_new_stab[anc] = [anc] # Store new stabilizer generators to the ancilla qubits # CNOT^\dagger = CNOT for anc in layout_c.anc_qubits: layout_c.set_param( gate_label, anc, { "new_stab_gen": anc_to_new_stab[anc], "new_stab_gen_inv": anc_to_new_stab[anc], }, ) for anc in layout_t.anc_qubits: layout_t.set_param( gate_label, anc, { "new_stab_gen": anc_to_new_stab[anc], "new_stab_gen_inv": anc_to_new_stab[anc], }, ) return