Solve a system of equations with Runge Kutta 4: Matlab - matlab

I want to solve a system of THREE differential equations with the Runge Kutta 4 method in Matlab (Ode45 is not permitted).
After a long time spent looking, all I have been able to find online are either unintelligible examples or general explanations that do not include examples at all. I would like a concrete example on how to implement my solution properly, or the solution to a comparable problem which I can build on.
I have come quite far; my current code spits out a matrix with 2 correct decimals on most of the components, which I am quite happy with.
However, when the step-size is decreased, the errors become enormous. I know the for-loop I have created is not entirely correct. I may have defined the functions incorrectly, but I am quite certain that the problem is solved if some minor changes are made to the for-loop because it appears to be solving the equation-system fairly well already in its current state.
clear all, close all, clc
%{
____________________TASK:______________________
Solve the system of differential equations below
in the interval 0<t<1, with stepsize h = 0.1.
x'= y x(0)=1
y'= -x-2e^t+1 y(0)=0 , where x=x(t), y=y(t), z=z(t)
z'= -x - e^t + 1 z(0)=1
THE EXACT SOLUTIONS for x y and z can be found in this pdf:
archives.math.utk.edu/ICTCM/VOL16/C029/paper.pdf
_______________________________________________
%}
h = 0.1;
t = 0:h:1
N = length(t);
%Defining the functions
x = zeros(N,1);%I am not entierly sure if x y z are supposed to be defined in this way.
y = zeros(N,1)
z = zeros(N,1)
f = #(t, x, y, z) -x-2*exp(t)+1;%Question: Do i need a function for x here as well??
g = #(t, x, y, z) -x - exp(t) + 1;
%Starting conditions
x(1) = 1;
y(1) = 0;
z(1) = 1;
for i = 1:(N-1)
K1 = h * ( y(i));%____I think z(i) is supposed to be here, but i dont know in what way.
L1 = h * f( t(i) , x(i) , y(i) , z(i));
M1 = h * g( t(i) , x(i) , y(i) , z(i));
K2 = h * (y(i) + 1/2*L1 + 1/2*M1);%____Again, z(i) should probably be here somewhere.
L2 = h * f(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
M2 = h * g(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
K3 = h * (y(i) + 1/2*L2 + 1/2*M2);%____z(i). Should it just be added, like "+z(i)" ?
L3 = h * f(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
M3 = h * g(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
K4 = h * (y(i) + L3 + M3);%_____z(i) ... ?
L4 = h * f( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
M4 = h * g( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
x(i+1) = x(i)+1/6*(K1+2*K2+2*K3+K4);
y(i+1) = y(i)+1/6*(L1+2*L2+2*L3+L4);
z(i+1) = z(i)+1/6*(M1+2*M2+2*M3+M4);
end
Answer_Matrix = [t' x y z]

So your main issue was not defining x properly. You were propagating its value using the Runge Kutta 4 (RK4) method, but never actually defined what its derivative was!
At the bottom of this answer is a function which can take any given number of equations and their initial conditions. This has been included to address your need for a clear example for three (or more) equations.
For reference, the equations can be directly lifted from the standard RK4 method described here.
Working Script
This is comparable to yours, but uses slightly clearer naming conventions and structure.
% Initialise step-size variables
h = 0.1;
t = (0:h:1)';
N = length(t);
% Initialise vectors
x = zeros(N,1); y = zeros(N,1); z = zeros(N,1);
% Starting conditions
x(1) = 1; y(1) = 0; z(1) = 1;
% Initialise derivative functions
dx = #(t, x, y, z) y; % dx = x' = dx/dt
dy = #(t, x, y, z) - x -2*exp(t) + 1; % dy = y' = dy/dt
dz = #(t, x, y, z) - x - exp(t) + 1; % dz = z' = dz/dt
% Initialise K vectors
kx = zeros(1,4); % to store K values for x
ky = zeros(1,4); % to store K values for y
kz = zeros(1,4); % to store K values for z
b = [1 2 2 1]; % RK4 coefficients
% Iterate, computing each K value in turn, then the i+1 step values
for i = 1:(N-1)
kx(1) = dx(t(i), x(i), y(i), z(i));
ky(1) = dy(t(i), x(i), y(i), z(i));
kz(1) = dz(t(i), x(i), y(i), z(i));
kx(2) = dx(t(i) + (h/2), x(i) + (h/2)*kx(1), y(i) + (h/2)*ky(1), z(i) + (h/2)*kz(1));
ky(2) = dy(t(i) + (h/2), x(i) + (h/2)*kx(1), y(i) + (h/2)*ky(1), z(i) + (h/2)*kz(1));
kz(2) = dz(t(i) + (h/2), x(i) + (h/2)*kx(1), y(i) + (h/2)*ky(1), z(i) + (h/2)*kz(1));
kx(3) = dx(t(i) + (h/2), x(i) + (h/2)*kx(2), y(i) + (h/2)*ky(2), z(i) + (h/2)*kz(2));
ky(3) = dy(t(i) + (h/2), x(i) + (h/2)*kx(2), y(i) + (h/2)*ky(2), z(i) + (h/2)*kz(2));
kz(3) = dz(t(i) + (h/2), x(i) + (h/2)*kx(2), y(i) + (h/2)*ky(2), z(i) + (h/2)*kz(2));
kx(4) = dx(t(i) + h, x(i) + h*kx(3), y(i) + h*ky(3), z(i) + h*kz(3));
ky(4) = dy(t(i) + h, x(i) + h*kx(3), y(i) + h*ky(3), z(i) + h*kz(3));
kz(4) = dz(t(i) + h, x(i) + h*kx(3), y(i) + h*ky(3), z(i) + h*kz(3));
x(i+1) = x(i) + (h/6)*sum(b.*kx);
y(i+1) = y(i) + (h/6)*sum(b.*ky);
z(i+1) = z(i) + (h/6)*sum(b.*kz);
end
% Group together in one solution matrix
txyz = [t,x,y,z];
Implemented as function
You wanted code which can "be applied to any equation system". To make your script more usable, let's take advantage of vector inputs, where each variable is on its own row, and then make it into a function. The result is something comparable (in how it is called) to Matlab's own ode45.
% setup
odefun = #(t, y) [y(2); -y(1) - 2*exp(t) + 1; -y(1) - exp(t) + 1];
y0 = [1;0;1];
% ODE45 solution
[T, Y] = ode45(odefun, [0,1], y0);
% Custom RK4 solution
t = 0:0.1:1;
y = RK4(odefun, t, y0);
% Compare results
figure; hold on;
plot(T, Y); plot(t, y, '--', 'linewidth', 2)
You can see that the RK4 function (below) gives the same result of the ode45 function.
The function RK4 is simply a "condensed" version of the above script, it will work for however many equations you want to use. For broad use, you would want to include input-checking in the function. I have left this out for clarity.
function y = RK4(odefun, tspan, y0)
% ODEFUN contains the ode functions of the system
% TSPAN is a 1D vector of equally spaced t values
% Y0 contains the intial conditions for the system variables
% Initialise step-size variables
t = tspan(:); % ensure column vector = (0:h:1)';
h = t(2)-t(1);% define h from t
N = length(t);
% Initialise y vector, with a column for each equation in odefun
y = zeros(N, numel(y0));
% Starting conditions
y(1, :) = y0(:)'; % Set intial conditions using row vector of y0
k = zeros(4, numel(y0)); % Initialise K vectors
b = repmat([1 2 2 1]', 1, numel(y0)); % RK4 coefficients
% Iterate, computing each K value in turn, then the i+1 step values
for i = 1:(N-1)
k(1, :) = odefun(t(i), y(i,:));
k(2, :) = odefun(t(i) + (h/2), y(i,:) + (h/2)*k(1,:));
k(3, :) = odefun(t(i) + (h/2), y(i,:) + (h/2)*k(2,:));
k(4, :) = odefun(t(i) + h, y(i,:) + h*k(3,:));
y(i+1, :) = y(i, :) + (h/6)*sum(b.*k);
end
end

Ok, turns out it was just a minor mistake where the x-variable was not defined as a function of y (as x'(t)=y according to the problem.
So: Below is a concrete example on how to solve a differential equation system using Runge Kutta 4 in matlab:
clear all, close all, clc
%{
____________________TASK:______________________
Solve the system of differential equations below
in the interval 0<t<1, with stepsize h = 0.1.
x'= y x(0)=1
y'= -x-2e^t+1 y(0)=0 , where x=x(t), y=y(t), z=z(t)
z'= -x - e^t + 1 z(0)=1
THE EXACT SOLUTIONS for x y and z can be found in this pdf:
archives.math.utk.edu/ICTCM/VOL16/C029/paper.pdf
_______________________________________________
%}
%Step-size
h = 0.1;
t = 0:h:1
N = length(t);
%Defining the vectors where the answer is stored.
x = zeros(N,1);
y = zeros(N,1)
z = zeros(N,1)
%Defining the functions
e = #(t, x, y, z) y;
f = #(t, x, y, z) -x-2*exp(t)+1;
g = #(t, x, y, z) -x - exp(t) + 1;
%Starting/initial conditions
x(1) = 1;
y(1) = 0;
z(1) = 1;
for i = 1:(N-1)
K1 = h * e( t(i) , x(i) , y(i) , z(i));
L1 = h * f( t(i) , x(i) , y(i) , z(i));
M1 = h * g( t(i) , x(i) , y(i) , z(i));
K2 = h * e(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
L2 = h * f(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
M2 = h * g(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
K3 = h * e(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
L3 = h * f(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
M3 = h * g(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
K4 = h * e( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
L4 = h * f( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
M4 = h * g( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
x(i+1) = x(i)+1/6*(K1+2*K2+2*K3+K4);
y(i+1) = y(i)+1/6*(L1+2*L2+2*L3+L4);
z(i+1) = z(i)+1/6*(M1+2*M2+2*M3+M4);
end
Answer_Matrix = [t' x y z]

Related

system of equation Runge-Kutta 4th order for system of equation using matlab [duplicate]

This question already has answers here:
Solve a system of equations with Runge Kutta 4: Matlab
(2 answers)
Closed 4 years ago.
I need to do matlab code to solve the system of equation by using Runge-Kutta method 4th order but in every try i got problem and can't solve
the derivative is
(d^2 y)/dx^(2) +dy/dx-2y=0
, h=0.1 Y(0)=1 , dy/dx (0)=-2
{clear all, close all, clc
%{
____________________TASK:______________________
Solve the system of differential equations below
in the interval 0<x<1, with stepsize h = 0.1.
y= y1 y(0)=0
y3= 2y1-y2 y2(0)=-2
_______________________________________________
%}
h = 0.1;
x = 0:h:1
N = length(x);
y = zeros(N,1);
y3 = zeros(N,1);
g = #(x, y, y1, y2) y1;
f = #(x, y, y1, y2) 2*y1-y2;
y1(1) = 0;
y2(1) =-2;
for i = 1:(N-1)
k_1 = x(i)+y(i)
k_11=g(x(i),y,y(i))
k_2 = (x(i)+h/2)+(y(i)+0.5*h*k_1)
k_22=g((x(i)+0.5*h),y,(y(i)+0.5*h*k_11))
k_3 = (x(i)+h/2)+(y(i)+0.5*h*k_2)
k_33=g((X(i)+0.5*h),y,(y(i)+0.5*h*k_22));
k_4 = (x(i)+h)+(y(i)+h*k_33)
k_44=g((x(i)+h),y,(y(i)+k_33*h));
y3(i+1) = y(i) + (1/6)*(k_1+2*k_2+2*k_3+k_4)*h
y3(:,i)=y;
end
Answer_Matrix = [x' y3 ];}
You used functions, that's not really necessary, but it might be easier that way to see the formula more clearly. In your functions however, you list arguments that used present in the function. That's not needed, and creates unwanted overhead.
In your initial conditions you should use y and y3, since that are the ones you use in the loop. Also in the first condition you've made a typo.
In the loop you forget to call the function f, and to update the y vector.
Making these changes in your code results in the following:
h = 0.1;
x = 0:h:1;
N = length(x);
y = zeros(N,1);
y3 = zeros(N,1);
g = #(y2) y2;
f = #(y1, y2) 2*y1-y2;
y(1) = 1;
y3(1) = -2;
for i = 1:(N-1)
k_1 = f(y(i), y3(i));
k_11 = g(y3(i));
k_2 = f(y(i)+0.5*h*k_1, y3(i) +0.5*h*k_11);
k_22 = g((y3(i)+0.5*h*k_11));
k_3 = f(y(i)+0.5*h*k_2, y3(i) +0.5*h*k_22);
k_33 = g((y3(i)+0.5*h*k_22));
k_4 = f(y(i)+h*k_3, y3(i) +h*k_33);
k_44 = g((y3(i)+h*k_33));
y3(i+1) = y3(i) + (1/6)*(k_1+2*k_2+2*k_3+k_4)*h ;
y(i+1) = y(i) + (1/6)*(k_11+2*k_22+2*k_33+k_44)*h ;
end
Answer_Matrix = [x' y];
% solution of DE is exp(-2x) and is plotted as reference
plot(x,y,x,exp(-2*x))
As mentioned before, you can also solve this without the use of functions:
h = .1;
x = 0:h:1;
N = length(x);
% allocate memory
y = zeros(N,1);
z = zeros(N,1);
% starting values
y(1) = 1;
z(1) = -2;
for i=1:N-1
ky1 = z(i);
kz1 = -z(i) + 2*y(i);
ky2 = z(i) + h/2*kz1;
kz2 = -z(i) - h/2*kz1 + 2*y(i) + 2*h/2*ky1;
ky3 = z(i) + h/2*kz2;
kz3 = -z(i) - h/2*kz2 + 2*y(i) + 2*h/2*ky2;
ky4 = z(i) + h*kz3;
kz4 = -z(i) - h*kz3 + 2*y(i) + 2*h*ky3;
y(i+1) = y(i) + h/6*(ky1 + 2*ky2 + 2*ky3 + ky4);
z(i+1) = z(i) + h/6*(kz1 + 2*kz2 + 2*kz3 + kz4);
end
% exp(-2*x) is solution of DE and is plotted as reference
plot(x,y,x,exp(-2*x))

matlab: not enough input arguments error

I am new to Matlab and trying to find a solution to the error of my code:
Not enough input arguments.
Error in F9>f (line 42)
y = (2 - 2*t*x) / (x^2 + 1) ;
Error in F9 (line 18)
e = euler(f, trange(1), y0_value, h, trange(end));
function [] = F9()
% Euler's Method to solve given functions
% Set initial values
hi = [1/2, 1/4];
trange = [0, 2];
y0_value = 1;
% Set functions' and exact functions' handles
% Calculate and show results
% Loop for functions
for i = 1:2
fprintf('###########\n');
fprintf('Function #%d\n', i)
fprintf('###########\n');
exact_value = f_exact(trange(end));
% Loop for h
for h = hi
% Euler calculations
e = euler(f, trange(1), y0_value, h, trange(end));
fprintf('\nh: %f\n', h);
fprintf('\nEuler: %f \n', e(end));
fprintf('Error: %f\n\n', abs((e(end)-exact_value)/exact_value));
end
fprintf('Exact: %f\n\n', exact_value);
end
end
% Euler's Method
function y = euler(f, t0, y0, h, tn)
n = (tn-t0)/h;
% Initialize t, y
[t, y] = deal(zeros(n, 1));
% Set t0, y0
t(1) = t0;
y(1) = y0;
for i = 1:n
t(i+1) = t(i) + h;
y(i+1) = y(i) + h/2 * (f(t(i), y(i))+ f(t(i+1) , y(i) + h * f(t(i), y(i))));
end
end
% Functions to solve
function y = f(t, x)
y = (2 - 2*t*x) / (x^2 + 1) ;
end
function y = f_exact(x)
y = (2*x + 1) / (x^2 + 1);
end
When you pass f to euler you need to pass it as a handle, i.e. precede it with a #:
e = euler(#f, trange(1), y0_value, h, trange(end));

Solving System of Second Order Ordinary Differential Equation in Matlab

Introduction
I am using Matlab to simulate some dynamic systems through numerically solving systems of Second Order Ordinary Differential Equations using ODE45. I found a great tutorial from Mathworks (link for tutorial at end) on how to do this.
In the tutorial the system of equations is explicit in x and y as shown below:
x''=-D(y) * x' * sqrt(x'^2 + y'^2)
y''=-D(y) * y' * sqrt(x'^2 + y'^2) + g(y)
Both equations above have form y'' = f(x, x', y, y')
Question
However, I am coming across systems of equations where the variables can not be solved for explicitly as shown in the example. For example one of the systems has the following set of 3 second order ordinary differential equations:
y double prime equation
y'' - .5*L*(x''*sin(x) + x'^2*cos(x) + (k/m)*y - g = 0
x double prime equation
.33*L^2*x'' - .5*L*y''sin(x) - .33*L^2*C*cos(x) + .5*g*L*sin(x) = 0
A single prime is first derivative
A double prime is second derivative
L, g, m, k, and C are given parameters.
How can Matlab be used to numerically solve a set of second order ordinary differential equations where second order can not be explicitly solved for?
Thanks!
Your second system has the form
a11*x'' + a12*y'' = f1(x,y,x',y')
a21*x'' + a22*y'' = f2(x,y,x',y')
which you can solve as a linear system
[x'', y''] = A\f
or in this case explicitly using Cramer's rule
x'' = ( a22*f1 - a12*f2 ) / (a11*a22 - a12*a21)
y'' accordingly.
I would strongly recommend leaving the intermediate variables in the code to reduce chances for typing errors and avoid multiple computation of the same expressions.
Code could look like this (untested)
function dz = odefunc(t,z)
x=z(1); dx=z(2); y=z(3); dy=z(4);
A = [ [-.5*L*sin(x), 1] ; [.33*L^2, -0.5*L*sin(x)] ]
b = [ [dx^2*cos(x) + (k/m)*y-g]; [-.33*L^2*C*cos(x) + .5*g*L*sin(x)] ]
d2 = A\b
dz = [ dx, d2(1), dy, d2(2) ]
end
Yes your method is correct!
I post the following code below:
%Rotating Pendulum Sym Main
clc
clear all;
%Define parameters
global M K L g C;
M = 1;
K = 25.6;
L = 1;
C = 1;
g = 9.8;
% define initial values for theta, thetad, del, deld
e_0 = 1;
ed_0 = 0;
theta_0 = 0;
thetad_0 = .5;
initialValues = [e_0, ed_0, theta_0, thetad_0];
% Set a timespan
t_initial = 0;
t_final = 36;
dt = .01;
N = (t_final - t_initial)/dt;
timeSpan = linspace(t_final, t_initial, N);
% Run ode45 to get z (theta, thetad, del, deld)
[t, z] = ode45(#RotSpngHndl, timeSpan, initialValues);
%initialize variables
e = zeros(N,1);
ed = zeros(N,1);
theta = zeros(N,1);
thetad = zeros(N,1);
T = zeros(N,1);
V = zeros(N,1);
x = zeros(N,1);
y = zeros(N,1);
for i = 1:N
e(i) = z(i, 1);
ed(i) = z(i, 2);
theta(i) = z(i, 3);
thetad(i) = z(i, 4);
T(i) = .5*M*(ed(i)^2 + (1/3)*L^2*C*sin(theta(i)) + (1/3)*L^2*thetad(i)^2 - L*ed(i)*thetad(i)*sin(theta(i)));
V(i) = -M*g*(e(i) + .5*L*cos(theta(i)));
E(i) = T(i) + V(i);
end
figure(1)
plot(t, T,'r');
hold on;
plot(t, V,'b');
plot(t,E,'y');
title('Energy');
xlabel('time(sec)');
legend('Kinetic Energy', 'Potential Energy', 'Total Energy');
Here is function handle file for ode45:
function dz = RotSpngHndl(~, z)
% Define Global Parameters
global M K L g C
A = [1, -.5*L*sin(z(3));
-.5*L*sin(z(3)), (1/3)*L^2];
b = [.5*L*z(4)^2*cos(z(3)) - (K/M)*z(1) + g;
(1/3)*L^2*C*cos(z(3)) + .5*g*L*sin(z(3))];
X = A\b;
% return column vector [ed; edd; ed; edd]
dz = [z(2);
X(1);
z(4);
X(2)];

How to iterate over functions?

I would like to apply loop over a function. I have the following "mother" code:
v = 1;
fun = #root;
x0 = [0,0]
options = optimset('MaxFunEvals',100000,'MaxIter', 10000 );
x = fsolve(fun,x0, options)
In addition, I have the following function in a separate file:
function D = root(x)
v = 1;
D(1) = x(1) + x(2) + v - 2;
D(2) = x(1) - x(2) + v - 1.8;
end
Now, I would like to find roots when v = sort(rand(1,1000)). In other words, I would like to iterate over function for each values of v.
You will need to modify root to accept an additional variable (v) and then change the function handle to root to an anonymous function which feeds in the v that you want
function D = root(x, v)
D(1) = x(1) + x(2) + v - 2;
D(2) = x(1) - x(2) + v - 1.8;
end
% Creates a function handle to root using a specific value of v
fun = #(x)root(x, v(k))
Just in case that equation is your actual equation (and not a dummy example): that equation is linear, meaning, you can solve it for all v with a simple mldivide:
v = sort(rand(1,1000));
x = [1 1; 1 -1] \ bsxfun(#plus, -v, [2; 1.8])
And, in case those are not your actual equations, you don't need to loop, you can vectorize the whole thing:
function x = solver()
options = optimset('Display' , 'off',...
'MaxFunEvals', 1e5,...
'MaxIter' , 1e4);
v = sort(rand(1, 1000));
x0 = repmat([0 0], numel(v), 1);
x = fsolve(#(x)root(x,v'), x0, options);
end
function D = root(x,v)
D = [x(:,1) + x(:,2) + v - 2
x(:,1) - x(:,2) + v - 1.8];
end
This may or may not be faster than looping, it depends on your actual equations.
It may be slower because fsolve will need to compute a Jacobian of 2000×2000 (4M elements), instead of 2×2, 1000 times (4k elements).
But, it may be faster because the startup cost of fsolve can be large, meaning, the overhead of many calls may in fact outweigh the cost of computing the larger Jacobian.
In any case, providing the Jacobian as a second output will speed everything up rather enormously:
function solver()
options = optimset('Display' , 'off',...
'MaxFunEvals', 1e5,...
'MaxIter' , 1e4,...
'Jacobian' , 'on');
v = sort(rand(1, 1000));
x0 = repmat([1 1], numel(v), 1);
x = fsolve(#(x)root(x,v'), x0, options);
end
function [D, J] = root(x,v)
% Jacobian is constant:
persistent J_out
if isempty(J_out)
one = speye(numel(v));
J_out = [+one +one
+one -one];
end
% Function values at x
D = [x(:,1) + x(:,2) + v - 2
x(:,1) - x(:,2) + v - 1.8];
% Jacobian at x:
J = J_out;
end
vvec = sort(rand(1,2));
x0 = [0,0];
for v = vvec,
fun = #(x) root(v, x);
options = optimset('MaxFunEvals',100000,'MaxIter', 10000 );
x = fsolve(fun, x0, options);
end
with function definition:
function D = root(v, x)
D(1) = x(1) + x(2) + v - 2;
D(2) = x(1) - x(2) + v - 1.8;
end

Forward Euler to solve a system of first order ODEs in Matlab

I have two first order ODEs that I got from a second order ODE:
y(0)=1
y'(0)=-1/3
u1'=u2
u2=u/9-(pi*u1*e^(x/3)*(2u2*sin(pi*x)+pi*u1cos(pi*x))
u1(0)=y(0)=1
u2(0)=y'(0)=-1/3
My question is how to set up forward Euler? I have that:
n=[0:0.01:2];
h=2./n;
Our equations are:
u1' = u2
u2' = u1/9 - \pi u1 exp(x/3)(2u2 sin(\pi x) + \pi u1 cos(\pi x))
Now the Euler Method for solving an y' = f(x,y) is:
y_{n+1} = y_{n} + h * f(x_n, y_n)
As MATLAB code, we could write this as:
h = 0.01; % Choose a step size
x = [0:h:2]; % Set up x
u = zeros(length(x),2);
u(1,:) = [1; -1/3]; % Initial Conditions for y
for ii = 2:length(x)
u(ii,:) = u(ii-1,:) + h * CalculateDeriv(x(ii-1),u(ii-1,:)); % Update u at each step
end
function deriv = CalculateDerivative(x,u)
deriv = zeros(2,1);
deriv(1) = u(2);
deriv(2) = u(1)/9 - pi*u(1)*exp(x/9)*(2*u(2)*sin(pi*x) + pi*u(1)*cos(pi*x))
end