Source code for qarp.blocks._primitives.brickwork_entangling_block
from typing import List, Optional
from .._block import SimpleBlock
[docs]
class BrickworkEntanglingBlock(SimpleBlock):
def __init__(
self,
n_qubits: int,
circular: bool,
use_cz: bool,
target_qubits: Optional[List[int]] = None,
name: Optional[str] = None,
):
"""
An object representing a brickwork entangling block.
The structure entangles qubit i with qubit i + 1 for even values of i, then for odd values of i. Corresponds to the
implementation in quri-parts and to the 'pairwise' option in qiskit, which also does even before odd.
Args:
n_qubits: The number of qubits to include in the block.
circular: if True, entangles the first qubit with the last one.
use_cz: if True replace the CX gate with a CZ gate.
target_qubits: The target qubits will act on when added to a Block object.
"""
self.use_cz = use_cz
if name is None:
if use_cz:
name = "BrickWork Entangler (CZ)"
else:
name = "BrickWork Entangler (CX)"
super().__init__(
n_qubits=n_qubits,
target_qubits=target_qubits,
name=name,
)
self.circular = circular
[docs]
def build_vanilla(self) -> None:
even_pairs = [(2 * i, 2 * i + 1) for i in range(self.n_qubits // 2)]
# (n_qubits - 1) // 2, not n_qubits // 2 - 1: the latter drops the final odd
# pair when n_qubits is odd, leaving the highest qubit unentangled.
odd_pairs = [(2 * i + 1, 2 * i + 2) for i in range((self.n_qubits - 1) // 2)]
pairs = even_pairs + odd_pairs
# The wrap is a new edge only from n >= 3: a 2-ring IS the 2-chain, so
# the wrap duplicates the only pair (CZ² = identity entangler), and a
# 1-ring would self-pair.
if self.circular and self.n_qubits >= 3:
pairs.append((self.n_qubits - 1, 0))
if self.use_cz:
self.cz(pairs)
else:
self.cx(pairs)