[数值算法]求根算法系列小结

本文总结了数值算法中几种常见的求根方法,包括二分法、迭代法、Aitken加速法、牛顿求根法和割线法。通过实例展示了每种方法的实现过程和应用,以求解不同的方程。所有方法均考虑了收敛性和精度要求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[数值算法]求根算法系列小结

1二分求根法:

       二分求根法主要用的思想是不断调整并缩小搜索区间的大小,当搜索区间的大小已小于搜索精度要求时,则可说明已找到满足条件的近拟根.

       当然,在这之前,首先是要准确的估计出根所处的区间,否则,是找不到根的。

Type binaryPationMethod(Type x1,Type x2,Type e,Type (*arguF)(Type),FILE* outputFile)

{

       Type x;/*The return answer*/

       Type mid;

       Type down,up;

       int iteratorNum=0;

 

 

       down=x1;

       up=x2;

      

       assertF(x1<=x2,"in twoPation x1>=x2");

       assertF(arguF!=NULL,"in twoPation arguF is NULL");

       assertF(outputFile!=NULL,"in twoPation outputFile is NULL");

       assertF((*arguF)(x1)*(*arguF)(x2)<=0,"in twoPation,f(x1)*f(x2)>0");

      

       fprintf(outputFile,"down/t/tup/t/t/r/n");

       /*two pation is a method that is surely to find root for a formula*/

       while(fabs(up-down)>(float)1/(float)2*e)

       {

              mid=(down+up)/2;

              if ((*arguF)(mid)==0)

                     break;

              else if(((*arguF)(down))*((*arguF)(mid))>0)

                     down=mid;

              else

                     up=mid;

             

              fprintf(outputFile,"% -12f% -12f/r/n",down,up);

              iteratorNum++;

       }

       /*get the answer*/

       x=mid;

      

       /*Output Answer*/

       fprintf(outputFile,"total iterator time is:%d/r/n",iteratorNum);           

       fprintf(outputFile,"a root of equation is :%f/r/n",x);

      

       return x;

}

       测试1:用二分法求:

f(x)=x^3-x^2-2*x+1=0(0,1)附近的根.

精度:0.001.

Output:

down             up          

0.000000    0.500000   

0.250000    0.500000   

0.375000    0.500000   

0.437500    0.500000   

0.437500    0.468750   

0.437500    0.453125   

0.437500    0.445313   

0.441406    0.445313   

0.443359    0.445313   

0.444336    0.445313   

0.444824    0.445313   

total iterator time is:11

a root of equation is :0.444824

 

 

2迭代法:

迭代法首先要求方程能够化到x=fi(x)的形式,并且还要保证这个式子在所给定的区间范围内满足收敛要求.

主要的迭代过程是简单的,就是:

x_k+1=fi(xk)

xk+1-xk满足精度要求时,则表示已找到方程的近拟根.

Type iteratorMethod(Type downLimit,Type upLimit,Type precise,Type (*fiArguF)(Type),FILE* outputFile)

{

       Type xk;

       int iteratorNum=0;

      

       assertF(downLimit<=upLimit,"in iteratorMethod x1>=x2");

       assertF(fiArguF!=NULL,"in iteratorMethod arguF is NULL");

       assertF(outputFile!=NULL,"in iteratorMethod outputFile is NULL");

      

       xk=downLimit;

      

       fprintf(outputFile,"k/t/tXk/t/t/r/n");

       fprintf(outputFile,"%-12d% -12f/r/n",iteratorNum,xk);

       iteratorNum++;

      

       while(fabs((*fiArguF)(xk)-xk)>(float)1/(float)2*precise)

       {

              /*in mathematic,reason:*/

              /*

              xk_1=(*fiArguF)(xk);

              */

              xk=(*fiArguF)(xk);

              fprintf(outputFile,"%-12d% -12f/r/n",iteratorNum,xk);

              iteratorNum++;

       }

       fprintf(outputFile,"root finded at x=%f/r/n",xk);

      

       return xk;

}

 

 

测试2:用迭代法求解方程

f(x)=1/(x+1)^2的近似根.

根的有效区间在(0.4,0.55).

精度为0.0001.

Output:

k            Xk         

0           0.400000   

1           0.510204   

2           0.438459   

3           0.483287   

4           0.454516   

5           0.472675   

6           0.461090   

7           0.468431   

8           0.463759   

9           0.466724   

10          0.464839   

11          0.466037   

12          0.465276   

13          0.465759   

14          0.465452   

15          0.465647   

16          0.465523   

17          0.465602   

18          0.465552   

root finded at x=0.465552

 

 

3Aitken加速法

       Aitken也是基于迭代法的一种求根方案,所不同的是它在迭代式的选取上做了一些工作,使得迭代的速度变得更快.

       Type AitkenAccMethod(Type startX,Type precise,Type (*fiArguF)(Type),FILE* outputFile)

{

       Type xk;

       int iteratorNum=0;

      

       assertF(fiArguF!=NULL,"in AitkenAccMethod arguF is NULL");

       assertF(outputFile!=NULL,"in AitkenAccMethod outputFile is NULL");

      

       xk=startX;

       fprintf(outputFile,"k/t/tXk/t/t/r/n");

       fprintf(outputFile,"%-12d% -12f/r/n",iteratorNum,xk);

       iteratorNum++;

      

       while(fabs((*fiArguF)(xk)-xk)>(float)1/(float)2*precise)

       {

              xk=(xk*(*fiArguF)((*fiArguF)(xk))-(*fiArguF)(xk)*(*fiArguF)(xk))/((*fiArguF)((*fiArguF)(xk))-2*(*fiArguF)(xk)+xk);

              fprintf(outputFile,"%-12d% -12f/r/n",iteratorNum,xk);

              iteratorNum++;

       }

      

       fprintf(outputFile,"root finded at x=%f/r/n",xk);

       return xk;

}

 

 

测试3:Aitken迭代加速算法的应用

计算的是方程

x=1/(x+1)^2x=0.4附近的近似根.

精度:0.0001

Ouput:

k            Xk         

0           0.400000   

1           0.466749   

2           0.465570   

root finded at x=0.465570

 

 

 

 

4牛顿求根法:

       牛顿求根法通过对原方程切线方程的变换,保证了迭代结果的收敛性,唯一麻烦的地方是要提供原函数的导数:

       Type NewTownMethod(Type startX,Type precise,Type (*fiArguF)(Type),Type (*fiArguFDao)(Type),FILE* outputFile)

{

      

       Type xk;

       int iteratorNum=0;

      

       assertF(fiArguF!=NULL,"in NewTownMethod,arguF is NULL/n");

       assertF(fiArguFDao!=NULL,"in NewTownMethod,fiArguFDao is NULL/n");

       assertF(outputFile!=NULL,"in NewTownMethod,fiArguFDao is NULL/n");

      

       xk=startX;

       fprintf(outputFile,"k/t/tXk/t/t/r/n");

       fprintf(outputFile,"%-12d% -12f/r/n",iteratorNum,xk);

       iteratorNum++;

      

       while(fabs((*fiArguF)(xk)/(*fiArguFDao)(xk))>(float)1/(float)2*precise)

       {

              /*

              Core Maths Reason

              Xk+1=Xk-f(Xk)/f'(Xk);

              */

              xk=xk-(*fiArguF)(xk)/(*fiArguFDao)(xk);

              fprintf(outputFile,"%-12d% -12f/r/n",iteratorNum,xk);

              iteratorNum++;

       }

      

       fprintf(outputFile,"root finded at x=%f/r/n",xk);

       return xk;

}

 

 

测试4:牛顿求根法的应用:

被求方程为:f(x)=x(x+1)^2-1=0

其导数为:f'(x)=(x+1)(3x+1)

所求其在0.4附近的近似根.

精度为0.00001

Output:

k            Xk         

0           0.400000   

1           0.470130   

2           0.465591   

3           0.465571   

root finded at x=0.465571

 

 

5割线法(快速弦截法):

       是用差商来代替避免求f’(x)的一种方案,由这种迭代式产生的结果序列一定是收敛的.

Type geXianMethod(Type down,Type up,Type precise,Type (*fiArguF)(Type),FILE* outputFile)

{

       Type xk,xk_1,tmpData;

       int iteratorNum=0;

      

       assertF(fiArguF!=NULL,"in geXian method,fiArguF is null/n");

       assertF(outputFile!=NULL,"in geXian method,outputFile is null/n");

       assertF(down<=up,"in geXian method,down>up/n");

      

       xk_1=down;

       xk=up;

      

       fprintf(outputFile,"k/t/tXk_1/t/tXk/t/t/r/n");

       fprintf(outputFile,"%-12d%-12f%-12f/r/n",iteratorNum,xk_1,xk);

       iteratorNum++;

      

       while(fabs(xk-xk_1)>(float)1/(float)2*precise)

       {

              tmpData=xk;

              xk=xk-(*fiArguF)(xk)*(xk-xk_1)/((*fiArguF)(xk)-(*fiArguF)(xk_1));

              xk_1=tmpData;

              fprintf(outputFile,"%-12d%-12f%-12f/r/n",iteratorNum,xk_1,xk);

              iteratorNum++;

       }

       fprintf(outputFile,"root finded at x=%f/r/n",xk);

      

       return xk;

}

       测试5:割线法的应用:

       所求的方程为:

f(x)=x*(x+1)^2-1=0

寻根范围:[0.4,0.6]

精度:0.00001

Output:L

k                 Xk_1            Xk       

0           0.400000    0.600000   

1           0.600000    0.457447   

2           0.457447    0.464599   

3           0.464599    0.465579   

4           0.465579    0.465571   

5           0.465571    0.465571   

root finded at x=0.465571

我的演示程序的源码下载:

http://free3.e-168.cn/as2forward/downloads/feature_FindRoot.rar

//如果上面这个链接无法响应下载(有可能是被网站给屏蔽掉了),则可使用下载工具(如迅雷等)下载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值