function multistep_demo

f = @(t,x) x; % x'(t) = x
xex = @(t) exp(t);

tspan = [0 2]; % integrate from t=0 to t=2

x0 = 1; % start with x(0) = 1

%%
h = 0.25; % time step
[t,x] = heun(f, tspan, x0, h); % call heun
semilogy(t,abs(xex(t)-x),'b--','markersize',15,'linewidth',2,'DisplayName','Heun, h = .25') % plot output
hold on

err_heun(1) = abs(xex(t(end))-x(end));

h = 0.125; % time step
[t,x] = heun(f, tspan, x0, h); % call heun
plot(t,abs(xex(t)-x),'r--','markersize',15,'linewidth',2,'DisplayName','Heun, h = .125') % plot output

err_heun(2) = abs(xex(t(end))-x(end));

h = 0.0625; % time step
[t,x] = heun(f, tspan, x0, h); % call heun
plot(t,abs(xex(t)-x),'k--','markersize',15,'linewidth',2,'DisplayName','Heun, h = .0625') % plot output

err_heun(3) = abs(xex(t(end))-x(end));

%%

h = 0.25; % time step
[t,x] = AB2(f, tspan, x0, h); % call AB2
semilogy(t,abs(xex(t)-x),'b-.','markersize',15,'linewidth',2,'DisplayName','AB2, h = .25') % plot output
hold on
err_AB(1) = abs(xex(t(end))-x(end));

h = 0.125; % time step
[t,x] = AB2(f, tspan, x0, h); % call AB2
plot(t,abs(xex(t)-x),'r-.','markersize',15,'linewidth',2,'DisplayName','AB2, h = .125') % plot output

err_AB(2) = abs(xex(t(end))-x(end));

h = 0.0625; % time step
[t,x] = AB2(f, tspan, x0, h); % call AB2
plot(t,abs(xex(t)-x),'k-.','markersize',15,'linewidth',2,'DisplayName','AB2, h = .0625') % plot output

err_AB(3) = abs(xex(t(end))-x(end));

grid on
legend show
set(gca,'fontsize',15)

%% plot convergence of errors

figure
h = [.25 .125 .0625];
loglog(h,err_heun,'ro-','markersize',15,'linewidth',2)
hold on
loglog(h,err_AB,'ko-','markersize',15,'linewidth',2)
loglog(h,h.^2,'k--','markersize',15,'linewidth',2)


legend('Heun','AB2','h^2')
grid on
xlabel('h')
set(gca,'fontsize',15)



function [t,x] = heun(f, tspan, x0, h)

t0 = tspan(1); tfinal = tspan(end);

% set up the t values at which we will approximate the solution
t=[t0:h:tfinal];

% include tfinal even if h does not evenly divide tfinal-t0
if abs(t(end)-tfinal)>1e-8
    t = [t tfinal]; 
end

% execute Heun's method
x = [x0 zeros(length(x0),length(t)-1)];
for j=1:length(t)-1 
    h = t(j+1)-t(j);
    k1 = feval(f,t(j),x(:,j));
    k2 = feval(f, t(j)+h, x(:,j) + h*k1);
    x(:,j+1) = x(:,j) + .5*h*(k1+k2);
end



function [t,x] = AB2(f, tspan, x0, h)

t0 = tspan(1); tfinal = tspan(end);

% set up the t values at which we will approximate the solution
t = [t0:h:tfinal];

% include tfinal even if h does not evenly divide tfinal-t0
if abs(t(end)-tfinal)>1e-8
    t = [t tfinal]; 
end

% execute AB with different starts
x = [x0 zeros(length(x0),length(t)-1)];
for j=1:length(t)-1     
    k1 = feval(f,t(j),x(:,j));     
    if j < 2
%         x(:,j+1) = exp(t(j+1));
        
        x(:,j+1) = x(:,j) + h*k1; % Forward Euler

%         k2 = feval(f, t(j)+h, x(:,j) + h*k1); % Heun's method
%         x(:,j+1) = x(:,j) + .5*h*(k1+k2);
    else        
        % AB-2
        x(:,j+1) = x(:,j) + .5*h*(3*k1-k2);        
    end
    
    k2 = k1;    
end



