qml.finite_diff

finite_diff(f, N=1, argnum=0, idx=None, delta=0.01)[source]

Returns a function that can be evaluated to compute the gradient or the second-order derivative of the callable function f using a centered finite difference approximation.

The first-order derivatives \(\frac{\partial f(x)}{\partial x_i}\) entering the gradient of the input function are given by,

\[\frac{\partial f(x)}{\partial x_i} \approx \frac{f(x_i + \delta/2) - f(x_i - \delta/2)}{\delta}\]

On the other hand, the second-order derivative \(\frac{\partial^2 f(x)}{\partial x_i \partial x_j}\) are evaluated using the following expressions:

For \(i = j\):

\[\frac{\partial^2 f(x)}{\partial x_i^2} \approx \frac{f(x_i + \delta) - 2 f(x) + f(x_i - \delta)}{\delta^2},\]

and for \(i \neq j\):

\[\frac{\partial^2 f(x)}{\partial x_i \partial x_j} \approx \frac{f(x_i + \delta/2, x_j + \delta/2) - f(x_i - \delta/2, x_j + \delta/2) - f(x_i + \delta/2, x_j - \delta/2) + f(x_i - \delta/2, x_j - \delta/2)} {\delta^2}.\]
Parameters
  • f (function) – function with signature f(*args, **kwargs)

  • N (int) – specifies the order of the finite difference approximation

  • argnum (int) – the argument of function f to differentiate

  • idx (list[int]) – If argument args[argnum] is an array, idx can be used to specify the indices of the argument argnum to differentiate. For N=1 it can be given to specify the gradient components to be computed. For example, for the function f(x, y, z), argnum=1, idx=[3, 2] the returned function will differentiate f with respect to elements 3 and 2 of argument y. For N=2, it specifies the indices i, j of the variables involved in the second-order derivative \(\frac{\partial^2 f(x, y, z)}{\partial y_i \partial y_j}\).

  • delta (float) – step size used to evaluate the finite differences

Returns

the function to compute the gradient (N=1) or the second-order derivative (N=2) of the input function f with respect to the arguments in argnum

Return type

function

Examples

>>> def f(x, y):
...     return np.sin(y[0])*np.sin(y[1]) - x**-3
>>> (x, y) = (0.376, np.array([1.975, 0.33, -0.4]))
>>> # We compute the gradient with respect to 'y' as
>>> gradient = qml.finite_diff(f, argnum=1)
>>> print(gradient(x, y))
[-0.12744129189670161 0.8698027233702277]
>>> # We can also compute the derivative with respect to 'y[1]'
>>> derivative = qml.finite_diff(f, argnum=1, idx=[1])
>>> print(derivative(x, y)[1])
0.8698027233702277
>>> # and the second derivative with respect to 'y[0], y[1]'
>>> second_derivative = qml.finite_diff(f, N=2, argnum=1, idx=[0, 1])
>>> print(second_derivative(x, y))
-0.372062798810191