泰勒展開式
以前學校數學教我們, 曲線 y=f(x) 在 x=a 附近, 可以用泰勒展開式來取得近似值:
f'(x) 為 f(x) 一次微分方程; f''(x) 為二次微分方程; ... 以此類推.
平方根
有了上面這個公式, 我們可以得到平方根函數 y=f(x) 在 x=1 附近的泰勒展開式:
注意 "x=1 附近", 因此上面這個公式 x 的範圍是 0 < x < 2 (該範圍稱為收斂半徑). 程式如下:
...
template<typename T> inline const T ABS(T const & x) {
return ( x<0 ) ? -x : x;
}
...
// PS: ABS() 用巨集寫很容易出錯
... static double _sqrt(double x) { double sum=0.00F,coffe=1.00F,factorial=1.00F,xpower=1.00F,term=1.00F; int i = 0; //if (x < 0.00F) return -1.00F; //if (x >= 2.00F) return -1.00F; while(ABS(term)>0.000001F) { sum+=term; coffe*=(0.5-i); factorial*=(i+1); xpower*=(x-1); term=coffe*xpower/factorial; i++; } return sum; } ...
上述這個程式有一個很大的限制是, 如果不在上述這個收斂半徑範圍內, 誤差會愈來愈大. 為了避開此限制, 請考慮下面的恆等式 (x >=0)
可知平方根號內的 4 是可以轉換成平方根號外的 2, 因此大於2的實數要轉化為 [0,2) 的區間再呼叫 _sqrt().
... #define _FACTOR 4.00F #define _FACTOR_SQRT 2.00F ... double sqrt(double x) { double correction=1.00F; while(x>=_FACTOR_SQRT) { x/=_FACTOR; correction*=_FACTOR_SQRT; } return _sqrt(x)*correction; } ...
考讀者一個問題, 上述程式碼中, 改為
#define _FACTOR 2.25F
#define _FACTOR_SQRT 1.50F
...
可不可以? 當然可以, 因為平方根號內的 2.25 是可以轉換成平方根號外的 1.5 . 再考讀者一個問題, 看了上述解說, 如何應用泰勒展開式來取得立方根的近似值? 這個問題我就留給讀者吧. cos(x), sin(x) 呢?
提示:
sin(x) 微分
y = f(x) = sin(x) x1 > x0 且 x1 趨近於 x0 dy/dx = (sin(x1) - sin(x0)) / (x1-x0) 令 α=(x1+x0)/2 β=(x1-x0)/2 dy/dx = 2 * cos(α) * sin(β) / (x1-x0) = 2 * cos(α) * sin(β) / (2*β) = cos(α) * (sin(β) / β) 因 β 趨近於 0 => (sin(β) / β) 趨近於 1 => dy/dx = cos(α) = cos(x0) dy/dx 在 x0 上的值是 cos(x0) 故 dy/dx = f`(x) = cos(x)
y = f(x) = sin(x) 微分 => f`(x) = cos(x) f``(x) = -sin(x) f```(x) = -cos(x) f````(x) = sin(x) .... n n (n) dy / dx = f (x) = sin(x) ,if n ≡ 0 cos(x) ,if n ≡ 1 -sin(x) ,if n ≡ 2 -cos(x) ,if n ≡ 3
cos(x) 微分
y = f(x) = cos(x) 微分 => f`(x) = -sin(x) f``(x) = -cos(x) f```(x) = sin(x) f````(x) = cos(x) .... n n (n) dy / dx = f (x) = cos(x) ,if n ≡ 0 -sin(x) ,if n ≡ 1 -cos(x) ,if n ≡ 2 sin(x) ,if n ≡ 3
sin(x) 在 x=0 附近的 泰勒展開式
3 5 7 sin(x) = x - (x / 3!) + (x / 5!) - (x / 7!) + ... = ∞ 2*n+1 Σ x / (2*n+1)! 0
cos(x) 在 x=0 附近的 泰勒展開式
2 4 6 cos(x) = d sin(x) / dx = 1 - (x / 2!) + (x / 4!) - (x / 6!) + ... = ∞ 2*n Σ x / (2*n)! 0
為何要介紹泰勒展開式
原因很簡單, 大多數時候我們在寫程式時是有數學函式館可以應用的. 但是在極少數的時候, 並無數學函式館可以應用.