Source code for spin_pulse.transpilation.passes.rzz_echo
# --------------------------------------------------------------------------------------
# This code is part of SpinPulse.
#
# (C) Copyright Quobly 2025.
#
# 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.
# --------------------------------------------------------------------------------------
""""""
import numpy as np
from qiskit.circuit import QuantumRegister
from qiskit.circuit.library import RXGate, RZZGate
from qiskit.dagcircuit import DAGCircuit
from qiskit.transpiler.basepasses import TransformationPass
[docs]
class RZZEchoPass(TransformationPass):
r"""Echo :math:`R_{ZZ}` gates with :math:`X` pulses to mitigate Stark shifts.
This transpiler pass replaces each two-qubit :math:`R_{ZZ}` gate by an echoed
sequence consisting of interleaved :math:`\pi` rotations around the :math:`x` axis and
:math:`R_{ZZ}` gates with half the original angle. The echo sequence is applied
locally on each occurrence of an RZZ gate in the input DAG circuit.
"""
[docs]
def run(
self,
dag: DAGCircuit,
) -> DAGCircuit:
r"""Apply the :math:`R_{ZZ}` echo transformation to all :math:`R_{ZZ}` gates in the DAG.
Each :math:`R_{ZZ}(\theta)` operation is replaced by the following pattern
on the two involved qubits:
- :math:`R_X(\pi)` on both qubits
- :math:`R_{ZZ}(\theta / 2)`
- :math:`R_X(\pi)` on both qubits
- :math:`R_{ZZ}(\theta / 2)`
All other operations are left unchanged.
Parameters:
dag (DAGCircuit): Input circuit represented as a DAG on which
the transformation is applied.
Returns:
DAGCircuit: New DAG circuit where each :math:`R_{ZZ}` gate has been replaced by the echoed :math:`R_{ZZ}` sequence.
"""
for node in dag.op_nodes():
if not node.op.name == "rzz":
continue
theta = node.op.params[0]
# instantiate mini_dag and attach quantum register
mini_dag = DAGCircuit()
register = QuantumRegister(2)
mini_dag.add_qreg(register)
for _ in range(2):
mini_dag.apply_operation_back(RXGate(np.pi), [register[0]])
mini_dag.apply_operation_back(RXGate(np.pi), [register[1]])
mini_dag.apply_operation_back(
RZZGate(theta / 2), [register[0], register[1]]
)
dag.substitute_node_with_dag(node, mini_dag)
return dag