MATLAB求解⽅程的根
%% 2022-1-12求⽅程的根
%{
求解⽅程的根 x^3+2^x+1=0,分别采⽤⼆分法,⽜顿法,简单迭代法,割线法,
上坡法和下坡法以及zeroin算法
%}
%% x^3+2^x+1=0 判断⽅程的根数,以及根的范围
clc;clo all;clear all;
%画函数图像判断
调御丈夫syms ('f','x');
f=@(x)x.^3+2.^x+1;%就是⼀个表达式就这样写了,⽅便
h=figure('name','函数');
fplot(f,'k');
magnifyOnFigure(h, 'displayLinkStyle','straight',...
'EdgeColor', 'black',...
'condaryAxesYLim',[-5,5],...
'condaryAxesXLim',[-3,3],...
'magnifierShape', 'rectangle',...
'mode', 'interactive',...
'initialPositionMagnifier',[200 180 180 40],...
'frozenZoomAspectratio', 'off',...
'edgeColor','g',...
'edgeWidth', 2);
%通过图像的局部放⼤图可以,发现根的范围在[-3,3]
%判断函数有⼏个根
figure('name','⼀阶导数');
diff(f,x,1);%log函数是以e为底
df=@(x)(2.^x.*log(2) + 3.*x.^2);%这⾥不加点会报错
fplot(df,[-3,3]);
%通过导函数的图像可以发现这个函数是单调递增的,根据零点定量+单调可知,只有⼀个根
%% 1.通过⼆分法求解,⼟⽊⼀般精度没有那种特别⾼,我们让它有四位有效数
epsilon=0.5*10^(-3);b=3;a=-3;k=0;
while (b-a)/(2^(k+1))>epsilon
k=k+1;
end
%f(a)<0,f(b)>0
lef=a;rig=b;
for i=1:k
隔壁听middle=(rig+lef)/2;
if f(middle)*f(rig)>0
rig=middle;
elif f(middle)*f(lef)>0
lef=middle;
end
end
disp(strcat('⼆分法⽅程的根为:',num2str(middle)));
%% 2.通过简单迭代法求解
% x=-(2^x+1)^(-3)黑洞宇宙
h=@(x)(-(2.^x+1).^(1/3));
diff(h,x,1);
Dh=@(x)-(2.^x.*log(2))./(3.*(2.^x + 1).^(2/3));
figure(3);
fplot(Dh)
%通过图像可以看出h(x)的导数在0-(-1)之间,h(a),h(b)都在[a,b]内,故迭代格式收敛
xj=2; %任取⼀个初始点
xi=h(xj);
while abs(xi-xj)>epsilon
xj=xi;
xi=h(xj);
end
disp(strcat('简单迭代法⽅程的根为:',num2str(xi)));
%{
先天卦%{
可以发现⼆分法求得的解为-1.1331,简单迭代法求得的解为-1.1334,
这和四位有效数的要求是满⾜的
%}外勤会计
%% ⽜顿迭代法⼤范围不收敛,所以⽤局部收敛性
figure('name','⼆阶导数');
diff(f,x,2);
df=@(x)(6.*x + 2.^x*log(2).^2);%这⾥不加点会报错
fplot(df,[-3,3]);
xp=-1.133400;
禄丰一中xq=xp-(f(xp)/df(xp));
while abs(xq-xp)>epsilon*10^(-1)
xp=xq;
xq=xp-(f(xp)/df(xp));
end
disp(strcat('⽜顿迭代法局部⽅程的根为:',num2str(xq)));
%% 割线法
x1=-1.13331;
x2=-1.13334;
dif=(f(x2)-f(x1))/(x2-x1);
x3=x2-(f(x2)/dif);
while abs(x3-x1)>epsilon*10^(-1)
x1=x2;
x2=x3;
dif=(f(x2)-f(x1))/(x2-x1);俄罗斯饮食
x3=x2-(f(x2)/dif);
end
disp(strcat('割线法局部⽅程的根为:',num2str(x3)));
%% steffenson这边称为上坡法
%% 上坡法
xd=-1.13331;
difd=(f(xd+f(xd))-f(xd))/f(xd);
xu=xd-(f(xd)/difd);
while abs(xu-xd)>epsilon*10^(-1)
xd=xu;
difd=(f(xd+f(xd))-f(xd))/f(xd);
xu=xd-(f(xd)/difd);
end
disp(strcat('上坡法局部⽅程的根为:',num2str(xu)));
%% MATLAB⼀些⾃带的求根函数
%% Zerions算法将⼆分法的可靠性和割线法快速性结合
options = optimt('Display','final','FunValCheck','off','TolX',epsilon);
z=fzero(f,[-3,3],options);
disp(strcat('Zerions算法⽅程的根为:',num2str(z)))
%% 寻找单变量的局部极⼩值,在求解根的时候也是⾮常有⽤的这⾥,演⽰⼀下[x,fval]=fminbnd(f,-3,3,options);
%fminarch使⽤⽆导数法计算⽆约束的多变量函数的最⼩值
%这⾥主要应⽤的是使⽤Lagarias 等的单纯形搜索法。
%% 最后看⼀下各个算法的结果和误差
A={};
A{1,1}='⼆分法';A{1,2}=middle;A{1,3}=f(middle);
A{2,1}='简单迭代法';A{2,2}=xi;A{2,3}=f(xi);
A{3,1}='⽜顿迭代法局部';A{3,2}=xq;A{3,3}=f(xq);
A{4,1}='割线法局部';A{4,2}=x3;A{4,3}=f(x3);
A{5,1}='⽜顿上坡法局部';A{5,2}=xu;A{5,3}=f(xu);
A{6,1}='Zerions算法';A{6,2}=z;A{6,3}=f(z);
Zx=A(:,1);
n=size(A);B=[];
for i=1:n(1)
B(i,1)=abs(A{i,3}-0);
end
figure
plot([1:2:12],B,'-*k','MarkerEdgeColor','r','MarkerSize',5);
plot([1:2:12],B,'-*k','MarkerEdgeColor','r','MarkerSize',5);
t(gca,'XTick',1:2:12,'XTickLabel',Zx,'XTickLabelRotation',45); title('各⽅法误差分析图')
>冷夜雨