qml.gradients.finite_diff_coeffs¶
- finite_diff_coeffs(n, approx_order, strategy)[source]¶
Generate the finite difference shift values and corresponding term coefficients for a given derivative order, approximation accuracy, and strategy.
- Parameters
n (int) – Positive integer specifying the order of the derivative. For example,
n=1
corresponds to the first derivative,n=2
the second derivative, etc.approx_order (int) – Positive integer referring to the approximation order of the returned coefficients, e.g.,
approx_order=1
corresponds to the first-order approximation to the derivative.strategy (str) – One of
"forward"
,"center"
, or"backward"
. For the"forward"
strategy, the finite-difference shifts occur at the points \(x_0, x_0+h, x_0+2h,\dots\), where \(h\) is some small step size. The"backwards"
strategy is similar, but in reverse: \(x_0, x_0-h, x_0-2h, \dots\). Finally, the"center"
strategy results in shifts symmetric around the unshifted point: \(\dots, x_0-2h, x_0-h, x_0, x_0+h, x_0+2h,\dots\).
- Returns
A
(2, N)
array. The first row corresponds to the coefficients, and the second row corresponds to the shifts.- Return type
array[float]
Example
>>> finite_diff_coeffs(n=1, approx_order=1, strategy="forward") array([[-1., 1.], [ 0., 1.]])
For example, this results in the linear combination:
\[\frac{-y(x_0) + y(x_0 + h)}{h}\]where \(h\) is the finite-difference step size.
More examples:
>>> finite_diff_coeffs(n=1, approx_order=2, strategy="center") array([[-0.5, 0.5], [-1. , 1. ]]) >>> finite_diff_coeffs(n=2, approx_order=2, strategy="center") array([[-2., 1., 1.], [ 0., -1., 1.]])
Details
Consider a function \(y(x)\). We wish to approximate the \(n\)-th derivative at point \(x_0\), \(y^{(n)}(x_0)\), by sampling the function at \(N<n\) distinct points:
\[y^{(n)}(x_0) \approx \sum_{i=1}^N c_i y(x_i)\]where \(c_i\) are coefficients, and \(x_i=x_0 + s_i\) are the points we sample the function at.
Consider the Taylor expansion of \(y(x_i)\) around the point \(x_0\):
\[\begin{split}y^{(n)}(x_0) \approx \sum_{i=1}^N c_i y(x_i) &= \sum_{i=1}^N c_i \left[ y(x_0) + y'(x_0)(x_i-x_0) + \frac{1}{2} y''(x_0)(x_i-x_0)^2 + \cdots \right]\\ & = \sum_{j=0}^m y^{(j)}(x_0) \left[\sum_{i=1}^N \frac{c_i s_i^j}{j!} + \mathcal{O}(s_i^m) \right],\end{split}\]where \(s_i = x_i-x_0\). For this approximation to be satisfied, we must therefore have
\[\begin{split}\sum_{i=1}^N s_i^j c_i = \begin{cases} j!, &j=n\\ 0, & j\neq n\end{cases}.\end{split}\]Thus, to determine the coefficients \(c_i \in \{c_1, \dots, c_N\}\) for particular shift values \(s_i \in \{s_1, \dots, s_N\}\) and derivative order \(n\), we must solve this linear system of equations.