Does anyone know how to use an IF statement with ODE's? I am trying to create an IF statement sigma > 0 , tau > 0 if dx(3,1) > 0, dx(1,1) > 0 and sigma = 0 , tau = 0 otherwise
Show older comments
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 x2 (y-axis) vs. x1 (x-axis)
subplot(3,1,1);
plot(t,x(:,1));
xlabel('Time')
ylabel('Output');
subplot(3,1,2);
plot(t,x(:,2));
xlabel('Time')
ylabel('Policy Rate');
subplot(3,1,3);
plot(t,x(:,3));
xlabel('Time')
ylabel('Wage Share');
y0 = [0.07; 0.07; 0.8];
%% System of three linear 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.3;
delta = 0.3;
mu = 0.4;
lambda = 1.0;
theta = 0.4;
omega = 0.4;
sigma = 0.1;
tau = 0.1;
% linear ODEs
dx(1,1) = alpha * y - beta * r * y;
dx(2,1) = - omega * r + gamma * w + sigma * w + delta * y + tau * y;
dx(3,1) = - theta * w + lambda * y * w - mu * w * w;
end
Accepted Answer
More Answers (3)
Torsten
on 18 Apr 2025
You mean
% linear 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
dx(2,1) = - omega * r + gamma * w + sigma * w + delta * y + tau * y;
else
dx(2,1) = - omega * r + gamma * w + delta * y;
end
?
7 Comments
Christopher
on 18 Apr 2025
Torsten
on 18 Apr 2025
I don't know if it makes physical sense.
I just technically did what you wanted: I set sigma and tau to 0 if at least one of ydot or wdot is <= 0.
Christopher
on 18 Apr 2025
Edited: Christopher
on 18 Apr 2025
Christopher
on 18 Apr 2025
Edited: Christopher
on 18 Apr 2025
Works for me. I also included the changes to be made for @William Rose interpretation of your question.
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 x2 (y-axis) vs. x1 (x-axis)
subplot(3,1,1);
plot(t,x(:,1));
xlabel('Time')
ylabel('Output');
subplot(3,1,2);
plot(t,x(:,2));
xlabel('Time')
ylabel('Policy Rate');
subplot(3,1,3);
plot(t,x(:,3));
xlabel('Time')
ylabel('Wage Share');
y0 = [0.07; 0.07; 0.8];
%% System of three linear 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.3;
delta = 0.3;
mu = 0.4;
lambda = 1.0;
theta = 0.4;
omega = 0.4;
sigma = 0.1;
tau = 0.1;
% linear ODEs
dx(1,1) = alpha * y - beta * r * y;
dx(3,1) = - theta * w + lambda * y * w - mu * w * w;
% My interpretation of your question
if dx(1,1) > 0 && dx(3,1) > 0
dx(2,1) = - omega * r + gamma * w + sigma * w + delta * y + tau * y;
else
dx(2,1) = - omega * r + gamma * w + delta * y;
end
% William Rose's interpretation of your question
%if dx(1,1) <= 0
% tau = 0;
%end
%if dx(3,1) <= 0
% sigma = 0;
%end
%dx(2,1) = - omega * r + gamma * w + sigma * w + delta * y + tau * y;
end
Frankly speaking, is the system still considered as a linear system given that dx(3) has a quadratic term?
Additionally, due to the relatively small magnitudes of sigma and tau, the change from (gamma + sigma)*w to gamma*w, and the change from (delta + tau)*y to delta*y seem to have insignificant effects on the responses.
William Rose
on 19 Apr 2025
Walter Roberson
on 18 Apr 2025
1 vote
Do not use an if statement inside an ODE...
Not unless
- the if statement will always follow the same branch for any one invocation of the ode function; OR
- the second derivative of the branches is continuous
sigma > 0 , tau > 0 if dx(3,1) > 0, dx(1,1) > 0 and sigma = 0 , tau = 0
That does not have a continuous second derivative; it probably does not have a continuous first derivative either.
In your particular case, it might make sense to impose 'NonNegative' https://www.mathworks.com/help/matlab/math/nonnegative-ode-solution.html -- but that depends on whether your conditions are "or" or "and"
What you should be doing is using an ODE event function to determine when the conditions are met, with the "isterminal" set to true, so that you leave the ode*() call when the conditions are true. Then modify boundary conditions as necessary and call the ode*() function again to pick up at the time you left off.
William Rose
on 18 Apr 2025
Edited: William Rose
on 18 Apr 2025
[edit: fix spelling error; no changes to code]
[Edit: Change "./" to "/" inside function odefcn(), since "./" is not needed. Should work either way.]
You say "I am trying to create an IF statement sigma > 0 , tau > 0 if dx(3,1) > 0, dx(1,1) > 0 and sigma = 0 , tau = 0 otherwise"
In the current version of your code, sigma=0.1 and tau=0.1. I assume you want sigma=0.1 when dx(3)>0, otherwise sigma=0. And I assume you want tau=0.1 when dx(1)>0, tau=0 otherwise. If that is not true, then please be more specific in your question.
I have dealt with this same issue when modeling the cardiovascular system: there are one-way valves in the system which allow forward flow, but not backflow. I learned that ode45() and other solvers do not like "if" statements.
Make sigma be a smooth (i.e. sigmoidal) function of dx(3).

where ws is the transition width for sigma*. Do the same for tau.
Here's a plot of sigma(dx(3)) when ws=0.01. I will also compute and plot sigma shifted to the right by 2*ws, in case you want the transition to happen on the positive side of zero:
ws=0.01; dx3=-1:.005:1;
sigma=0.1./(1+exp(-dx3/ws));
sigma2=0.1./(1+exp(-(dx3-2*ws)/ws));
plot(dx3,sigma,'-b.',dx3,sigma2,'--b'); grid on; xlabel('dx_3'); ylabel('\sigma')
legend('sigma','sigma2')
Inside odefcn():
- Comment out the lines that assign constant values to sigma and tau.
- Compute dx(1) and dx(3) (they don't depent on sigma or tau), but do not compute dx(2).
- Compute sigma and tau using sigmoid functions of dx(3) and dx(1) respectively.
- Compute dx(2) (depends on sigma and tau).
It will be easier for others to assist you if you format your code as code (highlight code section, then click the "code" icon at top of window).
%% System of three linear differential equations
function dx = odefcn(t, x)
% definitions
y = x(1); % output
r = x(2); % policy rate
w = x(3); % wage share
% parameters
alpha = 1.0;
beta = 1.0;
gamma = 0.3;
delta = 0.3;
mu = 0.4;
lambda = 1.0;
theta = 0.4;
omega = 0.4;
% sigma = 0.1;
% tau = 0.1;
ws = 0.01; % transition width for sigma (units: same as sigma)
wt = 0.01; % transition width for tau (units: same as tau)
% linear ODEs
dx=zeros(3,1); % allocate column vector
dx(1) = alpha * y - beta * r * y;
dx(3) = - theta * w + lambda * y * w - mu * w * w;
sigma = 0.1/(1+exp(-dx(3)/ws));
tau = 0.1/(1+exp(-dx(1)/wt));
dx(2) = - omega * r + gamma * w + sigma * w + delta * y + tau * y;
end
* Transition width, ws: In width 2*ws, sigma goes from 1/(1+e)=27% to e/(1+e)=73% of its final value. If you cannot tolerate any significant positive values of sigma when dx(3) is <=0, then you can make ws smaller or you can slide the function to the right a bit - see plot above.
1 Comment
William Rose
on 18 Apr 2025
Edited: William Rose
on 18 Apr 2025
You indicate in your comment to @Torsten that you want sigma and tau to depend on the "and" of dx(1) and dx(3). If you are still having trouble with if statements, then you can do something like
dx1=-1:.005:1; dx3=dx1; % this line would not be in your code - just to demonstrate
w=0.01;
sigma=0.1./((1+exp(-dx1'/w))*(1+exp(-dx3/w)));
surf(dx1,dx3,sigma,'EdgeColor','none')
xlabel('dx1'); ylabel('dx3'); zlabel('\sigma')
The plot shows that sigma=1 when dx1 and dx3 are both >0, and sigma=0 otherwise. Do likewise for tau. You can plug that idea into your odefcn().
Categories
Find more on Sensitivity Analysis 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!













