实验目的
通过实验加深理解非线性方程求根的各个方法,掌握Matlab内置求根函数的使用方法,学会编写重点求根方法的Matlab程序。
实验原理
Matlab有内置函数直接求解方程的数值解。多项式求根命令
>> roots§
其中,输入p为多项式系数组成的向量,输出为多项式所有实数和复数根。
Matlab中还有求一般非线性方程
f
(
x
)
=
0
f\left( x \right) = 0
f
(
x
)
=
0
的实数根的命令
>> x = fzero(‘fun’,x0)
其中,输入fun为非线性函数
f
(
x
)
f\left( x \right)
f
(
x
)
,x0为根的估计值,x0也可以用含根区间
[
a
,
b
]
\left[ {a,b} \right]
[
a
,
b
]
,代替(注意
[
a
,
b
]
\left[ {a,b} \right]
[
a
,
b
]
的函数值要求异号)。
牛顿迭代公式
x
n
+
1
=
x
n
−
f
(
x
n
)
f
′
(
x
n
)
{x_{n + 1}} = {x_n} – {
{f({x_n})} \over {f'({x_n})}}
x
n
+
1
=
x
n
−
f
′
(
x
n
)
f
(
x
n
)
实验内容与步骤
-
求方程
x2
+
4
sin
(
x
)
=
25
{x^2} + 4\sin \left( x \right) = 25
x
2
+
4
sin
(
x
)
=
2
5
在区间
[−
2
π
,
2
π
]
[ – 2\pi ,2\pi ]
[
−
2
π
,
2
π
]
,内的所有实数根.先画图判断根的情况,再利用以上介绍的fzero法,二分法,牛顿迭代法分别求解,一个方法求一个解。
原式子即求解
x2
+
4
sin
x
−
25
=
0
{x^2} + 4\sin x – 25 = 0
x
2
+
4
sin
x
−
2
5
=
0
的根。通过画图分析,它在%
[−
2
π
,
2
π
]
[ – 2\pi ,2\pi ]
[
−
2
π
,
2
π
]
内的根落在
[−
6
,
−
4
]
[ – 6, – 4]
[
−
6
,
−
4
]
,和
[4
,
6
]
[4,6]
[
4
,
6
]
之间
fzero法求解它的两个根为
x1
=
−
4
.
586052690568049
,
x
2
=
5
.
318580248846235
{x_1} = {\rm{ – 4}}{\rm{.586052690568049,}}{x_2}{\rm{ = 5}}{\rm{.318580248846235}}
x
1
=
−
4
.
5
8
6
0
5
2
6
9
0
5
6
8
0
4
9
,
x
2
=
5
.
3
1
8
5
8
0
2
4
8
8
4
6
2
3
5
二分法求解它的两个根为
x1
=
−
4
.
586425781250000
,
x
2
=
5
.
318847656250000
{x_1} = {\rm{ – 4}}{\rm{.586425781250000,}}{x_2}{\rm{ = 5}}{\rm{.318847656250000}}
x
1
=
−
4
.
5
8
6
4
2
5
7
8
1
2
5
0
0
0
0
,
x
2
=
5
.
3
1
8
8
4
7
6
5
6
2
5
0
0
0
0
迭代次数
k1
=
k
2
=
11
{k_1} = {k_2} = 11
k
1
=
k
2
=
1
1
牛顿法求解它的两个根为
x1
=
−
4
.
586052690440867
,
x
2
=
5
.
318580252569003
{x_1} = {\rm{ – 4}}{\rm{.586052690440867}},{x_2} = {\rm{5}}{\rm{.318580252569003}}
x
1
=
−
4
.
5
8
6
0
5
2
6
9
0
4
4
0
8
6
7
,
x
2
=
5
.
3
1
8
5
8
0
2
5
2
5
6
9
0
0
3
迭代次数
k1
=
k
2
=
2
{k_1} = {k_2} = 2
k
1
=
k
2
=
2
-
编写不动点迭代法的matlab程序,利用编写的程序求方程
sin
x
+
1
=
x
2
2
\sin x + 1 = {
{
{x^2}} \over 2}
sin
x
+
1
=
2
x
2
在区间
[−
4
,
4
]
[ – 4,4]
[
−
4
,
4
]
内的所有实数根。
由于将方程写为
x=
arcsin
(
x
2
2
−
1
)
x = \arcsin ({
{
{x^2}} \over 2} – 1)
x
=
arcsin
(
2
x
2
−
1
)
会超出最大迭代次数,将方程构造为
x=
±
2
sin
x
+
2
x = \pm \sqrt {2\sin x + 2}
x
=
±
2
sin
x
+
2
更好一些。通过画图分析,在
[−
4
,
4
]
[ – 4,4]
[
−
4
,
4
]
内有两个根,分别位于
[−
2
,
0
]
[ – 2,0]
[
−
2
,
0
]
和
[0
,
2
]
[ 0,2]
[
0
,
2
]
之间。
先使用fzero求解两个根分别为
x1
=
−
0
.
774980814423043
,
x
2
=
1
.
961884246410835
{x_1} = {\rm{ – 0}}{\rm{.774980814423043}},{x_2} = {\rm{1}}{\rm{.961884246410835}}
x
1
=
−
0
.
7
7
4
9
8
0
8
1
4
4
2
3
0
4
3
,
x
2
=
1
.
9
6
1
8
8
4
2
4
6
4
1
0
8
3
5
在
[0
,
2
]
[0,2]
[
0
,
2
]
内原方程是,选取初值为1,使用不动点迭代法解得
x1
=
1
.
96183
{x_1} = {\rm{1}}{\rm{.96183}}
x
1
=
1
.
9
6
1
8
3
,迭代次数
k1
=
5
{k_1} = 5
k
1
=
5
在
[−
2
,
0
]
[ – 2,0]
[
−
2
,
0
]
内原方程是
x=
−
2
sin
x
+
2
x = – \sqrt {2\sin x + 2}
x
=
−
2
sin
x
+
2
,选取初值为-1,使用不动点迭代法解得
x2
=
−
0
.
775443039377297
{x_2} = {\rm{ – 0}}{\rm{.775443039377297}}
x
2
=
−
0
.
7
7
5
4
4
3
0
3
9
3
7
7
2
9
7
,迭代次数
k2
=
76
{k_2} = 76
k
2
=
7
6
erfen.m
function [x,k]=erfen(a,b,e)
%输入(a,b)为估计的含跟区间,e为误差.
%输出x为方程的数值解,k求解次数.
format long;
k=0;
while abs(b-a)>e
if f((a+b)/2)==0
x=(a+b)/2;
return;
end
if f(a)*f((a+b)/2)<0
b=(a+b)/2;
else
a=(a+b)/2;
end
k=k+1;
disp([k,a,b]);
end
x=(a+b)/2;
question1_erfen.m
clc
format long
ezplot('x^2+4*sin(x)-25'),grid
%[x1,k1]=erfen(-6,-4,0.001)
[x2,k2]=erfen(4,6,0.001)
question1_fzero.m
clc
format long
ezplot('x^2+4*sin(x)-25'),grid
fzero('x^2+4*sin(x)-25',[-6 -4])
fzero('x^2+4*sin(x)-25',[4 6])
question1_niudun.m
clc
format long
[x2,k2]=ntdd(2,0.0001,100)
ntdd.m
function [x,k]=ntdd(x0,e,N)
%输入x0为估计的迭代初值,e为规定的误差,N为最大迭代次数.
%输出x数值解,k为迭代次数.
format long;
k=0;x1=x0-h(x0)/dh(x0);
while (abs(x0-x1))>e
x0=x1;
x1=x0-h(x0)/dh(x0);
k=k+1;
disp([k,x1]);
if k>N
return;
end
end
x=x1;
question2_1.m
clc
syms x;
f=sqrt(2*sin(x)+2);
p0=2;
perror=0.001;
maxK=100;
ezplot('x^2/2-1-sin(x)'),grid
[x,k,Y]=FPM(f,p0,perror,maxK)
question2_2.m
format long
clc
syms x;
%f=-sqrt(2*sin(x)+2);
%f=asin((x^2)/2-1);
f=x*x-3*x+2.3-exp(x);
p0=0.3;
perror=1e-6;
maxK=100;
ezplot('x^2-3*x+2.3-exp(x)'),grid
[x,k,Y]=FPM(f,p0,perror,maxK)
FPM.m
function [p,k,Y]=FPM(f,p0,perror,maxK)
%p0表示迭代初始值
%f表示迭代公式函数
%maxK表示规定的最大迭代次数
%pererr表示允许误差
%k表示最终迭代的次数
%p表示最终迭代的值
%Y用来记录每次迭代过程的迭代值
format long
syms x;
P(1)=p0;
k=2;
P(k)=subs(f,x,P(k-1)); %迭代
while k<=maxK
err=abs(P(k)-P(k-1)); %err表示相邻的迭代值的差值
if(err<perror)
fprintf('迭代%d次即可满足允许误差值退出\n',k-1);
break;
end
k=k+1;
P(k)=subs(f,x,P(k-1));
end %共迭代了k-1次
if(k-1==maxK)
disp("超过最大迭代次数!");
end
p=P(k);
k=k-1;
Y=P;
end
f.m
function y=f(x)
y=x*x+4*sin(x)-25;
df.m
function y=df(x)
y=2*x+4*cos(x);