Got Questions? Get Answers.
Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Passing Extra Arguments to ode solvers

Subject: Passing Extra Arguments to ode solvers

From: Richard Crozier

Date: 25 May, 2011 11:43:05

Message: 1 of 11

I'm trying out passing additional arguments to an ode solver through the syntax:

odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)

with evalfcn looking something like:

evalfcn(t, y, arg1, arg2, ...)

I would have expected that the solvers would simply pass in the arguments to the evaluation function as a series of arguments. In fact it seems the function 'odearguments' first tacks on an empty string to the cell array of arguments for no apparent reason so the arguments passed to the evaluation function are

args = {'', arg1, arg2, ...}

So evalfcn must look like:

evalfcn(t, y, mysteriousString, arg1, arg2, ...)

Is there any particular reason for this? I'm guessing it's something to do with simulink maybe? Will this work as I'm expecting it to?

Subject: Passing Extra Arguments to ode solvers

From: Torsten

Date: 25 May, 2011 12:18:42

Message: 2 of 11

On 25 Mai, 13:43, "Richard Crozier" <r.croz...@ed.ac.uk> wrote:
> I'm trying out passing additional arguments to an ode solver through the syntax:
>
> odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)
>
> with evalfcn looking something like:
>
> evalfcn(t, y, arg1, arg2, ...)
>
> I would have expected that the solvers would simply pass in the arguments to the evaluation function as a series of arguments. In fact it seems the function 'odearguments' first tacks on an empty string to the cell array of arguments for no apparent reason so the arguments passed to the evaluation function are
>
> args = {'', arg1, arg2, ...}
>
> So evalfcn must look like:
>
> evalfcn(t, y, mysteriousString, arg1, arg2, ...)
>
> Is there any particular reason for this? I'm guessing it's something to do with simulink maybe? Will this work as I'm expecting it to?

Try

[T,Y]=odeXX(@(t,y)evalfcn(t,y,arg1,arg2,...),tspan,y0,options)

dydt = evalfcn(t,y,arg1,arg2,...)
...

Best wishes
Torsten.

Subject: Passing Extra Arguments to ode solvers

From: Richard Crozier

Date: 25 May, 2011 12:33:02

Message: 3 of 11

Torsten <Torsten.Hennig@umsicht.fraunhofer.de> wrote in message <653d40fb-a4c6-4a70-b31c-3b100dcfaa4d@g16g2000yqj.googlegroups.com>...
> On 25 Mai, 13:43, "Richard Crozier" <r.croz...@ed.ac.uk> wrote:
> > I'm trying out passing additional arguments to an ode solver through the syntax:
> >
> > odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)
> >
> > with evalfcn looking something like:
> >
> > evalfcn(t, y, arg1, arg2, ...)
> >
> > I would have expected that the solvers would simply pass in the arguments to the evaluation function as a series of arguments. In fact it seems the function 'odearguments' first tacks on an empty string to the cell array of arguments for no apparent reason so the arguments passed to the evaluation function are
> >
> > args = {'', arg1, arg2, ...}
> >
> > So evalfcn must look like:
> >
> > evalfcn(t, y, mysteriousString, arg1, arg2, ...)
> >
> > Is there any particular reason for this? I'm guessing it's something to do with simulink maybe? Will this work as I'm expecting it to?
>
> Try
>
> [T,Y]=odeXX(@(t,y)evalfcn(t,y,arg1,arg2,...),tspan,y0,options)
>
> dydt = evalfcn(t,y,arg1,arg2,...)
> ...
>
> Best wishes
> Torsten.

Thanks Torsten, this is how I have been achieving this until now, but it seems a bit of a fudge when the solvers are capable of passing the arguments directly. The feature seems to be undocumented though.

Subject: Passing Extra Arguments to ode solvers

From: Torsten

Date: 25 May, 2011 12:41:51

Message: 4 of 11

On 25 Mai, 14:33, "Richard Crozier" <r.croz...@ed.ac.uk> wrote:
> Torsten <Torsten.Hen...@umsicht.fraunhofer.de> wrote in message <653d40fb-a4c6-4a70-b31c-3b100dcfa...@g16g2000yqj.googlegroups.com>...
> > On 25 Mai, 13:43, "Richard Crozier" <r.croz...@ed.ac.uk> wrote:
> > > I'm trying out passing additional arguments to an ode solver through the syntax:
>
> > > odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)
>
> > > with evalfcn looking something like:
>
> > > evalfcn(t, y, arg1, arg2, ...)
>
> > > I would have expected that the solvers would simply pass in the arguments to the evaluation function as a series of arguments. In fact it seems the function 'odearguments' first tacks on an empty string to the cell array of arguments for no apparent reason so the arguments passed to the evaluation function are
>
> > > args = {'', arg1, arg2, ...}
>
> > > So evalfcn must look like:
>
> > > evalfcn(t, y, mysteriousString, arg1, arg2, ...)
>
> > > Is there any particular reason for this? I'm guessing it's something to do with simulink maybe? Will this work as I'm expecting it to?
>
> > Try
>
> > [T,Y]=odeXX(@(t,y)evalfcn(t,y,arg1,arg2,...),tspan,y0,options)
>
> > dydt = evalfcn(t,y,arg1,arg2,...)
> > ...
>
> > Best wishes
> > Torsten.
>
> Thanks Torsten, this is how I have been achieving this until now, but it seems a bit of a fudge when the solvers are capable of passing the arguments directly. The feature seems to be undocumented though.- Zitierten Text ausblenden -
>
> - Zitierten Text anzeigen -


I thought you achieved it like


odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)


with evalfcn looking something like:


evalfcn(t, y, arg1, arg2, ...) ?


My suggestion was


[T,Y]=odeXX(@(t,y)evalfcn(t,y,arg1,arg2,...),tspan,y0,options)


dydt = evalfcn(t,y,arg1,arg2,...)
...


Best wishes
Torsten.

Subject: Passing Extra Arguments to ode solvers

From: Richard Crozier

Date: 25 May, 2011 12:54:05

Message: 5 of 11

Torsten <Torsten.Hennig@umsicht.fraunhofer.de> wrote in message <80a0f5d5-5092-4b48-b84e-9d49cdf2d425@s2g2000yql.googlegroups.com>...
> On 25 Mai, 14:33, "Richard Crozier" <r.croz...@ed.ac.uk> wrote:
> > Torsten <Torsten.Hen...@umsicht.fraunhofer.de> wrote in message <653d40fb-a4c6-4a70-b31c-3b100dcfa...@g16g2000yqj.googlegroups.com>...
> > > On 25 Mai, 13:43, "Richard Crozier" <r.croz...@ed.ac.uk> wrote:
> > > > I'm trying out passing additional arguments to an ode solver through the syntax:
> >
> > > > odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)
> >
> > > > with evalfcn looking something like:
> >
> > > > evalfcn(t, y, arg1, arg2, ...)
> >
> > > > I would have expected that the solvers would simply pass in the arguments to the evaluation function as a series of arguments. In fact it seems the function 'odearguments' first tacks on an empty string to the cell array of arguments for no apparent reason so the arguments passed to the evaluation function are
> >
> > > > args = {'', arg1, arg2, ...}
> >
> > > > So evalfcn must look like:
> >
> > > > evalfcn(t, y, mysteriousString, arg1, arg2, ...)
> >
> > > > Is there any particular reason for this? I'm guessing it's something to do with simulink maybe? Will this work as I'm expecting it to?
> >
> > > Try
> >
> > > [T,Y]=odeXX(@(t,y)evalfcn(t,y,arg1,arg2,...),tspan,y0,options)
> >
> > > dydt = evalfcn(t,y,arg1,arg2,...)
> > > ...
> >
> > > Best wishes
> > > Torsten.
> >
> > Thanks Torsten, this is how I have been achieving this until now, but it seems a bit of a fudge when the solvers are capable of passing the arguments directly. The feature seems to be undocumented though.- Zitierten Text ausblenden -
> >
> > - Zitierten Text anzeigen -
>
>
> I thought you achieved it like
>
>
> odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)
>
>
> with evalfcn looking something like:
>
>
> evalfcn(t, y, arg1, arg2, ...) ?
>
>
> My suggestion was
>
>
> [T,Y]=odeXX(@(t,y)evalfcn(t,y,arg1,arg2,...),tspan,y0,options)
>
>
> dydt = evalfcn(t,y,arg1,arg2,...)
> ...
>
>
> Best wishes
> Torsten.


Hi Torsten, sorry, I should have been more clear. What I meant was that I am already familiar with the syntax you have suggested, and have used it in the past, not in the example I provided.

It seems that it should be possible to do it in the way I suggested in my example however, and that this would be a much cleaner and (in my opinion) simpler syntax. Also, as it seems that the arguments may also be passed to the output function and events function this way, would mean we need only specify their function handle rather than creating a function handle for each of these as well similar to the one you demonstrate for the evaluation function. This seems a lot more convenient to me if it works.

Perhaps the TMW do not document this as the syntax is not guaranteed to change in the future?

Subject: Passing Extra Arguments to ode solvers

From: Richard Crozier

Date: 25 May, 2011 13:54:04

Message: 6 of 11

"Richard Crozier" wrote in message <iriq08$o5g$1@newscl01ah.mathworks.com>...
> I'm trying out passing additional arguments to an ode solver through the syntax:
>
> odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)
>
> with evalfcn looking something like:
>
> evalfcn(t, y, arg1, arg2, ...)
>
> I would have expected that the solvers would simply pass in the arguments to the evaluation function as a series of arguments. In fact it seems the function 'odearguments' first tacks on an empty string to the cell array of arguments for no apparent reason so the arguments passed to the evaluation function are
>
> args = {'', arg1, arg2, ...}
>
> So evalfcn must look like:
>
> evalfcn(t, y, mysteriousString, arg1, arg2, ...)
>
> Is there any particular reason for this? I'm guessing it's something to do with simulink maybe? Will this work as I'm expecting it to?


I have now discovered that you can happily pass the extra arguments if you pass in the evaluation function as a function handle, I had been passing it in as a string which results in slightly different behaviour from the argument parser function, possibly as some kind of legacy fudge.

Doing it this way means you can specify your evaluation function, events function and output function all with the same syntax and they will all helpfully see the extra arguments you have passed in.

Subject: Passing Extra Arguments to ode solvers

From: Steven_Lord

Date: 25 May, 2011 14:25:04

Message: 7 of 11



"Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
news:iristu$2pk$1@newscl01ah.mathworks.com...
> Torsten <Torsten.Hennig@umsicht.fraunhofer.de> wrote in message
> <653d40fb-a4c6-4a70-b31c-3b100dcfaa4d@g16g2000yqj.googlegroups.com>...
>> On 25 Mai, 13:43, "Richard Crozier" <r.croz...@ed.ac.uk> wrote:
>> > I'm trying out passing additional arguments to an ode solver through
>> > the syntax:
>> >
>> > odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)
>> >
>> > with evalfcn looking something like:
>> >
>> > evalfcn(t, y, arg1, arg2, ...)
>> >
>> > I would have expected that the solvers would simply pass in the
>> > arguments to the evaluation function as a series of arguments. In fact
>> > it seems the function 'odearguments' first tacks on an empty string to
>> > the cell array of arguments for no apparent reason so the arguments
>> > passed to the evaluation function are
>> >
>> > args = {'', arg1, arg2, ...}
>> >
>> > So evalfcn must look like:
>> >
>> > evalfcn(t, y, mysteriousString, arg1, arg2, ...)
>> >
>> > Is there any particular reason for this? I'm guessing it's something to
>> > do with simulink maybe? Will this work as I'm expecting it to?
>>
>> Try
>>
>> [T,Y]=odeXX(@(t,y)evalfcn(t,y,arg1,arg2,...),tspan,y0,options)
>>
>> dydt = evalfcn(t,y,arg1,arg2,...)
>> ...
>>
>> Best wishes
>> Torsten.
>
> Thanks Torsten, this is how I have been achieving this until now, but it
> seems a bit of a fudge when the solvers are capable of passing the
> arguments directly. The feature seems to be undocumented though.

The older ODE solvers used to accept additional input arguments after the
options structure. Even though they still accept that syntax for backwards
compatibility, we stopped documenting that syntax in favor of the anonymous
function approach when anonymous functions were introduced for a couple of
reasons.

1) Allowing additional parameters after the options structure limits our
ability to introduce new input arguments to the ODE solvers after the
options structure. To do so would cause a backwards incompatibility and the
behavior of code that depends on the trailing parameters could change.

2) People would often get it wrong the first time they tried to do this if
they had not only an ODE function but also a function specified in their
options structure (like an Events function or an OutputFcn.) If you use the
trailing parameters syntax, ALL functions you specify must accept ALL the
optional input arguments, even if they use NONE of them. With the anonymous
function "adapter" pattern, the signature of the function you create is
irrelevant to the ODE solver as all it sees is the adapter anonymous
function that provides the signature the ODE solver expects; what that
adapter does internally doesn't matter to the ODE solver.


For these reasons and others, some of the newer "function functions" do not
accept trailing additional parameters; for example, in release R2011a (and
for a few releases prior) the older BVP solver BVP4C does accept trailing
parameters but the newer BVP5C does not. Therefore going forward I encourage
you to use the anonymous function approach as shown in example 3 on the
reference page for the ODE solvers.

http://www.mathworks.com/help/techdoc/ref/ode23.html

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: Passing Extra Arguments to ode solvers

From: Steven_Lord

Date: 25 May, 2011 14:27:27

Message: 8 of 11



"Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
news:irj1ls$ib8$1@newscl01ah.mathworks.com...
> "Richard Crozier" wrote in message
> <iriq08$o5g$1@newscl01ah.mathworks.com>...
>> I'm trying out passing additional arguments to an ode solver through the
>> syntax:
>>
>> odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)
>>
>> with evalfcn looking something like:
>>
>> evalfcn(t, y, arg1, arg2, ...)
>>
>> I would have expected that the solvers would simply pass in the arguments
>> to the evaluation function as a series of arguments. In fact it seems the
>> function 'odearguments' first tacks on an empty string to the cell array
>> of arguments for no apparent reason so the arguments passed to the
>> evaluation function are args = {'', arg1, arg2, ...}
>>
>> So evalfcn must look like:
>>
>> evalfcn(t, y, mysteriousString, arg1, arg2, ...)
>>
>> Is there any particular reason for this? I'm guessing it's something to
>> do with simulink maybe? Will this work as I'm expecting it to?
>
>
> I have now discovered that you can happily pass the extra arguments if you
> pass in the evaluation function as a function handle, I had been passing
> it in as a string which results in slightly different behaviour from the
> argument parser function, possibly as some kind of legacy fudge.

That is correct; that is a legacy syntax that is supported for backwards
compatibility but discouraged.

> Doing it this way means you can specify your evaluation function, events
> function and output function all with the same syntax and they will all
> helpfully see the extra arguments you have passed in.

You may consider this a feature. In many cases, people found the "Too many
input arguments" error message they received when they tried it to be
confusing and called it a bug even though it wasn't.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: Passing Extra Arguments to ode solvers

From: Richard Crozier

Date: 25 May, 2011 14:43:04

Message: 9 of 11

"Steven_Lord" <slord@mathworks.com> wrote in message <irj3kf$nv3$1@newscl01ah.mathworks.com>...
>
>
> "Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
> news:irj1ls$ib8$1@newscl01ah.mathworks.com...
> > "Richard Crozier" wrote in message
> > <iriq08$o5g$1@newscl01ah.mathworks.com>...
> >> I'm trying out passing additional arguments to an ode solver through the
> >> syntax:
> >>
> >> odeXX(@evalfcn, tspan, t0, options, arg1, arg1, ...)
> >>
> >> with evalfcn looking something like:
> >>
> >> evalfcn(t, y, arg1, arg2, ...)
> >>
> >> I would have expected that the solvers would simply pass in the arguments
> >> to the evaluation function as a series of arguments. In fact it seems the
> >> function 'odearguments' first tacks on an empty string to the cell array
> >> of arguments for no apparent reason so the arguments passed to the
> >> evaluation function are args = {'', arg1, arg2, ...}
> >>
> >> So evalfcn must look like:
> >>
> >> evalfcn(t, y, mysteriousString, arg1, arg2, ...)
> >>
> >> Is there any particular reason for this? I'm guessing it's something to
> >> do with simulink maybe? Will this work as I'm expecting it to?
> >
> >
> > I have now discovered that you can happily pass the extra arguments if you
> > pass in the evaluation function as a function handle, I had been passing
> > it in as a string which results in slightly different behaviour from the
> > argument parser function, possibly as some kind of legacy fudge.
>
> That is correct; that is a legacy syntax that is supported for backwards
> compatibility but discouraged.
>
> > Doing it this way means you can specify your evaluation function, events
> > function and output function all with the same syntax and they will all
> > helpfully see the extra arguments you have passed in.
>
> You may consider this a feature. In many cases, people found the "Too many
> input arguments" error message they received when they tried it to be
> confusing and called it a bug even though it wasn't.
>
> --
> Steve Lord
> slord@mathworks.com
> To contact Technical Support use the Contact Us link on
> http://www.mathworks.com

Ok, I see where you're coming from here. I could certainly see some people being confused by this syntax when getting started. It's a shame though, as it seems a lot more convenient to be able to do this. I feel like I've just found some money in my pocket I didn't know I had, then had it blow away again in a gust of wind.

Personally I would have looked at having an option in the ode options structure whether or not to pass additional arguments to the events and output functions that defaulted to false in this case or something like this. Perhaps explaining this in the documentation would be even more confusing though.

Subject: Passing Extra Arguments to ode solvers

From: Steven_Lord

Date: 25 May, 2011 15:00:12

Message: 10 of 11



"Richard Crozier" <r.crozier@ed.ac.uk> wrote in message
news:irj4ho$qpe$1@newscl01ah.mathworks.com...
> "Steven_Lord" <slord@mathworks.com> wrote in message
> <irj3kf$nv3$1@newscl01ah.mathworks.com>...

*snip*

> Ok, I see where you're coming from here. I could certainly see some people
> being confused by this syntax when getting started. It's a shame though,
> as it seems a lot more convenient to be able to do this. I feel like I've
> just found some money in my pocket I didn't know I had, then had it blow
> away again in a gust of wind.
>
> Personally I would have looked at having an option in the ode options
> structure whether or not to pass additional arguments to the events and
> output functions that defaulted to false in this case or something like
> this. Perhaps explaining this in the documentation would be even more
> confusing though.

Particularly if the ODE solver required some but not all of the additional
inputs, the Events function required a different (potentially overlapping)
subset of the additional inputs, and the OutputFcn a third subset, yes.


If you find you're passing a lot of additional inputs into each of the three
functions, there are two other alternatives that will work with both the
older solvers (that support the trailing input arguments) and newer solvers
(that don't.) The first alternative is to pack your additional inputs into
one struct array and pass that into the various functions. The second is to
make each of the functions nested functions inside one outer function that
contains the additional inputs. The latter will work because nested
functions can "see" variables in their parent function's workspace.

http://www.mathworks.com/help/techdoc/matlab_prog/f4-39683.html

Here's an example of the second syntax:


function [t, y] = solveODE
mu = 2;
[t, y] = ode45(@myODEfun, [0 2], 1);

    % Begin nested function myODEfun
    function dydt = myODEfun(t, y)
        dydt = mu*y;
    end
    % end nested function myODEfun

    % Begin nested function myEventsfun that depends on mu ...

end


Call this like:

[t, y] = solveODE;
plot(t, y, '-', t, exp(2*t), 'o')

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: Passing Extra Arguments to ode solvers

From: Richard Crozier

Date: 25 May, 2011 15:43:05

Message: 11 of 11

 *snip*
>
> If you find you're passing a lot of additional inputs into each of the three
> functions, there are two other alternatives that will work with both the
> older solvers (that support the trailing input arguments) and newer solvers
> (that don't.) The first alternative is to pack your additional inputs into
> one struct array and pass that into the various functions. The second is to
> make each of the functions nested functions inside one outer function that
> contains the additional inputs. The latter will work because nested
> functions can "see" variables in their parent function's workspace.
>
> http://www.mathworks.com/help/techdoc/matlab_prog/f4-39683.html
>
> Here's an example of the second syntax:
>
>
> function [t, y] = solveODE
> mu = 2;
> [t, y] = ode45(@myODEfun, [0 2], 1);
>
> % Begin nested function myODEfun
> function dydt = myODEfun(t, y)
> dydt = mu*y;
> end
> % end nested function myODEfun
>
> % Begin nested function myEventsfun that depends on mu ...
>
> end
>
>
> Call this like:
>
> [t, y] = solveODE;
> plot(t, y, '-', t, exp(2*t), 'o')
>
> --
> Steve Lord
> slord@mathworks.com
> To contact Technical Support use the Contact Us link on
> http://www.mathworks.com

Thanks, I already pack all my arguments into two structures which are passed to the ode solver. It's just so much simpler if you just have one call to the functions without having to muck around with function handles for all of them. I'm also not 100% convinced that preventing you from passing any arguments at all is the solution to wanting different numbers of arguments passed to OutputFcn and the Events function. If someone wanted to do this, presumably more unusual case, the more complicated methods such as function handles and the other methods you suggest are still available after all.

I also have a dislike of nested functions which means I refuse to use them (just a personal preference of course). They seem a bit too global variablish to me.

I think what I'm really going to do is just use this syntax and hope TMW don't ever get round to changing it for the existing solvers for which it works. When that day comes I'll just have to deal with it, and possibly write outraged complaints about how TMW shouldn't go changing things like this with no warning even though it's not even documented ;-).

p.s. I do appreciate your input and suggestions, thanks!

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us