Skip to content

Commit

Permalink
Merge pull request #74 from kevinsung/crzz-decomp
Browse files Browse the repository at this point in the history
add crzz decomposition
  • Loading branch information
nbronn authored May 2, 2023
2 parents 80fa48c + 3af4ca1 commit 0deff97
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 9 deletions.
40 changes: 37 additions & 3 deletions qiskit_research/utils/gate_decompositions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
from collections.abc import Iterator

from qiskit import QuantumRegister
from qiskit.circuit import Gate, Qubit
from qiskit.circuit import ControlledGate, Gate, Qubit
from qiskit.circuit.library import (
CXGate,
HGate,
SGate,
SdgGate,
RXGate,
RZGate,
RZXGate,
SdgGate,
SGate,
XGate,
XXMinusYYGate,
XXPlusYYGate,
Expand Down Expand Up @@ -122,6 +123,39 @@ def run(
return dag


class ControlledRZZToCX(TransformationPass):
"""Transformation pass to decompose Controlled RZZGate to CXGate."""

def _decomposition(
self,
register: QuantumRegister,
gate: ControlledGate,
) -> Iterator[tuple[Gate, tuple[Qubit, ...]]]:
a, b, c = register
(theta,) = gate.params

yield CXGate(), (b, c)
yield RZGate(theta).control(1), (a, c)
yield CXGate(), (b, c)

def run(
self,
dag: DAGCircuit,
) -> DAGCircuit:
for run in dag.collect_runs(["crzz"]):
for node in run:
mini_dag = DAGCircuit()
register = QuantumRegister(3)
mini_dag.add_qreg(register)

for instr, qargs in self._decomposition(register, node.op):
mini_dag.apply_operation_back(instr, qargs)

dag.substitute_node_with_dag(node, mini_dag)

return dag


class XXPlusYYtoRZX(TransformationPass):
"""Transformation pass to decompose XXPlusYYGate to RZXGate."""

Expand Down
29 changes: 23 additions & 6 deletions test/utils/test_gate_decompositions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@

import numpy as np
from qiskit.circuit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import XXMinusYYGate, XXPlusYYGate
from qiskit.transpiler import PassManager
from qiskit.circuit.library import RZZGate, XXMinusYYGate, XXPlusYYGate
from qiskit.quantum_info import Operator
from qiskit.transpiler import PassManager

from qiskit_research.utils.gate_decompositions import (
ControlledRZZToCX,
RZXWeylDecomposition,
XXMinusYYtoRZX,
XXPlusYYtoRZX,
Expand All @@ -29,10 +31,24 @@
class TestPasses(unittest.TestCase):
"""Test passes."""

def test_controlled_rzz_to_cx(self):
"""Test controlled RZZGate to CXGate decomposition."""
rng = np.random.default_rng()
theta = rng.uniform(-10, 10)
gate = RZZGate(theta).control(1)
register = QuantumRegister(3)
circuit = QuantumCircuit(register)
circuit.append(gate, register)
pass_ = ControlledRZZToCX()
pass_manager = PassManager([pass_])
decomposed = pass_manager.run(circuit)
self.assertTrue(Operator(circuit).equiv(Operator(decomposed)))

def test_xxplusyy_to_rzx(self):
"""Test XXPlusYYGate to RZXGate decomposition."""
theta = np.random.uniform(-10, 10)
beta = np.random.uniform(-10, 10)
rng = np.random.default_rng()
theta = rng.uniform(-10, 10)
beta = rng.uniform(-10, 10)
gate = XXPlusYYGate(theta, beta)
register = QuantumRegister(2)
circuit = QuantumCircuit(register)
Expand All @@ -44,8 +60,9 @@ def test_xxplusyy_to_rzx(self):

def test_xxminusyy_to_rzx(self):
"""Test XXMinusYYGate to RZXGate decomposition."""
theta = np.random.uniform(-10, 10)
beta = np.random.uniform(-10, 10)
rng = np.random.default_rng()
theta = rng.uniform(-10, 10)
beta = rng.uniform(-10, 10)
gate = XXMinusYYGate(theta, beta)
register = QuantumRegister(2)
circuit = QuantumCircuit(register)
Expand Down

0 comments on commit 0deff97

Please sign in to comment.