Repository navigation
Initial attempt at documenting new ODE interface (design-doc #19) - #213
Conversation
|
@mitzimorris adding you here. I don't think you need to review the text so much (let's let @wds15 take a pass or two first), but do you have suggestions on #1 and #2 above? |
SteveBronder
left a comment
There was a problem hiding this comment.
idk anything about ODEs but thought I'd help give some comments. The info is v good but I think the structure needs changed a bit
| `...` are any number of arguments passed through unmodified from the ODE integrate | ||
| call. | ||
|
|
||
| The ODE system function should return the derivative of the state with | ||
| respect to time at the time and state provided. The length of the returned | ||
| vector must match the length of the state input into the function. | ||
|
|
||
| The arguments to this function are: | ||
|
|
||
| * *`time`*, the time to evaluate the ODE system | ||
|
|
||
| * *`state`*, the state of the ODE system at the time specified | ||
|
|
||
| * *...*, all other arguments passed through from the integrate call. Each | ||
| argument can be any type. |
There was a problem hiding this comment.
Before this section I would show an example signature for the ODE integrators because
all other arguments passed through from the integrate call
Doesn't really make sense without knowing what the integrators look like
| `...` are any number of arguments passed through unmodified from the ODE integrate | |
| call. | |
| The ODE system function should return the derivative of the state with | |
| respect to time at the time and state provided. The length of the returned | |
| vector must match the length of the state input into the function. | |
| The arguments to this function are: | |
| * *`time`*, the time to evaluate the ODE system | |
| * *`state`*, the state of the ODE system at the time specified | |
| * *...*, all other arguments passed through from the integrate call. Each | |
| argument can be any type. | |
| Where the arguments to the function are: | |
| * *`time`*, the time to evaluate the ODE system | |
| * *`state`*, the state of the ODE system at the time specified | |
| * *...*, Any additional arguments needed in the ODE. Each of these can be arguments of any type. | |
| The ODE system function should return the derivative of the `state` with | |
| respect to `time` at the `time` and `state` provided. The length of the returned | |
| vector must match the length of the state input into the function. |
There was a problem hiding this comment.
I moved the ODE system function definition below the signatures and the arguments to the integrator functions.
It's still slightly confusing because the first argument to the integrator function is the ODE system function, but there's a little inline doc there that hopefully works.
| * *`ode`*: function literal referring to a function specifying the | ||
| system of differential equations with signature: |
There was a problem hiding this comment.
What does function literal mean? Should we use that same term when talking about the ODE function above?
There was a problem hiding this comment.
Is this section the same as the one above?
There was a problem hiding this comment.
Is this section the same as the one above?
I left a copy of the old integrator docs there. The function signature will be deprecated but I figure it should still have docs so people know how to convert old models. So there is duplicate information.
|
Thanks @SteveBronder , those were useful comments. I resolved most of the simpler things and left open the big things if you wanna check them. |
|
Beginning of the stan user guides for odes it says "Stan provides a built-in mechanism for specifying and solving systems of ordinary differential equations (ODEs). Stan provides three different integrators, tuned for solving non-stiff systems and for stiff systems." can you please change that to "Stan provides a built-in mechanism for specifying and solving systems of ordinary differential equations (ODEs). Three different integrators, tuned for solving non-stiff systems and for stiff systems are available." |
|
Also here: docs/src/stan-users-guide/odes.Rmd Line 19 in f145344 It states that stiff solver are slower, but more robust. Well... that's not quite right. For a non-stiff system the stiff solver will be slower than the non-stiff one, but whenever a system is stiff, then the non-stiff solver will be much slower than the stiff solver. If you could clarify that, this would be great. So for non-stiff problems the non-stiff solvers shine and leave behind the stiff solvers by a large margin, but if the problems are stiff, then the reverse is true. |
wds15
left a comment
There was a problem hiding this comment.
Just some cleanups to be done.
| region of parameter space. The function signatures for Stan's ODE | ||
| solvers can be found in the reference manual section on ODE solvers. | ||
|
|
||
|
|
There was a problem hiding this comment.
It appears to me that we went with the convention to say
There was a problem hiding this comment.
I agree. The fact that the rest of the ODE literature is sloppy about explaining their conventions doesn't mean we have to be! That
| parameters. A full example for the simple harmonic oscillator, which | ||
| does not depend on any constant data variables, is provided in the | ||
| simple harmonic oscillator trajectory plot. | ||
| Every ODE system function has the same first two arguments and the |
There was a problem hiding this comment.
this section is confusing here as the ode_* calls have not been defined yet. You could include in 1.2 a paragraph saying how one gets from the coded ODE RHS, the solution
There was a problem hiding this comment.
Or at least cross-reference.
|
|
||
| * solution times and number of vectors in the output, | ||
|
|
||
| ## Old integrate_ode_X ODE Interface {#old-functions-ode-solver} |
There was a problem hiding this comment.
Maybe call this section "Deprecated integrate_ode_* ODE Interface" ?
There was a problem hiding this comment.
It's probably best to start an appendix with deprecated functions as we do in the reference manual.
There was a problem hiding this comment.
Better yet, move to an appendix the same way we do in the reference manual. Doc for deprecated function can be abbreviated.
|
bob-carpenter
left a comment
There was a problem hiding this comment.
Done. Now you have two reviews.
| <!-- vector[]; ode_rk45; (function ode, vector initial_state, real initial_time, real[] times, ...); --> | ||
| \index{{\tt \bfseries ode\_rk45 }!{\tt (function ode, real[] initial\_state, real initial\_time, real[] times, ...): vector[]}|hyperpage} | ||
|
|
||
| `vector[]` **`ode_rk45`**`(function ode, vector initial_state, real initial_time, real[] times, ...)`<br>\newline |
There was a problem hiding this comment.
The ... thing really needs to be explained up front. I was reading along assuming it was just tolerances or something like that and I find out it's the whole new way of dealing with ODEs. This needs to be said up front!
| ``` | ||
|
|
||
| In general it is better to integrate up to `t_lag` in one solve and | ||
| then integrate from `t_lag` onwards in another. |
There was a problem hiding this comment.
Cool. I was wondering about that. Definitely include this.
|
@wds15 @bob-carpenter, just warning, but didn't finish or push my changes here yet, so it'll probably be confusing if you try to make sense of my responses here (because I haven't pushed code yet). |
|
@bob-carpenter is there a standard way we link from the user's guide to the functions reference? |
|
Alright I made my changes so this is ready for review again. The comments were super helpful btw. @bob-carpenter if you want to leave the full final review to @wds15 that's fine by me, but I'd like you to take a look at the changes to the language reference and how I organized the function-reference appendix. |
|
There's not a good way to link to the functions reference. It's doubly hard when they're getting published concurrently. You can link to a specific version or to the top-level versionless one. Obviously the versioned one will be stable and the other one less so. |
|
I'll just approve to leave the final review for @wds15. Let me know if there's something you want to look at. This is less of a big deal than the code, because we don't introduce backward compatibility issues, etc. We can just change it in the next release if we don't like this one. |
|
Should we wait to merge this till the code goes in? |
|
Will read this once more on Monday. |
wds15
left a comment
There was a problem hiding this comment.
Some minor things so far and could you please add
img/sho-ode-trajectory.png
this file is missing such that I cannot build the reference section, which makes it hard to review. Thanks.
| In general it is better to integrate up to `t_lag` in one solve and | ||
| then integrate from `t_lag` onwards in another. Mathematically, the | ||
| discontinuity can make the problem ill-defined and the numerical integrator | ||
| may behave erratically around it. |
There was a problem hiding this comment.
Could we mention that in case the ODE integrator is to be "run-through" the discontinuity, then it's strongly advisable to output some function values in the vicinity of the discontinuity? There are discontinuities which are not jumps, but rather sudden (but still continuous) changes - for example in forcing functions.
There was a problem hiding this comment.
then it's strongly advisable to output some function values in the vicinity of the discontinuity
I don't think this will improve the behavior of the integrator around those points though. Intermediate outputs are just interpolated from the actual path the solver took.
I guess I could suggest this if there was something to do with the output. Like make plots or something. I just don't think there's an obvious way to diagnose if there are problems or not here.
There was a problem hiding this comment.
No, it really does make a difference. I had experienced this myself when coding dosing events as approximate delta peaks (using normal distributions). Only when I added observation time points around the dosing time, only then the integrator picked up the dosing event. The big disadvantage of the approach you propose to restart is that you must restart the integration process with the initials being parameters whereas if you keep integrating in a single go, then - for pharmacokinetic problems at least - you can use data as the initial. This will dramatically speedup the solve process as the sensitivity system is a lot smaller as compared to making initials varying.
| section](#stiff-ode.section). In a nutshell, the stiff solvers are | ||
| slower, but more robust; how much so depends on the system and the | ||
| region of parameter space. The function signatures for Stan's ODE | ||
| section](#stiff-ode.section). The function signatures for Stan's ODE |
There was a problem hiding this comment.
In this section we talk of "stiff solvers are"... and so on. We only have a single stiff solver.
It could be worthwhile to mention that the non-stiff Adams is a suitable choice for - obviously non-stiff - problems where the ODE RHS is very expensive to calculate. This is due to the attempt of Adams to do a higher order approximation of the function in order to make large steps and in turn avoid excessive calls to the ODE RHS (whereas RK45 just calls brutally the ODE RHS very often).
There was a problem hiding this comment.
This is due to the attempt of Adams to do a higher order approximation of the function in order to make large steps and in turn avoid excessive calls to the ODE RHS (whereas RK45 just calls brutally the ODE RHS very often).
I think we should work on a separate workflow ODE document because we have no real guidance on picking between the solvers. I'd like to just leave this for the future.
There was a problem hiding this comment.
I find the text as is confusing as there is no guidance at all to pick between the two non-stiff ones. I would prefer to tell people: Start with RK45 in any case; if stiffness is a concern go with bdf and whenever the problem is non-stiff and the ODE RHS is expensive to evaluate, then try Adams (after having tried RK45).
This would reflect my intuition and I think is a fair summary. If you think we are not ready for this... ok.
|
Oh whoops. Added the missing png. |
…ng rk45/adams/bdf (design-doc #19)
Submission Checklist
Summary
Here's a rough attempt at rewriting the ODE docs for the new interfaces.
@wds15 add this to your list to review. The user's guide portion is pretty rough. I don't think we should plan on doing anything more than a compatibility rewrite before the next release, but I think we should rewrite this shortly.
Issues:
There's a missing plot currently. I have a pull req. to remake it here: Missing plot in ODE section of user's guide #160 , and but the plot appears to be as a repo as a .pdf but that's not rendering on the web (here). Can I just convert it to a .png?
We can get rid of the old interface stuff in the user's guide, and it doesn't take up much space in the language reference, however, I think we should keep the full docs around in the function's guide since even though this is a deprecated feature there are going to be lots of models out there using
integrate_ode_Xfunctions. How do we demarcate this in the function guide? Presumably we need to make it easy for people to find that page, but also easy once they've found that page to realize that they should be using the new interfaces (on a different page).Copyright and Licensing
Please list the copyright holder for the work you are submitting (this will be you or your assignee, such as a university or company): Columbia University
By submitting this pull request, the copyright holder is agreeing to license the submitted work under the following licenses: