loom_rotated_surface_code.applicator.move_corners

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.

loom_rotated_surface_code.applicator.move_corners.cut_corner_stabilizer(block, corner_qubit)[source]

Create a new 3-body stabilizer by cutting the corner qubit from initial 4-body stabilizer.

Parameters:
  • block (RotatedSurfaceCode) – Initial block

  • corner_qubit (tuple[int, int, int]) – Corner qubit that is cut

Returns:

New stabilizer with the corner qubit cut

Return type:

Stabilizer

loom_rotated_surface_code.applicator.move_corners.cut_corner_syndrome_circuit(block, cut_stabilizer, corner_qubit, which_corner)[source]

Cut the corner qubit from the syndrome circuit that measures the stabilizer to cut. Note that the name of the SyndromeCircuit is always vertical_dir-horizontal_dir-pauli.

Parameters:
  • block (RotatedSurfaceCode) – Initial block

  • cut_stabilizer (Stabilizer) – Stabilizer with the corner qubit cut out

  • corner_qubit (tuple[int, int, int]) – Corner qubit to cut

  • which_corner (tuple[Direction, Direction]) – Position of the corner qubit to cut

Returns:

Syndrome circuit with the corner qubit cut

Return type:

SyndromeCircuit

loom_rotated_surface_code.applicator.move_corners.find_new_boundary_direction(corner_boundaries, move_direction)[source]

Find the modified boundary direction that corresponds to moving the corner in the specified direction. E.g. moving the top left corner towards the right modifies the top boundary.

Parameters:
  • corner_boundaries (tuple[Direction, ...]) – Description of the corner in terms of the geometric directions. E.g. (TOP, LEFT) describes the top left corner. A topological corner can be included in a single boundary or two boundaries.

  • move_direction (Direction) – Direction in which to move the corner

Returns:

Direction of the boundary that will be modified

Return type:

Direction

loom_rotated_surface_code.applicator.move_corners.find_new_boundary_stabilizers(block, corner_qubit, modified_boundary_direction, unit_vector, how_far, two_body_is_included)[source]

Finds the stabilizers of the new modified boundary after moving the corner. Some stabilizers of the old boundary are not modified and returned as well. If a 2-body stabilizer is involved in the selected corner and the modified boundary, the corner stabilizer is cut and the stabilizer that is moved is returned. It returns, the kept boundaries stabilizers, the newly created ones, the cut bulk stabilizer and the stabilizer evolution.

Parameters:
  • block (RotatedSurfaceCode) – Initial block

  • corner_qubit (tuple[int, int, int]) – Corner qubit to move

  • modified_boundary_direction (Direction) – Direction of the modified boundary

  • unit_vector (tuple[int, int]) – Unit vector describing the movement of the corner

  • how_far (int) – Distance by which to move the corner

  • two_body_is_included (bool) – Is there a two-body stabilizer involved in the corner and the modified boundary in the direction of movement.

Returns:

Kept boundaries stabilizers, new boundary stabilizers, cut stabilizer, stabilizer evolution.

Return type:

tuple[list[Stabilizer], list[Stabilizer], Stabilizer | None, dict[str, str]]

Raises:

ValueError – If the distance is not odd when a 2-body stabilizer is involved or if the distance is not even when there is no 2-body stabilizer involved.

loom_rotated_surface_code.applicator.move_corners.generate_updated_2_body_stabilizers(old_corner_qubit, new_boundary_direction, unit_vector, how_far, pauli_type)[source]

Generate the new boundary stabilizers that are created when moving the corner.

Parameters:
  • old_corner_qubit (tuple[int, int, int]) – Old corner qubit

  • new_boundary_direction (Direction) – Direction of the modified boundary

  • unit_vector (tuple[int, int]) – Unit vector of the movement

  • how_far (int) – Distance by which the corner is moved

  • pauli_type (str) – Pauli type of the new stabilizers

Returns:

List of new stabilizers

Return type:

list[Stabilizer]

loom_rotated_surface_code.applicator.move_corners.get_associated_boundaries(block, corner_qubit)[source]

Get the boundary direction(s) associated with the corner qubit

Parameters:
  • block (RotatedSurfaceCode) – Block of rotated surface code

  • corner_qubit (tuple[int, int, int]) – Corner qubit

Returns:

Boundary direction(s) associated with the corner qubit

Return type:

tuple[Direction, …]

Raises:

ValueError – If the corner given is not a topological corner of the rotated surface code block, i.e. the product of stabilizers at this point is not Y.

loom_rotated_surface_code.applicator.move_corners.is_2_body_included(block, corner_qubit, boundary)[source]

Check if the corner qubit is included in a 2-body stabilizer that is part of the chosen boundary.

Parameters:
  • block (RotatedSurfaceCode) – Initial block

  • corner_qubit (tuple[int, int, int]) – Corner qubit to check

  • boundary (Direction) – Boundary to check

Returns:

True if the corner qubit is included in a 2-body stabilizer that is part of the chosen boundary. False otherwise.

Return type:

bool

loom_rotated_surface_code.applicator.move_corners.move_corner(interpretation_step, block, corner_qubit, move_direction, how_far)[source]

Move the selected topological corner of the block in the specified direction. We assume that the initial state is a RotatedSurfaceCode with a single logical qubit and the topological corners are located at the geometric corners.

The algorithm is the following:

  • A.) STABILIZERS

    • A.1) Cut the corner stabilizer if a 2-body stabilizer is involved

    • A.2) Generate the two-body stabilizers to be added

    • A.3) Find which stabilizers are untouched on the modified boundary

    • A.4) Compute the evolution of the stabilizers

    • A.5) Construct the set of kept bulk stabilizers

    • A.6) Construct the new set of stabilizers

  • B.) LOGICAL OPERATORS

    • B.1) Move the logical operators so they stay on the right boundary or

      extend/contract them

    • B.2) Update the logical operators

    • B.3) Collect the necessary stabilizers for logical operator updates

  • C.) SYNDROME CIRCUITS

    • C.1) Find corner configuration of new block

    • C.2) Generate new syndrome circuits and stabilizer schedules based on corner

      config

    • C.3) Update stabilizer evolution

  • D.) CIRCUIT

    • D.1) Measure the corner if needed

    • D.2) Create stabilizer and logical operator updates

  • E.) BUILD BLOCK

Parameters:
  • interpretation_step (InterpretationStep) – The interpretation step before moving the corner

  • block (RotatedSurfaceCode) – The initial block

  • corner_qubit (tuple[int, int, int],) – Corner to move

  • move_direction (Direction) – Direction in which to move the corner

  • how_far (int) – Distance by which to move the corner

Return type:

tuple[InterpretationStep, tuple[tuple[Stabilizer, ...], tuple[Stabilizer, ...]], tuple[tuple[Stabilizer, ...], tuple[Stabilizer, ...]]]

Returns:

  • tuple[ – InterpretationStep, tuple[tuple[Stabilizer, …], tuple[Stabilizer, …]], tuple[tuple[Stabilizer, …], tuple[Stabilizer, …]],

  • ]

    The interpretation step after moving the corner, the set of X and Z stabilizers

    removed during the move that are required for logical updates and the set of X and Z stabilizers added during the move that are required for logical updates.

loom_rotated_surface_code.applicator.move_corners.move_corner_circuit(interpretation_step, block, corner_qubit, cut_stabilizer, move_direction, how_far)[source]

Create the circuit that measures out the corner if needed. Returns the measurement circuit and the cbit that contains the measurement of the corner or None if the corner isn’t cut.

Parameters:
  • interpretation_step (InterpretationStep) – Interpretation step before moving the corner

  • block (RotatedSurfaceCode) – The initial block

  • corner_qubit (tuple[int, int, int],) – Corner to move

  • cut_stabilizer (Stabilizer | None) – Stabilizer after being cut (only if a 2-body is involved in the movement, else None)

  • move_direction (Direction) – Direction in which to move the corner

  • how_far (int) – Distance by which to move the corner

Returns:

Circuit measuring the corner qubit and Cbit that contains the corner measurement or None if the corner isn’t cut.

Return type:

tuple[Circuit, Cbit] | None

loom_rotated_surface_code.applicator.move_corners.move_corner_logical_operators(block, corner_qubit, unit_vector, how_far, old_stabs_to_be_removed, new_stabs_to_be_added)[source]

Modify the logical operators of the block after moving the corner. There is no guarantee that the distance of the block is preserved after moving the corners, therefore no guarantee on the length of the operators. Note that the logical operator is not modified if the movement does not affect the commutation properties, it may not be of minimal weight anymore. The distance of the code may not be preserved.

Parameters:
  • block (RotatedSurfaceCode) – Initial block

  • corner_qubit (tuple[int, int, int]) – Corner qubit to move

  • unit_vector (tuple[int, int]) – Unit vector describing the movement of the corner

  • how_far (int) – Distance by which to move the corner

  • old_stabs_to_be_removed (list[Stabilizer]) – Stabilizers that are removed by the corner movement.

  • new_stabs_to_be_added (list[Stabilizer]) – Stabilizers that are added by the corner movement.

Returns:

New logical X operator, new logical Z operator, logical X evolution dictionary, logical Z evolution dictionary.

Return type:

tuple[PauliOperator, PauliOperator, dict[str, str], dict[str, str]]

loom_rotated_surface_code.applicator.move_corners.move_corners(interpretation_step, block, corner_args, same_timeslice, debug_mode)[source]

Move the selected topological corners of the block in the specified direction. We assume that the initial state is a RotatedSurfaceCode with a single logical qubit and the topological corners are located at the geometric corners.

This function can move he topological corners mutlitple times in a row, as long as the qubits selected are topological corners of the block.

NOTE: This function automatically measures the syndromes of the final block once.

Parameters:
  • interpretation_step (InterpretationStep) – The interpretation step before moving the corners

  • block (RotatedSurfaceCode) – The initial block

  • corner_args (tuple[tuple[tuple[int, int, int], Direction, int], ...]) – List of tuples containing the corner qubit to move, the direction in which to move it and the distance by which to move it

  • same_timeslice (bool) – Flag to apply move_corners in the same timeslice as the previous operation(s).

  • debug_mode (bool) – Flag to apply validation of the new block or not.

Returns:

The interpretation step after moving the corners

Return type:

InterpretationStep