Re: [問題] 多項式 跑出一堆不預期的數字..
※ 引述《EarthQ (地球人崛起)》之銘言:
恕刪
架構我覺得真的很不好,我第一次看到有人用 struct 存 dfx_value 和 fx_value
有幾個問題也一起提出來
1. while(nroot<np)
你的 np 是你整個方程式的「最大冪次」,假設是 10 冪次,
不代表剛好有 10 個點
2. 步進問題
第 57 行裡面, x=x+1.0e-8;
你每次給的初始點是增 1E-8,且你收斂的 EPS 也是 1E-8,
我估就算找到了 10 個解,這十個解指向的都是同一個解。
3. 多項式算值
原本的寫法可能我比較看不懂,附上我的寫法..
double CalFx(double *Coef, int n, double xvalue)
{
int i;
double ans=0;
double pow_t=1; // 紀錄 x^i, i=[0,n]
for(i=0; i<=n; ++i){
ans += pow_t*Coef[i];
pow_t*=xvalue; // pow_t = x^i
}
return ans;
}
如果是 dfx 的話
for(i=1; i<=n; ++i){ // x^0 微分後省掉
ans += pow_t*Coef[i]*i;
pow_t*=xvalue; // pow_t = x^i
}
另外不建議設 struct 去存 fx 和 dfx 之值,
看了反而會誤解是二個點: double x, double y;
------------
整體架構我認為最重大的缺失是在第 2 點,步進只用 1E-8,
通常在算非線性方程式要求根時,大致會這麼做:
(1) 設上界值 a 與下界值 b ,注意 distance(a,b) 不能太大,但太小也沒意義。
通常我是設 distance(a,b) = 0.5~1.0,這是視問題大小而定。
(2) 利用勘根定理,若 f(a) * f(b) <=0,代表[a,b] 必「至少」存有一根;
若 f(a) * f(b) > 0,代表 [a,b] 可能沒有根
例外情況是,[a,b] 間的根是偶數個,將使得 f(a) * f(b) > 0
(3) 用勘根定理確定 [a,b] 間有根時,再用非線性解法
(你的是牛頓法,其他的還有割線法、二分法、定點回路法等)
去求 [a,b] 間存在之根其值為何。
牛頓法去做大概只有二個前題:可微、連續,
(用牛頓法求不出來的 連續、可微函式 目前只有一種,不過不是你這種函式),
但我認為應先用勘根定理,把求解區間縮小為佳。
------
以上,供參閱。
--
YouLoveMe() ? LetItBe() : LetMeFree();
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.78.41
→
07/14 23:31, , 1F
07/14 23:31, 1F
→
07/14 23:34, , 2F
07/14 23:34, 2F
→
07/14 23:36, , 3F
07/14 23:36, 3F
→
07/14 23:42, , 4F
07/14 23:42, 4F
那段副函式我會設計成這樣
double Cal(double *Coef, int n, double xvalue)
{
int i;
double fx=Coef[0], dfx=0;
double pow_t=1; // 紀錄 x^i, i=[0,n]
for(i=1; i<=n; ++i){
dfx += pow_t*Coef[i]*i;
pow_t*=xvalue; // pow_t = x^i
fx += pow_t*Coef[i];
}
return fx/dfx;
}
的確用一個 loop 就算出來, 因收斂條件用到的是 f(x)/f'(x),
也可以直接傳回 delta 也沒問題,
return (x-fx/dfx);
這樣就可以當作是下一個 x 之迭代,更方便,
實在沒必要還要多設一個 struct 還是引數再用二個 int *fx , int *dfx。
※ 編輯: tropical72 來自: 180.177.78.41 (07/15 00:09)
推
07/16 11:51, , 5F
07/16 11:51, 5F
→
07/16 11:52, , 6F
07/16 11:52, 6F
→
07/16 11:53, , 7F
07/16 11:53, 7F
→
07/16 11:54, , 8F
07/16 11:54, 8F
→
07/16 11:55, , 9F
07/16 11:55, 9F
→
07/16 11:55, , 10F
07/16 11:55, 10F
推
07/16 11:57, , 11F
07/16 11:57, 11F
推
07/16 11:59, , 12F
07/16 11:59, 12F
→
07/16 14:07, , 13F
07/16 14:07, 13F
→
07/16 14:07, , 14F
07/16 14:07, 14F
→
07/16 14:07, , 15F
07/16 14:07, 15F
→
07/16 14:08, , 16F
07/16 14:08, 16F
→
07/16 14:08, , 17F
07/16 14:08, 17F
推
07/16 21:00, , 18F
07/16 21:00, 18F
→
07/16 21:01, , 19F
07/16 21:01, 19F
→
07/16 21:02, , 20F
07/16 21:02, 20F
→
07/17 17:08, , 21F
07/17 17:08, 21F
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):