# The original version of the following code is sourced from Qiskit circuit library:
# https://github.com/Qiskit/qiskit/blob/stable/2.3/qiskit/circuit/library/arithmetic/linear_pauli_rotations.py#L171-L242
#
# Original repository link:
# https://github.com/Qiskit/qiskit/tree/f14e0b29a484795034447ea5bfb637fe845c194f
#
# This program is adapted for use as a benchmark in controlled software testing experiments.
# Modifications made to the original code include (for Apache License 2.0):
# - Refactored to unify the inherent class as QuantumCircuit:
# - _define() -> _build()
# - Modified __init__() to call QuantumCircuit's __init__()
# - self.definition replaced with self.compose(...) to build the circuit
#
# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2020.
#
# 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.
"""Linearly-controlled X, Y or Z rotation."""
from __future__ import annotations
from typing import Optional
from qiskit.circuit import QuantumRegister, QuantumCircuit
# ---------- benchmark registration ----------
from ..benchmark_registry import register_benchmark
from pathlib import Path
@register_benchmark(
Path(__file__).stem,
family=Path(__file__).resolve().parent.name,
description="A gate implementing linear Pauli rotations.",
class_name="LinearPauliRotations",
source={
"repo": "https://github.com/Qiskit/qiskit/tree/f14e0b29a484795034447ea5bfb637fe845c194f",
"file": "qiskit/circuit/library/arithmetic/linear_pauli_rotations.py",
"sdk": "Qiskit",
"available_doc": True
},
testability_refactoring=[
"Structure reorganization"
]
)
def create_linear_pauli_rotations(
num_state_qubits: int,
slope: float = 1,
offset: float = 0,
basis: str = "Y",
):
return LinearPauliRotations(
num_state_qubits=num_state_qubits,
slope=slope,
offset=offset,
basis=basis,
)
[docs]
class LinearPauliRotations(QuantumCircuit): # Gate -> QuantumCircuit
r"""
Linearly-controlled X, Y or Z rotation.
"""
def __init__(
self,
num_state_qubits: int,
slope: float = 1,
offset: float = 0,
basis: str = "Y",
label: str | None = None,
) -> None:
r"""
Args:
num_state_qubits : The number of qubits representing the state, i.e., :math:`n`.
slope: The slope of the linear function, i.e., :math:`2a`. The default is 1.0.
offset: The offset of the linear function, i.e., :math:`2b`. The default is 0.0.
basis: The type of Pauli rotation (``"X"``, ``"Y"``, ``"Z"``). The default is
``"Y"``.
"""
# super().__init__("LinPauliRot", num_state_qubits + 1, [], label=label)
super().__init__(num_state_qubits + 1, name="LinPauliRot" or label) # Modified for QuantumCircuit
self.slope = slope
self.offset = offset
self.basis = basis.lower()
# build the circuit
self._build()
def _build(self):
circuit = QuantumCircuit(self.num_qubits)
# build the circuit
qr_state = circuit.qubits[: self.num_qubits - 1]
qr_target = circuit.qubits[-1]
if self.basis == "x":
circuit.rx(self.offset, qr_target)
elif self.basis == "y":
circuit.ry(self.offset, qr_target)
else: # 'Z':
circuit.rz(self.offset, qr_target)
for i, q_i in enumerate(qr_state):
if self.basis == "x":
circuit.crx(self.slope * pow(2, i), q_i, qr_target)
elif self.basis == "y":
circuit.cry(self.slope * pow(2, i), q_i, qr_target)
else: # 'Z'
circuit.crz(self.slope * pow(2, i), q_i, qr_target)
# self.definition = circuit
self.compose(circuit, inplace=True)