In this tutorial, we explain how to generate phase portraits and state-space trajectories of dynamical systems in MATLAB. The YouTube video accompanying this post is given below. The GitHub page with all the codes is given here. Besides this tutorial, we created a tutorial on how to generate phase plots of dynamical systems in Python. The Python tutorial is given here.
For example, consider the following dynamical system:
(1)
In this tutorial, you will learn how to generate a phase portrait of this system. The phase portrait is shown in the figure below.
Also, you will learn how to plot a particular state-space trajectory obtaining by simulating (1) from a given initial condition. A simulated state trajectory (blue line) is shown in Figure 2 below.
The basic idea for drawing the phase portraits is illustrated in Fig. 3. and Fig. 4.
Consider the general form of a state-space model of a dynamical system:
(2)
The vector
In the sequel, we explain how to generate phase portraits and state-space trajectories in MATLAB. The first step is to define a MATLAB function that describes the dynamics of the system (1). This function is given below.
% define the nonlinear, continious-time, state-space model
% t is time
% x is the vector of state coordinates
% Author: Aleksandar Haber
% Date: December 2022
function dx = dynamics(t,x)
%dx=[x(2); -sin(x(1));];
%dx=[-2*x(1);-3*x(2)];
dx=[-1*x(1)-3*x(2);3*x(1)-1*x(2)];
end
This function should be saved as “dynamics.m” since it will be called from other functions. The function takes time and state vector
Next, we define the function that actually plots the phase portrait. This function is given below.
% Function that sketches a phase portrait of a dynamical system
% Author: Aleksandar Haber, December 2022
% f is a function that defines the nonlinear state-space model
% this function should be defined in an external file
% vectors x1 and x2 define the coordinates of points
% in a rectangular region that is defined by the meshgrid function
function phase_portrait(f,x1,x2)
[x,y] = meshgrid(x1,x2);
u = zeros(size(x));
v = zeros(size(x));
% we can use a single loop over each element to compute the derivatives at each point
t=0;
% we want the derivatives at each point at t=0, i.e. the starting time
[d1,d2]=size(x);
for i = 1:d1
for j=1:d2
Yprime = f(t,[x(i,j); y(i,j)]);
u(i,j) = Yprime(1);
v(i,j) = Yprime(2);
end
end
% for i = 1:d1
% for j=1:d2
% Vmod = sqrt(u(i,j)^2 + v(i,j)^2);
% u(i,j) = u(i,j)/Vmod;
% v(i,j) = v(i,j)/Vmod;
% end
% end
figure(1)
hold on
% quiver(X,Y,U,V) plots velocity vectors as arrows with components (u,v) at the points (x,y)
quiver(x,y,u,v,'r');
xlabel('x_{1}')
ylabel('x_{2}')
axis tight equal;
box
end
This function should be saved as “phase_portrait.m”. The first argument of this function is a MATLAB function handle that defines the system dynamics. In our case the dynamics is defined in the file “dynamics.m”. Consequently, a handle to this function will be passed as the first argument to “phase_portrait.m”. The second and third arguments are vectors that represent the
[x,y] = meshgrid(x1,x2);
u = zeros(size(x));
v = zeros(size(x));
are used to generate the meshgrid matrices x and y. Also, these code lines are used to define empty matrices u and v. These matrices are used to store
for i = 1:d1
for j=1:d2
Yprime = f(t,[x(i,j); y(i,j)]);
u(i,j) = Yprime(1);
v(i,j) = Yprime(2);
end
end
Basically, we compute the right-hand side of (1) for meshgrid points defined by the matrices x and y. This is done by calling the function f, which in our case is a function handle. We actually call the previously defined function
The plotting function “phase_portrait” is called from our main code which is given below.
% Phase portraits of dynamical systems
% Author: Aleksandar Haber,
% Date: December 2022
clear
% time steps for control
% First draw the phase portrait of the system
x1=linspace(-2,2,20);
x2=linspace(-2,2,20);
phase_portrait(@dynamics,x1,x2)
% discretization steps
T=0.01;
% check the discrete-time model vs. continious time model
time=[0:T:20];
initialState=[2;0.5];
% generate continious-time response
[ts,ys] = ode45(@dynamics,time,initialState);
hold on;
plot(ys(:,1),ys(:,2),'b','LineWidth',3)
plot(ys(1,1),ys(1,2),'bo') % starting point
plot(ys(end,1),ys(end,2),'ks') % ending point
First, we define two vectors
These code lines generate figures 1 and 2 given at the beginning of this post.