% 例题4，求微分方程:Adams-Bashforth二步法
clear all
clc
close all

x_in=2; %要求点的自变量值
y=@(x)exp(-0.5*x.^2); %精确值
x=0:0.001:x_in;

%h=input('请输入步长h=');
h=0.1;
x0=0;y0=1;
m=(x_in-x0)/h;
yy=zeros(1,m+1);
xx=zeros(1,m+1);
xx(1)=x0;     %第一个启动点
yy(1)=y0;
xx=x0:h:x0+m*h;

%下面调用Euler法与泰勒级数法，与上述AB二步法比较
ye=zeros(1,m+1);
yt=zeros(1,m+1);
ye(1)=1;
for n=1:m   %Euler method
   % xx(n)=x0+(n-1)*h;
    ye(n+1)=ye(n)-h*xx(n)*ye(n);
end

yt(1)=1;
for n=1:m
    yt(n+1)=yt(n)-h*xx(n)*yt(n)+0.5*h^2*(-yt(n)+xx(n)^2*yt(n));
end
%用Euler法或泰勒级数法产生第二个启动点
xx(2)=x0+h;
%yy(2)=ye(2); %第二个启动点，来自泰勒级数法
%yy(2)=ye(2); %第二个启动点，来自Euler法
yy(2)=y(xx(2)); %第二个启动点，来自精确值,假设已知

for n=2:m   %Adams-Bashforth二步法
    %xx(n)=x0+(n-1)*h;
    yy(n+1)=yy(n)+h*(-1.5*xx(n)*yy(n)+0.5*xx(n-1)*yy(n-1));
end
%xx(m+1)=x0+m*h;


figure;plot(x,y(x),'r',xx,ye,'b',xx,yt,'k',xx,yy,'g') 
%画Euler法,泰勒级数法与二步法结果
legend('精确解','Euler法','泰勒级数法','二步法')
xlabel('x')
ylabel('y')
title('采用Euler法、泰勒级数法和二步法求解常微分方程的初值问题')

figure; plot(xx,y(xx)-ye,'r',xx,y(xx)-yt,'b',xx,y(xx)-yy,'g')
%画Euler法,泰勒级数法与二步法的误差
legend('Euler法','泰勒级数法','二步法')
xlabel('x')
ylabel('error')
title('Euler法、泰勒级数法和二步法的误差')
%plot(x,y(x),'r',xx,yy,'b')
%legend('精确解','Adams-Bashforth二步法')

fprintf('y(x_in)的精确值为：%f\n',y(x_in));
fprintf('Adams-Bashforth二步法求得的值为：%f\n',yy(m+1));
error=y(x_in)-yy(m+1);
fprintf('Adams-Bashforth二步法误差为：%f\n',error);


