1. 程式人生 > 其它 >【機器學習】數值分析01——緒論及誤差分析

【機器學習】數值分析01——緒論及誤差分析

數值分析——緒論及誤差分析

全文目錄

(部落格園)機器學習

(Github)MachineLearning Math

數值分析的作用及其學習工具使用

數值分析方法是在解決科學研究和實踐中遇到的各種奇怪複雜問題時,構建一種簡單的數學物理模型來進行研究,最終得到我們需要的解。例如對於一個無法求得原函式的積分,我們可以用足夠多的曲邊梯形面積和進行求解。或者對於一個高次方程,我們也無法直接求得它的零點,那麼這個時候,我們建立對應的數值分析模型時非常有必要的。

數值分析常用工具

對於本系列課程,建議讀者對包括但不限於以下三種語言有一定的瞭解:C#、Matlab、Python ,本系列文章將用以下三種語言對其中涉及的演算法進行Coding和解析。同時推薦安裝以下庫及應用程式:

應用程式:

  • Visual Studio Code:當今最強大的支援拓展的編輯器,適合各種語言的開發工作。強力建議安裝。
  • Visual Studio 2022:宇宙第一IDE,微軟出品的最強開發套件,配合C#如虎添翼事半功倍,建議使用C#的同學們安裝
  • Pycharm:JB公司出品的Python IDE,適合於大型Python專案開發使用。如果只是寫寫小演算法小程式,此軟體過於龐大,吃效能。
  • Matlab:科學計算、建模第一開發工具,其中各種庫可以有效的支撐你的需求,非常強大的一款工具軟體,但是軟體收費且非專業人員許多功能用不上
  • Octave:你可以理解為一個開源免費的Matlab,沒有了商業用途的各種工具庫,只留下了最基礎的一些科學計算和Matlab語言,在科學計算方面非常不錯,吳恩達在機器學習教程中也使用這款工具,推薦使用。
  • GeoGebra全家桶:科學計算、2、3D繪圖最好用的工具之一。

庫及SDK:

  • .NET 6(C#):微軟最新的開發框架,效能速度以及語法已經達到了前幾名的位置,單論語言執行速度效率已經在前幾名,支援U3d,web、ML等各種開發。單獨拎出來是因為微軟旗下庫版本眾多,這裡推薦最新的.NET6
  • MathNet.Numerics:C#.NET上最強大的科學計算工具,在nuget中可以進行下載。
  • NPlot:C#.NET上一個優秀的繪圖工具庫
  • Numpy:python上一個優秀的科學計算庫
  • Matplotlib:python上用於函式、資料等繪圖的工具庫。

數值分析的具體例項(多項式簡化求值)

對於一個複雜多項式的計算,我們往往需要花費巨大的人力逐次計算,比如求:

\[f(x)=3x^4-2x^3+4x^2+5x-1,求f(\frac{1}{2}) \]

最最直接的方法就是進行計算

\[3\times\frac{1}{2}\times\frac{1}{2}\times\frac{1}{2}\times\frac{1}{2}-2\times\frac{1}{2}\times\frac{1}{2}\times\frac{1}{2}+4\times\frac{1}{2}\times\frac{1}{2}+5\times\frac{1}{2}-1 \]

我們計算了10次的乘法,同時還計算了四次加減法運算,這實在是太複雜了,那麼我們試著去優化一下,倘若我將\(a=\frac{1}{2}\times\frac{1}{2}\)記錄一下,那麼式子就可以變成

\[3\times a\times a-2\times a\times\frac{1}{2}+4\times a+5\times\frac{1}{2}-1 \]

這樣,我們包含計算a在內大概需要計算7次乘法,四次加減法運算。很明顯我們減少了不少的計算步驟,那麼繼續試試是否又其他的做法?

\[f(x)=3x^4-2x^3+4x^2+5x-1\\ =x(5+4x-2x^2+3x^3)-1\\ =x(5+x(4-2x+3x^2))-1\\ =x(5+x(4+x(3x-2)))-1 \]

通過這個變換(稱為霍納方法、巢狀乘法),我們只需要進行4次乘法和4次加法,計算的時候從內往外計算。一般而言,任意一個n次多項式都可以通過n次乘法和n次加法求得。

這個例子展示了科學計算的主題特徵,簡單計算的速度總是比複雜的計算快得多,同一個問題當我們採取不同的方法時可能可以有效的提升我們的效率和速度。這也是為什麼數值分析(計算方法)顯得尤為重要的原因。

計算機數值誤差產生機理

計算機的數值儲存方式

這裡我們直接對計算機數值儲存方式進行講解而不作過多的展開。詳細的內容可以參考我《.NET Guide》—— 基本資料型別及其儲存方式 #5.2

計算機誤差產生原因

數值分析是一門建立在計算機計算的基礎上的學科,我們需要詳細解釋一下在計算機中,是什麼導致了誤差的出現。首先丟擲一個問題,為什麼計算機會存在精度問題?或者換句話說,任何非0、5結尾的小數在計算機中都不是一個精確值?

上述問題是一個非常有建設意義的問題,我們知道計算機時使用二進位制進行資料的運算和儲存的,那麼根據二進位制的計演算法則,浮點數的二進位制表示應當是\(\sum i*2^{-n},i \in \{0,1 \},n \in N^+\),根據這個式子不難看出對於二進位制而言,並不能用有限的位數表示所有的浮點數。舉個淺顯的例子,例如十進位制數\((\frac{1}{3})_{10}=0.\dot{3}\),無論我們怎麼寫都無法用有限的十進位制位數寫出準確的數值,只能通過近似的值進行描述,當我們採用三進位制數,我們就能用有限小數 \((0.1)_3\) 進行描述。

因此對於二進位制儲存資訊的計算機來說,資料的儲存位數總是有限度的,我們不可能準確的表述每一個浮點數,於是,對於那些無法表示的數值,我們只能採取近似的手段進行擬合,誤差就出現了。

誤差

誤差限與精度

首先我們給出這樣一個定義,設\(x^*\)是某量的一個精確值,而 \(x\) 是此量的近似值,那麼我們將 \(e = |x^*-x|\) 定義為值的 絕對誤差,也就是誤差

不過在工程實踐中,我們往往是不知道實際值\(x^*\)的,同時誤差e也並不是已知量,我們只能設法在計算過程中採取某些手段,對誤差進行一個估計。這個估計是一個區間範圍,那麼給出下面條件

\[\exist \epsilon>0,\\ |e| = |x^*-x|\leq\epsilon\]

若上式成立,我們則給出了\(x-\epsilon\leq x^*\leq x+\epsilon,x\in[x-\epsilon,x+\epsilon]\),於是我們稱\(\epsilon\)為絕對誤差限,又稱為精度。它描繪了我們近似值與絕對值的相似程度,給出了誤差的最大值。

通常,在同一範圍或數量級內,誤差限越小,也就是我們的資料越精確。當逾越這條線的時候,絕對誤差限就顯得心有餘而力不足了。例如數字的近似值是9999,精確值是10000,它的誤差限是1;若近似值是9,精確值是10,誤差限也是1,很明顯前者的擬合效果要好於後者。我們稱前者是99.99%的吻合度,而後者的吻合度是90%。

上述式子很明顯是因為比較的數量級不同而導致的,為了更好的描述,我們採用相對誤差及相對誤差限進行描述。相對誤差定義為\(e_r=\frac{e}{x^*}=1-\frac{x}{x^*}\),根據量綱的計演算法則,很明顯相對誤差區別於絕對誤差的地方就在於相對誤差是一個無量綱常量,通常也採用百分比作為表示。

與絕對誤差一樣,我們通常無法直接得出\(e_r\)的值,精確值往往也是未知的,同樣的,我們使用相對誤差限去給出一個區間估計。

\[|e_r| = |\frac{e}{x^*}|\leq \epsilon_r \]

這裡我們可以給出任意數值的誤差估計方法,如下式所示:

設有精確值\(x^*_1\),估計值\(x_1\),建構函式\(y=f(x),f(x_1)\)\(x^*_1\)處Taylor展開得:

\[f(x_1) = f(x^*_1)+(\frac{df}{dx_1})^*(x_1-x^*_1)+\frac{1}{2!}(\frac{d^2f}{d^2x_1})^*(x_1-x^*_1)^2+\frac{1}{3!}(\frac{d^3f}{d^3x_1})^*(x_1-x^*_1)^3+\dotsb \]

同時我們知道估計值和精確值的差即為誤差\(e(x_1)\),且為無窮小量,那麼上述式子化為

\[f(x_1)=f(x^*_1)+e(x_1)(\frac{df}{dx_1})^*+\dotsb\\ 故e(f(x))=f(x)-f(x^*)=f(x_1)-f(x^*_1)\approx e(x_1)(\frac{df}{dx_1})^*\]

因此我們得出了誤差的一個分析式,\((\frac{df}{dx_1})^*\)則稱為絕對誤差增長因子,表示誤差經過運算\(f\)後變化的速率或倍數。

同時給出相對誤差估計推導:

\[e(f(x))_r=\frac{e(f(x))}{f(x^*_1)}=(\frac{df}{dx_1})^* \cdot \frac{e(x_1)}{f(x_1^*)}\\ =\frac{x_1^*}{f(x_1^*)}(\frac{df}{dx_1})^*\cdot e_r(x_1)\]

同樣的,\(\frac{x_1^*}{f(x_1^*)}(\frac{df}{dx_1})^*\)則稱為相對誤差增長因子,表示誤差經過運算\(f\)後變化的速率或倍數。

更一般的,給出任意函式的誤差分析式:

\[絕對誤差:e(f)\approx\sum_{i=1}^n \left [\left( \frac{\partial f}{\partial x_i}\right)\cdot e(x_i)\right]\\ 相對誤差:e_r(f)\approx\sum_{i=1}^n \left [\left( \frac{x_i^*}{f(\dotsb)}\cdot\frac{\partial f}{\partial x_i}\right)\cdot e_r(x_i)\right] \]

模型誤差

模型誤差往往是建模過程中,忽略了那些影響細微的次要因素,最終在要求精度的情況下,出現了模型的誤差。例如我們初高中學過的公式\(G=mg\),我們往往會有一句g取9.8N/kg,數學模型描述就為\(G=9.8m\),這裡的g就是一個近似值,而我們知道重力加速度在不同的地方是會受到高度、海拔、地殼密度分佈等等因素影響的,由於我們的重力加速度取了近似值,因此這個模型也是一個近似模型,而這裡必然會產生誤差,由於近似模型導致的誤差我們就稱為模型誤差。

觀測誤差

觀測誤差往往是因為資料的來源受到主觀因素的影響,假設我有一個絕對精準的彈簧式重力計,我們用它去測量物體重量的時候必須通過肉眼去讀取儀器上的刻度數字,在這裡我們因讀數不準產生的誤差就是觀測誤差。或者同上面的質量和重量的方程中,假設我們知道了G,通過計算得出了質量m,它與實際質量的差值就是觀測誤差。

截斷誤差

截斷誤差在計算機和生活中是一個常見誤差。我們在進行大筆金錢交易的時候往往會討價還價,最常見的還價就是“抹零頭”,284元的飯錢講價成280元,這就是一種截斷。計算機因資料溢位而直接抹去首尾的資料時,也是一種截斷,只是這種更多視為一種錯誤,而不是誤差。

如果你對高等數學瞭解一些,那必然知道泰勒展開式是一個無窮級數,我們常常採用帶拉格朗日或皮亞諾餘項去描述誤差,這個誤差也是因為我們只取了有限的項而導致了資料的不精確。

例如下列展開:

\[e^x=S(x)=1+x+\frac{x^2}{2!}+\dotsb+\frac{x^n}{n!} \]

因為我們只採用前n項作為計算,實際的誤差(拉格朗日餘項)就為

\[e^x-S(x) = \frac{x^{n+1}}{(n+1)!}e^{\theta x} \]

舍入誤差

這是平時可能用到最多的一種誤差形式了,四捨五入就是一種常見的舍入誤差。計算機預設就是使用舍入誤差去處理誤差的。只不過計算機由於是二進位制的原因,因此它只要是1就向上進1。採用舍入誤差有一個特性就是你的誤差絕對不會超過區間的一半。

有效數字缺失

有效數字是指數字位數裡第一個非零值到最後的數字,例如0.001就具有一位有效數字。那麼我們為什麼需要去討論有效數字這個問題呢?事實上,仔細想想,如果說我現在需要計算\(\sqrt{9.01}-3\)\(\sqrt{9.01}\)大約是3.0016662,假定我們的計算機只能儲存三位有效數字,上述式子的差異卻需要在第四位有效數字的時候才取到,那麼\(\sqrt{9.01}-3=3-3=0.00\),我們最終得到的資料連一位有效數字都沒有,而實際上我們需要儲存的是\(1.67\times 10^{-3}\)即可獲得更為精確的數字,同樣是三位有效數字,0的答案就是我們的有效數字缺失。那麼如何去避免這個問題呢?

我們如果做下列變換

\[\frac{(\sqrt{9.01}-3)(\sqrt{9.01}+3)}{\sqrt{9.01}+3}=\frac{9.01-9}{6.00}=1.67\times 10^{-3} \]

這樣就避免了在減法過程使得我們早早的丟失了有效資料。

再舉一個例子,有下列式子

\[E_1=\displaystyle \lim_{ x \to 0}\frac{1-cosx}{sin^2x},E_2=\displaystyle \lim_{ x \to 0}\frac{1}{1+cosx} \]

如果高等數學底子好的朋友們應該一眼就能看出這兩個式子是相等的,結果應當是0.5,但是計算機會老老實實的去計算這些資料,先從分子的減法開始計算,如果x足夠的小,那麼\(1-cosx\)最終會因為有效數字過於靠後以至於計算機無法儲存到有效數字從而使得\(E_1=0\)

如下圖所示,當x越發減小,對整個式子結果的改變就越大:

這不是我們希望的結果,於是我們進行恆等變形:

\[\frac{(1+cosx)(1-cosx)}{(1+cosx)sin^2x}=\frac{sin^2x+cos^2x-cos^2x}{(1+cosx)sin^2x}=\frac{sin^2x}{(1+cosx)sin^2x} \]

通過這個變換,巧妙的利用了消去可能導致有效位數缺失的減法操作。

誤差的產生和避免

我們的模型誤差、觀測誤差屬於不可抗力導致的誤差,我們只能儘可能去優化模型和提高精度,但是往往付出了極大代價卻收穫甚微。我們對於誤差的避免更多是採取減少在計算過程中產生的截斷和舍入誤差,儘可能避免有效數字的缺失導致的資料丟失。

一般而言,這些誤差產生通常是因為:

  1. 兩個相近的數字進行減法導致了有效數字的缺失,例如剛才講到的第一個例子,因此實際計算時我們應當避免過於接近的數字進行減法,如果無法避免,則通過平方和一類的公式進行升階擴大處理。
  2. 臨界數(接近資料儲存最大值)先做了加法,例如如果計算機只能儲存3位數字,若不考慮符號位,以無符號數進行計算,最大值應當是7,那麼7+2-3=6很顯然是能在計算機儲存下的,但計算機按著順序計算時會先計算7+2=9=0b1001,最高位將會被丟棄,最終卻得到了7+2=1的答案,顯然是不對的,如果調整成先做減法則不會有這個問題。
  3. 過於繁雜的計算步驟,當計算步驟過多的時候,每一次運算都會產生舍入誤差,這些誤差將會在後續不斷的傳播累計,最後影響結果。同時如果計算不穩定(經常出現舍入操作,例如每一次計算的尾數都大於4),也會導致誤差過大。我們需要設計好計算簡單,同時每一次舍入操作得到的舍和入都是相同結果(例如每次尾數都小於5)
  4. 極限狀態下的誤差擴大化,例如我們的估計值和真實值很接近,或者運算中有趨近於0的數字產生,往往就會導致有效位數的缺失,我們最好採用泰勒展開、和差化積,利用三角、對指數函式的運演算法則對其進行處理,從而避免誤差的繼續累計。
  5. 絕對值過小的數字做除數,事實上誤差有如下公式成立:\(e(\frac{x}{y})\approx\frac{ye_x+xe_y}{y^2}\),若y過小,則會導致誤差成平方倍擴大。因此我們也需要避免這種情況,最簡便的方法就是通過放大分子分母,使得其分母可以儘可能多的保留下有效數字

誤差的傳播

和的絕對誤差即誤差的和

\[f(x_1,x_2\dotsb,x_n)=\sum^n_{i=1}x_i\\ e(\sum_{i=1}^n x_i)\approx\sum_{i=1}^n e(x_i)\\ e_r(\sum_{i=1}^n x_i)\approx\sum_{i=1}^n \frac{x^*_i}{\sum_{i=1}^n x^*_i}e_r(x_i)\]

由此可以看出,我們傳入的資料在進行加法運算時,誤差大約和各個近似值的代數和是差不多的。因此我們可以得出結論:初始輸入的近似值對於求和運算的影響時並不大的。

差的絕對誤差相對而言較難估計,但是差的相對誤差與我們的初始值關係是非常大的,就好比我們上文提到的,過於接近的數相減的時候,往往容易導致有效數字的嚴重缺失。因此我們儘可能要避免差的運算。

\[設f(x_1,x_2)=x_1-x_2\\ e_r(x_1-x_2)\approx\frac{x_1^*}{x_1^*-x_2^*}e_r(x_1)-\frac{x_2^*}{x_1^*-x_2^*}e_r(x_2)\\ 即e_r(x_1-x_2)\leq\left|\frac{x_1^*}{x_1^*-x_2^*}\right|e_r(x_1)+\left|\frac{x_2^*}{x_1^*-x_2^*}\right|e_r(x_2)\]

從這個式子也能看出如果輸入的初始近似值過於接近,一旦做差,分母就會急劇的趨近0,使得整體的誤差變大。

算數中積的誤差公式為:

\[f(x_1,x_2\dotsb,x_n)=\prod_{i=1}^{n}x_i\\ e(\prod_{i=1}^{n}x_i)\approx\sum_{i=1}^n \left [\left (\prod_{j=1,j\neq i}^{n}x^*_j\right )e(x_i)\right]\\ e_r(\prod_{i=1}^{n}x_i)\approx \sum_{i=1}^n e_r(x_i) \]

事實上我們換個角度,積在某種意義上就是一個累加的過程,因此誤差的累計傳播規律也類似於和的規律,積的相對誤差積累是一個累加過程,但是對於絕對誤差而言,積很受大數的乘法影響,例如估計值是0.9,精確值是1,當他們各自乘一百倍後,相對誤差因為只有一項,故沒有什麼變化,但是絕對誤差卻從0.1放大到了10。所以如果在需要避免絕對誤差的情況之下,我們要儘可能的去避免大數去直接乘一個近似值。

商的誤差就可以類比減法的誤差,直接給出我們的證明推論:

\[f(x_1,x_2) = \frac{x_1}{x_2}\\ e_r(\frac{x_1}{x_2})\approx\frac{1}{x_2^*}e(x_1)-\frac{x_1^*}{(x^*_2)^2}e(x_2)=\\ \frac{x_1^*}{x^*_2}[e_r(x_1)-e_r(x2)]\approx\\ e_r(x_1)-e_r(x_2)\]

不難看出,商的相對誤差就是被除數和除數的相對誤差的差,乘法在某種意義上也是除法,因此乘法中存在的問題在除法中也必定存在。乘法如果乘數過大會導致絕對誤差過大,那麼乘數取倒數就成為了除法,也就是說除法中要儘可能避免過小的數作為除數,這樣才能最大的保護資料的準確性。

乘方、開方帶來的誤差和乘除法類似,這裡不再過多贅述,直接給出我們的公式:

\[e(x^p) = p(x^*)^{p-1}e(x)\\ e_r(x^p)=pe_r(x)\]

綜上所述,我們知曉了初始資料誤差對於計算結果的影響,而前文提到的誤差增長因子能很好的反映處計算結果和原始資料誤差變化的情況及計算結果對於初始值的敏感程度。如果初始近似值變動而計算結果變化很小的時候,說明該計算是良態的。如果初始的近似值輕微擾動,但是結果變化極大的時候,則說明我們的計算是敏感的,病態的。

演算法設計的穩定性與病態條件

病態問題

我們剛分析完了我們的演算法的敏感、病態的理論,這裡我以一個例子來展示病態函式是如何影響我們的結果的。

\[設f(x) = x^2-x-10100,求f(99)的相對誤差,並討論x=99附近的性態。 \\其中99的相對誤差為1\%(即99是一個估計值,存在1\%的誤差)\]

我們直接利用前文提到的泰勒展開誤差估計公式計算,接下去分析:

\[e_r(f)={f}\\'(99)\times \frac{-99}{200}\times1\%=-99\% \]

這就說明當初始輸入了一個相對誤差在1%的初始值的時候,經過函式計算,函式值的相對誤差會放大99倍。

\[f(99)=-200,f(99.9)=-20.9,f(99)=10f(99.9) \]

在我們初始的擾動只有0.9的情況,經過計算後的值卻擴大到了10倍,按著相對誤差的計算,也就是10%的擾動帶來了1000%的函式變化。因此我們稱這個函式早x=99附近是一個病態的函式。

因此我們在分析問題的時候,要額外注意問題是否是良態的。

計算的穩定性

計算的穩定性主要體現在當處理同一問題的時候,選用不同的計算方法或演算法,往往對結果有著顯著的區別。例如下面這個例子:

\[a_0 = ln6-ln5\approx0.1823,a_{20}\approx0.0087301587\approx0.0087\\a_n=-5a_{n-1}+\frac{1}{n},a_{10}=? \]

這個題目大家一看,驚呼:真是簡單,直接將\(a_0\)套進遞推式,直接就能解出來了。但結果恰恰出乎你的預料。如果你利用題中給出的公式進行計算,會得出一個極端奇怪的答案,往往你還不自知錯誤所在。我們嘗試分析一下。

得出錯誤結論的原因很顯然是因為\(a_0=0.1823\)發生了舍入誤差,如果我們取六位有效數字,我們捨去了0.000022左右的大小,誤差會隨著計算式不斷累積,如下

\[\epsilon+0.1823=ln6-ln5\\ a_1 = -5(0.1823+\epsilon)+1\\ a_2 = -5[-5(0.1823+\epsilon)+\frac{1}{2}]\\ \dotsb\\ a_n = -5^n(0.1823+\epsilon)+\dotsb\]

我們可以發現,誤差是呈現指數函式的形式進行增長的,我們可以算算到了第十項誤差已經達到了原始誤差的9,765,625倍,大概我們多算了214的樣子,這顯然是無法接受的答案,並且當你寫出演算法沒有第十項的參考數值的時候,你會無法意識到自己的錯誤所在,因為你的演算法邏輯完全正確,但你的錯誤恰恰發生在了最難注意到的誤差之上。

那我們如何取解決這個問題呢?很顯然對於這個遞推而言,誤差永遠呈現指數函式形式進行變化。如果我們期許指數函式縮小,那麼我們能不能試著把指數函式的底數換成一個絕對值小於1的數字呢?

答案顯然是可以的,如果我們將原有遞推式更改為以下這種情況:

\[\frac{1}{5n}-\frac{1}{5}a_{n}=a_{n-1} \]

我只是反過來求解前一項,我們從後往前進行計算,那麼,誤差分析式就變成了

\[\epsilon+0.0087\\ a_{19} = \frac{1}{5\cdot 20}-\frac{1}{5}(\epsilon+0.0087)\\ a_{18} = \frac{1}{5\cdot 19}-\frac{1}{5}(\frac{1}{5\cdot 20}-\frac{1}{5}(\epsilon+0.0087))\\ \dotsb\\\]

很顯然我們的誤差項\(\epsilon\)已經是一次比一次更小,呈現指數函式的縮小狀態,這樣得出的值很明顯是要精確於前者的,最終的誤差也不會超過0.000022。

通過這個例子我們可以發現,實際上對於同一個問題,採用的演算法、分析的思路不同,帶來的結果卻天差地別。對於第一種解法,我們稱為不穩定的演算法,它會導致我們失真。第二種解法,我們的誤差逐步在縮小,說明我們的演算法是穩定的演算法

剛剛介紹的是因為演算法不同的誤差擴大化問題,還有另一種情況就是因為犯了我們之前說過的大數吃小數的問題。如題

\[求x^2-(10^9+1)x+10^9=0的根 \]

通過因式分解我們很容易知道答案是\(x_1=10^9,x_2=1\),但當我們利用求根公式\(\frac{-b\pm\sqrt{\Delta}}{2a}\),我們能解出第一個更大解,但是當我們解第二個解的時候,由於\(-b-\sqrt{\Delta}\)在我們計算機的字長不夠時,會產生極為嚴重的截斷誤差,最終會得出一個等於0的解,很顯然時不對的,這裡犯了我們之前提到的大數和小數加減法的時候,往往會導致一些資料的丟失,因此我們轉變思路,如果利用韋達定理:

\[x_1\times x_2=\frac{c}{a}\\ x_1+x_2=-\frac{b}{a}\]

不僅極為有效的減少了計算量,也不會再次出現剛才提到的問題了。

因此對於保持演算法穩定性的原則就是,我們既要防止數字由於數量級相差過大,從而導致較小的數字喪失其計算作用;也要防止數字過於接近,使得有效數字缺失,產生不可避免的誤差。更需要注意的就是我們的演算法中產生的誤差,應當是越來越小且收斂的。

練習題

  1. 已知對數\(lga\)的絕對誤差限為\(0.5\times 10^{-n}\),求相對誤差限

  2. 如何使得\((\frac{1-cosx}{x},x>>1),ln(30-\sqrt{30^2-1})\)計算更精確

  3. \(f(x)=x^2-\frac{log_{2}x}{x},x=4.1\pm0.05\),若以\(u=f(4.1)\)作為近似值,請問u能有幾位有效數字

  4. 用電錶測得一個電阻兩端電壓和電流為\(V=220\pm 2V,I=10\pm 0.1A,求阻值R和相對、絕對誤差。\)(PS:歐姆定律\(R=\frac{V}{I}\)

  5. 找到方程\(x^2+9^{12}x=3\)的根

Reference

《數值分析》(原書第二版) —— Timothy Sauer

《數值計算方法》(清華大學出版社) —— 呂同富等

About Me


作  者:WarrenRyan
出  處:https://www.cnblogs.com/WarrenRyan/
本文對應視訊:BiliBili(待重錄)
關於作者:熱愛數學、熱愛機器學習,喜歡彈鋼琴的不知名小菜雞。
版權宣告:本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。若需商用,則必須聯絡作者獲得授權。
特此宣告:所有評論和私信都會在第一時間回覆。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信
聲援博主:如果您覺得文章對您有幫助,可以點選文章右下角推薦一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!


博主一些其他平臺:
微信公眾號:寤言不寐
BiBili——小陳的學習記錄
Github——StevenEco
BiBili——記錄學習的小陳(計算機考研紀實)
掘金——小陳的學習記錄
知乎——小陳的學習記錄


聯絡方式

電子郵件:[email protected]



社交媒體聯絡二維碼: