How to pass step forcing function in system model to ode15s
Mostrar comentarios más antiguos
I am using ode15s to solve a system that has quasi-step forcing inputs that are defined by data. I have used griddedinterpolant with a variety of methods but all result in a smoothed forcing that is not realistic for the problem. The data are available in time steps of 10 minutes, and I know that at minute 30, the infusions change abruptly. How can I represent the forcings to ode15s to account for the fact that it has a variable time step and needs to compute the intermediate data?
Respuesta aceptada
Más respuestas (1)
Hi @Andrew
While the ODE solver can change its integration step size on the fly to find sharp corners, by drastically shrinking its step size to
, the gold standard for handling discontinuities in numerical simulation is to stop right at the sharp corner, reset, and restart with a clean slate.
If you know exactly when the discontinuities happen, you can use the stopping-and-restarting method (in just 5 steps) so that the solver integrates smoothly up to the exact time step of the change, stops, and starts fresh without carrying over historical error terms.
Here is the basic code setup:
%% STEP 1: Visually inspect the External input signal
tau = 20; % period of signal
Tf = 40; % duration of signal
Ts = 0.01; % step size of signal
[u, tu] = gensig("square", tau, Tf, Ts);
figure
plot(tu, u), grid on
ylim([-1, 2])
title('External input signal u(t) with discontinuous jumps')
xlabel('Time (minutes)')
ylabel('Amplitude')
%% STEP 2: Identify the jumping segments where the discontinuities happen
T = 0:10:40
%% STEP 3: Test the loop first
figure
hold on
for k = 1:(length(T) - 1)
tspan = [T(k), T(k+1)]
idx = tu >= T(k) & tu <= T(k+1);
plot(tu(idx), u(idx));
end
hold off
grid on
ylim([-1, 2])
title('Plot external input signal u(t) after each jumping segment')
xlabel('Time (minutes)')
ylabel('Amplitude')
%% STEP 4: Describe the ODE with time-dependent parameters
function dx = system45(t, x, tu, u)
% External input forced signal, u(t)
u = interp1(tu, u, t); % Interpolate the data set (tu, u) at time t
% Dynamics of system45
dx = zeros(2, 1);
dx(1) = x(2);
dx(2) = 4*u - 4*x(1) - 4*x(2);
end
%% STEP 5: Loop the ODE calls and plot the result simultaneously
x0 = [1; 0]; % Initial conditions at t=0
figure
hold on
for k = 1:(length(T) - 1)
% identify simulation segment before the next jump
tspan = [T(k), T(k+1)];
idx = tu >= T(k) & tu <= T(k+1);
% run ODE solver (for each tspan segment)
[t, x] = ode45(@(t, x) system45(t, x, tu(idx), u(idx)), tspan, x0);
% plot the 1st component of the solution
plot(t, x(:, 1))
% extract final state to use as the NEW initial condition
x0 = x(end, :);
end
hold off
grid on
ylim([-1, 2])
title('Time history of the 1st component of the solution')
xlabel('Time (minutes)')
ylabel('Amplitude')
1 comentario
Andrew
el 30 de Ag. de 2026 a las 13:22
Categorías
Más información sobre Ordinary Differential Equations en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


