1

我已经实现了 regula 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;
  }
}
4

3 回答 3

1

割线法更容易找不到根。你确定它应该找到它吗?

对于测试,这里有一个例子: http: //www.mathcs.emory.edu/ccs/ccs315/ccs315/node18.html (例子4.7)你想运行那个例子(f(x)=x^6 -x-1 , x0=1 x1=2, 根 x=1.347)

于 2011-06-09T19:15:52.030 回答
0

PDF 是错误的,或者您误解了它。如果不阅读 PDF,就不可能说出或进一步解释。当我解释这两种方法时,我说 regula falsi 和 secant 方法之间的区别在于更新 a 和 b 的规则。

手动计算割线法的前两次迭代。然后修改您的程序以在每次迭代时打印 a、b 和 m 的值(或使用调试器)。这应该给你一个正在发生的事情的提示。

在您的示例中,割线方法应在几次迭代中收敛。

于 2011-06-10T11:38:09.430 回答
0

割线法是开括号法,而 Regula-Falsi 是闭括号法。所以,你的PDF是正确的。要将 Regula-Falsi 方法修改为割线方法,您必须将闭括号更改为开放类型。

有关Regula-Falsi 方法,请参见此示例。在这里,编码使得一个间隔始终保持不变。

现在,这里是割线法的示例程序。在这里,像 Regula 方法一样,进行两个初始猜测,但两个间隔都在不断变化,直到获得正确的根。手动获取最初的两个猜测。

并且,关于收敛速度,对于 Secant 方法,它是超线性的,而对于 Regula,它是线性的。因此,割线法收敛得更快。

于 2014-04-09T07:42:51.350 回答