有一位數學家叫泰勒,某天看到一個函數 \(y = cosx\),瞬間眉頭一皺,心里面不斷犯嘀咕。有些函數它就是很惡心,本來這些函數具備很優秀的品質(可以輕松地無限次求導),但如果代入數值計算的話就比較困難了。比如這里的 \(f(x) = cosx\),在沒有計算機的年代,很難計算出 \(x = 2\) 時 \(f(x)\) 的值。
為避免這種尷尬局面,泰勒就開始想:我能不能找到另一條曲線 \(g(x)\),它和 \(f(x)\) 無限相似,但相比之下卻能更簡單地進行求值呢?所以面對 \(f(x) = cosx\),泰勒的目的是仿造一條一模一樣的曲線,從而避免余弦計算。
想要復制這段曲線,首先得找一個切入點,可以是這條曲線最左端的點,也可以是最右端的點,亦或是這條線上任何一點,而泰勒選擇了 \((0, 1)\)。由於這段曲線經過 \((0, 1)\) 這個點,那么仿造的第一步就是讓仿造的曲線也經過這個點。並且仿造的曲線也要能夠很輕松地根據 x 進行求值,否則仿造就沒有意義了。
經過 \((0, 1)\) 的曲線有很多,比如 \(f(x) = x^2 + 1\),但它們僅僅是經過了 \((0, 1)\) 這個點,至於其它的部分則和 \(f(x) = cosx\) 沒有任何相似之處。所以泰勒不僅要保證仿造的曲線過 \((0, 1)\) 點,還要保證在這一點導數和原曲線也是相等的,導數相同意味着變化趨勢相同。
還沒結束,起始點相同,變化趨勢相同,還要考慮曲線的凸凹性。我們知道表征曲線的凸凹性的參數被稱為"導數的導數",所以還要保證導數的導數相等。於是泰勒開始動手計算了,首先他知道自己要仿照一段曲線,從 \((0, 1)\) 入手,要保證:
- 初始值相同:\(g(0) = f(0)\)
- x = 0 處的一階導相同:\(g'(0) = f'(0)\)
- x = 0 處的二階導相同:\(g''(0) = f''(0)\)
- ............
- x = 0 處的 n 階導相同:\(g^{'''...}(0) = f^{'''...}(0)\),光有一階和二階是不夠的
這時候,泰勒思考了兩個問題:
1)余弦函數能夠無限次求導,為了讓這兩條曲線無限相似,自己仿造出來的 g(x) 必須也能夠無限次求導,那 g(x) 得是什么樣類型的函數呢?
2)實際操作過程中,肯定不能無限次求導,只需要求幾次,就可以達到想要的精度。那么,實際過程中應該求幾次比較合適呢?
綜合考慮這兩個問題以后,泰勒給出了一個比較折中的方法:令 \(g(x)\) 為多項式,多項式能求幾次導數取決於多項式本身。比如五次多項式 \(g(x) = ax^5 + bx^4 + cx^3 + dx^2 + ex + f\) 能求 5 次導,再求就是 0 了,所以幾次多項式就能求幾次導數。
所以泰勒就開始使用多項式來模擬了,很明顯為了發現規律,要從最低次開始,所以選擇了 \(g(x) = 1\)。
由於 \(cos'x = -sinx,sin'x = cosx\),所以 \(cosx\) 在 x = 0 處的一階導數為 0(\(-sin0\))、二階導數為 -1(\(-cos0\))、三階導數為 0(\(sin0\))、四階導數為 1(\(cos0\)),以此類推。
除了都經過 \((0, 1)\)、以及在 x=0 處的導數均為 0 之外,沒有任何相似之處,那么下面要滿足二階導也相等。所以泰勒選擇了 \(g(x) = -{\frac 1 2}x^{2} + 1\):
我們看到在 \((0, 1)\) 附近的一個小范圍內,二者擬合的比較好。那么多項式的階數再提高一些,也就是保證更高階的導數相等,比如 4 介導。於是泰勒經過一番計算之后,找到了一階到四階都和 \(cosx\) 相等的多項式:\(g(x) = {\frac 1 {24}}x^{4} - {\frac 1 2}x^{2} + 1\)。
可以看到兩條曲線擬合的程度變高了,因此不光是泰勒,相信我們也可以想到,如果繼續提高多項式的階數,只要使得它們在 n 次求導之后的導數都相同,那么無窮高階后,兩條曲線一定是無限相似的。
但問題是泰勒當時沒有計算機,只能手算,和我們一樣算到四階就算不動了,他就開始發呆:我在哪?我是誰?我在做什么?哦對了,是為了找一個多項式,方便計算 cos2。但問題他是從 \(x=0\) 開始算的,距離 \(x=2\) 還有一段距離,必須得繼續算才能將兩曲線重合的范圍輻射到 \(x=2\) 處。站在上帝視角的我們從上圖中可以看到,兩條曲線在 \(x=2\) 處還是沒有擬合的,如果想擬合,那么至少需要再找一個 5 階多項式,保證讓它們的五階導也相同。
但很明顯它算不下去了,咋辦呢?突然他一拍腦門,恍然大悟,既然我選的點離着我想要的點比較遠,那我為啥不直接選個近的點呢,反正能從這條曲線上任何一個點作為切入,開始仿造,近了能省很多計算量啊。比如上圖是從 \((0, 1)\) 切入的,雖然計算 \(x=2\) 還有誤差,但計算 \(x=1\) 是可以的,因為 \(x=1\) 離選擇的點要更近。
x = 1
print(np.cos(x)) # 0.5403023058681398
print(x ** 4 / 24 - x ** 2 / 2 +1) # 0.5416666666666667
保留兩位小數的話,顯然是相等的。於是為了計算 \(cos2\) 的泰勒,不從 \((0, 1)\) 開始切入了,他選擇了從 \(({\frac π 2}, 1)\)、也就是 \(x={\frac π 2}\) 處開始切入。
所以這就是泰勒展開式,相信你已經理解了。本質上就是"仿造",即:把一個三角函數、指數函數、亦或是其它比較難纏的函數用多項式替換掉。也就是說,有一個原函數 \(f(x)\),再造一個圖像與之相似的函數 \(g(x)\),為了保證兩者圖像相似,只需要保證在某一點的初始值、以及一階導函數的值、二階導函數的值、......、n 階導函數的值相等即可。只要能保證這一點,那么兩個函數的圖像就是相似的。
但是泰勒算到四階之后就不想算了,所以他想把這種計算過程推廣到 n 階,算出一個代數式,然后直接代數就可以了,於是就有了下面的推導過程。
首先要在原曲線 \(f(x)\) 上選擇一個點,為了方便就選 \((0, f(0))\),而仿造的曲線是一個能求 n 介導的多項式,所以它的最高次數一定也是 n,所以其解析式肯定是下面這種形式:
\(g(x) = a_{0} +a_{1}x + a_{2}x^{2} + a_{3}x^{3}...... + a_{n}x^{n}\)
首先要保證初始值相同,由於我們選擇的是 \((0, f(0))\),那么一定有 \(f(0) = g(0) = a_{0}\)。然后保證 n 階導數相等,即\(g^{n}(0) = f^{n}(0)\),因為對 \(g(x)\) 求 n 階導數時,只有最后一項非零值,所以我們只看最后一項。
- \(a_{n}x^{n}\) 求一階導,得到 \(na_{n}x^{n-1}\);
- \(a_{n}x^{n}\) 求二階導,得到 \(n(n-1)a_{n}x^{n-2}\);
- \(a_{n}x^{n}\) 求三階導,得到 \(n(n-1)(n-2)a_{n}x^{n-3}\);
- \(a_{n}x^{n}\) 求 n 階導,得到 \(n(n-1)(n-2)··· 2*1*a_{n}x^{0}\),即 \(n!a_{n}\);
所以 \(g^{n}(0) = n!a_{n} = f^{n}(0)\),由此得出 \(a_{n} = {\frac {f^{n}(0)} {n!}}\)。然后根據規律,對 \(g(x)\) 中的 \({a_{i}}\) 進行替換,即可得出:
\(g(x) = g(0) + {\frac {f^{1}(0)} {1!}}x + {\frac {f^{2}(0)} {2!}}x^{2} + {\frac {f^{3}(0)} {3!}}x^{3}...... + {\frac {f^{n}(0)} {n!}}x^{n}\)
以上就是整個推導過程,還是很簡單的,但是到這里泰勒又想到了一個問題,那就是不一定非要從 \(x=0\) 的位置切入,也可以從 \(x=x_{0}\) 處開始。只要將 0 換成 \(x_{0}\) 再按照上面的流程重來一遍,即可得到如下結果:
\(g(x) = g(x_{0}) + {\frac {f^{1}(x_{0})} {1!}}(x-x_{0}) + {\frac {f^{2}(x_{0})} {2!}}(x-x_{0})^{2} + {\frac {f^{3}(x_{0})} {3!}}(x-x_{0})^{3}...... + {\frac {f^{n}(x_{0})} {n!}}(x-x_{0})^{n}\)
寫到這里,泰勒長舒一口氣,寫下結論:有一條解析式很惡心的曲線 \(f(x)\),那么可以用多項式仿照一條曲線 \(g(x)\),並且滿足:
\(f(x) ≈ g(x) = g(x_{0}) + {\frac {f^{1}(x_{0})} {1!}}(x-x_{0}) + {\frac {f^{2}(x_{0})} {2!}}(x-x_{0})^{2} + {\frac {f^{3}(x_{0})} {3!}}(x-x_{0})^{3}...... + {\frac {f^{n}(x_{0})} {n!}}(x-x_{0})^{n}\)
泰勒指出:在實際操作過程中,可根據精度要求選擇 n 值,只要 n 不是正無窮,那么一定要保留上式中的約等號。若想去掉約等號,需要寫成下面形式:
\(f(x) = g(x) = g(x_{0}) + {\frac {f^{1}(x_{0})} {1!}}(x-x_{0}) + {\frac {f^{2}(x_{0})} {2!}}(x-x_{0})^{2} + {\frac {f^{3}(x_{0})} {3!}}(x-x_{0})^{3}...... + {\frac {f^{n}(x_{0})} {n!}}(x-x_{0})^{n} + ······\)
以上就是泰勒展開式,只要理解了背后的思想還是很好推理的。
那么根據泰勒展開式,像 \(e^{x}\)、\(sin(x)\)、\(cos(x)\) 這些函數我們可以很輕松地用多項式進行替代,舉個栗子:
- 當 \(x_{0}\) 取 \(0\) 時, \(e^{x} = 1 + x + {\frac 1 {2!}}x^{2}+{\frac 1 {3!}}x^{3}+···\)
- 當 \(x_{0}\) 取 \(0\) 時,\(sinx = x - {\frac 1 {3!}}x^{3}+{\frac 1 {5!}}x^{5}+···\);
- 當 \(x_{0}\) 取 \(0\) 時,\(cosx = 1-{\frac 1 {2!}}x^{2}+{\frac 1 {4!}}x^{4}···\)
以上也被成為麥克勞林公式,當然麥克勞林公式只是泰勒展開式在 \(x_{0}\) 取 \(0\) 時的一種特殊形式。但這不是關鍵,如果將 \(e^{x}\) 里面的 \(x\) 換成 \(ix\),其中 \(i\) 為虛數,那么就有:
\(e^{ix} = 1 + ix -{\frac 1 {2!}}x^{2}-i{\frac 1 {3!}}x^{3}+{\frac 1 {4!}}x^{4}+i{\frac 1 {5!}}x^{5}+···= cosx + i*sinx\)
所以我們就得到了著名的公式,歐拉公式:\(e^{ix} = cosx + i*sinx\),如果將 \(x\) 換成 \(π\),那么便可得到一個最美的式子:\(e^{iπ} + 1 = 0\)。這個式子它美在哪兒呢?我們看到 \(e\) 是自然對數的底數、\(i\) 是虛數、\(pi\) 是無理數、\(1\) 是有理數,這幾個看起來毫無關系的數組合起來,相加居然等於 \(0\)。
后續
但是故事還沒有結束,泰勒雖然留下了這個式子,但是他沒有告訴你到底該求導幾次,所以便有了一幫人幫他擦屁股。
第一個幫他擦屁股的人叫佩亞諾,泰勒只將展開式寫到了第 n 項,佩亞諾將省略號的部分給補全了。
\(f(x) = g(x) = g(x_{0}) + {\frac {f^{1}(x_{0})} {1!}}(x-x_{0}) + {\frac {f^{2}(x_{0})} {2!}}(x-x_{0})^{2} + {\frac {f^{3}(x_{0})} {3!}}(x-x_{0})^{3}+··· + {\frac {f^{n}(x_{0})} {n!}}(x-x_{0})^{n} + {\frac {f^{(n+1)}(x_{0})} {(n+1)!}}(x-x_{0})^{n+1}+···+{\frac {f^{(∞)}(x_{0})} {∞!}}(x-x_{0})^{∞}\)
從第 n + 1 項開始的部分就是誤差,於是佩亞諾開始思考,怎么能讓誤差無限趨近於 0。因為一旦誤差趨近於 0 了,那么就可以省去了,泰勒展開只需要展開到 n 階就可以了。
於是這個小機靈鬼發現只要讓 \(x\) 趨近於 \(x_{0}\) 不就行了嗎?看到這,是不是一臉無語。總結一下皮亞諾的思路:首先它把泰勒展開式中沒寫出來的部分給補全,然后將這些項之和稱為誤差項,之后他想把誤差項變成 0。於是對式子做了一些變換,最后發現只有當 \(x\) 趨近於 \(x_{0}\) 的時候,誤差項才為 0。
說實話,感覺像是說了一堆廢話,但是為了紀念他,將這些誤差項稱為佩亞諾余項。
下面第二個擦屁股的人登場了,這個人叫拉格朗日,我們從頭說起。有一天拉格朗日閑得無聊,思考了一個特別簡單的問題:一輛車從 \(S_{1}\) 處走到了 \(S_{2}\) 處,用了時間 \(t\),那么這輛車的平均速度就是 \(v={\frac {S_{1}-S_{2}} t}\)。
但車不是勻速直線運動,那么肯定有一個時刻的瞬時速度是小於 \(v\) 的,同理也會有一個時刻的瞬時速度是大於 \(v\) 的。由於車的速度不能突變,那么從小於 \(v\) 到大於 \(v\) 這一過程,肯定有一個瞬間,車的速度等於 \(v\)。
即使沒有聽過拉格朗日,相信也能想明白這個問題,但拉格朗日的牛逼之處在於,能把生活中的小事翻譯成數學語言,並畫成了圖像。
把上面這個簡單的問題用數學語言描述出來的話,就得到了拉格朗日中值定理:有一個函數 \(S(t)\),如果在 \(t_{1}\) 到 \(t_{2}\) 范圍連續且可導,那么有:\({\frac {S(t_{2}) - S(t_{1})} {t_{2} - t{1}}} = S'(t)\),其中 \(t∈[t_{1}, t_{2}]\)。
后來拉格朗日的中值定理被柯西看到了,柯西天生對於算式敏感。柯西認為,縱坐標是橫坐標的函數,那我也可以把橫坐標寫成一個函數啊,於是他提出了柯西中值定理:
\({\frac {S(t_{2}) - S(t_{1})} {T(t_{2}) - T(t_{1})}} = {\frac {S'(t) } {T'(t)}}\)
拉格朗日聽說了這事之后,心里憤憤不平,又覺得很可惜。明明是自己的思路,明明是我先的,結果差這么一步,就讓柯西撿便宜了,不過柯西確實說的有道理,這件事給拉格朗日留下了很深的心理陰影。
接下來,拉格朗日開始思考泰勒級數的誤差問題,他同佩亞諾一樣,也只考慮誤差部分。先把誤差項寫出來,記為 \(R(x)\)。
\(R(x) = {\frac {f^{(n+1)}(x_{0})} {(n+1)!}}(x-x_{0})^{n+1}+{\frac {f^{(n+2)}(x_{0})} {(n+2)!}}(x-x_{0})^{n+2}+···+{\frac {f^{(∞)}(x_{0})} {∞!}}(x-x_{0})^{∞}\)。
顯然 \(R(x_{0}) = 0\)。
誤差項 \(R(x)\) 中的每一項都是兩數的乘積,假如是你,你肯定是想兩邊同時除掉一個 \((x - x_{0})^{n+1}\) 對吧。為了簡單,我們將其記作 \(T(x)\)。
所以除過之后,就變成了:
等等,這一串東西怎么看着如此眼熟?咦,這不是柯西老哥推廣的我的中值定理么?剩下的不就是……
然后拉格朗日繼續嘗試,先看分子:
再看分母:
好巧,又可以用一次柯西的中值定理了。
總之,按照這種方法,可以一直求解下去,最終的結果就是:誤差項 = \({\frac {f^{n+1}(ξ)} {(n+1)!}}(x - x_{0})^{n+1}\)
至此,拉格朗日把后面無數多的誤差項給整合成了一項,而且比配諾亞更加先進的地方在於,不一定非要讓 \(x\) 趨近於 \(x_{0}\),可以在二者之間的任何一個位置 ξ 處展開,極其好用。
本文來自於:知乎陳二喜,一個騷氣十足的美男子,擁有着萬里挑一的有趣靈魂。