qml.labs.transforms.select_pauli_rot_phase_gradient¶
- select_pauli_rot_phase_gradient(tape, angle_wires, phase_grad_wires, work_wires)[source]¶
Quantum function transform to decompose all instances of
SelectPauliRotgates into additions using a phase gradient resource state.For this routine to work, the provided
phase_grad_wiresneed to hold the 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. Look at the example below to see how this state can be prepared.
Note that this operator contains
SemiAdderthat typically uses additionalwork_wiresfor the semi-in-place addition \(\text{SemiAdder}|x\rangle_\text{ang} |y\rangle_\text{phg} = |x\rangle_\text{ang} |x + y\rangle_\text{phg}\).- Parameters:
tape (QNode or QuantumTape or Callable) – A quantum circuit containing
SelectPauliRotoperators.angle_wires (Wires) – The qubits that conditionally load the angle \(\phi\) of the
SelectPauliRotgate in binary as a multiple of \(2\pi\). The length of theangle_wires, i.e. \(b\), implicitly determines the precision with which the angle is represented. E.g., \((1 \cdot 2^{-1} + 0 \cdot 2^{-2} + 1 \cdot 2^{-3}) 2\pi\) is represented by three bits as101.phase_grad_wires (Wires) – Qubits with the catalytic phase gradient state prepared on them. Needs to be at least \(b\) wires and will only use the first \(b\).
work_wires (Wires) – Additional work wires to realize the
SemiAdderandQROM. Needs to be at least \(b-1\) wires.
- Returns:
The transformed circuit as described in
qml.transform.- Return type:
qnode (QNode) or quantum function (Callable) or tuple[List[QuantumTape], function]
Example
from pennylane.labs.transforms import select_pauli_rot_phase_gradient from functools import partial import numpy as np precision = 4 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)] def phase_gradient(wires): # prepare phase gradient state for i, w in enumerate(wires): qml.H(w) qml.PhaseShift(-np.pi / 2**i, w) @partial( select_pauli_rot_phase_gradient, angle_wires=angle_wires, phase_grad_wires=phase_grad_wires, work_wires=work_wires, ) @qml.qnode(qml.device("default.qubit")) def select_pauli_rot_circ(phis, control_wires, target_wire): phase_gradient(phase_grad_wires) # prepare phase gradient state for wire in control_wires: qml.Hadamard(wire) qml.SelectPauliRot(phis, control_wires, target_wire, rot_axis="X") return qml.probs(target_wire) phis = [ (1 / 2 + 1 / 4 + 1 / 8) * 2 * np.pi, (1 / 2 + 1 / 4 + 0 / 8) * 2 * np.pi, (1 / 2 + 0 / 4 + 1 / 8) * 2 * np.pi, (0 / 2 + 1 / 4 + 1 / 8) * 2 * np.pi, ]
>>> print(select_pauli_rot_circ(phis, control_wires=[0, 1], target_wire=wire)) [0.41161165 0.58838835]