# qml.templates.subroutines.ApproxTimeEvolution¶

ApproxTimeEvolution(hamiltonian, time, n)[source]

Applies the Trotterized time-evolution operator for an arbitrary Hamiltonian, expressed in terms of Pauli gates.

The general time-evolution operator for a time-independent Hamiltonian is given by

$U(t) \ = \ e^{-i H t},$

for some Hamiltonian of the form:

$H \ = \ \displaystyle\sum_{j} H_j.$

Implementing this unitary with a set of quantum gates is difficult, as the terms $$H_j$$ don’t necessarily commute with one another. However, we are able to exploit the Trotter-Suzuki decomposition formula,

$e^{A \ + \ B} \ = \ \lim_{n \to \infty} \Big[ e^{A/n} e^{B/n} \Big]^n,$

to implement an approximation of the time-evolution operator as

$U \ \approx \ \displaystyle\prod_{k \ = \ 1}^{n} \displaystyle\prod_{j} e^{-i H_j t / n},$

with the approximation becoming better for larger $$n$$. The circuit implementing this unitary is of the form:

It is also important to note that this decomposition is exact for any value of $$n$$ when each term of the Hamiltonian commutes with every other term.

Note

This template uses the PauliRot operation in order to implement exponentiated terms of the input Hamiltonian. This operation only takes terms that are explicitly written in terms of products of Pauli matrices (PauliX, PauliY, PauliZ, and Identity). Thus, each term in the Hamiltonian must be expressed this way upon input, or else an error will be raised.

Parameters
Raises

ValueError – if inputs do not have the correct format

The template is used inside a qnode:

import pennylane as qml
from pennylane.templates import ApproxTimeEvolution

n_wires = 2
wires = range(n_wires)

dev = qml.device('default.qubit', wires=n_wires)

coeffs = [1, 1]
obs = [qml.PauliX(0), qml.PauliX(1)]
hamiltonian = qml.Hamiltonian(coeffs, obs)

@qml.qnode(dev)
def circuit(time):
ApproxTimeEvolution(hamiltonian, time, 1)
return [qml.expval(qml.PauliZ(wires=i)) for i in wires]

>>> circuit(1)
[-0.41614684 -0.41614684]