Regula-Falsi算法?

时间:2014-03-08 19:08:03

标签: c algorithm

我正在尝试实施Regula-Falsi算法来解决2(x^3)-x-2的等式 但问题是变量c值保持不变并且不会改变,即使我的代码应该改变它。

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


float fonc(float x)
{
    int result;
    result=2*(pow(x,3))-x-2;
    return result;
}

int main(void)
{
    float eps=pow(10,-4);
    int i=0;
    float a,b,c;
    a=1;
    b=2;
    do
    {
        c=((a*fonc(b))-(b*fonc(a)))/((fonc(b)-fonc(a)));
        if(fonc(c)*fonc(a)<0)
        {
            b=c;
        }
        else
        {
            a=c;
        }
        i++;    
        printf("\n%f",c);
    }
    while(fabs(b-c)>eps);

    printf("le nombre d'itération %d",i);
}

3 个答案:

答案 0 :(得分:3)

好的,只是为了纠正算法以实际执行它的意图:

除了将result的类型从int更改为float之外,您还需要更改循环条件。目前它是:

    while ( fabs( b - c ) > eps );

这意味着循环将继续发生,直到值bc之间的距离变得低于0.0001,并且在这种情况下,目前,至少在我的结尾,代码永远运行。

我们不是在减少bc之间的差异之后。我们真正之后的是fonc( c ) = 2*c*c*c - c - 2小于eps。最后,我们希望它尽可能接近零,以便c成为函数的根。简单地说:

    while ( fabs( fonc( c ) ) > eps );

是我们应该的条件。这样,随着int --> float更改,它不会陷入无限循环,在14次迭代中完成作业。

答案 1 :(得分:2)

一个问题是resultint。您几乎肯定希望成为floatdouble,否则fonc()的结果将被截断为整数。

答案 2 :(得分:2)

已添加前言:即使所有数据类型都合适,所提出的算法可能出现什么问题?

与二分法相比,纯正则falsi不会强制区间长度为零。如果使用单调和凸函数,则迭代将在仅改变具有几何收敛的区间的一侧时停止。

要正确捕捉此行为,应在计算后立即将中点c与两个间隔结束进行比较。作为奖励点,检查c处的值是否足够小并且如果为真,则无论距离这个区间的末端有多远,也要打破迭代。

存在许多简单的技巧来强制间隔长度为零。复杂的技巧引领了布伦特的方法。一个简单的技巧是伊利诺伊州的变种在这些变体中,中点被认为是凸和

c = |f(b)|/(|f(a)|+|f(b)|) * a + |f(a)|/(|f(a)|+|f(b)|) * b

由于f(a)和f(b)的符号相反,这相当于原始公式。如果b侧没有变化,则通过减小函数值f(b),即乘以额外的权重因子,增加其在该凸总和中的重要性。


以下是伊利诺斯州的falsi变种(或假位置方法)的实现。该算法在6次迭代中找到函数值为2.2e-6且长度为6e-7的封闭区间的解。

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


float fonc(float x)
{
   return (2*x*x-1)*x-2;
}

int main(void)
{
    float eps=1e-6;
    int i=0;
    float a=1, fa = fonc(a);
    float  b=2, fb = fonc(b);

    printf("\na=%10.7f b=%10.7f  fa=%10.7f  fb=%10.7f\n------\n",a,b, fa,fb);

    if(signbit(fb)==signbit(fa)) {
        printf("Attention, les valeurs initiales de 'fonc' n'ont pas de signe opposeés!\n");

    }
    do
    {
        float c=(a*fb-b*fa)/(fb-fa), fc = fonc(c);

        if( signbit(fc)!=signbit(fa) )
        {
            b=a; fb=fa;
            a=c; fa=fc;
        }
        else
        {
            a=c; fa=fc;
            fb *= 0.5;
        }
        i++;  
        printf("\na=c=%10.7f b=%10.7f  fa=fc=%10.7f  fb=%10.7f",c,b, fc,fb);

        if(fabs(fc)<eps) break;
    }
    while(fabs(b-a)>eps);

    printf("\nle nombre d'itération %d\n",i);

    return 0;
}

输出

 a= 1.0000000 b= 2.0000000  fa=-1.0000000  fb=12.0000000
 ------

 a=c= 1.0769231 b= 2.0000000  fa=fc=-0.5789710  fb= 6.0000000
 a=c= 1.1581569 b= 2.0000000  fa=fc=-0.0512219  fb= 3.0000000
 a=c= 1.1722891 b= 1.1581569  fa=fc= 0.0497752  fb=-0.0512219
 a=c= 1.1653242 b= 1.1722891  fa=fc=-0.0003491  fb= 0.0497752
 a=c= 1.1653727 b= 1.1722891  fa=fc=-0.0000022  fb= 0.0248876
 a=c= 1.1653733 b= 1.1653727  fa=fc= 0.0000020  fb=-0.0000022
 le nombre d'itération 6