Solving a system of differential equations with a variable stored in an array

5 ビュー (過去 30 日間)
Mahima
Mahima 2024 年 3 月 19 日
編集済み: Sam Chak 2024 年 3 月 20 日
I have these 3 equations:
dS/dt = -β * S * I/N,
dI/dt = β * S * I/N - γ * I,
dR/dt = γ * I,
In my case, the beta is varying and I have an array of the values that beta is supposed to take
beta_values = [0.50, 0.49, 0.45, 0.33, 0.27, 0.32, 0.37, 0.47, 0.46, 0.50, 0.50, 0.50]
Now, I want to run the code for 360 days and I want the beta to change values every 30 days, hence 30*12 = 360.
So far, I've written this :
syms t x
b = [0.49*ones(1,30), 0.39*ones(1,30), 0.48*ones(1,30), 0.48*ones(1,30), 0.43*ones(1,30), 0.28*ones(1,30), 0.37*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30)];
k = 1/5
for j=1:360
g = @(t,x)[-b(j)*x(1)*x(2);b(j)*x(1)*x(2)-k*x(2);k*x(2)]
[t,xa] = ode45(@(t,x) g(t,x),[0 360],[0.99999 0.00001 0]);
end
figure
for i=1:3
plot(t,xa(:,i))
hold on;
title(['y(t) for a=',num2str(i)'])
end
This is giving me a plot, but that has just 1 peak and is not quite what I was looking for.
And this is what I want:
I'm new to MATLAB therefore not even sure where I went wrong.
Looking for help. Thanks.

回答 (3 件)

Star Strider
Star Strider 2024 年 3 月 19 日
The β value does not cause the curves to vary much. There may be other problems with your initial conditions for the outbreaks or the way you set this up.
This varies β a bit more efficiently, and shows the results —
% syms t x
% b = [0.49*ones(1,30), 0.39*ones(1,30), 0.48*ones(1,30), 0.48*ones(1,30), 0.43*ones(1,30), 0.28*ones(1,30), 0.37*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30)];
beta = [0.50, 0.49, 0.45, 0.33, 0.27, 0.32, 0.37, 0.47, 0.46, 0.50, 0.50, 0.50];
k = 1/5;
g = @(t,x,b)[-b*x(1)*x(2);b*x(1)*x(2)-k*x(2);k*x(2)];
tspan = linspace(1, 30, 30);
ic = [0.99999 0.00001 0];
for j=1:12
[t{j},xa{j}] = ode45(@(t,x) g(t,x,beta(j)),[tspan+30*(j-1)], ic);
ic = xa{j}(end,:);
end
figure
for i=1:numel(t)
hp{i} = plot(t{i},xa{i}, 'DisplayName',sprintf('\\beta = %.2f',beta(i)));
hp1{i} = hp{i}(1);
hold on
end
hold off
grid
axis('padded')
xlabel('Time')
ylabel('Number of Cases')
legend([hp1{:}], 'Location','best')
% title(['y(t) for a=',num2str(i)'])
.
  5 件のコメント
Mahima
Mahima 2024 年 3 月 20 日
@Star Strider what I mean is, let's take last 30 days for an example. I want the beta value to be same for all the 3 plots for those last 30 days. And I believe in your plot, same color means same value (sometimes it doesn't) but in your plot say in the last time step (last 30 days) the color is not same. Do those 3 plots have different values of beta for the same time step?
Star Strider
Star Strider 2024 年 3 月 20 日
The colours in the curves have nothing to do with the β value, they relate to the order in which the curves are drawn. The β in a specific time (month) is the same for all the curves in that month.
% syms t x
% b = [0.49*ones(1,30), 0.39*ones(1,30), 0.48*ones(1,30), 0.48*ones(1,30), 0.43*ones(1,30), 0.28*ones(1,30), 0.37*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30), 0.50*ones(1,30)];
cm = colormap(turbo(12));
beta = [0.50, 0.49, 0.45, 0.33, 0.27, 0.32, 0.37, 0.47, 0.46, 0.50, 0.50, 0.50];
k = 1/5;
g = @(t,x,b)[-b*x(1)*x(2);b*x(1)*x(2)-k*x(2);k*x(2)];
tspan = linspace(1, 30, 30);
ic = [0.99999 0.00001 0];
for j=1:12
[t{j},xa{j}] = ode45(@(t,x) g(t,x,beta(j)),[tspan+30*(j-1)], ic);
ic = xa{j}(end,:);
end
figure
for i=1:numel(t)
hp{i} = plot(t{i},xa{i}, 'DisplayName',sprintf('\\beta = %.2f',beta(i)));
hp1{i} = hp{i}(1);
hold on
end
hold off
% grid
xline(0:30:360, ':k', 'LineWidth',1.3)
axis('padded')
xlabel('Time')
ylabel('Number of Cases')
legend([hp1{:}], 'Location','best')
% title(['y(t) for a=',num2str(i)'])
.

サインインしてコメントする。


Torsten
Torsten 2024 年 3 月 19 日
This is what you get with your equations and your data for beta:
T = 0:30:360;
b = [0.50, 0.49, 0.45, 0.33, 0.27, 0.32, 0.37, 0.47, 0.46, 0.50, 0.50, 0.50];
b = [b(1) (b(1:end-1)+b(2:end))/2 b(end)];
k = 1/5;
B = @(t)interp1(T,b,t);
g = @(t,x)[-B(t)*x(1)*x(2);B(t)*x(1)*x(2)-k*x(2);k*x(2)];
[t,xa] = ode45(@(t,x) g(t,x),[0 360],[0.99999 0.00001 0]);
plot(t,xa)
  5 件のコメント
Torsten
Torsten 2024 年 3 月 20 日
I wonder what N is in your equations.
Sam Chak
Sam Chak 2024 年 3 月 20 日
Ha... I also overlooked this. 😅

サインインしてコメントする。


Sam Chak
Sam Chak 2024 年 3 月 19 日
編集済み: Sam Chak 2024 年 3 月 20 日
In addition to the standard integration methods suggested by @Star Strider and @Torsten, you can solve the SIR model by mathematically describing the piecewise beta function. It's akin to stepping stones reminiscent of the Giant's Causeway in Ireland. You can use a formula that I fondly refer to as the "Piecewise Function Put Together (PFPT)".
Edit: The code is updated to include N, as shown in the SIR model.
%% Call ode45
T = 0:30:360;
t = linspace(0, 360, 36001);
[t, xa] = ode45(@sirODE, t, [0.99999 0.00001 0]);
B = zeros(1, numel(t));
for j = 1:numel(t)
[~, B(j)] = sirODE(t(j), xa(j,:).');
end
%% Plot results
subplot(211)
plot(t, B, 'linewidth', 1.5, 'Color', '#265EF5'), grid on, axis([0, 360, 0, 0.6])
xticks(T), ylabel \beta, title('\beta')
subplot(212)
plot(t, xa), grid on, xlim([0, 360])
xticks(T), xlabel Days, title('SIR'), legend('S', 'I', 'R', 'location', 'east')
%% SIR Model with the piecewise beta function
function [dx, B] = sirODE(t, x)
S = x(1);
I = x(2);
R = x(3);
N = x(1) + x(2) + x(3);
b = [0.50, 0.49, 0.45, 0.33, 0.27, 0.32, 0.37, 0.47, 0.46, 0.50, 0.50, 0.50];
k = 1/5;
T = 0:30:360;
M = zeros(numel(b), numel(t));
for i = 1:numel(b)
M(i,:) = heaviside(t - T(i));
end
% Construction of the beta function using PFPT formula
B = b(1)*M(1,:) - (b(1) - b(2))*M(2,:) - (b(2) - b(3))*M(3,:) - (b(3) - b(4))*M(4,:) - (b(4) - b(5))*M(5,:) - (b(5) - b(6))*M(6,:) - (b(6) - b(7))*M(7,:) - (b(7) - b(8))*M(8,:) - (b(8) - b(9))*M(9,:) - (b(9) - b(10))*M(10,:) - (b(10) - b(11))*M(11,:) - (b(11) - b(12))*M(12,:);
% ODEs of SIR model
dx = [-B*S*I/N;
B*S*I/N - k*I;
k*I];
end

製品


リリース

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by