close

幹達語翻譯

若 f(b) * f(c) > 0,則代表根位在 [ c翻譯社 b] 之間,此時該把上界 a 值調成 c。

固然也有可能會一向都大於 eps ,但後果已算可接受程式翻譯

圖形與申明

這只是終止前提之其中一種方式。而上述的小於某個誤差值,

因非主題原故,此處不再深切研究切磋翻譯

 

此次若在 [c, b] 間,於是將 a 換成 c。

只要有一前提符合,即視為收斂情形。但在某些函數情況下,

假設最大迭代次數為 100,進行 100 次還沒法收斂的話即強迫終了求值動作。

 

是否是要寫成

 

 

(可以使用勘根定理辨別),以二分法體例求出 f(x) 於 [a翻譯社b] 區間之解翻譯

可能有心人士誤設為 0 ,為避免這種環境,筆者建議要加上等號。

BiSect02.png

(3) 絕對值 (x2-x1)/x2 <= eps 視為收斂

 

(b) 傳回值無法判別是收斂竣事,仍是迭代次數太長強制竣事。

(max_itera && fabs(y) > eps);

    E1 :  c = (a+b)  / 2

 

 

若 f(a) * f(c) < 0 ,則代表根位在 [a,c] 之間,所以把下界 b 值調劑為 c,

之時候可能不小,故在設計時,盡量利用暫存變數,

一起頭,以 a, b 值代入 f(x),獲得 f(a), f(b) ,對應之圖形以下

BiSect01.png

 

 


上述是將 f(c) 小於某個可接管誤差 eps 視為終止前提,

    E4 :  goto E1

這部分過分細節鎖碎,且可爭議切磋部分其實太多,

就將 c 點視為此方程式之一組解,此算法即可終了翻譯

此系列文章只做初步示範,必會留下一些思慮與改善空間,往後此系列文亦如斯,

 

 

重覆以上動作,一直到 f(c) 小於某個可接受誤差 eps,

 

底下程式碼是依上述虛擬碼直譯而言。

(1) f(x) <= eps 視為收斂

終止前提

    E2 :  if abs ( f(c)  ) <= EPS ,演算法結束,傳回 c 值翻譯

BiSect05.png

於是會再用一個強制終止之前提,最多見到的體式格局是,限制最大迭代次數。

(a) 呼叫副函式竣事時,只傳回 x 值,沒記下 y 值,回到 main 裡後要看函數值還要再挪用一次,虛耗時候本錢。

 

 

 

C 說話程式碼

 

較大問題在於挪用 fx 次數太多,在現實問題上,

在給定函式 f(x) 之環境下,給定了下界 a 與上界 b,同時肯定了 [a翻譯社 b] 含有一解

 

 

 

將上一次求得之 f(x1) 與 此次求得之 f(x2) 相減,若小於等於 eps 視為收斂,


  BiSect04.png  

這份程式碼還不是最好的設計模式,緣由以下述

Algorithm BiSect

做下去才成心義翻譯

 

以取代調用 fx 所破費之時候本錢。完整程式碼以下

接下來,選擇 a, b 當中點 c,即 c = (a+b) / 2,再求 f(c) 之值。

等號非常重要,在大多環境下城市加,因大多情形下會將 eps 設非常小,可能為 1E-6 ~ 1E-12,甚至

這類終止體例叫「收斂」,因其解答已在可領受的誤差規模內。

 

 


若 f(b) * f(c) > 0,則代表根位在 [ c翻譯社 b] 之間,此時該把上界 a 值調成 c。

求解進程可能沒法順遂收斂,3 種環境可能都沒法殺青,

至於常見到的 

    E3 :  if ( f(c) * f(a) <= 0)   b = c;
            else  a = c;

 

和上面一樣,又是一次勘根定理的利用,算出 f(c) 後,

 

[回目次]

/*******************************************************************/
/*                                                                 */
/*     filename : BiSector.c                                       */
/*     author   : edison.shih/edisonx                              */
/*     compiler : Visual C++ 2008                                  */
/*     date     : 2011.03.07                                       */
/*                                                                 */
/*         A.L.L.      R.I.G.H.T.S.     R.E.S.E.R.V.E.             */
/*                                                                 */
/*******************************************************************/

/*----------------------------------------------------------------*\
|
|  Assume there is a root at [low, up] in f(x)
|
|  (1) yup = f(up)
|
|  (2) mid <- (low + up) / 2 , y <- f(mid)
|
|  (3) if fabs(y) < eps ---> algorithm terminate, mid is answer
|
|  (4) if y1 * f(up) < 0  ( f(mid) * f(up) < 0 ) ---> low = mid
|      else ---> up = mid 翻譯社 yup = y
|
|  (5) goto step (2)

\*----------------------------------------------------------------*/

#include <stdio.h>
#include <math.h>

// [ -2.00 , -1.00 ] , [ 2.00 , 3.00 ] , [ +4.00 , +5.00 ]
double func(double x)
{
     double x2=x*x翻譯社 x3=x2*x;
     return (x3 - 5.48*x2 -  1.4883*x + 20.394828);
}

// -------------------------------------------------------
double BiSector(double low,             /*  
下界  */
                double up翻譯社              /*   上界  */
                double (*fx)(double),   /* 順應函式*/
                double eps,             /* 允許誤差*/
                int max_itera)          /* 最大迭代*/
{
     double mid, y;
     double yup = fx(up);

     if( yup *fx(low) > 0.0) {
           printf(" >   has no root at [%lf, %lf]", low翻譯社 up);
           return low;
     }
     do{
           mid = (low+up)*0.5;
           y   = fx(mid);
           if(y * yup <= 0.0) low = mid;
           else up = mid, yup=y;
           --max_itera;
     }while(max_itera && fabs(y) > eps);
     return mid;
}

int main()
{
     double low, up, x;
     const int max_itera=100;
     const double eps = 1E-9;

     low = -2.0 , up = -1.0;
     x = BiSector(low翻譯社 upfunc, eps, max_itera);
     printf(" > func(%+e) = %+e", x, func(x));

     low = +2.0 翻譯社 up = +3.0;
     x = BiSector(low, up翻譯社  func, eps, max_itera);
     printf(" > func(%+e) = %+e"翻譯社 x, func(x));

     low = +4.0 , up = +5.0;
     x = BiSector(low翻譯社 up翻譯社  func, eps, max_itera);
     printf(" > func(%+e) = %+e", x, func(x));

     low = -10.0 翻譯社 up = -20.0; // for test翻譯社 can't find root.
     x = BiSector(low翻譯社 upfunc, eps, max_itera);
     printf(" > func(%+e) = %+e"翻譯社 x, func(x));
     return 0;
}

將上一次求得之 x1 與此次求得之 x2 相減,若小於等於 eps 視為收斂,

有可能非線性方程式代入一次值 ( 上述 fx(mid)、fx(up) 都是在代值)

 

如上所述,這種方式是較為在乎求到之解代入函數後,誤差必須極小,但不一定可以收斂到 eps 這麼小的數。

double BiSector(double low,              /*   下界  */
                 double up,              /*   上界  */
                 double (*fx)(double)翻譯社   /* 順應函式*/
                 double eps,             /* 允許誤差*/
                 int max_itera)          /* 最大迭代*/
{
     double mid;
     do{
           mid = (low+up)*0.5;
           if( fx(mid) * fx(up) <= 0.0) low = mid;
           else up = mid;
           --max_itera;
     }while(fabs( fx(mid)) > eps && max_itera!=0);
     return mid;
}


C語言初階程式碼

虛擬碼

 

有樂趣之讀者可現實再對於函式做適度之點竄翻譯

[回目次]

 

(5) 強迫終止方式

    E0 : 初始化最小誤差 EPS,初始化上界 a,下界 b翻譯

大致上該有的變數都有,結果也正常,但並不是很好的程式碼。

執行成績

上述四種方式,有時會混用,如挑 1翻譯社 2 混用 或 1, 4 混用等等,

若解之更動率小於一數值,則視為收斂。

若 f(a) * f(c) < 0 ,則代表根位在 [a,c] 之間,所以把下界 b 值調劑為 c,

BiSect03.png

 

 
> func(-1.781504e+000) = -5.953638e-011
> func(+2.313838e+000) = +2.521503e-010
> func(+4.947666e+000) = +1.224798e-010
>   has no root at [-10.000000, -20.000000]
> func(-1.000000e+001) = -1.512722e+003

 

其他增補申明

(max_itera && (y>eps || y<-eps));

注意到上圖,這裡又是一次勘根定理的運用,算出 f(c) 後,

接下來繼續找 c = (a+b) / 2,並算出 f(c) 值

(2) 絕對值 (x2-x1) <= eps 視為收斂

(4) 絕對值 f(x2)-f(x1) <= eps 視為收斂

End Algorithm

要提醒的是,二分法在執行前,一定要選確定在 [a, b] 區間有根,

 

調完之後把本來的 b 擦掉,以下圖

筆者見過的終止前提有下述幾種


 

若該函式在求解區間之斜率極度大的話,幾近不成能收斂。



文章來自: http://edisonx.pixnet.net/blog/post/35760704-%5bc%e8%aa%9e%e8%a8%80%e6%95%b8%e5%80%bc%e5%88%86%e6%9e有關各國語文翻譯公證的問題歡迎諮詢天成翻譯公司02-77260931
arrow
arrow
    文章標籤
    翻譯社
    全站熱搜
    創作者介紹
    創作者 richara2ap6 的頭像
    richara2ap6

    richara2ap6@outlook.com

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