数值计算作业:matlab实现

题目一

在这里插入图片描述

syms x;
fx=inline('54*x^6+45*x^5-102*x^4-69*x^3+35*x^2+16*x-4');
% 首先利用diff(54*x^6+45*x^5-102*x^4-69*x^3+35*x^2+16*x-4)求解函数的导数
dfx=inline('324*x^5 + 225*x^4 - 408*x^3 - 207*x^2 + 70*x + 16');
%% 绘图
x=-1.5:0.0001:1.2;
y=54.*x.^6+45.*x.^5-102.*x.^4-69.*x.^3+35.*x.^2+16.*x-4;
y2=0.*(1<=x);% 找到零点的大致范围,以便在牛顿迭代法中设置初值
plot(x,y,x,y2)
%% 调用函数分别求出五个根
[re1,step1]=NewtonDiedai(fx,dfx,-1.39);
[re2,step2]=NewtonDiedai(fx,dfx,-0.68);
[re3,step3]=NewtonDiedai(fx,dfx,0.23);
[re4,step4]=NewtonDiedai(fx,dfx,0.51);
[re5,step5]=NewtonDiedai(fx,dfx,1.18);
function [result,step] = NewtonDiedai(fx,dfx,x0)
%此方法为牛顿迭代法求解非线性方程的根
%   fx为原函数 dfx为导函数 x0为初值
%   result为结果,step为迭代步数
x1=x0;
step=1;
while 1
    x0=x1;
    x1=x0-feval(fx,x0)/feval(dfx,x0);  %feval()函数执行指定的函数
    if abs(x0-x1)<0.0001   %判断迭代结果精度是否达到要求
        break;
    end
    if(step>50)  %当步数大于50时认为迭代不收敛,退出
        break;
    end
    step=step+1; %记录步数
end
result=x0;
end

在这里插入图片描述
在这里插入图片描述

题目二

在这里插入图片描述
在这里插入图片描述

%% 求导
syms x;
fx=(1-3/(4*x))^(1/3);
diff(fx)  %求出函数的导数

%% 绘图
x=-3:0.0001:3;
y=(1-3./(4.*x)).^(1/3);
y2=0.*(1<=x);% 找到零点的大致范围,以便在牛顿迭代法中设置初值
plot(x,y,x,y2)

%% 调用函数求出根
fx_line=inline('(1-3/(4*x))^(1/3)');
dfx_line=inline('1/(4*x^2*(1 - 3/(4*x))^(2/3))');
[re1,step,x0_list]=NewtonDiedai(fx_line,dfx_line,0.78);
function [result,step,x0_list] = NewtonDiedai(fx,dfx,x0)
%此方法为牛顿迭代法求解非线性方程的根
%   fx为原函数 dfx为导函数 x0为初值
%   result为结果,step为迭代步数 x0_list为迭代结果的列表
x1=x0;
step=1;
x0_list=0;
while 1
    x0=x1;
    x1=x0-feval(fx,x0)/feval(dfx,x0);  %feval()函数执行指定的函数
    if abs(x0-x1)<0.0001   %判断迭代结果精度是否达到要求
        break;
    end
    if(step>55)  %当步数大于50时认为迭代不收敛,退出
        break;
    end
    step=step+1; %记录步数
    x0_list=[x0_list x0];
end
result=x0;
end

在这里插入图片描述
在这里插入图片描述

题目三

在这里插入图片描述

%设置矩阵维数分别为100 1000 10000
n=[100,1000,10000];
stepj_list=0;  %存储Jacobi方法的迭代步数
stepgs_list=0; %存储Gauss-Seidel方法的迭代步数
for k=1:3
    %制造A矩阵
a=zeros(n(k));
a(1,2)=-1;  
a(n(k),n(k)-1)=-1;
for i=1:n(k)
    a(i,i)=3;    
end
for i=2:n(k)-1
     a(i,i-1)=-1;
    a(i,i+1)=-1;  
end
%制造b向量
b=ones(n(k),1);
b(1)=2;
b(n(k))=2;
%分别调用函数,求解各自的方程解,以及迭代次数
[xj,countj]=Jacobi(a,b,zeros(n(k),1),10^(-6));
[xgs,countgs]=Gauss_Seidel(a,b,zeros(n(k),1),10^(-6));
stepj_list=[stepj_list,countj];
stepgs_list=[stepgs_list,countgs];
end
function [x,count] = Jacobi(A,b,x0,eps)
%利用jacobi计算Ax=b的解
%   x为计算所得解
%   count为迭代次数
%   A,b分别为Ax=b的系数与常数 x0为初值,eps为精度
%分离D L U 
D=diag(diag(A)); %A的对角矩阵   只有一个diag是一个列向量
L=-tril(A,-1);   %利用tril求解下三角矩阵,-1代表不包含对角线
U=-triu(A,1);  %利用triu求解上三角矩阵,1代表不包含对角线
M=D\(L+U);   %计算迭代矩阵
B=D\b;
x=M*x0+B;
count=1;
while norm(x-x0)>=eps   %循环,直至数值解满足精度要求
    x0=x;
    x=M*x0+B;
    count=count+1;
    if count>=10000       %当迭代次数过多,则不收敛
            disp('Warning:迭代次数太多,仍未达精度要求,可能不收敛!')
            return;
    end
end
function [x,count] = Gauss_Seidel(A,b,x0,eps)
%GAUSS_SEIDEL 计算Ax=b的解
%   x为计算所得解
%   count为迭代次数
%   A,b分别为Ax=b的系数与常数 x0为初值,eps为精度
%分离D L U 
D=diag(diag(A)); %A的对角矩阵   只有一个diag是一个列向量
L=-tril(A,-1);   %利用tril求解下三角矩阵,-1代表不包含对角线
U=-triu(A,1);  %利用triu求解上三角矩阵,1代表不包含对角线
M=-(D+L)\U;  %计算迭代矩阵
B=(D+L)\b;
x=M*x0+B;
count=1;
while norm(x-x0)>=eps  %循环,直至数值解满足精度要求
    x0=x; 
    x=M*x0+B;
    count=count+1;
    if count>=10000     %当迭代次数过多,则不收敛
            disp('Warning:迭代次数太多,仍未达精度要求,可能不收敛!')
            return;
    end
end
end

在这里插入图片描述
在这里插入图片描述

题目四

在这里插入图片描述

%% 提供原函数图像的点
x_yuan=linspace(-1,1,100);
y_yuan=1./(1.+12.*x_yuan.*x_yuan);

%% 分别用4次、8次、16次,20次插值多项式
dist=2;     %区间长度
list_poly_count=[4,8,16,20];  %多项式的次数

% 任意一个次数构造
%四次
step=dist/list_poly_count(1);  
x0=-1:step:1;        %计算需多少个节点
y0=1./(1.+12.*x0.*x0);
[C,L]= Lagrange(x0,y0);  %调用函数计算
resultx4=-1:0.0001:1;
resulty4=polyval(C,resultx4);   %计算resultx4对应的插值多项式的值,用于画图

%8次
step=dist/list_poly_count(2);
x0=-1:step:1;           %计算需多少个节点
y0=1./(1.+12.*x0.*x0);
[C,L]= Lagrange(x0,y0);  %调用函数计算
resultx8=-1:0.0001:1;
resulty8=polyval(C,resultx8);   %计算resultx8对应的插值多项式的值,用于画图

%16次
step=dist/list_poly_count(3);
x0=-1:step:1;                %计算需多少个节点
y0=1./(1.+12.*x0.*x0);
[C,L]= Lagrange(x0,y0);%调用函数计算
resultx16=-1:0.0001:1;
resulty16=polyval(C,resultx16);%计算resultx对应的插值多项式的值,用于画图


%20次
step=dist/list_poly_count(4);
x0=-1:step:1;
y0=1./(1.+12.*x0.*x0);%计算需多少个节点
[C,L]= Lagrange(x0,y0);%调用函数计算
resultx20=-1:0.0001:1;
resulty20=polyval(C,resultx20);%计算resultx对应的插值多项式的值,用于画图

%% 图像绘制
subplot(2,2,1);
plot(resultx4,resulty4,x_yuan,y_yuan,'linewidth',5);
title("\fontsize{20}4次插值与原函数对比图");
legend("4次插值","原函数图像");

subplot(2,2,2);
plot(resultx8,resulty8,x_yuan,y_yuan,'linewidth',5);
title("\fontsize{20}8次插值与原函数对比图");
legend("8次插值","原函数图像");

subplot(2,2,3);
plot(resultx16,resulty16,x_yuan,y_yuan,'linewidth',5);
title("\fontsize{20}16次插值与原函数对比图");
legend("16次插值","原函数图像");

subplot(2,2,4);
plot(resultx20,resulty20,x_yuan,y_yuan,'linewidth',5);
title("\fontsize{20}20次插值与原函数对比图");
legend("20次插值","原函数图像");

function [C,L]= Lagrange(X,Y)
%  Lagrange用于求解拉格朗日插值
%  X为各插值点的x坐标  
%  Y为各插值点的y坐标  
%  C为返回的插值多项式系数
%  L为插值多项式(sym)
m = length(X); %求解共有多少插值点
for k = 1 : m
    V = 1;
    for i = 1 : m
        if k ~= i
            %求解每个基函数的每一项
            V = conv(V,poly(X(i))) / (X(k) - X(i));   %用conv进行多项式的计算 
                                                                            %其中poly函数返回一个类似于x-xi的形式
        end
    end
    L1(k, :) = V; %存储每个基函数的各个系数
    l(k, :) = poly2sym(V);%将基函数的系数转为多项式形式,并存储
end
%分别计算多项式系数以及sym形式的多项式,方便展示
C = Y * L1;
L = Y * l;
end

在这里插入图片描述
根据图4-1,我们可以发现对于拉格朗日插值多项式,插值的次数越高,中间部分对原函数的贴合程度越高,但是Runge现象会非常明显;次数较低时中间部分的逼近效果会比较差,但是Runge现象也会减弱。

题目五

在这里插入图片描述

%% 传入数据
year={'1994','1995','1996','1997','1998','1999','2000','2001','2002','2003'};
year0=1994;
year_add=[0,1,2,3,4,5,6,7,8,9];
bbl=[67.052,68.008,69.803,72.024,73.400,72.063,74.669,74.487,74.065,76.777];

%% 拉格朗日插值
[C,L]= Lagrange(year_add,bbl);%为了方便计算,特将x化到0-9
predit_x=0:0.01:9;%计算需多少个节点
result=polyval(C,predit_x);%计算predit_x对应的插值多项式的值,用于画图
%绘制插值多项式图
hold on
plot(predit_x,result,'linewidth',5);
plot(year_add,bbl,"*",'linewidth',5);
set(gca,'XTicklabel',year);
title('\fontsize{20}9次插值多项式');


%%  求解2010年
add=2010-year0;
result_2010=polyval(C,add);%计算2010年对应的插值多项式的值
% 可以看出有Runge现象

%% 求解三次插值
year_1_4=year_add(1:4);
bbl_1_4=bbl(1:4);
%利用上述方法继续求解三次插值
[C_4,L_4,L1_4,l_4]= Lagrange(year_1_4,bbl_1_4);
predit_x=0:0.01:9;
result_1_4=polyval(C_4,predit_x);
hold on
plot(predit_x,result_1_4,'linewidth',5);
plot(year_add,bbl,"*",'linewidth',5);
set(gca,'XTicklabel',year);
title('\fontsize{20}3次插值多项式');

%%3次求1998年
add_98=1998-year0;
result_98=polyval(C_4,add_98);
% 没有Runge现象

%% 数据传入
year0=1994;
year_add=[0,1,2,3,4,5,6,7,8,9];
bbl=[67.052,68.008,69.803,72.024,73.400,72.063,74.669,74.487,74.065,76.777];
year={'1994','1995','1996','1997','1998','1999','2000','2001','2002','2003'};

%% 最小二乘直线拟合
a(:,1)=year_add';
a(:,2)=1;
%运用最小二乘原理计算
a_predit_=(a'*a)\(a'*bbl');
x_predit_=0:0.0001:9;
y_predit_=x_predit_*a_predit_(1)+a_predit_(2);
subplot(2,2,1);
hold on;
plot(x_predit_,y_predit_,'linewidth',5);
plot(year_add,bbl,"*",'linewidth',5);
set(gca,'XTicklabel',year);
title('\fontsize{20}最小二乘直线拟合');


%% 抛物线拟合
%运用polyfit进行二次拟合
c_predit_2=polyfit(year_add,bbl,2);
x_predit_2=0:0.0001:9;
%此处运用polyval计算拟合函数中各点坐标,用于绘图
y_predit_2=polyval(c_predit_2,x_predit_2);
subplot(2,2,2);
hold on;
plot(x_predit_2,y_predit_2,'linewidth',5);
plot(year_add,bbl,"*",'linewidth',5);
set(gca,'XTicklabel',year);
title('\fontsize{20}抛物线拟合');


%% 三次多项式拟合
%运用polyfit进行三次拟合
c_predit_3=polyfit(year_add,bbl,3);
x_predit_3=0:0.0001:9;
%此处运用polyval计算拟合函数中各点坐标,用于绘图
y_predit_3=polyval(c_predit_3,x_predit_3);
subplot(2,2,3);
hold on;
plot(x_predit_3,y_predit_3,'linewidth',5);
plot(year_add,bbl,"*",'linewidth',5);
set(gca,'XTicklabel',year);
title('\fontsize{20}三次多项式拟合');

%% 综合图
subplot(2,2,4);
hold on;
plot(x_predit_,y_predit_,x_predit_2,y_predit_2,x_predit_3,y_predit_3,'linewidth',2);

plot(year_add,bbl,"*",'linewidth',2);
legend('最小二乘','抛物线','三次多项式','原图像');
title('\fontsize{20}综合图像');

%% 预计2010年原油产量
add=2010-1994;
% 用最小二乘
predit_10_1=add*a_predit_(1)+a_predit_(2);

% 用抛物线拟合
predit_10_2=polyval(c_predit_2,add);

% 三次多项式拟合
predit_10_3=polyval(c_predit_3,add);
function [C,L]= Lagrange(X,Y)
%  Lagrange用于求解拉格朗日插值
%  X为各插值点的x坐标  
%  Y为各插值点的y坐标  
%  C为返回的插值多项式系数
%  L为插值多项式(sym)
m = length(X); %求解共有多少插值点
for k = 1 : m
    V = 1;
    for i = 1 : m
        if k ~= i
            %求解每个基函数的每一项
            V = conv(V,poly(X(i))) / (X(k) - X(i));   %用conv进行多项式的计算 
                                                                            %其中poly函数返回一个类似于x-xi的形式
        end
    end
    L1(k, :) = V; %存储每个基函数的各个系数
    l(k, :) = poly2sym(V);%将基函数的系数转为多项式形式,并存储
end
%分别计算多项式系数以及sym形式的多项式,方便展示
C = Y * L1;
L = Y * l;
end

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
经过分析图5-3以及表5-2,我们首先可以看出相比于插值多项式,三种类型的拟合多项式都可以比较好地预测原油产量。
通过分析图5-4,我们可以发现,虽然最小二乘直线能比较好地刻画原油产量随时间的变化,但是通过散点图我们可以看出点的分布在之后有弯的趋势,这更加符合二次或者三次多项式的特征;
在比较抛物线拟合与三次多项式拟合的图像后,我们可以发现三次多项式能顾及更多结点,而且走势也基本符合散点的走势,而且也没有出现过拟合的情况。
综上所示,我们可以得出三次多项式拟合曲线更能最好的表示表格中的数据。

题目六

在这里插入图片描述

%% 用复合梯形公式计算第一题
ft1=@(x)x^2*log(x);
[a,nn]=fuhuatixing(ft1,1,3,0.5*10^(-8));
%% 用复合梯形公式计算第二题
ft2=@(x)log(cos(x)+sin(x));
[a1,nn1]=fuhuatixing(ft2,0,pi/2,0.5*10^(-8));
%% 用复合梯形公式计算第三题
ft3=@(x)x/(2*exp(x)-exp(-x));
[a2,nn2]=fuhuatixing(ft3,0,1,0.5*10^(-8));

%% 用复合Simpson公式计算第一题
syms x;
f1=x^2*log(x);
[s,n] = Simpson(1,3,f1);

%% 用复合Simpson公式计算第二题
syms x;
f2=log(cos(x)+sin(x));
[s2,n2] = Simpson(0,pi/2,f2);

%% 用复合Simpson公式计算第三题
syms x;
f3=x/(2*exp(x)-exp(-x));
[s3,n3] = Simpson(0,1,f3);

%% 用Romberg公式计算第一题
[i1,num1]=Romberg(1,3,f1);


%% 用Romberg公式计算第二题
[i2,num2]=Romberg(0,pi/2,f2);


%% 用Romberg公式计算第三题
[i3,num3]=Romberg(0,1,f3);
function [A,N] = fuhuatixing(f1,a,b,q)
%用复化梯形公式进行积分求解
% a b:积分上下限  q:精度
%f1: 为所求函数的句柄
%A:积分结果
%N:小区间数量
 m=1;
 h=b-a;
 T(1)=h/2*(f1(a)+f1(b));%初始值设定
 
 %循环划分区间
 while 1
    h=h/2;
    sum=0;
    for j=1:2^(m-1)
        sum=sum+f1(a+(2*j-1)*h);
    end
    S(1)=T(1)/2+h*sum;
    for j=1:m
        S(j+1)=S(j)+(S(j)-T(j))/(4^j-1);
    end
    if(abs(S(m+1)-T(m))<=q) %直至精度满足要求
        A=S(m+1);
        break;
    end
    T=S;
    m=m+1;
 end
 %计算区间数量
 N=(b-a)/h;
end
function [i,num] = Romberg(low,up,L)
%利用ROMBERG 方法进行复化求积
% low,up是积分上下限
%   L是公式(sym的形式)
%   i为积分结果,num为区间数量
tolerance=0.5*10^(-8); %限差
h=(up-low)/2;
t(1,1)=h*(eval(subs(L,low))+eval(subs(L,up)));   
%subs()函数 表示将符号表达式中的某些符号变量替换为指定的新的变量
k=1;n=1;
m=1;
%根据书中的伪代码,可以写出复化函数
while 1    
    f=0;
    for i=1:n
        f=f+eval(subs(L,(low+(2*i-1)*h)));
    end
    t(k+1,1)=t(k,1)/2+h*f;
    for m=1:k
        t(k-m+1,m+1)=(4^m*t(k-m+2,m)-t(k-m+1,m))/(4^m-1);
    end
    if abs(t(1,m+1)-t(1,m))<tolerance
        break;
    end
    %将区间分半,继续求解
    h=h/2;
    n=2*n;
    k=k+1;
end
%取出romberg计算矩阵的最外侧数值即为最终积分解
i=t(1,m);
%计算区间数量
num=(up-low)/h;
function [ss,num] = Simpson(low,up,L)
%   Simpson方法进行复化求积
% low,up是积分上下限
%   L是公式(sym的形式)
%   ss为积分结果,num为区间数量
tolerance=0.5*10^(-8); %限差
%进行初值计算
f1=eval(subs(L,low)+subs(L,up));
f2=eval(subs(L,(low+up)/2));
s0=(up-low)*(f1+4*f2)/6;
n=2;
h=(up-low)/4;
st=0;
%根据书中的伪代码,可以写出复化函数
while(1)
    f3=0;
    for i=1:n
        f3=f3+eval(subs(L,low+(2*i-1)*h));
    end
    s=h*(f1+2*f2+4*f3)/3;
    if abs(s-s0)<15*tolerance   %直至精度满足要求
        ss=s;
        break;
    end
    st=st+1;
    %将区间分半,继续求解
    n=2*n;
    h=h/2;
    f2=f2+f3;
    s0=s;    
end
%计算区间数量
num=(up-low)/h;
end

在这里插入图片描述
根据表6-1、6-2、6-3所示,我们可以看出,两个方法在求不同的积分时,最终求得的值相等。
但Romberg求积方法是在复化梯形求积公式的基础上,应用了Richardson外推法构造的一种算法,是一种加速计算方法,故而与复合梯形公式/Simpson公式相比,所需的区间数量更少,能更快地求解。

题目七

在这里插入图片描述

%首先用dsolve('Dy=x','x')求解准确函数

%% 准确函数绘制
x0=0:0.001:1;
y0=x0.^2./2+1;


%% 用euler法求解第一个函数
%根据公式依次求解被积函数的积分值
% 分别按照步长0.1 0.05 0.025计算求解
% 步长为0.1求解
step=0.1;           
x1=0:step:1;
y1=zeros(1,1/step+1);%存储每次迭代值
y1(1)=1;%初值为1
for i=2:size(y1,2)  %euler法只与前一项有关,循环求解即可
    y1(i)=y1(i-1)+step*x1(i-1);       
end
% 0.05
step=0.05;
x2=0:step:1;
y2=zeros(1,1/step+1);
y2(1)=1;
for i=2:size(y2,2)
    y2(i)=y2(i-1)+step*x2(i-1);       
end
% 0.025
step=0.025;
x3=0:step:1;
y3=zeros(1,1/step+1);
y3(1)=1;
for i=2:size(y3,2)
    y3(i)=y3(i-1)+step*x3(i-1);       
end

%% 绘制用Euler法求解y'=x图
hold on;
plot(x0,y0,'linewidth',2);
plot(x1,y1,'linewidth',2);
plot(x2,y2,'linewidth',2);
plot(x3,y3,'linewidth',2);
legend('原函数','步长为0.1','步长为0.05','步长为0.025','Location','Best' );
title("\fontsize{20}用Euler法求解y'=x");

%% 用改进的euler法求解
%根据公式依次求解被积函数的积分值
% 分别按照步长0.1 0.05 0.025计算求解
% 步长为0.1求解
step=0.1;
x1=0:step:1;
y1=zeros(1,1/step+1);%存储每次迭代值
y1(1)=1;%初值为1
y11=y1;%存储y''
for i=2:size(y1,2)
    y1(i)=y1(i-1)+step*x1(i-1);       
    y11(i)=y11(i-1)+step/2*(x1(i-1)+x1(i));
end

% 0.05
step=0.05;
x2=0:step:1;
y2=zeros(1,1/step+1);
y2(1)=1;
y21=y2;
for i=2:size(y2,2)
    y2(i)=y2(i-1)+step*x2(i-1);       
    %首先运用euler做预估校正
    y21(i)=y21(i-1)+step/2*(x2(i-1)+x2(i));  
    %将预估校正的值代入进行迭代,所得为改进的euler法所求的积分值
end

% 0.025
step=0.025;
x3=0:step:1;
y3=zeros(1,1/step+1);
y3(1)=1;
y31=y3;
for i=2:size(y3,2)
    y3(i)=y3(i-1)+step*x3(i-1);       
    y31(i)=y31(i-1)+step/2*(x3(i-1)+x3(i));
end
%% 绘制用改进的Euler法求解y'=x图
hold on;
plot(x0,y0,'linewidth',2);
plot(x1,y1,'linewidth',2);
plot(x2,y2,'linewidth',2);
plot(x3,y3,'linewidth',2);
legend('原函数','步长为0.1','步长为0.05','步长为0.025','Location','Best' );
title("\fontsize{20}用改进的Euler法求解y'=x");
%首先用dsolve('Dy=x^2*y','x')求解准确函数

%% 准确函数
x0=0:0.001:1;
y0=exp(x0.^3./3);


%% 用euler法求解
%根据公式依次求解被积函数的积分值
% 分别按照步长0.1 0.05 0.025计算求解
% 0.1
step=0.1;
x1=0:step:1;
y1=zeros(1,1/step+1);%存储每次迭代值
y1(1)=1;%初值为1
for i=2:size(y1,2)
    y1(i)=y1(i-1)+step*x1(i-1)^2*y1(i-1);
end%euler法只与前一项有关,循环求解即可

% 0.05
step=0.05;
x2=0:step:1;
y2=zeros(1,1/step+1);
y2(1)=1;
for i=2:size(y2,2)
    y2(i)=y2(i-1)+step*x2(i-1)^2*y2(i-1);
end

% 0.025
step=0.025;
x3=0:step:1;
y3=zeros(1,1/step+1);
y3(1)=1;
for i=2:size(y3,2)
    y3(i)=y3(i-1)+step*x3(i-1)^2*y3(i-1);
end

%% 绘制用Euler法求解y'=x^{2}y图
hold on;
plot(x0,y0,'linewidth',2);
plot(x1,y1,'linewidth',2);
plot(x2,y2,'linewidth',2);
plot(x3,y3,'linewidth',2);
legend('原函数','步长为0.1','步长为0.05','步长为0.025','Location','Best' );
title("\fontsize{20}用Euler法求解y'=x^{2}y");

%% 用改进的euler法求解
% 步长0.1 0.05 0.025
% 0.1
step=0.1;
x1=0:step:1;
y1=zeros(1,1/step+1);
y1(1)=1;
y11=y1;
for i=2:size(y1,2)
    y1(i)=y1(i-1)+step*x1(i-1)^2*y1(i-1);%首先运用euler做预估校正
    y11(i)=y11(i-1)+step/2*(x1(i-1)^2*y11(i-1)+x1(i)^2*y1(i));
    %将预估校正的值代入进行迭代,所得为改进的euler法所求的积分值
end

% 0.05
step=0.05;
x2=0:step:1;
y2=zeros(1,1/step+1);%存储每次迭代值
y2(1)=1;%初值为1
y21=y2;%存储y''
for i=2:size(y2,2)
    y2(i)=y2(i-1)+step*x2(i-1)^2*y2(i-1);
    y21(i)=y21(i-1)+step/2*(x2(i-1)^2*y21(i-1)+x2(i)^2*y2(i));
end

% 0.025
step=0.025;
x3=0:step:1;
y3=zeros(1,1/step+1);
y3(1)=1;
y31=y3;
for i=2:size(y3,2)
    y3(i)=y3(i-1)+step*x3(i-1)^2*y3(i-1);
    y31(i)=y31(i-1)+step/2*(x3(i-1)^2*y31(i-1)+x3(i)^2*y3(i));
end
%% 绘制用改进的Euler法求解y'=x^{2}y图
hold on;
plot(x0,y0,'linewidth',2);
plot(x1,y1,'linewidth',2);
plot(x2,y2,'linewidth',2);
plot(x3,y3,'linewidth',2);
legend('原函数','步长为0.1','步长为0.05','步长为0.025','Location','Best' );
title("\fontsize{20}用改进的Euler法求解y'=x^{2}y");

%首先用dsolve('Dy=2*(x+1)*y','x')求解准确函数

%% 准确函数
x0=0:0.001:1;
y0=exp(x0.*(x0+ 2));


%% 用euler法求解
%根据公式依次求解被积函数的积分值
% 分别按照步长0.1 0.05 0.025计算求解
%步长: 0.1
step=0.1;
x1=0:step:1;
y1=zeros(1,1/step+1);%存储每次迭代值
y1(1)=1;%初值为1
for i=2:size(y1,2)
    y1(i)=y1(i-1)+step*2*(x1(i-1)+1)*y1(i-1);
end
% 0.05
step=0.05;
x2=0:step:1;
y2=zeros(1,1/step+1);
y2(1)=1;
for i=2:size(y2,2)%euler法只与前一项有关,循环求解即可
    y2(i)=y2(i-1)+step*2*(x2(i-1)+1)*y2(i-1);
end

% 0.025
step=0.025;
x3=0:step:1;
y3=zeros(1,1/step+1);
y3(1)=1;
for i=2:size(y3,2)
    y3(i)=y3(i-1)+step*2*(x3(i-1)+1)*y3(i-1);
end

%% 绘制用Euler法求解y'=2(x+1)y图
hold on;
plot(x0,y0,'linewidth',2);
plot(x1,y1,'linewidth',2);
plot(x2,y2,'linewidth',2);
plot(x3,y3,'linewidth',2);
legend('原函数','步长为0.1','步长为0.05','步长为0.025','Location','Best' );
title("\fontsize{20}用Euler法求解y'=2(x+1)y");

%% 用改进的euler法求解
% 步长0.1 0.05 0.025
% 0.1
step=0.1;
x1=0:step:1;
y1=zeros(1,1/step+1);
y1(1)=1;
y11=y1;
for i=2:size(y1,2)
    y1(i)=y1(i-1)+step*2*(x1(i-1)+1)*y1(i-1);%首先运用euler做预估校正
    y11(i)=y11(i-1)+step/2*(2*y11(i-1)*(x1(i-1)+1)+2*y1(i)*(x1(i)+1));
    %将预估校正的值代入进行迭代,所得为改进的euler法所求的积分值
end

% 0.05
step=0.05;
x2=0:step:1;
y2=zeros(1,1/step+1);
y2(1)=1;
y21=y2;
for i=2:size(y2,2)
    y2(i)=y2(i-1)+step*2*(x2(i-1)+1)*y2(i-1);
    y21(i)=y2(i-1)+step/2*(2*y21(i-1)*(x2(i-1)+1)+2*y2(i)*(x2(i)+1));
end

% 0.025
step=0.025;
x3=0:step:1;
y3=zeros(1,1/step+1);%存储每次迭代值
y3(1)=1;%初值为1
y31=y3;%存储y''
for i=2:size(y3,2)
    y3(i)=y3(i-1)+step*2*(x3(i-1)+1)*y3(i-1);
    y31(i)=y3(i-1)+step/2*(2*y31(i-1)*(x3(i-1)+1)+2*y3(i)*(x3(i)+1));
end
%% 绘制用改进的Euler法求解y'=2(x+1)y图
hold on;
plot(x0,y0,'linewidth',2);
plot(x1,y1,'linewidth',2);
plot(x2,y2,'linewidth',2);
plot(x3,y3,'linewidth',2);
legend('原函数','步长为0.1','步长为0.05','步长为0.025','Location','Best' );
title("\fontsize{20}用改进的Euler法求解y'=2(x+1)y");

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 13
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值