计算方法与误差 实验报告.docx

上传人:b****8 文档编号:11360129 上传时间:2023-02-28 格式:DOCX 页数:21 大小:431.23KB
下载 相关 举报
计算方法与误差 实验报告.docx_第1页
第1页 / 共21页
计算方法与误差 实验报告.docx_第2页
第2页 / 共21页
计算方法与误差 实验报告.docx_第3页
第3页 / 共21页
计算方法与误差 实验报告.docx_第4页
第4页 / 共21页
计算方法与误差 实验报告.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

计算方法与误差 实验报告.docx

《计算方法与误差 实验报告.docx》由会员分享,可在线阅读,更多相关《计算方法与误差 实验报告.docx(21页珍藏版)》请在冰豆网上搜索。

计算方法与误差 实验报告.docx

计算方法与误差实验报告

方程求根—牛顿迭代法

摘要

通过对牛顿迭代法的编程练习,掌握方程求根的牛顿迭代法的算法,进一步体会牛顿迭代法的特点。

关键字:

牛顿迭代;方程求根;编程;运算次数

1、算法

流程图:

算法:

用迭代法的结构,增设4个工作单元F0,F0’,F1,F1’,并把用作终止迭代的误差控制改为两个|x1-x0|

1.1、准备:

选定初始值x0,计算F0=f(x0);F0’=f’(x0),如果F0’=0,则输出“方法失败”并结束。

1.2、迭代:

对k=1,2,…,N,做:

1)x1=x0-F0/F0’,

2)计算F1=f(x1);F1’=f’(x1)

3)若F1’=0,则输出“方法失败”并结束。

1.3、控制:

若|x1-x0|

1.4、k>N时输出“经N次迭代无满足要求的近似解”结束。

2、实验步骤

1)完成牛顿迭代法的程序设计及录入;

2)完成程序的编译和链接,并进行修改;

3)用书上的例子对程序进行验证,并进行修改;

4)分别输入两组不同的根的误差限,观察运算次数的变化;

5)分别取不同的初时值x0,观察运算结果的变化;

6)完成实验报告。

3、实验结果

3.1、经编译、链接及例子验证结果正确的源程序:

#include

#include

#defineN100

#defineeps5e-6

#definedelta1e-6

voidmain()

{

floatx0,x1,d,f1;

intk=0;

printf("请输入迭代初值x0:

");

scanf("%f",&x0);

printf("x(0)=%f\n",x0);

do

{

x1=x0-(x0*x0*x0+x0*x0-3*x0-3)/(3.0*x0*x0+2*x0-3);

if(k++>N||fabs(3.0*x1*x1+2*x1-3)

{

printf("\n发散");

break;

}

d=fabs(x1)<1?

x1-x0:

(x1-x0)/x1;

x0=x1;

printf("x(%d)=%f\t",k,x0);

}

while(fabs(d)>eps&&fabs(x1*x1*x1+x1*x1-3*x1-3)>delta);

printf("方程的根为:

%f\n",x1);

}

3.2、实例验证结果:

1)方程:

f(x)=x3+x2-3x-3=0

2)输入初始参数:

x0=1,EPS=1e-6

3)结果输出:

请输入迭代初值x0:

1.0

x(0)=1.000000

x

(1)=3.000000

x

(2)=2.200000

x(3)=1.830151

x(4)=1.737795

x(5)=1.732072

x(6)=1.732051

方程的根为:

1.732051

Pressanykeytocontinue

3.3、改变初值x0的值为:

x0=1.5,EPS不变,仍为1e-6,其结果为:

请输入迭代初值x0:

1.0

x(0)=1.000000

x

(1)=3.000000

x

(2)=2.200000

x(3)=1.830151

x(4)=1.737795

x(5)=1.732072

x(6)=1.732051

方程的根为:

1.732051

Pressanykeytocontinue

3.4、改变初值x0的值为:

x0=0.1,EPS不变,仍为1e-6,其结果为:

请输入迭代初值x0:

0.1

x(0)=0.100000

x

(1)=-1.087365

x

(2)=-0.989802

x(3)=-0.999899

x(4)=-1.000000

方程的根为:

-1.000000

Pressanykeytocontinue

3.5、改变EPS的值为:

EPS=5e-4,x0不变,仍为1,其结果为:

请输入迭代初值x0:

1.0

x(0)=1.000000

x

(1)=3.000000

x

(2)=2.200000

x(3)=1.830151

x(4)=1.737795

x(5)=1.732072

x(6)=1.732051

方程的根为:

1.732051

Pressanykeytocontinue

3.6.改变EPS的值为:

EPS=1e-3,x0不变,仍为1,其结果为:

请输入迭代初值x0:

1.0

x(0)=1.000000

x

(1)=3.000000

x

(2)=2.200000

x(3)=1.830151

x(4)=1.737795

x(5)=1.732072

方程的根为:

1.732072

Pressanykeytocontinue

4、分析和讨论

1.输入不同的初值x0,迭代次数的变化情况

答:

初值X0越大,迭代的次数越多

2.输入不同的误差限EPS,迭代次数的变化情况

答:

随着误差限EPS的增大,迭代次数会相应的减少。

5、心得

①调试过程中遇到的问题和解决对策;②经验体会等。

答:

通过实验进一步了解牛顿迭代法的计算特点,从而使我对牛顿迭代的知识了解更深。

 

方程求根——二分法

摘要

通过对二分法的编程练习,掌握方程求根的二分法的算法,进一步体会二分法的特点。

关键词:

求根;二分法;编程;估算次数

1、算法

流程图:

1)准备:

计算f(x)在有根区间[a,b]端点处的值f(a),f(b)。

2)二分:

计算f(x)在区间中点c=

处的函数值f(c)。

3)判断

•若f(c)与f(a)异号,则根位于区间[a,c]内,以c代替b;

•若f(c)与f(a)同号,则根位于区间[c,b]内,以c代替a;

反复执行步2和步3,直到区间[a,b]长度缩小到允许误差范围之内或f(c)=0,此时区间中点c即可作为所求的根。

 

2、实验步骤

1)完成二分法的程序设计及录入;

2)完成程序的编译和链接,并进行修改;

3)用书上的例子对程序进行验证,并进行修改;

4)对比估算次数与实际二分次数;

5)输入不同的区间初值a,b,查看二分次数的变化;

6)输入不同的误差限,查看二分次数的变化;

7)完成实验报告。

3、实验结果

3.1经编译、链接及例子验证结果正确的源程序:

#include

#include

#defineeps5e-6

#definedelta1e-6

voidmain()

{

floata=1,b=2,fa,fb,fab,c,fc;

intn=1;

fa=a*a*a+a*a-3*a-3;

fb=b*b*b+b*b-3*b-3;

fab=fa*fb;

while

(1)

{

if(fab>0)

{

printf("不能使用二分法");

break;

}

c=(a+b)/2;

fc=c*c*c+c*c-3*c-3;

if(fabs(fc)

elseif(fa*fc<0){b=c;fb=fc;}

else{a=c;fa=fc;}

if(b-a

printf("%d\t%f\t%f\n",n++,c,fc);

}

printf("\n方程的根是:

%f",c);

}

3.2、实例验证结果:

1)方程:

f(x)=x3+x2-3x-3=0

2)输入初始参数:

a=1,b=2,EPS=5e-6

3)结果输出:

1.改变a,b的值为:

a=0,b=2,EPS不变,仍为5e-6,其结果为:

4.改变EPS的值为:

EPS=5e-4,a,b不变,仍为a=1,b=2,其结果为:

 

4、分析和讨论

1.估算次数与实际二分次数的分析和讨论

答:

估算的次数与实际二分次数相等,即估算好多次,就二分了好多次

2.输入不同的区间初值a,b,二分次数的变化情况

答:

输入的区间范围越大,要达到相同的精确值,二分次数会相应的增加

3.输入不同的误差限EPS,二分次数的变化情况

答:

随着误差限EPS的增大,二分次数会相应的减少。

5、心得

①调试过程中遇到的问题和解决对策;②经验体会等。

答:

通过二分计算在电脑中的演示更一步了解了二分法的特点:

用对分区间的方法根据分点处函数f(x)值的符号逐步将有根区间缩小,使在足够小的区间内,方程有且仅有一个根.二分法收敛速度较慢,在编程过程中,对变量的定义采用哪种类型,主要是对条件的判断做准确分析,对中断条件的准确把握,在调试过程中,对k值采用哪种类型的定义。

对k值的输出有很大关系,

 

曲线拟合—最小二乘法

摘要

了解最小二乘法的基本原理,熟悉最小二乘算法;掌握最小二乘进行曲线拟合的编程,通过程序解决实际问题。

关键词:

曲线拟合;最小二乘法;拟合次数

1、算法

1)输入数据节点数n,拟合的多项式次数m,循环输入各节点的数据xj,yj(j=0,1,…,n-1)

2)由xj求S;由xj,yj求T:

Sk=

(k=0,1,2,…2*m)

Tk=

(k=0,1,2,…m)

3)由S形成系数矩阵数组ci,j:

c[i][j]=S[i+j](i=0,1,2,…m,j=0,1,2,…,m);由T形成系数矩阵增广部分ci,m+1:

c[i][m+1]=T[i](i=0,1,2,…m)

4)对线性方程组CA=T[或

],用列主元高斯消去法求解系数矩阵A=(a0,a1,…,am)T

2、实验步骤

1)完成最小二乘法进行曲线拟合的程序设计及录入、编辑;

2)完成程序的编译和链接,并进行修改;

3)用书上P105例2的例子对程序进行验证,并进行修改;

4)用完成的程序求解下面的实际问题。

5)完成实验报告。

3、实验结果

3.1、经编译、链接及例子验证结果正确的源程序:

#include

#defineN10

#defineM20

#defineDELTA1e-7

#include

voidmain()

{

intn,m,i,j,S;

intk=0;

floatx[N],y[N],s[2*M]={0},t[M]={0},c[M+1][M+2],z[M],A,q,sum=0;

doublel;

printf("输入数据节点数n:

");

scanf("%d",&n);//输入n

printf("拟合的多项式次数m:

");

scanf("%d",&m);//输入m

 

printf("x[i]:

");

for(i=0;i

{

scanf("%f",&x[i]);//输入x[i]

}

printf("y[i]:

");

for(i=0;i

{

scanf("%f",&y[i]);//输入y[i]

}

printf("\n");

/*-------------------

求s,t

-----------------------*/

for(i=0;i<=2*m;i++)

{

for(j=0;j

{

s[i]=s[i]+pow(x[j],i);

}

}

for(i=0;i<=m;i++)

{

for(j=0;j

{

t[i]=t[i]+y[j]*pow(x[j],i);

}

}

for(i=0;i<=m;i++)

{

for(j=0;j<=m;j++)

{

c[i][j]=s[i+j];

}

c[i][m+1]=t[i];

}

/*输出c[i][j]*/

for(i=0;i<=m;i++)

for(j=0;j<=m+1;j++)

{

printf("%-10.0f",c[i][j]);

if(j==m+1)

printf("\n");

}

/*用高斯列主元解方程*/

for(j=k,S=k;j

{

A=fabs(c[k][k]);

for(i=k;i

{

if(A

{

A=fabs(c[i][j]);S=i;//找出每列最大数

}

}

if(A

{printf("A奇异,结束程序.");break;}

if(S!

=k)

{

for(j=k;j<=m+1;j++)

{

q=c[k][j];c[k][j]=c[S][j];c[S][j]=q;//将最大数所在行与第K行的数交换

}

}

for(i=k+1;i<=m;i++)

{

j=k;

l=c[i][j]/c[k][j];//计算消元因子

for(j=k;j<=m+1;j++)

c[i][j]=c[i][j]-l*c[k][j];

}

for(i=0;i

for(j=0;j<=m+1;j++)

{

printf("%-15f",c[i][j]);//输出中间过程

if(j==m+1)

printf("\n");

}

j=k;printf("\n");

}

/*回代*/

if(fabs(c[m][m])

printf("A奇异,结束程序");

else

{

z[m]=c[m][m+1]/c[m][m];

printf("z[%d]=%-11f\n",m+1,z[m]);

for(i=m-1;i>=0;i--)

{

for(j=i+1,sum=0;j<=m;j++)

sum=sum+c[i][j]*z[j];

z[i]=(c[i][m+1]-sum)/c[i][i];

printf("z[%d]=%-11f\n",i+1,z[i]);

}

}

/*计算误差*/

floatp=0,d,e=0;;

for(i=0;i

{

p=z[0];

for(j=1;j<=m;j++)

{

d=pow(x[i],j);

p+=d*z[j];

}

e+=(p-y[i])*(p-y[i]);

}

printf("\n误差计算为:

%f.\n",e);//输出误差

}

 

3.2、实例验证结果:

1)输入初始参数:

n=9,m=2

X:

1345678910

Y:

1054211234

2)结果输出:

4、实际应用

问题:

作物体运动的观测实验,得出以下实验测量数据,用最小二乘拟合求物体的运动方程。

时间t(秒)

0

0.9

1.9

3.0

3.9

5.0

距离s(cm)

0

10

30

50

80

110

解题步骤:

1)画草图

2)确定拟合方程次数为1:

用完成的程序输入数据,求取拟合方程中的未知数,得出方程:

f(x)=-7.855058+22.253763*x

计算误差:

答:

误差为209.858978

3)确定拟合方程次数为2:

用完成的程序输入数据,求取拟合方程中的未知数,得出方程:

f(x)=-0.583343++11.081374*x+2.248814*(x^2)

计算误差:

答:

误差为23.292877

5、分析和讨论

1.结合实际问题,进行拟合次数的分析和讨论:

答:

通过实验M值取1—9的时候。

m=8的误差最小为0.000015。

m继续增加会使得误差增大。

所以做最小二乘法时应取适当的m值,可以多次实验,去验证最合适的拟合次数。

6、心得

①调试过程中遇到的问题和解决对策;②经验体会等。

答:

编程过程中用到的for循环很多,很容易忘记打大括号,而且在循环输入数组时,加上大括号才对,这个问题没有想通,就数组输入的地方那调试了很久才弄出来。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 党团建设

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1