qml.transforms.sum_expand¶

sum_expand
(tape, group=True)[source]¶ Splits a quantum tape measuring a Sum expectation into multiple tapes of summand expectations, and provides a function to recombine the results.
 Parameters
tape (QuantumTape) – the quantum tape used when calculating the expectation value of the Hamiltonian
group (bool) – Whether to compute disjoint groups of Pauli observables acting on different wires, leading to fewer tapes.
 Returns
Returns a tuple containing a list of quantum tapes to be evaluated, and a function to be applied to these tape executions to compute the expectation value.
 Return type
tuple[list[QuantumTape], function]
Example
Given a Sum operator,
S = qml.sum(qml.prod(qml.PauliY(2), qml.PauliZ(1)), qml.s_prod(0.5, qml.PauliZ(2)), qml.PauliZ(1))
and a tape of the form,
with qml.tape.QuantumTape() as tape: qml.Hadamard(wires=0) qml.CNOT(wires=[0, 1]) qml.PauliX(wires=2) qml.expval(S) qml.expval(qml.PauliZ(0)) qml.expval(qml.PauliX(1)) qml.expval(qml.PauliZ(2))
We can use the
sum_expand
transform to generate new tapes and a classical postprocessing function to speedup the computation of the expectation value of the Sum.>>> tapes, fn = qml.transforms.sum_expand(tape, group=False) >>> for tape in tapes: ... print(tape.measurements) [expval(PauliY(wires=[2]) @ PauliZ(wires=[1]))] [expval(PauliZ(wires=[2]))] [expval(PauliZ(wires=[1]))] [expval(PauliZ(wires=[0]))] [expval(PauliX(wires=[1]))]
Five tapes are generated: the first three contain the summands of the Sum operator, and the last two contain the remaining observables. Note that the scalars of the scalar products have been removed. In the processing function, these values will be multiplied by the result obtained from executing the tapes.
Additionally, the observable expval(PauliZ(wires=[2])) occurs twice in the original tape, but only once in the transformed tapes. When there are multipe identical measurements in the circuit, the measurement is performed once and the outcome is copied when obtaining the final result. This will also be resolved when the processing function is applied.
We can evaluate these tapes on a device:
>>> dev = qml.device("default.qubit", wires=3) >>> res = dev.batch_execute(tapes)
Applying the processing function results in the expectation value of the Hamiltonian:
>>> fn(res) [0.5, 0.0, 0.0, 0.9999999999999996]
Fewer tapes can be constructed by grouping observables acting on different wires. This can be achieved by the
group
keyword argument:S = qml.sum(qml.PauliZ(0), qml.s_prod(2, qml.PauliX(1)), qml.s_prod(3, qml.PauliX(0))) with qml.tape.QuantumTape() as tape: qml.Hadamard(wires=0) qml.CNOT(wires=[0, 1]) qml.PauliX(wires=2) qml.expval(S)
With grouping, the Sum gets split into two groups of observables (here
[qml.PauliZ(0), qml.s_prod(2, qml.PauliX(1))]
and[qml.s_prod(3, qml.PauliX(0))]
):>>> tapes, fn = qml.transforms.sum_expand(tape, group=True) >>> for tape in tapes: ... print(tape.measurements) [expval(PauliZ(wires=[0])), expval(PauliX(wires=[1]))] [expval(PauliX(wires=[0]))]