So... here is how I would do it, it is very difficult for me to read what is going on in your code snippet, but I hope this helps you out. Additionally, matlab has built in rk solvers I would suggest becoming familiar with those.
%rk4 solver
dt = .2;
t = 0:dt:1;
u = zeros(2,numel(t));
u(:,1) = 1;
for jj = 2:numel(t)
u_ = u(:,jj-1);
t_ = t(jj-1);
fa = rhs(u_,t_);
fb = rhs(u_+dt/2.*fa,t_+dt/2);
fc = rhs(u_+dt/2.*fb,t_+dt/2);
fd = rhs(u_+dt.*fc,t_+dt);
u(:,jj) = u(:,jj-1) + dt/6*(fa+2*fb+2*fc+fd);
end
disp([t;u]')
and rhs.m is the following:
function dudt = rhs(u,t)
dudt = [(3*u(1) + 2*u(2) - (2*t^2 + 1)*exp(2*t));
(4*u(1) + u(2) + (t^2 + 2*t - 4)*exp(2*t))];
This returns the following:
>> rkorder4
0 1.0000 1.0000
0.2000 2.1204 1.5070
0.4000 4.4412 3.2422
0.6000 9.7391 8.1634
0.8000 22.6766 21.3435
1.0000 55.6612 56.0305
Alternatively, you could invoke ode45 with something like:
dt = .2;
t = 0:dt:1;
rhs=@(t,u)[(3*u(1) + 2*u(2) - (2*t^2 + 1)*exp(2*t));
(4*u(1) + u(2) + (t^2 + 2*t - 4)*exp(2*t))];
[ts,us]=ode45(@(t,u) rhs(t,u),t,[1 1],[]);
disp([ts us]);
Which gives you:
0 1.000000000000000 1.000000000000000
0.200000000000000 2.125018862140859 1.511597928697035
0.400000000000000 4.465156492097592 3.266022178547346
0.600000000000000 9.832481410895053 8.256418221678395
0.800000000000000 23.003033457636558 21.669270713784108
1.000000000000000 56.738351357036301 57.106230777717208
Which is pretty close to what you get from my code. The agreement between the two can be increased by decreasing the time step, dt
. They will always be in greatest agreement at the low values of t with the difference between the two increasing as t increases. Both implementations are also in pretty close agreement with the analytic solutions.