qml.apply¶
- apply(op, context=<class 'pennylane.queuing.QueuingManager'>)[source]¶
Apply an instantiated operator or measurement to a queuing context.
- Parameters
op (Operator or MeasurementProcess) – the operator or measurement to apply/queue
context (QueuingManager) – The queuing context to queue the operator to. Note that if no context is specified, the operator is applied to the currently active queuing context.
- Returns
the input operator is returned for convenience
- Return type
Example
In PennyLane, operations and measurements are ‘queued’ or added to a circuit when they are instantiated.
The
apply
function can be used to add operations that might have already been instantiated elsewhere to the QNode:op = qml.RX(0.4, wires=0) dev = qml.device("default.qubit", wires=2) @qml.qnode(dev) def circuit(x): qml.RY(x, wires=0) # applied during instantiation qml.apply(op) # manually applied return qml.expval(qml.Z(0))
>>> print(qml.draw(circuit)(0.6)) 0: ──RY(0.6)──RX(0.4)──┤ ⟨Z⟩
It can also be used to apply functions repeatedly:
@qml.qnode(dev) def circuit(x): qml.apply(op) qml.RY(x, wires=0) qml.apply(op) return qml.expval(qml.Z(0))
>>> print(qml.draw(circuit)(0.6)) 0: ──RX(0.4)──RY(0.6)──RX(0.4)──┤ ⟨Z⟩
Warning
If you use
apply
on an operator that has already been queued, it will be queued for a second time. For example:@qml.qnode(dev) def circuit(): op = qml.Hadamard(0) qml.apply(op) return qml.expval(qml.Z(0))
>>> print(qml.draw(circuit)()) 0: ──H──H─┤ <Z>
Usage Details
Instantiated measurements can also be applied to queuing contexts using
apply
:meas = qml.expval(qml.Z(0) @ qml.Y(1)) dev = qml.device("default.qubit", wires=2) @qml.qnode(dev) def circuit(x): qml.RY(x, wires=0) qml.CNOT(wires=[0, 1]) return qml.apply(meas)
>>> print(qml.draw(circuit)(0.6)) 0: ──RY(0.6)──╭●──╭┤ ⟨Z ⊗ Y⟩ 1: ───────────╰X──╰┤ ⟨Z ⊗ Y⟩
By default,
apply
will queue operators to the currently active queuing context.When working with low-level queuing contexts such as quantum tapes, the desired context to queue the operation to can be explicitly passed:
with qml.tape.QuantumTape() as tape1: qml.Hadamard(wires=1) with qml.tape.QuantumTape() as tape2: # Due to the nesting behaviour of queuing contexts, # tape2 will be queued to tape1. # The following PauliX operation will be queued # to the active queuing context, tape2, during instantiation. op1 = qml.X(0) # We can use qml.apply to apply the same operation to tape1 # without leaving the tape2 context. qml.apply(op1, context=tape1) qml.RZ(0.2, wires=0) qml.CNOT(wires=[0, 1])
>>> tape1.operations [Hadamard(wires=[1]), <QuantumTape: wires=[0], params=1>, X(0), CNOT(wires=[0, 1])] >>> tape2.operations [X(0), RZ(0.2, wires=[0])]