% the program takes the initial data y_0 at the initial time x_0 and % computes up to time x_final using N timesteps of size dx. It creates % two vectors, x and y, which you can then plot against each other % plot(x,y) % % To call the routine, use the command: % % [x,y] = adams_bashforth_4(y_0,x_0,x_final,N,@f) % function [x,y] = adams_bashforth_4(y_0,x_0,x_final,N,f) % step-size: dx = (x_final-x_0)/N; % for dy/dx = f(x,y(x)) % % y(x+dx) ~ y(x)+dx/12*(23*f(x,y(x))-16*f(x-dx,y(x-dx))+5*f(x-2*dx,y(x-2*dx))) % pux initial data into vector x(1) = x_0; y(:,1) = y_0; % I need to get y(x_0+dx) with local truncation error O(h^4). I'll % do this with Richardson extrapolation on Euler timestepping... ii=1; F1 = feval(f,x(ii),y(:,ii)); F_now = F1; % take one big step to reach y_big y_big = y(:,ii) + dx*F1; % take two small steps to reach y_med y_temp = y(:,ii) + dx/2*F1; F = feval(f,x(ii)+dx/2,y_temp); y_med = y_temp + dx/2*F; % take four smaller yet steps to reach y_small % y at x + dx/4 y_temp = y(:,ii) + dx/4*F1; F = feval(f,x(ii)+dx/4,y_temp); % y at x + 2*(dx/4) y_temp = y_temp + dx/4*F; F = feval(f,x(ii)+2*(dx/4),y_temp); % y at x + 3*(dx/4) y_temp = y_temp + dx/4*F; F = feval(f,x(ii)+3*(dx/4),y_temp); y_small = y_temp + dx/4*F; % use Richardson extrapolation rich_big = 2*y_med - y_big; rich_small = 2*y_small - y_med; y(:,ii+1) = (4/3)*rich_small - (1/3)*rich_big; x(ii+1) = x_0 + ii*dx; ii=2; F_old = F_now; F1 = feval(f,x(ii),y(:,ii)); F_now = F1; % take one big step to reach y_big y_big = y(:,ii) + dx*F1; % take two small steps to reach y_med y_temp = y(:,ii) + dx/2*F1; F = feval(f,x(ii)+dx/2,y_temp); y_med = y_temp + dx/2*F; % take four smaller yet steps to reach y_small % y at x + dx/4 y_temp = y(:,ii) + dx/4*F1; F = feval(f,x(ii)+dx/4,y_temp); % y at x + 2*(dx/4) y_temp = y_temp + dx/4*F; F = feval(f,x(ii)+2*(dx/4),y_temp); % y at x + 3*(dx/4) y_temp = y_temp + dx/4*F; F = feval(f,x(ii)+3*(dx/4),y_temp); y_small = y_temp + dx/4*F; % use Richardson extrapolation rich_big = 2*y_med - y_big; rich_small = 2*y_small - y_med; y(:,ii+1) = (4/3)*rich_small - (1/3)*rich_big; x(ii+1) = x_0 + ii*dx; ii=3; F_older = F_old; F_old = F_now; F1 = feval(f,x(ii),y(:,ii)); F_now = F1; % take one big step to reach y_big y_big = y(:,ii) + dx*F1; % take two small steps to reach y_med y_temp = y(:,ii) + dx/2*F1; F = feval(f,x(ii)+dx/2,y_temp); y_med = y_temp + dx/2*F; % take four smaller yet steps to reach y_small % y at x + dx/4 y_temp = y(:,ii) + dx/4*F1; F = feval(f,x(ii)+dx/4,y_temp); % y at x + 2*(dx/4) y_temp = y_temp + dx/4*F; F = feval(f,x(ii)+2*(dx/4),y_temp); % y at x + 3*(dx/4) y_temp = y_temp + dx/4*F; F = feval(f,x(ii)+3*(dx/4),y_temp); y_small = y_temp + dx/4*F; % use Richardson extrapolation rich_big = 2*y_med - y_big; rich_small = 2*y_small - y_med; y(:,ii+1) = (4/3)*rich_small - (1/3)*rich_big; x(ii+1) = x_0 + ii*dx; for ii=4:N F_oldest = F_older; F_older = F_old; F_old = F_now; F_now = feval(f,x(ii),y(:,ii)); y(:,ii+1) = y(:,ii) + dx/24*(55*F_now - 59*F_old + 37*F_older - 9*F_oldest); x(ii+1) = x_0 + ii*dx; end