我正在尝试实施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);
}
答案 0 :(得分:3)
好的,只是为了纠正算法以实际执行它的意图:
除了将result
的类型从int
更改为float
之外,您还需要更改循环条件。目前它是:
while ( fabs( b - c ) > eps );
这意味着循环将继续发生,直到值b
和c
之间的距离变得低于0.0001
,并且在这种情况下,目前,至少在我的结尾,代码永远运行。
我们不是在减少b
和c
之间的差异之后。我们真正之后的是fonc( c ) = 2*c*c*c - c - 2
小于eps
。最后,我们希望它尽可能接近零,以便c
成为函数的根。简单地说:
while ( fabs( fonc( c ) ) > eps );
是我们应该的条件。这样,随着int --> float
更改,它不会陷入无限循环,在14次迭代中完成作业。
答案 1 :(得分:2)
一个问题是result
是int
。您几乎肯定希望成为float
或double
,否则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