qml.transforms.hamiltonian_expand¶
-
hamiltonian_expand
(tape, group=True)[source]¶ Splits a tape measuring a Hamiltonian expectation into mutliple tapes of Pauli expectations, and provides a function to recombine the results.
- Parameters
tape (QuantumTape) – the tape used when calculating the expectation value of the Hamiltonian
group (bool) – Whether to compute disjoint groups of commuting Pauli observables, leading to fewer tapes. If grouping information can be found in the Hamiltonian, it will be used even if group=False.
- 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 Hamiltonian,
H = qml.PauliY(2) @ qml.PauliZ(1) + 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(H)
We can use the
hamiltonian_expand
transform to generate new tapes and a classical post-processing function for computing the expectation value of the Hamiltonian.>>> tapes, fn = qml.transforms.hamiltonian_expand(tape)
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
Fewer tapes can be constructed by grouping commuting observables. This can be achieved by the
group
keyword argument:H = qml.Hamiltonian([1., 2., 3.], [qml.PauliZ(0), qml.PauliX(1), qml.PauliX(0)]) with qml.tape.QuantumTape() as tape: qml.Hadamard(wires=0) qml.CNOT(wires=[0, 1]) qml.PauliX(wires=2) qml.expval(H)
With grouping, the Hamiltonian gets split into two groups of observables (here
[qml.PauliZ(0)]
and[qml.PauliX(1), qml.PauliX(0)]
):>>> tapes, fn = qml.transforms.hamiltonian_expand(tape) >>> len(tapes) 2
Without grouping it gets split into three groups (
[qml.PauliZ(0)]
,[qml.PauliX(1)]
and[qml.PauliX(0)]
):>>> tapes, fn = qml.transforms.hamiltonian_expand(tape, group=False) >>> len(tapes) 3
Alternatively, if the Hamiltonian has already computed groups, they are used even if
group=False
:obs = [qml.PauliZ(0), qml.PauliX(1), qml.PauliX(0)] coeffs = [1., 2., 3.] H = qml.Hamiltonian(coeffs, obs, grouping_type='qwc') # the initialisation already computes grouping information and stores it in the Hamiltonian assert H.grouping_indices is not None with qml.tape.QuantumTape() as tape: qml.Hadamard(wires=0) qml.CNOT(wires=[0, 1]) qml.PauliX(wires=2) qml.expval(H)
Grouping information has been used to reduce the number of tapes from 3 to 2:
>>> tapes, fn = qml.transforms.hamiltonian_expand(tape, group=False) >>> len(tapes) 2