【问题标题】:modifying regula falsi method to the secant method将regula falsi方法修改为割线方法
【发布时间】:2011-06-09 18:03:22
【问题描述】:

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

【问题讨论】:

  • “不起作用”?你可以再详细一点吗?程序是否崩溃,它没有收敛,它是否收敛太慢,是否存在极限环,或者它是否射向无穷大?还是发生了其他事情...
  • 糟糕。我刚才澄清了它没有找到函数的根

标签: c numerical-methods


【解决方案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)

【讨论】:

  • 谢谢,刚刚测试过,割线方法需要 6 次迭代,而最初的 regula falsi 方法需要 1360 次,所以我猜它像宣传的那样工作
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

    看到这个example for Regula-Falsi method。 在这里,编码是这样的,一个间隔总是保持不变。

    现在,这里是sample program for Secant method。 在这里,像 Regula 方法一样,进行两个初始猜测,但两个间隔都在不断变化,直到获得正确的根。手动获取最初的两个猜测。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 2012-12-19
      • 2014-02-26
      • 1970-01-01
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多