Mercurial > octave
changeset 23079:17dc6c7ef427
Ignore ODE event function at t==0 for Matlab compatibility (bug #49919).
* integrate_adaptive.m: new variable have_EventFcn to make code more readable.
* ode_event_handler.m: New persistent variable firstrun. Set to true when
called with 'init'. Toggled back to false after one normal invocation.
Ignore terminating the ODE integration if it occurs on the first time step.
author | Rik <rik@octave.org> |
---|---|
date | Sat, 21 Jan 2017 16:19:38 -0800 |
parents | 6f4569690de1 |
children | c56d30ea6cd4 |
files | scripts/ode/private/integrate_adaptive.m scripts/ode/private/ode_event_handler.m |
diffstat | 2 files changed, 16 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/ode/private/integrate_adaptive.m Sat Jan 21 16:02:38 2017 -0800 +++ b/scripts/ode/private/integrate_adaptive.m Sat Jan 21 16:19:38 2017 -0800 @@ -101,7 +101,9 @@ endif ## Initialize the EventFcn + have_EventFcn = false; if (! isempty (options.Events)) + have_EventFcn = true; ode_event_handler (options.Events, tspan(1), x, "init", options.funarguments{:}); endif @@ -162,7 +164,7 @@ ## Call Events function only if a valid result has been found. ## Stop integration if eventbreak is true. - if (! isempty (options.Events)) + if (have_EventFcn) break_loop = false; for idenseout = 1:numel (t_caught) id = t_caught(idenseout); @@ -224,7 +226,7 @@ ## Call Events function only if a valid result has been found. ## Stop integration if eventbreak is true. - if (! isempty (options.Events)) + if (have_EventFcn) solution.event = ... ode_event_handler (options.Events, t(istep), x(:, istep), [], options.funarguments{:});
--- a/scripts/ode/private/ode_event_handler.m Sat Jan 21 16:02:38 2017 -0800 +++ b/scripts/ode/private/ode_event_handler.m Sat Jan 21 16:19:38 2017 -0800 @@ -72,6 +72,7 @@ ## evtcnt the counter for how often this function has been called persistent evtold told yold retcell; persistent evtcnt = 1; # Don't remove. Required for Octave parser. + persistent firstrun = true; if (isempty (flag)) ## Process the event, i.e., @@ -109,7 +110,12 @@ ## Create new output values if a valid index has been found if (! isempty (idx)) ## Change the persistent result cell array - retcell{1} = any (term(idx)); # Stop integration or not + if (firstrun) + ## Matlab compatibility requires ignoring condition on first run. + retcell{1} = false; + else + retcell{1} = any (term(idx)); # Stop integration or not + endif retcell{2}(evtcnt,1) = idx(1,1); # Take first event found ## Calculate the time stamp when the event function returned 0 and ## calculate new values for the integration results, we do both by @@ -122,6 +128,8 @@ endif endif + + firstrun = false; evtold = evt; told = t; yold = y; retval = retcell; @@ -130,6 +138,8 @@ ## initialize the internal variables of the event function and to get ## a value for evtold. + firstrun = true; + if (! iscell (y)) inpargs = {evtfun, t, y}; else @@ -148,6 +158,7 @@ elseif (strcmp (flag, "done")) ## Clear this event handling function + firstrun = true; evtold = told = yold = evtcnt = []; retval = retcell = cell (1,4);