关于高等数学:泰勒展开的一点笔记

· · 个人记录

评价:是个很nb的东西。

引入

泰勒展开就是让一个多项式函数代替原来的复杂的函数的作用,在工程学中可以用作近似计算。

引入泰勒展开,需要我们掌握一点高数知识。那首先先给出几个比较重要的极限:

\begin{aligned} &\lim_{x\to 0}\dfrac{\sin x}{x}=1&\qquad (1)\\ &\lim_{x\to \infty}(1+\dfrac{1}{x})^x=e &\qquad (2)\\ &\lim_{x\to 0}\dfrac{\log_a(1+x)}{x}=\dfrac{1}{\ln a} &\qquad (3)\\ &\lim_{x\to 0}\dfrac{a^x-1}{x}=\ln a &\qquad (4)\\ &\lim_{x\to 0}\dfrac{(1+x)^{\alpha}-1}{x}=\alpha &\qquad (5)\\ \end{aligned}

其中 (2)e 的定义,所以我们就证明该式是收敛的即可。

证明先鸽。

所以就有以下常用无穷小关系:\sin x\sim x\ln (1+x)\sim xe^x\sim 1+x(1+x)^{\alpha}\sim \alpha x+1,我们可以认为,在 |x| 足够小的时候,式子近似相等。这时的误差为 o(x),即 x 的高阶无穷小。

但是这种近似表达式的精确度不高,它所产生的误差仅是关于 x 的高阶无穷小。为了提高精确度,自然想到用更高次的多项式来逼近函数。——高等数学 上册

正题:Taylor Formula(%%%泰勒%%%)

提出公式

从上面的问题,我们提出:

f(x)x_0 处具有 n 阶导数,试找出一个关于 (x-x_0)n 次多项式

p_n(x)=\sum_{i=0}^{n}a_i(x-x_0)^i=a_0+a_1(x-x_0)+a_2(x-x_0)^2+\cdots+a_n(x-x_0)^n

来近似表达 f(x),要求使得 p_n(x)f(x) 的差是当 x\to x_0 时比 (x-x_0)^n 高阶的无穷小。下假设 \forall \,i\le n,f^{(n)}(x_0)=p_n^{(n)}(x_0)。按照这个关系来确定 a_i 的值,得到

a_i=\dfrac{f^{(i)}(x_0)}{i!}

所以就有

p_n(x)=\sum_{i=0}^{n}a_i(x-x_0)^i=\sum_{i=0}^{n}\dfrac{f^{(i)}(x_0)}{i!}(x-x_0)^i

其中 x_0 是自己为了方便计算而选取的一个数。

证明公式

前置知识

费马引理 \to 罗尔定理 \to 拉格朗日中值定理 and 柯西中值定理

证明有点多,暂时不想写。。。

泰勒(Taylor)中值定理 1

如果函数 f(x)x_0 处具有 n 阶导数,那么存在 x_0 的一个邻域,对于该邻域的任一 x,有

f(x)=\sum_{i=0}^{n}\dfrac{f^{(i)}(x_0)}{i!}(x-x_0)^i+R_n(x)

其中

R_n(x)=o(\,(x-x_0)^n\,)

R_n(x)=f(x)-p_n(x),则

R_n(x_0)=R_n'(x_0)=R_n''(x_0)=\cdots=R_n^{(n)}(x_0)=0

可以反复应用洛必达法则,得

\begin{aligned} \lim_{x\to x_0}\dfrac{R_n(x)}{(x-x_0)^{}} &=\lim_{x\to x_0}\dfrac{R_n'(x)}{n(x-x_0)^{n-1}}=\lim_{x\to x_0}\dfrac{R_n''(x)}{n(n-1)(x-x_0)^{n-2}}\\ &=\cdots =\lim_{x\to x_0}\dfrac{R_n^{(n-1)}(x)}{(x-x_0)}\\ &=\dfrac{1}{n!}\lim_{x\to x_0}\dfrac{R_n^{(n-1)}(x)-R_n^{(n-1)}(x_0)}{(x-x_0)^{}}\\ &=\dfrac{1}{n!}R_n^{(n)}(x_0)=0 \end{aligned}

因此 R_n(x)=o(\,(x-x_0)^n\,),定理证毕。

然后这个 f(x) 的展开式子被称为 f(x)x_0 处(或按 (x-x_0) 的幂展开)的带有佩亚诺(Peano)余项n 次泰勒公式。

我们发现,这里的误差 R_n(x)x\to x_0 时比 (x-x_0)^n 高阶的无穷小,但不能估算出误差的大小,于是就有了下面的定理2。

泰勒(Taylor)中值定理 2

如果函数 f(x)x_0 的某个邻域 U(x_0) 内具有 (n+1) 阶导数,那么对任一 x\in U(x_0),有

f(x)=\sum_{i=0}^{n}\dfrac{f^{(i)}(x_0)}{i!}(x-x_0)^i+R_n(x)

其中

R_n(x)=\dfrac{f^{(n+1)}(\xi)}{(n+1)!}(x-x_0)^{n+1}

这里 \xix_0x 之间的某个值。

R_n(x)=f(x)-p_n(x),则

R_n(x_0)=R_n'(x_0)=R_n''(x_0)=\cdots=R_n^{(n)}(x_0)=0

对两个函数 R_n(x)(x-x_0)^{n+1} 在以 x_0x 为端点的区间上应用柯西中值定理(显然满足柯西中值定理的条件),得

\begin{aligned} \dfrac{R_n^{}(x)}{(x-x_0)^{n+1}} &=\dfrac{R_n^{}(x)-R_n(x_0)}{(x-x_0)^{n+1}-0}=\dfrac{R_n'(\xi_1)}{(n+1)(\xi_1-x_0)^{n}} &(\text{ $\xi_1$ 在 $x_0$ 与 $x$ 之间})\\ &=\dfrac{R_n'^{}(\xi_1)-R_n(x_0)}{(n+1)(\xi_1-x_0)^{n+1}-0}=\dfrac{R_n''(\xi_2)}{(n+1)n(\xi_2-x_0)^{n-1}} &(\text{ $\xi_2$ 在 $x_0$ 与 $\xi_1$ 之间})\\ &=\cdots\\ &=\dfrac{R_n^{(n+1)}(x)}{(n+1)!} &(\text{ $\xi$ 在 $x_0$ 与 $\xi_n$ 之间,因而也在 $x_0$ 和 $x$ 之间})\\ \end{aligned}

又有 p_n^{(n+1)}=0,所以 R_n^{(n+1)}(x)=f^{(n+1)}(x),则可得到

R_n(x)=\dfrac{f^{(n+1)}(\xi)}{(n+1)!}(x-x_0)^{n+1}

定理证毕。

于是,由这个东西我们可以得到,当 x\in U(x_0) 时,若 |f^{(n+1)}(x_0)|\le M,则有误差估计

|R_n(x)|\le \dfrac{M}{(n+1)!}|x-x_0|^{n+1}

而这个 f(x) 的展开式子被称为 f(x)x_0 处(或按 (x-x_0) 的幂展开)的带有拉格朗日余项n 次泰勒公式,而 R_n(x) 的表达式称为拉格朗日余项

另外,从这里我们就可以发现,当 n=0 时,就变成了拉格朗日中值公式

f(x)=f(x_0)+f'(\xi)(x-x_0)\qquad\qquad(\text{ $\xi$ 在 $x_0$ 与 $x$ 之间})

麦克劳林公式

其实就是泰勒公式取 x_0=0 的情况。

例子

根据泰勒公式,我们可以对 \sin x 进行展开,然后可以看到下面这幅图,当展开的更多的时候,就越来越接近了:

\color{green}\text{绿色的线为 }\sin x

应用

常用公式

根据这个,我们得到了几个常用的泰勒公式:

\begin{aligned} \sin x&=x-\dfrac{x^3}{3!}+\dfrac{x^5}{5!}-\dfrac{x^7}{7!}+\cdots\\ \cos x&=1-\dfrac{x^2}{2!}+\dfrac{x^4}{4!}-\dfrac{x^6}{6!}+\cdots\\ e^x&=1+1+\dfrac{x^2}{2!}+\dfrac{x^3}{3!}+\dfrac{x^4}{4!}+\cdots\\ \ln (1+x)&=x-\dfrac{x^2}{2}+\dfrac{x^3}{3}-\dfrac{x^4}{4}+\cdots\\ (1+x)^{\alpha}&=1+\alpha x+\dfrac{\alpha(\alpha-1)}{2!}x^2+\dfrac{\alpha(\alpha-1)(\alpha-2)}{3!}x^3+\cdots,\alpha\in \mathbb{R} \end{aligned}

通过这个,我们还可以证明 e^{i\pi}=\cos \pi+i\sin \pi=-1

e 的无穷级数公式

直接选择 e^x 那个,就可以得到了 e=1+1+\dfrac{1}{2!}+\dfrac{1}{3!}+\cdots

\pi 的无穷级数公式

要有 e 当然也要有 \pi 啊。

这里就不写了,给出这个和这个。

牛顿迭代法

就是一个求近似根的工具,具体是这样的:

首先我们假设 f(x)=0[l,r] 中有且仅有一个根 x。然后取 1 阶展开

f(x)=f(x_0)+f'(x_0)(x-x_0)

移项得

x=x_0-\dfrac{f(x_0)}{f'(x_0)}

但是实际上这不是真正的 x,我们需要对其进行多次迭代,使得误差变小。

牛顿迭代法的时间复杂度怎么计算?看不懂,但知道很快就行(虽然都好像是 O(\log n),但是比二分快得多)

例如可以求 \sqrt{n},这里有实现。

float SqrtByNewton(float x)
{
    float res=x;
    float last;
    while(abs(res-last)>eps)
    {
        last=res;
        res=(res+x/res)/2;
    }
    return res;
}

顺便 mark 一下超越 system 的平方根做法(神奇的常数 0x5f3759df):

其实使用的也是牛顿迭代法,但是一开始猜想一个根的部分就使得迭代次数非常少(甚至一次就搞定了),都归功于这个神奇的常数。

float Q_rsqrt(float number)
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;   //evil floating point bit level hacking
    i  = 0x5f3759df - (i >> 1 ); //what the fuck?
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) );// 1st iteration
//    y  = y * ( threehalfs - ( x2 * y * y ) );// 2nd iteration, this can be removed

    #ifndef Q3_VM
    #ifdef __linux__
        assert( !isnan(y) );// bk010122 - FPE?
    #endif
    #endif
    return y;
}