How do I pass out extra parameters using ODE23 or ODE45 from the MATLAB ODE suite?

279 views (last 30 days)
I would like to return some parameters from the ode45 solution that do not need to be integrated, but which are important to the result. I would like to have the function I pass to ODE23/ODE45 return extra parameters which the ODE solver ignores during the computation but stores for later review.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 5 Nov 2010
There is no method for passing out additional parameters from the ODE function using the ODE solvers provided in the MATLAB ODE suite (e.g., ODE45). These additional parameters, however, can be passed out after ODE45 returns a solution.
For example, consider the ODE:
y' = x + k*y
where
k = x^2 + y^2
If you have a need to obtain "k" for specified "x" and "y", you can create the following ODE function:
function [dydx k] = myode(x, y)
k = x.^2 + y.^2;
dydx = x + k.*y;
The solution to the ODE can be solved using the commands:
[X Y] = ode45(@myode, [0 5], 1);
Then, "k" can be obtained via the command:
[dydx k] = myode(X, Y);
If you would like to obtain a series of values that are computed during the solution algorithm, you can declare a variable as PERSISTENT, and append the value computed during each call to the ODE function to the end of this persistent variable.
For example, consider the previous ODE. If you would like to obtain a vector of the "x" and "y" values specified for each call to the ODE function, try the following ODE function:
function [dydx xvt yvt] = myode(x, y)
persistent xv yv
xv = [xv; x];
yv = [yv; y];
k = x.^2 + y.^2;
dydx = x + k.*y;
if nargout>1
xvt = xv; yvt = yv;
end
The solution to the ODE can be solved using the commands:
[X Y] = ode45(@myode, [0 5], 1);
Then, "xv" and "yv" can be obtained via the command:
[dydx xv yv] = myode([], []);
You could also use the ASSIGNIN, EVALIN, or SAVE functions. The ASSIGNIN function allows you to assign variables into workspace, and the EVALIN function evaluates an expression in the workspace. The SAVE function saves workspace variables to disk. The following example demonstrates how to assign the variable 'dy' from the ODEFUN to the workspace. Save the following into a function file named "odefun.m":
function dy =odefun(t,y)
dy=1;
varToPassOut=2;
assignin('base','varInBase',varToPassOut);
evalin('base','varPassedOut(end+1)=varInBase');
After writing this function, execute the following at the MATLAB command prompt:
varPassedOut=0
[T,Y] = ode45(@odefun,[0 12],[0]);
varPassedOut=varPassedOut(2:end);
Note that you need to define the variable "varPassedOut" in the base workspace before calling ODE45, or you will receive an error.
  6 Comments
瑞 李
瑞 李 on 2 Mar 2022
Edited: 瑞 李 on 2 Mar 2022
Hi
When I use the above code, I find that the length of varpassedout is inconsistent with the length of T and Y. this may be due to the variable step size characteristic of ode45 solver. How should I solve this?
thanks
Lirry
function dy =odefun(t,y)
dy=1;
varToPassOut=2;
assignin('base','varInBase',varToPassOut);
evalin('base','varPassedOut(end+1)=varInBase');

Sign in to comment.

More Answers (3)

Vincent DUFOUR
Vincent DUFOUR on 14 Mar 2017
I am sorry, but the solution with the "persistent" doesn't seem to work for me, when I am calling the "myode" directly with the command myode([],[]) it asks me for parameters because of a t and x varying... I have a function with a lot of input arguments but even when I replace all of them by [] it doesn't work anyway...
  2 Comments
mazin alseadi
mazin alseadi on 23 Jun 2020
Did you solved this problem ? I a have the same when I am calling the "myode" directly with the command myode([],[]) it asks me for parameters !!
Please , If you have any suggestion I will be glad to listen for you !
B.R.

Sign in to comment.


Tim Coon
Tim Coon on 14 Mar 2017
This doesn't appear to work because the function called by ode45 executes more times than the length of its output vector (at least in my problem). I believe this is due to the ode45 integration method having to throw away an integration if it does not meet the error tolerance, then going back and recalculating with a different step size. Anyone care to comment on my assumption?
  3 Comments
Walter Roberson
Walter Roberson on 19 Jun 2017
This is normal.
When you specify only two endpoints in tspan, so the timesteps for output are chosen adaptively, then outputs from ode45 are interpolated based upon nearby points, using a Runge-Kutta 4th order adaptive method. The points the function are evaluated at do not exactly match the points of output.
When you specify more than two points in tspan, the approach is very similar but the solver ensures that it specifically interpolates for the times given, and will only output those points, not any other intermediate points. Specifying tspan does not make ode45 into a fixed-step solver with step diff(tspan) !!
Either way there will not be an exact correspondence between points evaluated at and points output. If that is a problem then you probably should not be trying to output intermediate values using persistent or assignin() or nested variables.
If you need the internal variables corresponding to outputs at a particular time point, then you should use a framework such as
function [dydx xvt yvt] = myode(x, y)
[...]
if nargout>1; xvt = xv; yvt = yv; end
with no persistent, and then you should go back and call myode() once for each (t,y) combination that was output from the ode45 call, having it calculate the intermediate values appropriate to that exact combination.

Sign in to comment.


Bicheng Guo
Bicheng Guo on 15 Dec 2018
Why my state variables length is 20000 but, using the assignin/evalin method, the length of the extra prameters caculated by stats is only 475 when the simulation time is 20s and step is 0.001s.

Community Treasure Hunt

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

Start Hunting!