Skip to content

Commit

Permalink
Add equivalence-library rules between rzz and cp (#13019)
Browse files Browse the repository at this point in the history
* Add equivalence-library rules between `rzz` and `cp`

These gates are locally equivalence (as are all the Ising-interaction
gates), and this simple additional rule lets things like QFT, which are
defined by Qiskit's default constructor in terms of `cp`, get converted
into `rzz` or `rzx`.

One `ControlledGate` test needed a case removing, because the underlying
control mechanism now works correctly.

* Rewrite release note
  • Loading branch information
jakelishman committed Sep 9, 2024
1 parent 734560e commit 3aa58cc
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
43 changes: 43 additions & 0 deletions qiskit/circuit/library/standard_gates/equivalence_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,21 @@ def _cnot_rxx_decompose(plus_ry: bool = True, plus_rxx: bool = True):
cphase_to_cu1.append(CU1Gate(theta), [0, 1])
_sel.add_equivalence(CPhaseGate(theta), cphase_to_cu1)

# CPhaseGate
#
# global phase: ϴ/4
# ┌─────────┐
# q_0: ─■──── q_0: ─■─────────┤ Rz(ϴ/2) ├
# │P(ϴ) ≡ │ZZ(-ϴ/2) ├─────────┤
# q_1: ─■──── q_1: ─■─────────┤ Rz(ϴ/2) ├
# └─────────┘
theta = Parameter("theta")
cphase_to_rzz = QuantumCircuit(2, global_phase=theta / 4)
cphase_to_rzz.rzz(-theta / 2, 0, 1)
cphase_to_rzz.rz(theta / 2, 0)
cphase_to_rzz.rz(theta / 2, 1)
_sel.add_equivalence(CPhaseGate(theta), cphase_to_rzz)

# RGate
#
# ┌────────┐ ┌───────────────────────┐
Expand Down Expand Up @@ -394,6 +409,19 @@ def _cnot_rxx_decompose(plus_ry: bool = True, plus_rxx: bool = True):
def_rzx.append(inst, qargs, cargs)
_sel.add_equivalence(RZXGate(theta), def_rzx)

# RZXGate to RZZGate
# ┌─────────┐
# q_0: ┤0 ├ q_0: ──────■───────────
# │ Rzx(ϴ) │ ≡ ┌───┐ │ZZ(ϴ) ┌───┐
# q_1: ┤1 ├ q_1: ┤ H ├─■──────┤ H ├
# └─────────┘ └───┘ └───┘
theta = Parameter("theta")
rzx_to_rzz = QuantumCircuit(2)
rzx_to_rzz.h(1)
rzx_to_rzz.rzz(theta, 0, 1)
rzx_to_rzz.h(1)
_sel.add_equivalence(RZXGate(theta), rzx_to_rzz)


# RYGate
#
Expand Down Expand Up @@ -654,6 +682,21 @@ def _cnot_rxx_decompose(plus_ry: bool = True, plus_rxx: bool = True):
rzz_to_rzx.h(1)
_sel.add_equivalence(RZZGate(theta), rzz_to_rzx)

# RZZ to CPhase
#
# global phase: ϴ/2
# ┌───────┐
# q_0: ─■───── q_0: ─■────────┤ Rz(ϴ) ├
# │ZZ(ϴ) ≡ │P(-2*ϴ) ├───────┤
# q_1: ─■───── q_1: ─■────────┤ Rz(ϴ) ├
# └───────┘
theta = Parameter("theta")
rzz_to_cphase = QuantumCircuit(2, global_phase=theta / 2)
rzz_to_cphase.cp(-theta * 2, 0, 1)
rzz_to_cphase.rz(theta, 0)
rzz_to_cphase.rz(theta, 1)
_sel.add_equivalence(RZZGate(theta), rzz_to_cphase)

# RZZ to RYY
q = QuantumRegister(2, "q")
theta = Parameter("theta")
Expand Down
17 changes: 17 additions & 0 deletions releasenotes/notes/cphase-rzz-equivalence-e8afc37b71a74366.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
features_circuits:
- |
The standard equivalence library (:data:`.SessionEquivalenceLibrary`) now has rules that can
directly convert between Qiskit's standard-library 2q continuous Ising-type interactions (e.g.
:class:`.CPhaseGate`, :class:`.RZZGate`, :class:`.RZXGate`, and so on) using local equivalence
relations. Previously, several of these conversions would go via a 2-CX form, which resulted
in less efficient circuit generation.
.. note::
In general, the :class:`.BasisTranslator` is not guaranteed to find the "best" equivalence
relation for a given :class:`.Target`, but will always find an equivalence if one exists. We
rely on more expensive resynthesis and gate-optimization passes in the transpiler to improve
the output. These passes are currently not as effective for basis sets with a continuously
parametrized two-qubit interaction as they are for discrete super-controlled two-qubit
interactions.
1 change: 0 additions & 1 deletion test/python/circuit/test_controlled_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -1438,7 +1438,6 @@ def test_control_zero_operand_gate(self, num_ctrl_qubits):
@data(
RXGate,
RYGate,
RZGate,
RXXGate,
RYYGate,
RZXGate,
Expand Down

0 comments on commit 3aa58cc

Please sign in to comment.