我已经实施了规则的falsi方法。我试图修改它,因此它成为割线方法。我读过的pdf提到它只有一个变化基本相同。 未来对我的'm'值的猜测应该有一个略有不同的公式,而不是:
m = a - f(a) * ( (b-a)/( f(b)-f(a) ) );
它应该是:
m = a - f(a) * ( (m-a)/( f(m)-f(a) ) );
但不幸的是它不起作用(它从未找到根)。我应该修复什么才能将其纳入割线方法?
源代码如下:
#include <stdio.h>
#include <math.h>
void
secant(double a, double b, double e, double (*f)(double), int maxiter ) {
double m, fm, fa, fb;
int i;
fa=(*f)(a);
fb=(*f)(b);
m = a - fa * ( (b-a)/( fb - fa ) );
fm=(*f)(m);
for(i=0; i<maxiter; i++) {
if ( fabs(fm) <= e ) {
printf("f(%f) = %f\n", m, fm);
return;
} else if ((fa*fm) < 0) {
b=m;
fb=fm;
} else {
a=m;
fa=fm;
}
// the guess below works for regula falsi method:
// m = a - fa * ( (b-a)/(fb - fa));
//this was supposed to be the change to turn this into the secant method
m = a - fa * ( (m-a)/(fm - fa) );
fm=(*f)(m);
}
}
int main(){
secant(1,4,0.0001,sin,500);
return 0;
}
提前致谢
编辑:好好用笔和纸玩完后我终于明白了它并不像我最初想的那样简单改变:void secant(double a, double b, double e, double (*f)(double), int maxiter ) {
double m, fm, fa, fb;
int i;
fa=(*f)(a);
fb=(*f)(b);
for(i=0; i<maxiter; i++) {
m = a - fa * ( (b-a)/(fb - fa) );
fm=(*f)(m);
if ( fabs(fm) <= e ) {
printf("f(%f)=%f, iter: %d\n", m,fm,i);
return;
}
a=b;
b=m;
fa=fb;
fb=fm;
}
}
答案 0 :(得分:1)
割线方法更容易找不到根。你确定它应该找到它吗?
对于测试,这是一个示例:http://www.mathcs.emory.edu/ccs/ccs315/ccs315/node18.html (例4.7)你想运行那个例子(f(x)= x ^ 6-x-1,x0 = 1 x1 = 2,root x = 1.347)
答案 1 :(得分:0)
PDF是错误的还是您误解了它。如果不阅读PDF,就不可能说出哪些或进一步解释。当我解释这两种方法时,我说调节falsi和割线方法之间的区别是更新a和b的规则。
手动计算割线方法的前两次迭代。然后修改程序以在每次迭代时打印a,b和m的值(或使用调试器)。这应该会给你一些正在发生的事情。
在您的示例中,割线方法应该在几次迭代中收敛。
答案 2 :(得分:0)
正割方法是一种开括号方法,而Regula-Falsi是闭括号类型。所以,你的PDF是正确的。要将Regula-Falsi方法修改为割线方法,您必须将闭括号更改为打开类型。
见example for Regula-Falsi method。 这里,编码使得一个间隔始终保持不变。
现在,这是一个sample program for Secant method。 这里,与Regula方法一样,进行了两次初始猜测,但两个间隔都在不断变化,直到获得正确的根。手动获取最初的两个猜测。
而且,关于收敛速度,对于正割方法,它是超线性的,而对于Regula,它是线性的。因此,割线方法收敛速度更快。