close

泰勒展開式
 




以前學校數學教我們, 曲線 y=f(x) 在 x=a 附近, 可以用泰勒展開式來取得近似值: 


taylers.png

f'(x) 為 f(x) 一次微分方程; f''(x) 為二次微分方程; ... 以此類推. 

 

平方根
 

400px-Square_root_0_25.svg.png

有了上面這個公式, 我們可以得到平方根函數 y=f(x) 在 x=1 附近的泰勒展開式: 


square_root.png
 

注意 "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_square_root.png


可知平方根號內的 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


 

為何要介紹泰勒展開式
 

原因很簡單, 大多數時候我們在寫程式時是有數學函式館可以應用的. 但是在極少數的時候, 並無數學函式館可以應用. 

 

 

 

arrow
arrow
    文章標籤
    平方根 泰勒展開式
    全站熱搜
    創作者介紹
    創作者 Lexra 的頭像
    Lexra

    Lexra Pixnet

    Lexra 發表在 痞客邦 留言(0) 人氣()