ode45 varargin - additional arguments after options

3 Ansichten (letzte 30 Tage)
Nshine
Nshine am 28 Jun. 2019
Kommentiert: Nshine am 30 Jun. 2019
Hi.
I'm looking at some code which calls ode45 using the following code:
[t_intermediate,x_intermediate] = ode45(system,[t0, t0+T], x0, options, u);
wheer the function system is defined as
function y = system(t, x, u, T)
y = x+u;
end
I am confused about the additional last argument 'u' of the call to ode45, and how this feeds into the solver. The documentation doesnt list any arguments after options, but opening the code I can see it accepts additional arguments through varargin, but I cant find any information about how 'u' would fit into this. Within the ode45 code, It looks like the varargin are processed in the function "odearguments", but there is no documentation on this function either.
In this example, 'u' is a control input into the system.
Thanks for the help in advance!
  4 Kommentare
Torsten
Torsten am 28 Jun. 2019
Bearbeitet: Torsten am 28 Jun. 2019
Because this was the 'normal' way in former MATLAB days.
Walter Roberson
Walter Roberson am 28 Jun. 2019
That code would have failed.
ode45(system,....)
would have called system with no arguments and expected it to return a function handle. The call would fail due to not enough inputs.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

John D'Errico
John D'Errico am 28 Jun. 2019
Bearbeitet: John D'Errico am 28 Jun. 2019
Long ago and far away, in an age long since past, MATLAB did not have function handles. There were no anonymous functions. There were no nested functions.
So the writers of MATLAB came up with a way to pass in arguments through functions like ODE45, like FMINSEARCH and FMINCON, etc. This was because all of these functions sometimes need to allow extra arguments to be passed in, essentially through those tools.
The idea was that if your function has "extra" arguments beyond those expected, then they are added as extra arguments to the optimizer or the ODE solver. Then the solver is smart enough to attach them to the function call itself when that call is done internally. It worked, but it was a programming kludge, and a massive one. It was confusing to users. To be honest, global variables were a better solution, and I hate global variables.
So at some point, the powers at MATLAB realized that this was indeed a bad idea. So, for years they warned us users that the option would be "removed" from those tools, but they had by then provided us with function handles, with nested functions. They had provided us with better ways to solve the problem.
At some point, they removed the option from the documentation for those functions, although I think it still worked for some years, so that legacy code would not fail. Without testing some code, a quick scan through the code for fminsearch suggests that it still (in R2019a) allows that legacy form of call for extra arguments, although I saw nothing in the help that said it was legal. I also just scanned the code for ODE45, and it too looks like it is allowed as a hidden option. Without testing, I would not state this to be true though.
You must remember that it is important that legacy code should generally work, if at all possible. I have code that is now over 30 years old, code that still works nicely. Unfortunately, that means sometimes people who never saw this capability will not know it ever existed. And some people like you will be confused when looking at legacy code, perhaps written by a MATLAB neanderthal like me.
  2 Kommentare
Steven Lord
Steven Lord am 28 Jun. 2019
The idea was that if your function has "extra" arguments beyond those expected, then they are added as extra arguments to the optimizer or the ODE solver.
It was even more confusing than that. When you call an ODE solver you must pass in your ODE function but you can also pass in Events functions, OutputFcn functions, etc. via the options structure.
If you used that very old syntax (which we stopped documenting about 15 years ago when we introduced anonymous functions in release R14[*]) all those functions that you specified had to accept all those additional inputs even if only one of your functions used them. Using anonymous functions or one of the other techniques for parameterizing functions avoids that particular issue; you can pass additional parameters into just the functions that require them.
[*] No, I don't mean release R2014a or R2014b. Release R14 predates the Ryear{a,b} release naming convention. I mean the release that came out in June 2004.
Nshine
Nshine am 30 Jun. 2019
Thanks for that clear answer. Its so helpful and fascinating to know some of the history of the development of Matlab.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by