# Stoping a specific matlab function

• MATLAB

## Main Question or Discussion Point

Hi all,

I'm having some issues with Matlab.

I'm running ode45 inside a function which is called repeatedly in a finite loop. As it is being called, Matlab is plotting and saving the data externally.

Here's a quick pseudo-code
Code:
func1 ( )
loop {
data = func2 (variables)
save data
plot data
}
end func1

func2 ( input vars)
--
--
options = odeset('events',@missile_event, 'RelTol',1e-14);
[t, x, te, xe, ie] = ode45 ( @de, [t0 tf], x0, options );
--
--
plot x vs t etc..
--
--
return data;
end
This is all well and good, but as soon as ode45 is unable to solve a DE (were the solution does not converge), Matlab gets stuck in an (almost?) infinite loop repeatedly calling ode45 until a solution is found. I can obviously stop this using "Ctrl-C" but this will screw up the data I'm trying to gather and plot.

Is there a way to get ode45 to return some value if it takes more than x seconds to find a solution? Or perhaps get it to stop executing func2 and resume func1 (see above code).

I am already using the events function to stop ode45 as soon as it has converged close to the solution.

i.e,
Code:
function [lookfor stop direction ] = missile_event(t, x)
r = sqrt(x(1)^2 + x(2)^2) ;
lookfor = r - 0.1;
stop = 1;
direction = 0;

Related MATLAB, Maple, Mathematica, LaTeX News on Phys.org
Pythagorean
Gold Member
Well... what you can do is plot chunks of time series at at a time (i.e. a smaller [to tf], then stop, check the result, put the result back in as the initial condition for a short chunk of time.

Then you can somehow analyze the trajectory of your results to see if its diverging.

Unfortunately (and I've tested this with ode113) an ODE solved by doing the whole [t0 tf] comes out different than if you to partials of [t0 tf], using the result from each 'chunk' as the IC for the next 'chunk'. So that means some kind of window analysis is going on (or something).

I'd like to hear a better solution, personally

Hi Pythagorean,

I found a simple solution that works for me.

Inside func2 and just before line "[t, x, te, xe, ie] = ode45 ( @de, [t0 tf], x0, options );" i record the internal CPU time.

Inside function 'de', i check the new CPU time against what was recorded initially, and if 'x' seconds have passed, the solution is not going to converge or will take too long. If that occurs, I change the parameters of de such that it calls the event function and terminates ODE45 (in other words, ODE "thinks" it found a solution and stops).

Here's an example code:

Code:
func2 ( input vars)
--
--
options = odeset('events',@missile_event, 'RelTol',1e-14);
initial_time = cputime;
[t, x, te, xe, ie] = ode45 ( @de, [t0 tf], x0, options );

if (status == -1)
problem occured etc..
return error value;
end
otherwise
--
plot x vs t etc..
--
return data;
end

function d_x = de(t, x) {        //this is the function ode45 calls
--
--
if (cputime - initial_time > 15 )  then //i.e 15 seconds have passed
d_x(1) = 0
d_x(2) = 0
etc....
status = -1;
end
--
--
}