Wang Haihua
🍈 🍉🍊 🍋 🍌
上文《数学 微积分05 一阶导数与最优值点》讲到我们可以通过解导数为零的方程求解临界值点进而获得最小值点或最大值点。然而,导数并不能提供关于临界点性质的信息,因为它对于极大值点、极小值点和鞍点都等于零。
上一讲导数给出了数在点附近的线性特性。在临界点,当导数为零时,这种线性特性就不起作用了。我们可以通过观察该点周围的二阶导来获得进一步的信息。这也对应于函数与抛物线的最佳(局部)近似:
对于函数 $f(x)$ 和点 $x_0$. 该函数在点处的二次(抛物线)逼近(quadradic approximation)可由以下表达式给出:
$$ f_p(x) = a (x - x_0)^2 + \dfrac{df(x_0)}{dx} (x - x_0) + f(x_0) $$我们已经知道常数项是$f(x_0)$,一次项系数为$\dfrac{df(x_0)}{dx}$. 我们怎样确定二次项系数$a$呢?为此,我们需要引入二阶导数(second derivative)的概念。 函数$f(x)$的二阶导数定义为其导数的导数:
$$ \dfrac{d^2 f(x)}{d x^2} = \dfrac{d}{dx}\left(\dfrac{df(x)}{dx} \right) $$考虑如下二次函数
$$ q(x) = \alpha (x - x_0)^2 + \beta (x - x_0) + \gamma $$它的导数是:
$$ \dfrac{q(x)}{dx} = 2 \alpha (x - x_0) + \beta $$然后我们对导数继续求导:
$$ \dfrac{d}{dx}\left(\dfrac{dq(x)}{dx} \right) = \dfrac{d (2 \alpha (x - x_0) + b)}{dx} = 2 \alpha $$我们发现二次函数的二阶导数等于其二次系数$\alpha$的两倍。 这样我们就可以通过求函数在点$x_0$的二阶导数来获得逼近原函数的二次近似函数的系数$a$了。
从上例求解过程我们也可以总结出来,对于一个二次函数而言,它的二阶导等于它二次项系数的两倍:
$$ a = \dfrac{1}{2}\dfrac{d^2 f(x_0)}{d x^2} $$因此,局部二次逼近由下式给出
$$ f_p(x) = \dfrac{1}{2}\dfrac{d^2 f(x_0)}{d x^2} (x - x_0)^2 + \dfrac{df(x_0)}{dx} (x - x_0) + f(x_0) $$我们来考虑临界点附近的最佳二次逼近的情况。在这种情况下,一阶导数消失了,我们只剩下一个更简单的近似:
$$ f_p(x) = \dfrac{1}{2}\dfrac{d^2 f(x_0)}{d x^2} (x - x_0)^2 + f(x_0) $$如图所示线性近似是一个常数函数,二次逼近是一条开口向下的抛物线,其最大值点在函数$f(x)$的最大值处。
我们再来看一个关于最小值点的二次逼近:
在这种情况下,二阶导数是正的,抛物线开口向上。 这样我们就找出了一种找出临界点是最大值点还是最小值点的方法。我们只需要看一下临界点处二阶导数的符号。如果二阶导数是正的,临界点就是最小点;如果二阶导数是负的,临界值点就是最大值点。
考虑如下函数
$$ f(x) = x \mathrm{e}^x + 1 $$它的导数是:
$$ \frac{f(x)}{dx} = \mathrm{e}^x(1 + x) $$可根据下列方程求出临界点
$$ \mathrm{e}^x (1 + x) = 0 $$因为 $\mathrm{e}^x$ 恒大于0, 我们将方程两边同除 $\mathrm{e}^x$ 就得到:
$$ 1 + x = 0 $$进而
$$ x_c = -1 $$现在我们来看看二阶导数在这个临界点的值。二阶导数为:
$$ \dfrac{d(\mathrm{e}^x (1 + x))}{dx} = \mathrm{e}^x (2 + x) $$在点 $x = x_c = -1$处的二阶导为:
$$ \dfrac{d^2f(-1)}{dx} = \mathrm{e}^{-1} (2 - 1) = \mathrm{e}^{-1} = \dfrac{1}{\mathrm{e}} $$因为二阶导值为正数,因此$x_c = -1$ 是最小值点
我们可以将二阶导数推广到任意高阶的$k$阶导数,只需对函数进行连续$k$次求导:
$$\frac{d^k f}{d x^k} = \underbrace{\frac{d}{d x} \frac{d}{dx} ... \frac{d}{d x}}_{k \text{ times}} f(x)$$我们可以用这些高阶导数来寻找函数更好的局部逼近。这些近似形式称为泰勒展开式。线性近似是一阶泰勒展开式,而二次近似是二阶展开式。$k$-阶展开式是$k$-次多项式近似函数。由以下公式定义:
$$ f_K(x) = \displaystyle\sum_{j = 0} ^K \dfrac{1}{j!} \dfrac{d^j f(x_0)}{d x^j} (x - x_0)^j $$其中 $j! = j \cdot (j-1) \cdot (j - 2) \cdot \ldots \cdot 2 \cdot 1$ 是 $j$的阶乘. 在这个公式中,0阶导数可以理解为函数本身: $$ \dfrac{d^0 f(x)}{d x^0} = f(x) $$
由阶乘定义 $0!=1$
这些越来越好的多项式近似如下图所示:
import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
import pandas as pd
import scipy.stats
plt.rcParams['font.family']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
%matplotlib inline
二次近似
f = lambda x: np.sin(x)
df = lambda x: np.cos(x)
ddf = lambda x: -np.sin(x)
x_range = np.linspace(-np.pi,np.pi,100)
x0 = 1/2
fl = lambda x: f(x0) + df(x0)*(x - x0)
fp = lambda x: f(x0) + df(x0)*(x - x0) + 0.5*ddf(x0)*(x - x0)**2
plt.plot(x_range, f(x_range), c="k", label ="f(x)")
plt.plot(x_range, fl(x_range), label="线性近似")
plt.plot(x_range, fp(x_range), label="二次近似")
plt.axvline(x0, ls="--", c="k", label="近似点")
plt.ylim(-1.2,1.2)
plt.legend(loc="best")
plt.savefig('images/cal0601.png')
x_range = np.linspace(-np.pi,np.pi,100)
x0 = np.pi/2
fl = lambda x: f(x0) + df(x0)*(x - x0)
fp = lambda x: f(x0) + df(x0)*(x - x0) + 0.5*ddf(x0)*(x - x0)**2
plt.plot(x_range, f(x_range), c="k", label ="f(x)")
plt.plot(x_range, fl(x_range), label="线性近似")
plt.plot(x_range, fp(x_range), label="二次近似")
plt.axvline(x0, ls="--", c="k", label="近似点")
plt.ylim(-1.2,1.2)
plt.legend(loc="best")
plt.savefig('images/cal0602.png')
x_range = np.linspace(-np.pi,np.pi,100)
x0 = -np.pi/2
fl = lambda x: f(x0) + df(x0)*(x - x0)
fp = lambda x: f(x0) + df(x0)*(x - x0) + 0.5*ddf(x0)*(x - x0)**2
plt.plot(x_range, f(x_range), c="k", label ="f(x)")
plt.plot(x_range, fl(x_range), label="线性近似")
plt.plot(x_range, fp(x_range), label="二次近似")
plt.axvline(x0, ls="--", c="k", label="近似点")
plt.ylim(-1.2,1.2)
plt.legend(loc="best")
plt.savefig('images/cal0603.png')
例2
f = lambda x: x*np.exp(x)
df = lambda x: np.exp(x)*(1 + x)
ddf = lambda x: np.exp(x)*(2 + x)
x_range = np.linspace(-3,0.5,100)
x0 = -1
fl = lambda x: f(x0) + df(x0)*(x - x0)
fp = lambda x: f(x0) + df(x0)*(x - x0) + 0.5*ddf(x0)*(x - x0)**2
plt.plot(x_range, f(x_range), c="k", label ="f(x)")
plt.plot(x_range, fl(x_range), label="线性近似")
plt.plot(x_range, fp(x_range), label="二次近似")
plt.axvline(x0, ls="--", c="k", label="近似点")
plt.ylim(-1.2,1.2)
plt.legend(loc="best")
plt.savefig('images/cal0604.png')