I am trying to incorporate multiple IF statements in my ODE to generate a single output.
조회 수: 5 (최근 30일)
이전 댓글 표시
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
Walter Roberson
2025년 5월 10일
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
채택된 답변
Sam Chak
2025년 5월 10일
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
추가 답변 (1개)
Walter Roberson
2025년 5월 9일
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
참고 항목
카테고리
Help Center 및 File Exchange에서 Particle & Nuclear Physics에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


