I am trying to incorporate multiple IF statements in my ODE to generate a single output.
5 views (last 30 days)
Show older comments
There are four cases that I am trying to incorporate as multiple IF statements. Here are the four cases below. The first case is the one I used in my code to generate the output.
dx(1,1) > 0 && dx(3,1) > 0
dx(1,1) > 0 || dx(3,1) > 0
dx(1,1) > 0 && dx(3,1) <= 0
dx(1,1) <= 0 && dx(3,1) > 0
Below is the code that I used to generate the first case:
close all
clear all
clc
tspan = [0 100];
y0 = 0.7; % initial value of state variable x1
r0 = 0.7; % initial value of state variable x2
w0 = 0.8; % initial value of state variable x3
x0 = [y0; r0; w0];
[t, x] = ode45(@odefcn, tspan, x0);
%% Plot results
figure
subplot(3,1,1);
plot(t, x(:,1)); grid on
xlabel('Time'), ylabel('Output');
subplot(3,1,2);
plot(t, x(:,2)); grid on
xlabel('Time'), ylabel('Policy Rate');
subplot(3,1,3);
plot(t, x(:,3)); grid on
xlabel('Time'), ylabel('Wage Share');
y0 = [0.7; 0.7; 0.8];
%% System of three differential equations
function dx = odefcn(t, x)
% definitions
y = x(1);
r = x(2);
w = x(3);
% parameters
alpha = 1.0;
beta = 1.0;
gamma = 0.6;
delta = 0.6;
mu = 0.1;
lambda = 0.6;
theta = 0.4;
omega = 0.4;
sigma = 0.1;
tau = 0.1;
% ODEs
dx(1,1) = alpha * y - beta * r * y;
dx(3,1) = - theta * w + lambda * y * w - mu * w * w;
% Asymmetrical Reaction Function
if dx(1,1) > 0 && dx(3,1) > 0
dx(2,1) = - omega * r + gamma * w * r + sigma * w * r + delta * y * r + tau * y * r;
else
dx(2,1) = - omega * r + gamma * w * r + delta * y * r;
end
end
9 Comments
Walter Roberson
on 10 May 2025
All of the branches are the same except for the last one. You could compact the if tree to
if dx(1,1) <= 0 && dx(3,1) <= 0
dx(2,1) = - omega * r + gamma * w * r + delta * y * r;
else
dx(2,1) = - omega * r + gamma * w * r + sigma * w * r + delta * y * r + tau * y * r;
end
Accepted Answer
Sam Chak
on 10 May 2025
Hi @Christopher
Based on your definitions of the four cases in this comment and @Walter Roberson's input, we can run the simulation to observe the effect of the discontinuous term,
, on the 2nd differential equation for the asymmetrical reaction.

tspan = linspace(0, 100, 100001);
y0 = 0.7; % initial value of state variable x1
r0 = 0.7; % initial value of state variable x2
w0 = 0.8; % initial value of state variable x3
x0 = [y0; r0; w0];
[t, x] = ode45(@odefcn, tspan, x0);
%% Plot results
figure
subplot(3,1,1);
plot(t, x(:,1)); grid on
xlabel('Time'), ylabel('Output');
subplot(3,1,2);
plot(t, x(:,2)); grid on
xlabel('Time'), ylabel('Policy Rate');
subplot(3,1,3);
plot(t, x(:,3)); grid on
xlabel('Time'), ylabel('Wage Share');
dx = zeros(numel(t), 3);
term = zeros(numel(t), 1);
for i = 1:numel(t)
[dx(i,:), term(i,:)] = odefcn(t', x(i,:)');
end
%% Observe the effect of discontinuous term
figure
subplot(211)
plot(t, term), grid on, title({'Effect of discontinuous term, $\delta y r + \tau y r$'}, 'interpreter', 'latex', 'fontsize', 12)
ylim([-1, 5])
subplot(212)
plot(t, dx(:,2)), grid on, title('dx_2')
ylim([-2, 4])
%% System of three differential equations
function [dx, term] = odefcn(t, x)
% definitions
y = x(1);
r = x(2);
w = x(3);
% parameters
alpha = 1.0;
beta = 1.0;
gamma = 0.6;
delta = 0.6;
mu = 0.1;
lambda = 0.6;
theta = 0.4;
omega = 0.4;
sigma = 0.1;
tau = 0.1;
% ODEs
dx(1,1) = alpha * y - beta * r * y;
dx(3,1) = - theta * w + lambda * y * w - mu * w * w;
if dx(1,1) <= 0 && dx(3,1) <= 0
term = 0;
else
term = delta * y * r + tau * y * r;
end
% for comparison without if–else
% dx(2,1) = - omega * r + gamma * w * r + sigma * w * r + delta * y * r + tau * y * r;
% Asymmetrical Reaction Function
if dx(1,1) <= 0 && dx(3,1) <= 0
dx(2,1) = - omega * r + gamma * w * r + delta * y * r;
else
% dx(2,1) = - omega * r + gamma * w * r + sigma * w * r + delta * y * r + tau * y * r;
dx(2,1) = - omega * r + gamma * w * r + sigma * w * r + term;
end
end
3 Comments
More Answers (1)
Walter Roberson
on 9 May 2025
The mathematics of ode45 and similar routines is such that the second derivative of the input expressions must be continuous over any one call to the ode*() routine.
If the first derivative is not continuous, then about 1/3 of the time, ode45 detects that and issues an error message.
If the second derivative is not continuous, then typically ode45 does not notice and simply gives the wrong answer.
It is rather uncommon for ode routines that contain if statements to be continuous in the second derivative. The sample code you provided is not continuous in the second derivative.
The right way to handle this situation is to use ode event functions to determine the transition boundaries, marking each transition as "terminal", and to loop over ode45() calls, recording the partial outputs produced, and calling ode45() again to pick up from where the previous call left off.
0 Comments
See Also
Categories
Find more on Particle & Nuclear Physics in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!