数学实验非线性方程求解.docx

上传人:b****7 文档编号:23835315 上传时间:2023-05-21 格式:DOCX 页数:42 大小:237.49KB
下载 相关 举报
数学实验非线性方程求解.docx_第1页
第1页 / 共42页
数学实验非线性方程求解.docx_第2页
第2页 / 共42页
数学实验非线性方程求解.docx_第3页
第3页 / 共42页
数学实验非线性方程求解.docx_第4页
第4页 / 共42页
数学实验非线性方程求解.docx_第5页
第5页 / 共42页
点击查看更多>>
下载资源
资源描述

数学实验非线性方程求解.docx

《数学实验非线性方程求解.docx》由会员分享,可在线阅读,更多相关《数学实验非线性方程求解.docx(42页珍藏版)》请在冰豆网上搜索。

数学实验非线性方程求解.docx

数学实验非线性方程求解

《大学数学实验》作业

非线性方程求解

班级:

姓名:

学号:

日期:

 

注:

本实验作业脚本文件均以ex6_1_1形式命名,其中ex代表作业,6_1_1表示第六章第一小题第一个程序。

本次试验编的脚本文件较多,word中每个脚本均有对应M文件。

自编函数均以exf6_1_1形式命名,exf代表作业函数,6_1_1表示第六章第一题第一个自编函数。

特殊函数,如混沌函数chaos、分岔点函数fenchadian2、iter函数除外。

【实验目的】

1、掌握用MATLAB软件求解非线性方程和方程组的基本用法,并对结果作出初步的分析;

2、练习用非线性方程组建立实际问题的模型并进行求解。

【实验内容】

【题目1】(课本习题第六章第1题)

分别用fzero和fsolve程序求方程

的所有根,准确到

,取不同的初值计算,输出初值、根的近似值和迭代次数,分析不同根的收敛域;自己构造某个迭代公式(如

等)用迭代法求解,并自己编写牛顿法的程序进行求解和比较。

1.1模型分析

fzero命令主要用于单变量方程的求根,主要采用二分法、割线法和逆二次插值法等的混合方法。

fzero至少需要两个输入参数:

函数、迭代初值(或有根区间)。

fsolve命令主要用于非线性方程组的求解,可以输出结果(如x点对应的雅可比矩阵等)。

已知y=sinx是一个周期性有界函数,而二次函数在对称轴两边增长无界。

我们可以直接观察出x=0是方程的解,再作出该方程两边所代表的函数的图像。

从图上可以观察到另外一个根的范围。

而由两函数性质,在第二根之外,二次函数增长,而三角函数波动,再也不会有交点。

从而大致可知此方程只有两解。

1.2模型求解

编写待求解函数M文件:

%-------------------作业题6_1待求解求解函数程序exf6_1------------------------

functiony=exf6_1(x)

y=sin(x)-x^2/2;

end

 

1.2.1fzero求解

因另外一个解范围未知,故先编一段程序估计解的范围。

%--------------------作业题6_1估计解的范围源程序ex6_1_1------------------------

clear;clc;clf;

x=-2:

0.1:

2;%估计根的范围

y1=sin(x);

y2=x.^2/2;%分别先作出两函数图像

plot(x,y1,x,y2);%图像交点处即为根,观察出解的数目与分布

xlabel('x');

ylabel('y1/y2');

title('y1、y2函数图像');%加入X轴、Y轴标记和标题

legend('y1=sin(x)','y2=x.^2/2');%加入图例

得到如下图像,已知一个解为0,由图像可得另一解在[1,2]之间。

图1:

y1=sin(x),y2=x.^2/2交点图

根据两解分布,x1∈[-1,1],x2∈[1,2],编写matlab:

%------------------作业题6_1用fzero求方程的所有根源程序ex6_1_2-----------------

clear;clc;

opt=optimset('fzero');

opt=optimset(opt,'tolx',1e-10);%opt设定求解精度

formatlongg;

[x,fv,ef,out]=fzero(@exf6_1,[1,2],opt)

[x,fv,ef,out]=fzero(@exf6_1,[-1,1],opt)%根据解分布,用fzero函数求解

输出结果如下:

x=1.40441482402454

fv=8.41122727024413e-011

ef=1

out=intervaliterations:

0

iterations:

7

funcCount:

9

algorithm:

'bisection,interpolation'

message:

'Zerofoundintheinterval[1,2]'

另一根为:

x=1.74713912083679e-011

fv=1.74713912082153e-011

ef=1

out=intervaliterations:

0

iterations:

8

funcCount:

10

algorithm:

'bisection,interpolation'

message:

'Zerofoundintheinterval[-1,1]'

从而可知,方程一根为x=1.40441482402454,另一根即为x=0。

1.2.2用fslove求解

%-----------------作业题6_1用fsolve求方程的所有根源程序ex6_1_3----------------

clear;clc;

opt=optimset('fzero');

opt=optimset(opt,'tolx',1e-10);%opt设定求解精度

formatlongg;

[x,fv,ef,out]=fsolve(@exf6_1,1,opt)

[x,fv,ef,out]=fsolve(@exf6_1,0,opt)%根据解分布,用fsolve函数求解

输出结果如下:

x=1.40441482411066

fv=-2.25777174733821e-011

ef=1

out=

iterations:

6

funcCount:

13

algorithm:

'trust-region-dogleg'

firstorderopt:

2.79692747209721e-011

message:

[1x76char]

jac=-1.23879992536652

另一根为:

x=0

fv=0

ef=1

out=

iterations:

0

funcCount:

2

algorithm:

'trust-region-dogleg'

firstorderopt:

0

message:

[1x76char]

表1:

fzero与fsolve求解结果

fzero求解

fsolve求解

x1

1.40441482402454

1.40441482411066

x2

1.74713912083679e-011

x=0

1.3不同初值给出的结果

1.3.1变化fzero的初值

fzero主要是利用二分法、割线法等的混合来求解,因此x的初值对其计算出数值解是有影响的。

下面的列表给出了不同x的初值,fzero函数输出的不同结果。

根据根的范围,x取值从-2变化到3.5。

表2:

不同x的初值,fzero函数输出的不同结果

x初值

根的近似值

迭代次数

函数调用次数

-2

5.824116516731E-13

8

31

-1.5

8.278977421518E-12

7

31

-1

-8.948271056829E-11

6

30

-0.5

-1.904088574048E-15

6

30

0

0

0

1

0.5

1.619924113706E-16

7

31

1

1.40441482409027

6

25

1.5

1.40441482409198

5

13

2

1.40441482409243

5

21

2.5

1.40441482409243

5

23

3

1.40441482409242

8

28

3.5

1.40441482405939

6

26

由表2可得,x在0附近取值时,根的近似值都为0,迭代次数在7次左右,函数调用次数约为30次;x在1.4附近取值,根的近似值都为1.404414,迭代次数在6次左右。

发现x取1.5时函数调用次数较少,说明离根很近;x=0时,直接取到根,因此迭代次数与函数调用次数均最少。

1.3.2变化fsolve的初值

根据根的范围,x取值从-2变化到3.5。

表3:

不同x的初值,fsolve函数输出的不同结果

x初值

根的近似值

迭代次数

函数调用次数

-2

-2.6071879498599e-010

5

12

-1.5

-1.04384412156096e-012

5

12

-1

-2.6071879498599e-010

4

10

-0.5

-1.0438441213492e-012

4

10

0

0

0

2

0.5

-8.02139615750056e-013

6

13

1

1.40441482411066

6

13

1.5

1.40441482492707

3

8

2

1.40441484097319

4

10

2.5

1.40441482411003

5

12

3

1.40441484097319

5

12

3.5

1.40441482411003

6

14

由表3可得,x在0附近取值时,根的近似值都为0,迭代次数在5次左右,函数调用次数约为12次;x在1.4附近取值,根的近似值都为1.404414,迭代次数在5次左右。

发现x取1.5时函数调用次数较少,说明离根很近;x=0时,直接取到根,因此迭代次数与函数调用次数均最少。

1.4根收敛域的计算

有了以上不同x初值时根的近似值结果,进一步计算函数收敛域

1.4.1fzero的收敛域

首先进行简单的试探,大致得出如下结论:

函数有两个根,根x=0的收敛域形式为

,大致确定

根x=1.4044的收敛域形式为

,大致确定b

当x0>b时,fzero解法不收敛,将会解出x=NaN

为了确定ab两个数,编写两条循环语句如下:

%---------------------作业题6_1根收敛域的计算源程序ex6_1_4-------------------

clearall;clc;

a=0.7;%设定a的初值

opt=optimset('fzero');

opt=optimset(opt,'tolx',1e-10);%opt设定求解精度

while(x<1)

a=a+0.00001;

x=fzero(@exf6_1,a,opt);

end

a%输出函数值趋向无穷大时的a

b=14;%设定b的初值

x=1;

while(x<2)

b=b+0.00001;

x=fzero(@exf6_1,b,opt);

end

b%输出函数值趋向无穷大时的b

得到近似值a=0.73719,b=14.79838

由上我们可以列出表格如下:

表4:

fzero函数的收敛域

收敛域

x=0

(﹣∞,0.73719)

x=1.4044

(0.73719,14.79838)

x=NaN(不收敛)

x=NaN(不收敛)

1.4.2fslove的收敛域

同样仿照以上循环语句稍作修改可以得到结果:

表5:

fsolve函数的收敛域

收敛域

x=0

(﹣∞,0.7391)

x=1.4044

(0.7391,+∞)

【小结】fzero与fsolve都是常见的方程求根函数。

上面的比较大致给出了它们的不同点。

当给出不同初值的时候,总是fsolve比fzero所需的迭代次数更少,即fsolve收敛得更快。

而在函数调用次数方面,它也远少于fzero。

fzero在计算收敛域时,出现了不收敛的情况,而fsolve不会。

综合这两方面看,我觉得fsolve比fzero稍微有效一些。

1.5构造迭代公式与牛顿法求解

1.5.1构造一个迭代公式:

编写代码如下:

%-------------------作业题6_1构造迭代公式源程序ex6_1_5-------------------

clear;clc;

x0=1;x

(1)=x0;%给定迭代初值

tol=1e-10;%给定误差极限

u=1;n=100;%迭代计数,i大于100时跳出

i=1;

while((abs(u)>tol)&(sin(x(i))>eps))

x(i+1)=(2*sin(x(i)))^0.5;

u=x(i+1)-x(i);

i=i+1;

if(i>n)error('nisfull');

end

end

x'

i-1%输出迭代结果及迭代次数

输出结果如下:

ans=1

1.29728253268738

1.38767986886849

1.40234159737526

1.4041688093621

1.40438579137907

1.40441140012416

1.40441442031852

1.40441477647754

1.40441481847747

1.40441482343029

1.40441482401435

1.40441482408323

ans=12

迭代次数为12。

对该方法迭代次数进行统计:

 

表6:

求解函数不同初值的迭代次数

求解

初值

根的近似值

迭代次数

1

1.40441482408323

12

2

1.40441482408832

12

3

1.40441482408353

14

7

1.40441482408353

13

8

1.40441482408353

10

9

1.40441482409073

14

13

1.4044148240908

14

14

1.4044148240908

11

当初值取其他值时,x=(2sinx)^(1/2)无意义。

该迭代方法收敛次数多于fzero法和fsolve法。

1.5.2牛顿法求解

牛顿法程序代码:

%---------------------作业题6_1牛顿法求解源程序ex6_1_6-------------------

clear;clc;

x0=1;x

(1)=x0;%给定迭代初值

tol=1e-6;%给定误差极限

u=1;n=10;%迭代计数,i大于10时跳出

i=1;

while(abs(u)>tol)

x(i+1)=x(i)-(sin(x(i))-x(i)^2/2)/(cos(x(i))-x(i));

u=x(i+1)-x(i);

i=i+1;

if(i>n)error('nisfull');

end

end

x'

i-1%输出迭代结果及迭代次数

迭代次数为6。

对牛顿法迭代次数进行统计:

表7:

用牛顿法求解函数不同初值的迭代次数

用牛顿法求解

初值

根的近似值

迭代次数

-2

0

6

-1

0

6

0

0

1

1

1.40441482409243

6

2

1.40441482409243

6

3

1.40441482409243

7

4

1.40441482409243

7

5

1.40441482409243

7

6

1.40441482409243

7

7

1.40441482409243

8

8

1.40441482409243

8

9

1.40441482409243

8

10

1.40441482409243

8

11

1.40441482409243

8

12

1.40441482409243

8

13

1.40441482409243

8

14

1.40441482409243

9

牛顿法迭代次数随初值渐渐远离根的真实值而逐渐增大,增大速度递减。

【公式迭代与牛顿法比较】

公式法:

由于选取的迭代公式在某些初值设定下,会使表达式无意义,故该公式迭代只给出部分值的迭代结果。

另外,在尝试中,我发现当表达式在实数范围内无意义,给出复数解时,给出的实部总是1.4044这个根。

如果给定的初值不为0,就永远不可能迭代出0这个根。

这是由于

的图形在1.4044附近斜率是小于1的,根据局部收敛性定理,它在1.4044附近连续可微,导数绝对值小于1,因此会收敛到根。

但是在0附近不满足不动点收敛的条件,是一个蛛网型的迭代。

故不论以其他任何值迭代,都不会迭代到0。

牛顿法:

比较可知,等精度的情况下牛顿法的迭代次数较少,是一种更有效的算法。

而且牛顿法适当改变初值就可以得到两个根,而迭代法由于局部收敛性的限制,则只能得到一个根。

总体来说不如牛顿法。

1.6结果分析与讨论

以上四种迭代方法(fzero、fsolve、x=(2sinx)^(1/2))、牛顿),均可得到根x2的近似值。

其中,自己构造的迭代公式无法得到根x1的值。

四种迭代方法中fsolve和牛顿法迭代次数较少,收敛较快。

从本质上讲,牛顿法只是一种特殊的迭代法,它在迭代函数的选择上有讲究。

相对于其他迭代方法,也许牛顿法不是最有效的,但是它是一种有具体表达形式的迭代法。

但是它利用导数构造公式,可能让运算稍慢。

【题目2】(课本习题第六章第3题)

(1)小张夫妇以按揭方式贷款买了一套价值20万的房子,首付了5万元,每月还款1000元,15年还清。

问贷款利率是多少?

(2)某人欲贷款50万元购房,他咨询了两家银行,第一家银行开出的条件是每月还4500元,15年还清;第二家银行开出的条件是每年还45000元,20年还清。

从利率方面看,那家银行较优惠(简单的假设年利率=月利率*12)?

2.1模型建立

设yk为第k个月的欠款数,设月利率为r,房价为c万元,首付为d万元,每月还款b万元,则有

整理得

根据递推关系知

根据题意,c=20,d=5,b=0.1,y180=0,求解月利率r。

上式即为按揭方式贷款购房(按月计算)的数学模型。

2.2第

(1)问求解

按照已经建立好的按揭方式贷款购房模型,将第一问中的条件数据(房价c=20,首付d=5,每月还款数b=0.1,还款月数k=180)代入,可得

2.2.1求根的大致范围:

利用MATLAB输出f(r)的图像。

%-----------------------作业题6_3第一问图解根的范围ex6_3_1---------------------

clearall;clc;

n=30;

fori=1:

n

r(i)=0.0001*i;b=r(i);

f(i)=150*b*(1+b).^180;

g(i)=(1+b).^180-1;

c=f(i);d=g(i);

h(i)=c-d;

end;

plot(r,h),holdon,gridon;

xlabel('r');

ylabel('f(r)');

title('f(r)图像');%加入X轴、Y轴标记和标题

图2:

函数

零点图

得到上图,从上图可作出初步估计,r在0.00200和0.00225之间。

2.2.2下面利用二分法、牛顿法、fzero函数三种不同的方法求解:

①利用二分法求解

下面的程序实现的是用二分法求解方程,需要说明几点:

1、r1和r2分别表示之前估计的r的范围的上下限。

2、由于在这个实际问题中,不可能出现某个r3=0.5(r1+r2)正好是非线性方程

(1)的解,故在编写程序的时候未将这种情况考虑进去,而是假设f(r1)×f(r3)和f(r2)×f(r3)总有一个大于零另一个小于零。

3、二分的次数达到100次时,认为已经求出足够精确的解。

%---------------------作业题6_3第一问二分法求解源程序ex6_3_2-------------------

clearall;clc;

m=200000;a=50000;n=15*12;x=1000;p=m-a;i=0;

r1=0.002;r2=0.00225;

while(i<=100)

f1=p*(1+r1).^n+x*(1-(1+r1).^n)/r1;

f2=p*(1+r2).^n+x*(1-(1+r2).^n)/r2;

r3=(r1+r2)/2;

f3=p*(1+r3).^n+x*(1-(1+r3).^n)/r3;

if(f1*f3>0&&f2*f3<0)

r1=r3;

elseif(f1*f3<0&&f2*f3>0)

r2=r3;

end;

end;

i=i+1;

end;

r=(r1+r2)/2;

formatlongg;[r]

输出的结果如下:

r=0.00208116388945975≈0.2081%

②利用牛顿法求解

已知

那么对r求导得

故有

根据迭代公式

可求出非线性方程

(1)的解。

先利用MATLAB输出的曲线,观察{rk}是否收敛。

%-----------------作业题6_3第一问牛顿法观察图解观察根ex6_3_3-------------------

clearall;clc;

n=15;

fori=1:

n

r(i)=0.0001*(i+14);b=r(i);

c=(1+b).^180;d=(1+b).^179;

c1=b*c;d1=b*d;

f(i)=b-(150*c1-c+1)/(27000*d1+150*c-180*d);

g(i)=b;

end;

plot(r,f,r,g),holdon,gridon;

xlabel('r');

ylabel('y=r/y=φ(r)');

title('y=r/y=φ(r)图像');%加入X轴、Y轴标记和标题

legend('y=φ(r)','y=r')

图3:

牛顿法求解收敛性判断图

从上图可以看出,蓝色曲线在交点处的斜率的绝对值显然小于1,说明序列{rk}收敛。

下面的程序实现的是用牛顿法求解方程,需要说明几点:

1、取初值r0=0.0015。

2、根据上图可知,当取上条中指定的初值时,序列{rk}收敛,可得到方程的解。

3、取迭代次数为100次,认为此时得到的r已经足够精确。

%-------------------作业题6_3第一问牛顿法求解源程序ex6_3_4---------------------

clear;clc;

r=0.0015;m=0;

while(m<=100)

b=r;

c=(1+b).^180;

d=(1+b).^179;

c1=b*c;d1=b*d;

a=b-(150*c1-c+1)/(27000*d1+150*c-180*d);

r=a;m=m+1;

end

formatlongg;[r]

输出的结果为:

r=0.00208116388945918≈0.2081%

③利用fzero求解

fzero是MATLAB自带的求解单变量非线性方程的命令,所采用的算法主要是二分法、割线法和逆二次插值法等的混合方法。

需要说明的是:

fzero求解可以不事先知道解的范围。

在Matlab中编写程序如下:

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

当前位置:首页 > 自然科学 > 数学

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

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