qml.transforms.rz_phase_gradient¶
- rz_phase_gradient(tape, angle_wires, phase_grad_wires, work_wires)[source]¶
Quantum function transform to decompose all instances of
RZgates into additions using a phase gradient resource state.For example, an
RZgate with angle \(\phi = (0 \cdot 2^{-1} + 1 \cdot 2^{-2} + 0 \cdot 2^{-3}) 2\pi\) is translated into the following routine, where the angle is conditionally prepared on theangle_wiresin binary and added to aphase_grad_wiresregister semi-inplace viaSemiAdder.target: ─RZ(ϕ)─ = ────╭●──────────────╭●────exp(iϕ/2)─┤ ang_0: ────├|0⟩─╭SemiAdder─├|0⟩────────────┤ ang_1: ────├|1⟩─├SemiAdder─├|1⟩────────────┤ ang_2: ────╰|0⟩─├SemiAdder─╰|0⟩────────────┤ phg_0: ─────────├SemiAdder─────────────────┤ phg_1: ─────────├SemiAdder─────────────────┤ phg_2: ─────────╰SemiAdder─────────────────┤
For this routine to work, the provided
phase_grad_wiresneed to hold a phase gradient state \(|\nabla Z\rangle = \frac{1}{\sqrt{2^n}} \sum_{m=0}^{2^n-1} e^{2 \pi i \frac{m}{2^n}} |m\rangle\). Because this state is not modified and can be re-used at a later stage, the transform does not prepare it but rather assumes it has been prepared on those wires at an earlier stage.Note that
SemiAdderrequires additionalwork_wires(not shown in the diagram) for the semi-in-place addition \(\text{SemiAdder}|x\rangle_\text{ang} |y\rangle_\text{phg} = |x\rangle_\text{ang} |x + y\rangle_\text{phg}\).More details can be found on page 4 in arXiv:1709.06648 and Figure 17a in arXiv:2211.15465 (a generalization to multiplexed
RZrotations is provided in Figure 4 in arXiv:2409.07332).Note that technically, this circuit realizes
PhaseShift, i.e. \(R_\phi(\phi) = R_Z(\phi) e^{i\phi/2}\). The additional global phase is taken into account in the decomposition.- Parameters:
tape (QNode or QuantumTape or Callable) – A quantum circuit containing
RZgates.angle_wires (Wires) – The qubits that conditionally load the angle \(\phi\) of the
RZgate in binary as a multiple of \(2\pi\). The length of theangle_wiresimplicitly determines the precision with which the angle is represented. E.g., \((2^{-1} + 2^{-2} + 2^{-3}) 2\pi\) is exactly represented by three bits as111.phase_grad_wires (Wires) – The catalyst qubits with a phase gradient state prepared on them. Needs to be at least the length of
angle_wiresand will only use the firstlen(angle_wires).work_wires (Wires) – Additional work wires to realize the
SemiAdderbetween theangle_wiresandphase_grad_wires. Needs to be at leastb-1wires, whereb=len(phase_grad_wires)is the precision of the angle \(\phi\).
- Returns:
The transformed circuit as described in
qml.transform.- Return type:
qnode (QNode) or quantum function (Callable) or tuple[List[QuantumTape], function]
Example
from functools import partial import numpy as np import pennylane as qml from pennylane.transforms.rz_phase_gradient import rz_phase_gradient precision = 3 phi = (1 / 2 + 1 / 4 + 1 / 8) * 2 * np.pi wire = "targ" angle_wires = [f"ang_{i}" for i in range(precision)] phase_grad_wires = [f"phg_{i}" for i in range(precision)] work_wires = [f"work_{i}" for i in range(precision - 1)] wire_order = [wire] + angle_wires + phase_grad_wires + work_wires def phase_gradient(wires): # prepare phase gradient state qml.X(wires[-1]) qml.QFT(wires) @partial( rz_phase_gradient, angle_wires=angle_wires, phase_grad_wires=phase_grad_wires, work_wires=work_wires, ) @qml.qnode(qml.device("default.qubit")) def rz_circ(phi, wire): phase_gradient(phase_grad_wires) # prepare phase gradient state qml.Hadamard(wire) # transform rotation qml.RZ(phi, wire) qml.Hadamard(wire) # transform rotation return qml.probs(wire)
In this example we perform the rotation of an angle of \(\phi = (0.111)_2 2\pi\). Because phase shifts are trivial on computational basis states, we transform the \(R_Z\) rotation to \(R_X = H R_Z H\) via two
Hadamardgates.Note that for the transform to work, we need to also prepare a phase gradient state on the
phase_grad_wires.Overall, the full circuit looks like the following:
>>> print(qml.draw(rz_circ, wire_order=wire_order)(phi, wire)) targ: ──H──────╭(|Ψ⟩)@SemiAdder@(|Ψ⟩)──H─╭GlobalPhase(2.75)─┤ Probs ang_0: ─────────├(|Ψ⟩)@SemiAdder@(|Ψ⟩)────├GlobalPhase(2.75)─┤ ang_1: ─────────├(|Ψ⟩)@SemiAdder@(|Ψ⟩)────├GlobalPhase(2.75)─┤ ang_2: ─────────├(|Ψ⟩)@SemiAdder@(|Ψ⟩)────├GlobalPhase(2.75)─┤ phg_0: ────╭QFT─├(|Ψ⟩)@SemiAdder@(|Ψ⟩)────├GlobalPhase(2.75)─┤ phg_1: ────├QFT─├(|Ψ⟩)@SemiAdder@(|Ψ⟩)────├GlobalPhase(2.75)─┤ phg_2: ──X─╰QFT─├(|Ψ⟩)@SemiAdder@(|Ψ⟩)────├GlobalPhase(2.75)─┤ work_0: ─────────├(|Ψ⟩)@SemiAdder@(|Ψ⟩)────├GlobalPhase(2.75)─┤ work_1: ─────────╰(|Ψ⟩)@SemiAdder@(|Ψ⟩)────╰GlobalPhase(2.75)─┤
The additional work wires are required by the
SemiAdder. Executing the circuit, we get the expected result:>>> rz_circ(phi, wire) array([0.85355339, 0.14644661])