How can I extract a variable that is calculated inside an ode function and pass it as an input to the event function?

I am using ODE45 with an event function. Inside my ode function, I perform some calculations and compute a variable (at each time step). I want this computed variable to be passed to the event function in order to check when the integration should stop.
I provide a simplified example.
Calling ode:
eventFcn = @(t,xp) myEventFunction(t,xp);
options = odeset('Event',eventFcn);
[t,xp,te,ye,ie] = ode45(@(t,xp) myODE(t,xp),tspan,xp0,options);
My ode function:
function dxp = myODE(t,xp)
..
myVar = t*xp+... % (the variable I calculate)
end
My event function:
function [value,isterminal,direction] = myEventFunction(t,xp)
% I want to have access to myVar here.
end
So, how can I extract a variable that is calculated inside an ode function and pass it as an input to the event function?

 Accepted Answer

The simplest solution is to use nested functions:
Basically you would need to do something like this:
function mainfun()
myVar = []; % must be defined in the parent workspace!
options = odeset('Event',@myEventFunction);
[t,xp,te,ye,ie] = ode45(@(t,xp) myODE(t,xp),tspan,xp0,options);
...
%
function dxp = myODE(t,xp)
...
myVar = t*xp+... % (the variable I calculate)
...
end
%
function [value,isterminal,direction] = myEventFunction(t,xp)
... use myVar ...
end
end

3 Comments

Thank you so much for your response.
It sounds like a very good solution to my problem since the variable I am interested in would be accesible that way. So, even though I do not prefer using nested functions (especially in this case where I have a lot of functions in different files), I tried using them.
But I ran into a problem. I have some symbolic variables (e.g. x(t) ) so I get the error "Attempt to add variable to a static workspace".
I was wondering if there is another way. For example, to make my ode produce two outputs
function [dxp, myVar] = myODE(t,xp)
and then somehow to be able to pass that output to the event function
function [value,isterminal,direction] = myEventFunction(t,xp,myVar)
Is there a way to do it like that?
"Is there a way to do it like that?"
Not really.
You could use global, but I strongly advise against that. The best thing to do would be to use nested functions (note that the nested functions themselves can be simple wrappers that call functions in other files) and fix the cause of that error message:
Most likely you have not consistently used end with each function:
I also wanted to avoid global variables. I guess I will use nested functions as you suggest.
I fixed the error using your solution from the 2nd link like that:
x = [];
t = [];
syms x(t)
So, now everything works as intented.
Thank you very much for your help!

Sign in to comment.

More Answers (0)

Asked:

on 24 May 2019

Commented:

on 27 May 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!