qml.defer_measurements¶

defer_measurements
(tape)[source]¶ Quantum function transform that substitutes operations conditioned on measurement outcomes to controlled operations.
This transform uses the deferred measurement principle and applies to qubitbased quantum functions.
Support for midcircuit measurements is devicedependent. If a device doesn’t support midcircuit measurements natively, then the QNode will apply this transform.
Note
The transform uses the
ctrl()
transform to implement operations controlled on midcircuit measurement outcomes. The set of operations that can be controlled as such depends on the set of operations supported by the chosen device.Note
Devices that inherit from
QubitDevice
must be initialized with an additional wire for each midcircuit measurement after which the measured wire is reused or reset fordefer_measurements
to transform the quantum tape correctly. Hence, devices and quantum tapes must also be initialized without custom wire labels for correct behaviour.Note
This transform does not change the list of terminal measurements returned by the quantum function.
Note
When applying the transform on a quantum function that returns
state()
as the terminal measurement or contains theSnapshot
instruction, state information corresponding to simulating the transformed circuit will be obtained. No postmeasurement states are considered. Parameters
tape (QuantumTape) – a quantum tape
Example
Suppose we have a quantum function with midcircuit measurements and conditional operations:
def qfunc(par): qml.RY(0.123, wires=0) qml.Hadamard(wires=1) m_0 = qml.measure(1) qml.cond(m_0, qml.RY)(par, wires=0) return qml.expval(qml.PauliZ(0))
The
defer_measurements
transform allows executing such quantum functions without having to perform midcircuit measurements:>>> dev = qml.device('default.qubit', wires=2) >>> transformed_qfunc = qml.defer_measurements(qfunc) >>> qnode = qml.QNode(transformed_qfunc, dev) >>> par = np.array(np.pi/2, requires_grad=True) >>> qnode(par) tensor(0.43487747, requires_grad=True)
We can also differentiate parameters passed to conditional operations:
>>> qml.grad(qnode)(par) tensor(0.49622252, requires_grad=True)
Reusing and reseting measured wires will work as expected with the
defer_measurements
transform:dev = qml.device("default.qubit", wires=3) @qml.qnode(dev) def func(x, y): qml.RY(x, wires=0) qml.CNOT(wires=[0, 1]) m_0 = qml.measure(1, reset=True) qml.cond(m_0, qml.RY)(y, wires=0) qml.RX(np.pi/4, wires=1) return qml.probs(wires=[0, 1])
Executing this QNode:
>>> pars = np.array([0.643, 0.246], requires_grad=True) >>> func(*pars) tensor([0.76960924, 0.13204407, 0.08394415, 0.01440254], requires_grad=True)