qml.evolve¶
- evolve(*args, **kwargs)[source]¶
- evolve(op, **kwargs)
- evolve(op, coeff=1)
This method is dispatched and its functionality depends on the type of the input
op.Input: Operator
Returns a new operator that computes the evolution of
op.\[e^{-i x \bm{O}}\]- Parameters:
op (.Operator) – operator to evolve. This must be passed as a positional argument. Passing it as a keyword argument will result in an error.
coeff (float) – coefficient multiplying the exponentiated operator
- Returns:
evolution operator
- Return type:
.Evolution
Examples
We can use
qml.evolveto compute the evolution of any PennyLane operator:>>> op = qml.evolve(qml.X(0), coeff=2) >>> op Evolution(-2j PauliX)
Input: ParametrizedHamiltonian
- Parameters:
op (.ParametrizedHamiltonian) – Hamiltonian to evolve. This must be passed as a positional argument.
- Returns:
time evolution \(U(t_0, t_1)\) of the Hamiltonian
- Return type:
.ParametrizedEvolution
The function takes a
ParametrizedHamiltonianand solves the time-dependent Schrodinger equation\[\frac{\partial}{\partial t} |\psi\rangle = -i H(t) |\psi\rangle\]It returns a
ParametrizedEvolution, \(U(t_0, t_1)\), which is the solution to the time-dependent Schrodinger equation for theParametrizedHamiltonian, such that\[|\psi(t_1)\rangle = U(t_0, t_1) |\psi(t_0)\rangle\]The
ParametrizedEvolutionclass uses a numerical ordinary differential equation solver (here).Examples
When evolving a
ParametrizedHamiltonian, aParametrizedEvolutioninstance is returned:coeffs = [lambda p, t: p * t for _ in range(4)] ops = [qml.X(i) for i in range(4)] # ParametrizedHamiltonian H = qml.dot(coeffs, ops) # ParametrizedEvolution ev = qml.evolve(H)
>>> ev ParametrizedEvolution(wires=[0, 1, 2, 3])
The
ParametrizedEvolutionis anOperator, but does not have a defined matrix unless it is evaluated at set parameters. This is done by calling theParametrizedEvolution, which has the call signature(p, t):>>> matrix = qml.matrix(ev([1., 2., 3., 4.], t=[0, 4])) >>> print(matrix.shape) (16, 16)
Additional options regarding how the matrix is calculated can be passed to the
ParametrizedEvolutionalong with the parameters, as keyword arguments. These options are:atol (float, optional): Absolute error tolerancertol (float, optional): Relative error tolerancemxstep (int, optional): maximum number of steps to take for each time pointhmax (float, optional): maximum step size
If not specified, they will default to predetermined values.
The
ParametrizedEvolutioncan be implemented in a QNode:import jax jax.config.update("jax_enable_x64", True) dev = qml.device("default.qubit") @jax.jit @qml.qnode(dev, interface="jax") def circuit(params): qml.evolve(H)(params, t=[0, 10]) return qml.expval(qml.Z(0))
>>> params = [1., 2., 3., 4.] >>> circuit(params) Array(0.862..., dtype=float64)
>>> jax.grad(circuit)(params) [Array(50.63..., dtype=float64), Array(-9.42...e-05, dtype=float64), Array(-0.0001..., dtype=float64), Array(-0.0001..., dtype=float64)]
Note
In the example above, the decorator
@jax.jitis used to compile this execution just-in-time. This means the first execution will typically take a little longer with the benefit that all following executions will be significantly faster, see the jax docs on jitting. JIT-compiling is optional, and one can remove the decorator when only single executions are of interest.