Source code for qiskit_qec.geometry.tiles.octasquaretile

# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2022
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""OctaSquareTile class."""
from math import sqrt
import numpy as np
from qiskit.exceptions import QiskitError
from qiskit_qec.geometry.model.shell import Shell
from qiskit_qec.geometry.tiles.tile import Tile
from qiskit_qec.geometry.tiles.tilefactory import TileFactory
from qiskit_qec.operators.pauli_list import PauliList


# pylint: disable=anomalous-backslash-in-string)
[docs] class OctaSquareTile(Tile): r"""Octa-Square Tile The tile has the following structure:: q0 q1 v0 v1 q2 q3 o------o v0 v1 q3 / \ q4 o-----o v7 o o v2 | | | | | 0 | q6 | 1 | q7 o-----o v6 o o v3 v3 v4 \ / q5 q6 q9 o-----o q10 v5 v4 q5 q6 v0 v1 o-----o q9 q10 q8 / \ q9 v0 v1 v7 o o v2 o-----o | 2 | | | q11 | | q12 | 3 | v6 o o v3 o-----o \ / q12 q13 o-----o v3 v2 q14 q15 v5 v4 o------o / \ o-----o o | | | | 0 | 1 | o-----o o / \ / o (0,0) o-----o | . | | | 2 | 3 | o o-----o \ / o-----o """ wf_operator_dict = { "cXZZX": [ PauliList(["XXXX"], input_qubit_order="left-to-right"), PauliList(["ZZZZZZZZ"], input_qubit_order="left-to-right"), PauliList(["ZZZZZZZZ"], input_qubit_order="left-to-right"), PauliList(["XXXX"], input_qubit_order="left-to-right"), ], "cZXXZ": [ PauliList(["ZZZZ"], input_qubit_order="left-to-right"), PauliList(["XXXXXXXX"], input_qubit_order="left-to-right"), PauliList(["XXXXXXXX"], input_qubit_order="left-to-right"), PauliList(["ZZZZ"], input_qubit_order="left-to-right"), ], } # Descriptions of wireframes # qubit indices for each wireframe wf_q_indices = [ [2, 3, 6, 5], [0, 1, 4, 7, 10, 9, 6, 3], [5, 6, 9, 12, 15, 14, 11, 8], [9, 10, 13, 12], ] # pylint: disable=invalid-name s8 = sqrt(2 - sqrt(2)) / 2 c8 = sqrt(2 + sqrt(2)) / 2 # coordinates for each wireframe vertex in path list form to enable the # creation of the associate edges wf_coordinates = [ [[-s8, c8 + 2 * s8], [s8, c8 + 2 * s8], [s8, c8], [-s8, c8]], [ [c8, 2 * c8 + s8], [c8 + 2 * s8, 2 * c8 + s8], [2 * c8 + s8, c8 + 2 * s8], [2 * c8 + s8, c8], [c8 + 2 * s8, s8], [c8, s8], [s8, c8], [s8, c8 + 2 * s8], ], [[-s8, c8], [s8, c8], [c8, s8], [c8, -s8], [s8, -c8], [-s8, -c8], [-c8, -s8], [-c8, s8]], [[c8, s8], [c8 + 2 * s8, s8], [c8 + 2 * s8, -s8], [c8, -s8]], ] # If the wf's are closed loops or not wf_loop_indicator = [True, True, True, True] # How wireframes components combine into faces/operators faces_wf_components = [[0], [1], [2], [3]] # Face colors (wf's inherit colors from faces) face_colors = ["yellowgreen", "tomato", "tomato", "yellowgreen"] num_faces = 4 size = np.array([3 * c8 + s8, 3 * c8 + s8]) num_qubits = 16 u_vec = np.array([2 * (c8 + s8), 0]) v_vec = np.array([0, 2 * (c8 + s8)]) def __new__( cls, origin: np.array, qubit_count=None, qubit_data=None, operators=None, optype="cXZZX", ) -> Shell: r"""Octa Square Tile The tile has the following structure:: q0 q1 v0 v1 q2 q3 o------o v0 v1 q3 / \ q4 o-----o v7 o o v2 | | | | | 0 | q6 | 1 | q7 o-----o v6 o o v3 v3 v4 \ / q5 q6 q9 o-----o q10 v5 v4 q5 q6 v0 v1 o-----o q9 q10 q8 / \ q9 v0 v1 v7 o o v2 o-----o | 2 | | | q11 | | q12 | 3 | v6 o o v3 o-----o \ / q12 q13 o-----o v3 v2 q14 q15 v5 v4 o------o / \ o-----o o | | | | 0 | 1 | o-----o o / \ / o (0,0) o-----o | . | | | 2 | 3 | o o-----o \ / o-----o Face colors for faces [0,1,2,3] are ["yellowgreen","tomato", "tomato", "yellowgreen"] Preformatted operators are stored in HexagonTile.op_dict. Keys for op_dict are of the form [p|c|d]PPPP... where p = pattern and c = copy, d=double and P is a Pauli opertor X, Z or Y. "cX" -> face #0 operator is Pauli("XXXXXX"), face #1 operator is Pauli("ZZZZZZ"), ... "dXZ" -> face #0 operators are Pauli("XXXXXX") and Pauli("ZZZZZZ"), face #1 operators are Pauli("ZZZZZZ") and ... Available precomputed operator layouts are:: cXZZX, cZXXZ The operator variable may be used to define the operators specifically. The operator must be a list of PauliList objects where each PauliList describes the opertors to be built for the faces as indexed above 0,1,2,3, ... If the PauliList contains k Paulis then k operators will be created for the given face. Args: origin (np.array): Coordinates of origin of tile (shell) qubit_count: Qubit counter. Defaults to None. qubit_data: Qubit data. Defaults to None. operators: Operators for tile faces. Defaults to None. optype (optional): Which of the listed opertor mapppings to used. Defaults to "pXZXZ". A appropriately scalled lattice basis for tiling with the OctaSquareTile can be accessed from [OctaSquareTile.u_vec, OctaSquareTile.v_vec] Raises: QiskitError: Unsupported operator type Returns: Shell: Returns a Octa-Square tile (shell) with provided origin """ if operators is None: try: operators = OctaSquareTile.wf_operator_dict[optype] except KeyError as key_error: raise QiskitError(f"Unsupported operator type: {optype}") from key_error return TileFactory( origin=origin, wf_coordinates=OctaSquareTile.wf_coordinates, wf_q_indices=OctaSquareTile.wf_q_indices, wf_loop_indicator=OctaSquareTile.wf_loop_indicator, faces_wf_components=OctaSquareTile.faces_wf_components, num_qubits=OctaSquareTile.num_qubits, face_colors=OctaSquareTile.face_colors, qubit_count=qubit_count, qubit_data=qubit_data, operators=operators, )