loom_rotated_surface_code.code_factory.rotated_surface_code
Copyright 2024 Entropica Labs Pte Ltd
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- class loom_rotated_surface_code.code_factory.rotated_surface_code.RotatedSurfaceCode(*args, **kwargs)[source]
Bases:
BlockA sub-class of
Blockthat represents a rotated surface code block. Contains methods to create a rotated surface code block along with properties to access the block’s size, upper left qubit, stabilizers, logical operators, and other relevant information.- property all_boundary_stabilizers: tuple[Stabilizer, ...]
Return the stabilizers associated with any boundary.
- boundary_qubits(direction)[source]
Return the data qubits that are part of the specified boundary.
- Parameters:
direction (Direction | str) – Boundary (top, bottom, left, or right) for which the data qubits should be returned. If a string is provided, it is converted to a Direction enum.
- Returns:
Data qubits that are part of the specified boundary
- Return type:
list[tuple[int, …]]
- boundary_stabilizers(direction)[source]
Return the stabilizers associated with the given boundary direction.
- Return type:
tuple[Stabilizer,...]
- boundary_type(direction)[source]
Return the type of the specified boundary, either X or Z. This assumes that the block is a standard rotated surface code block which is a square block with Y charges at the four corners and X and Z charges at the boundaries.
Note that there are different conventions about when to call a boundary X or Z. We call a boundary X type if it exhibits X Pauli charges. In other words, it is of X type if the stabilizers along the boundary are Z stabilizers.
- Parameters:
direction (Direction | str) – Boundary (top, bottom, left, or right) for which the data qubits should be returned. If a string is provided, it is converted to a Direction enum.
- Returns:
Type of the boundary, either X or Z
- Return type:
str
- property bulk_stabilizers: tuple[Stabilizer, ...]
Return the stabilizers not associated with any boundary.
- property config_and_pivot_corners: tuple[int, tuple[tuple[int, int, int], ...]]
Classify the Block based on the geometry of its topological corners. Return the config and the topological corners ordered in a specific way that reflects their geometric arrangement.
- Type 1: Rectangular config
Four topological corners coincide with 4 geometric corners The list of corners is returned in the order: (top-left, bottom-left, bottom-right, top-right)
Visualized example:
1-------4 | | | | | | 2-------3
- Type 2: U-config
Block has rectangular shape with size (d, 2d-1) or (2d-1, d) Three of four topological corners coincide with three geometric corners, the last topological corner resides on the middle of the long edge whose ends occupy only one topological corner The list of corners is returned in the order: (long_end, middle_edge, angle, short_end)
Visualized example (can be rotated):
1-------| | | | 2 | | 3-------4
- Type 3: L-config
Block has rectangular shape with size (d, 2d-1) or (2d-1, d) Three of four topological corners coincide with three geometric corners, the last topological corner resides on the middle of the long edge whose ends occupy two topological corners. The list of corners is returned in the order as seen below: (long_end, middle_edge, angle, short_end)
Visualized example (can be rotated):
1-------| | | 2 | | | 3-------4
- Type 4: U-config (phase gate)
Block has rectangular shape with size (d, 2d) or (2d, d) Three of four topological corners coincide with three geometric corners, the last topological corner resides in the middle of the long edge whose ends occupy only one topological corner. Since the length of a long edge is even, there are two qubits near the middle point of the edge. Only support the case where the qubit is further away from the end occupied by a topological corner. The list of corners is returned in the order: (long_end, middle_edge, angle, short_end)
Visualized example (can be rotated):
1-------| | | | 2 | | | | 3-------4
Type 0: Other configs
- Returns:
int – The configuration type of the block.
tuple[tuple[int, int, int], …] – The list of corners in the order specified by the configuration type.
- classmethod create(dx, dz, lattice, unique_label=None, position=(0, 0), x_boundary=Orientation.HORIZONTAL, weight_2_stab_is_first_row=True, weight_4_x_schedule=None, logical_x_operator=None, logical_z_operator=None, skip_validation=False)[source]
Create a
Blockobject for a rotated surface code block. The orientation of the block (i.e. where which boundaries are) and where the weight-2 stabilizers are can be controlled with thex_boundaryandweight_2_stab_is_first_rowargument. By default, the top row and the left column are chosen as the logical operators. Their pauli string and whether they belong to the logical Z or X operator depends on the orientation of the boundaries.The coordinates used for data qubits are the following (here as an example for a d=3 rotated surface code, with
x_boundary=Orientation.Handweight_2_stab_is_first_row=True):..code-block:
Z (0,0) --- (1,0) --- (2,0) | | | X | Z | X | | | | (0,1) --- (1,1) --- (2,1) | | | | X | Z | X | | | (0,2) --- (1,2) --- (2,2) Z
- Parameters:
dx (int) – Size of the block in the horizontal direction
dz (int) – Size of the block in the vertical direction
lattice (Lattice) – Lattice on which the block is defined. The qubit indices depend on the type of lattice.
unique_label (str, optional) – Label for the block. It must be unique among all blocks in the initial Eka. If no label is provided, a unique label is generated automatically using the uuid module.
position (tuple[int, ...], optional) – Position of the top left corner of the block on the lattice, by default (0, 0)
x_boundary (Orientation, optional) – Specifies whether the X boundaries are horizontal (Orientation.HORIZONTAL), i.e. going from left to right, or vertical (Orientation.V), i.e. going from top to bottom. The X boundary is the boundary that exhibits X Pauli charges. In other words it is the boundary with 2-body Z stabilizers. By default Orientation.HORIZONTAL.
weight_2_stab_is_first_row (bool, optional) – Specifies whether the top most weight-2 stabilizer at the left boundary is in the first row (if True) or in the second row (if False), by default True
weight_4_x_schedule (FourBodySchedule, optional) – Schedule for measuring the XXXX stabilizer, by default None. If None is provided, the schedule is calculated from the orientation of the X boundary. E.g. if
x_boundaryis Orientation.HORIZONTAL, the schedule is set to FourBodySchedule.N. The default scheme is described in https://arxiv.org/abs/1404.3747 III, B. In the example above,weight_4_x_scheduleisFourBodySchedule.N, this is equivalent to measure the upper right XXXX stabilizer in the order (2,0) -> (2,1) -> (1,0) -> (1,1).logical_x_operator (PauliOperator | None, optional) – Logical X operator. If None is provided, by default the top row or the left column is chosen (depending on the orientation of the block as specified by the
x_boundaryandweight_2_stab_is_first_rowparameter)logical_z_operator (PauliOperator | None, optional) – Logical Z operator. If None is provided, by default the top row or the left column is chosen (depending on the orientation of the block as specified by the
x_boundaryandweight_2_stab_is_first_rowparameter)skip_validation (bool, optional) – Skip validation of the block object, by default False.
- Returns:
Block object for a rotated surface code block
- Return type:
- static find_padding(boundary, schedule)[source]
Finds the padding indices for the two body stabilizers. Padding indices are used to indicate empty time steps in the syndrome circuits. This allows to standardize the size of syndrome circuits for the rotated surface code.
- Parameters:
boundary (Direction) –
- Type of boundary for the surface code can be LEFT, RIGHT, TOP, or
BOTTOM
schedule (FourBodySchedule) –
- Schedule for measuring the four body stabilizers, we can deduce the two
body schedule from this.
- Returns:
Padding indices.
- Return type:
tuple[int, int]
- static generate_syndrome_circuit(pauli, padding, name)[source]
Generates a syndrome circuit for a given Pauli string. The syndrome circuits generated are all the same size, where padding indices indicate where to add empty time steps.
- Parameters:
pauli (str) – Pauli string associated the stabilizer
padding (tuple[int, int] | None) – Padding indices for the two body stabilizers. Padding indices are used to locate empty spaces in the syndrome circuits.
name (str) – Name of the syndrome circuit
- Returns:
Syndrome circuit for the Pauli string
- Return type:
- static generate_weight2_stabs(pauli, initial_position, num_stabs, orientation, is_bottom_or_right)[source]
Generate the list of all weight-2 stabilizers along one of the four boundaries. Note that the schedule for measuring the weight-4 stabilizers does not change the order in which we specify the weight-2 stabilizers. For stabilizers along the right and bottom boundaries, the stabilizers are generated differently. The stabilizers along the right and bottom boundary have the coordinates of the ancilla qubits shifted by (1, 0) and (0, 1) respectively.
- Parameters:
pauli (str) – Pauli string of the stabilizers
initial_position (tuple[int, int]) – Initial position where the chain of weight-2 stabilizers should start
num_stabs (int) – Number of weight-2 stabilizers to generate along this boundary
orientation (Orientation) – Orientation of the boundary, either HORIZONTAL or VERTICAL
is_bottom_or_right (bool) – If True, the stabilizers are along the bottom or right boundaries, this means their ancilla qubit is ‘outside’ of the block geometry. If False, the stabilizers are along the top or left boundaries.
- Returns:
List of weight-2 stabilizers along the specified boundary
- Return type:
list[Stabilizer]
- static generate_weight4_stabs(dx, dz, pauli, schedule, start_in_top_left_corner, initial_position=(0, 0))[source]
Generate the list of all weight-4 stabilizers of a rotated surface code block of the given type (= pauli string).
- Parameters:
dx (int) – Distance in the horizontal direction. If dx=3, there will be 2 weight-4 stabilizers created in the horizontal direction.
dz (int) – Distance in the vertical direction. If dz=3, there will be 2 weight-4 stabilizers created in the vertical direction.
pauli (str) – Pauli string of the stabilizers
start_in_top_left_corner (bool) – If True, the first stabilizer will start in the top left corner and then follow the alternating checkerboard pattern. If False, it will be exactly the opposite covering of the checkerboard pattern.
schedule (FourBodySchedule) – Schedule for measuring the four body stabilizers, see https://arxiv.org/abs/1404.3747, III, B. for more details.
initial_position (tuple[int, int], optional) – Initial position where the chain of weight-4 stabilizers should start, by default (0, 0)
- Returns:
List of weight-4 stabilizers of the specified type for the rotated surface code
- Return type:
list[Stabilizer]
- property geometric_corners: tuple[tuple[int, ...], ...]
Return the coordinates of the geometric corners of the block. The geometric corners that can be detected are qubits that may be the single most: - top-left qubit - top-right qubit - bottom-left qubit - bottom-right qubit - right-qubit - bottom-qubit - left-qubit - top-qubit
- get_corner_from_direction(which_corner)[source]
Get the coordinates of the qubit at the specified corner of the block.
- Return type:
tuple[int,int,int]
- get_shifted_equivalent_logical_operator(initial_operator, new_upleft_qubit)[source]
Shifts the initial operator to a valid operator in the block that contains new_upleft_qubit. NOTE: this function currently assumes that the block is a square rotated surface code block with a single logical X and Z operator.
- Parameters:
initial_operator (PauliOperator) – Initial logical operator for which the equivalent logical operator in the block should be found.
new_upleft_qubit (tuple[int, ...]) – New top left qubit of the operator in the block.
- Returns:
Equivalent logical operator in the block and the stabilizers that are required to go from the initial to the new operator.
- Return type:
tuple[PauliOperator, tuple[Stabilizer, …]]
- Raises:
NotImplementedError – If the block has more than one logical X or Z operator.
ValueError – If the new upleft qubit is not part of the data qubits of the block.
ValueError – If the initial operator is not one of the logical operators of the block.
ValueError – If the new upleft qubit is not part of the correct boundary.
ValueError – If the shift vector has more than a single non-zero dimension (ill defined logical operators to begin with).
- property is_horizontal: bool
Return True if the horizontal size is larger than the vertical size.
- property is_vertical: bool
Return True if the vertical size is larger than the horizontal size.
- property orientation: Orientation | None
Return the orientation of the block. If the block is square, return None.
- shift(position, new_label=None)[source]
Return a copy of the Block where all qubit coordinates are shifted by a given position.
- Parameters:
position (tuple[int, ...]) – Vector by which the block should be shifted
new_label (str | None, optional) – New label for the block. If None, the same label is used.
- Returns:
A new Block with the shifted qubit coordinates.
- Return type:
- property size: tuple[int, int]
Return the size of the block in the horizontal and vertical direction.
-
stabilizer_to_circuit:
dict[str,str] = FieldInfo(annotation=dict[str, str], required=False, default_factory=dict, validate_default=True)
- property stabilizers_labels: dict[str, dict[str, tuple[int, ...]]]
Builds a dictionary associating stabilizers, via their uuid, with a set of labels defined through a dictionary. Inside Block, this is generically populated with the space coordinates of the stabilizer check, corresponding to the ancilla which measures each stabilizer.
This functionality can be leveraged to later provide these labels to Syndromes and Detectors associated with a given Stabilizer.
- Returns:
Dictionary associating stabilizer uuids with their labels.
- Return type:
dict[str, dict[str, tuple[int, …]]]
-
syndrome_circuits:
tuple[SyndromeCircuit,...] = FieldInfo(annotation=tuple[SyndromeCircuit, ...], required=False, default_factory=tuple, validate_default=True)
- property topological_corners: tuple[tuple[int, ...], ...]
Return the coordinates of the topological corners of the block.
-
unique_label:
str= FieldInfo(annotation=str, required=False, default_factory=<lambda>)
- property upper_left_4body_stabilizer: Stabilizer
Return the 4-body stabilizer associated with the upper left qubit.
- property upper_left_qubit: tuple[int, ...]
Return the qubit with the smallest coordinates in the block.
-
uuid:
str= FieldInfo(annotation=str, required=False, default_factory=<lambda>, validate_default=True)
- property weight_2_stab_is_first_row: bool
Return whether the top most weight-2 stabilizer at the left boundary is in the first row.
- property weight_4_x_schedule: FourBodySchedule
Return the schedule for measuring the XXXX stabilizer.
- property weight_4_z_schedule: FourBodySchedule
Return the schedule for measuring the ZZZZ stabilizer.
- property x_boundary: Orientation
Return the orientation of the X boundary.