4.2. Approximation of the second derivative of a function#
Approximation of the second derivative can be obtained using the forward, back, and central approximation of the first derivatives. Note that,
Second derivative central difference:
Second derivative forward difference:
Second derivative backward difference:
Example:
Consider \(f(x) = 3x\exp(x) - \cos(x) + \sin(x)\). This function is defined and continuous on [0,1]. Discretize \([0,1]\) using \(h=0.01\) and approximate \(f''(x)\) using
Forward Difference approximation of the 1st derivative at \(\{0.02, 0.03, 0.04, \ldots,0.97,0.98 \}\).
Backward Difference approximation of the 1st derivative at \(\{0.02, 0.03, 0.04, \ldots,0.97,0.98 \}\).
Central Difference approximation of the 1st derivative at \(\{0.02, 0.03, 0.04, \ldots,0.97,0.98 \}\).
Solution:
Second derivative forward difference:
Similarly,
import numpy as np
import pandas as pd
# f(x)
f = lambda x: 3*x*np.exp(x) - np.cos(x)
# f''(x)
f2 = lambda x: np.cos(x) + 6*np.exp(x) + 3*x*np.exp(x)
a = 0
b = 1
h = 1e-2
xn = np.arange(a, b + h, h)
yn = f(xn)
Consider the inner points of this example. For these points
from IPython.display import display, Latex
Ind = np.arange(2, len(xn)-2)
# Exact
Exact = f2(xn[Ind])
# Forward difference
Forward = (yn[Ind+2]-2*yn[Ind+1]+yn[Ind])/(h**2)
# Backward difference
Backward = (yn[Ind]-2*yn[Ind-1]+yn[Ind-2])/(h**2)
# Central difference
Central = (yn[Ind+1]-2*yn[Ind]+yn[Ind-1])/(h**2)
display(Latex('''\\max_{2\leq i\leq N-2}\\left|f''(x_i)-\dfrac {\\Delta^2_{h}[f](x_i)}{h^2} \\right| = %.4e''' % max(abs(Forward - Exact))))
display(Latex('''\\max_{2\leq i\leq N-2}\\left|f''(x_i)-\dfrac {\\nabla^2_{h}[f](x_i)}{h^2} \\right| = %.4e''' % max(abs(Backward - Exact))))
display(Latex('''\\max_{2\leq i\leq N-2}\\left|f''(x_i)-\dfrac {\\delta^2_{h}[f](x_i)}{h^2} \\right| = %.4e''' % max(abs(Central - Exact))))
4.2.1. Order of Convergence#
Let \(f_{i+j}\) be \(f(x_i+ jh)\) for \(j \in \mathbb{Z}\). Using Taylor theorem, we have,
and
Forward difference:
Thus,
Backward difference
Therefore,
and,
Central difference
Then,
and,
To demonstrate the order of convergence numerically, we define
Then, It follows that,
From the theoretical part, we expect to see \(\alpha_{\text{F}} \approx 1\), \(\alpha_{\text{B}} \approx 1\), and \(\alpha_{\text{C}} =2 \).
Example: For the above example, test the order of convergence of the forward difference, the backward difference, and the central difference numerically.
Solution: We create a table in the form of the following table for this Example. Because of the nature of this question, it would be simpler to try this in Python, MATLAB, or another programming language.
import numpy as np
import pandas as pd
# f(x)
f = lambda x: 3*x*np.exp(x) - np.cos(x)
# f''(x)
f2 = lambda x: np.cos(x) + 6*np.exp(x) + 3*x*np.exp(x)
a = 0; b = 1; h = 0.1; t = 0.5;
h = [2**(-i) for i in range(4, 12)]
Cols = ['h', 'EhF', 'EhB', 'EhC']
Table = pd.DataFrame(np.zeros([len(h), len(Cols)], dtype = float), columns=Cols)
Table[Cols[0]] = h
for i in range(len(h)):
xn = np.arange(a, b, h[i])
yn = f(xn)
Ind = np.arange(2, len(xn)-2)
# Exact
Exact = f2(xn[Ind])
# Forward difference
Forward = (yn[Ind+2]-2*yn[Ind+1]+yn[Ind])/(h[i]**2)
Table[Cols[1]][i] = max(abs(Forward - Exact))
# Backward difference
Backward = (yn[Ind]-2*yn[Ind-1]+yn[Ind-2])/(h[i]**2)
Table[Cols[2]][i] = max(abs(Backward - Exact))
# Central difference
Central = (yn[Ind+1]-2*yn[Ind]+yn[Ind-1])/(h[i]**2)
Table[Cols[3]][i] = max(abs(Central - Exact))
del Forward, Backward, Central, Exact, xn, yn, Ind
Table.insert(1, 'N', ((b-a)/Table['h']).astype(int))
display(Table.style.set_properties(subset=['h', 'N'], **{'background-color': 'PaleGreen', 'color': 'Black',
'border-color': 'DarkGreen'}).format(dict(zip(Table.columns.tolist()[-3:], 3*["{:.4e}"]))))
h | N | EhF | EhB | EhC | |
---|---|---|---|---|---|
0 | 0.062500 | 16 | 1.6406e+00 | 1.4954e+00 | 1.0369e-02 |
1 | 0.031250 | 32 | 9.0253e-01 | 8.6172e-01 | 2.9146e-03 |
2 | 0.015625 | 64 | 4.7335e-01 | 4.6254e-01 | 7.7237e-04 |
3 | 0.007812 | 128 | 2.4240e-01 | 2.3962e-01 | 1.9879e-04 |
4 | 0.003906 | 256 | 1.2266e-01 | 1.2195e-01 | 5.0424e-05 |
5 | 0.001953 | 512 | 6.1696e-02 | 6.1519e-02 | 1.2698e-05 |
6 | 0.000977 | 1024 | 3.0941e-02 | 3.0896e-02 | 3.1860e-06 |
7 | 0.000488 | 2048 | 1.5493e-02 | 1.5482e-02 | 8.0559e-07 |
# This part is used for producing tables and figures
import sys
sys.path.insert(0,'..')
import hd_tools as hd
from bokeh.plotting import show
hd.derivative_ConvergenceOrder(vecs = [Table['EhF'].values, Table['EhB'].values, Table['EhC'].values],
labels = ['Forward Difference', 'Backward Difference', 'Central Difference'],
xlabel = r"$$i$$",
ylabel = r"$$\log_{2} \left( E_{h_{i}} / E_{h_{i-1}} \right)$$",
title = 'Order of accuracy: Forward, Backward and Central Differences',
legend_orientation = 'horizontal', ylim = [0, 2.1])