-
-
Notifications
You must be signed in to change notification settings - Fork 49
Conversation
* ode23 and ode45 accept non-default tolerances and norms as keyval args * all solvers also have a scalar version
See also #4 |
Just saw the message on julia-users. Let's transfer this package to julialang if ok and I would also integrate it better with sundials. I like experimenting with a solver interface. Do take a look at the original paper on ODE solvers in matlab. |
Integrating with Sundials is a good idea - as an end user, I'd probably think it natural that all the ODE stuff came in the same package, so maybe we should even merge the packages (eventually - it would be nice if this package was good enough to stand on its own legs first...). I'll definitely take a look at the MATLAB paper. For transferring this repo to julialang, @vtjnash is the man. |
GitHub tells me I can't transfer it because I don't have admin rights on JuliaLang |
Done. Can you try again? |
done. (I moved a few others too -- RPMmd, Gtk, and JuliaWebRepl) |
Thanks @vtjnash |
Wouldn't the usual constructor for a solver object be something like The I would also tend to prefer an interface like: I would also tend to use the same keywords as |
Also, your arguments are overtyped (a common problem in the Julia libraries). You shouldn't require them to be Just don't declare a type at all for the "vectors" to be integrated; this is called duck typing. (For example, if we get a Julia chebfun implementation up and running, then the chebfun objects will be (conceptually) infinite-dimensional vectors, and won't be an |
@stevengj Thanks for a lot of useful input! Re. solver objects: The api for this is extremely experimental at this moment. Re. vector norms: The idea was based on a question in the julia-users group - I don't know if I can come up with a use case for it, but since someone wants it and it's easy to implement I didn't see why not =) Re. argument order: I think there's value here in keeping the order of the arguments the same as in MATLAB (see e.g. the MATLAB help page on Re. other keyval args: I'll gladly introduce Re. duck typing: This is good input. I'll try to work something out here, but since some of the solvers use the type argument |
I think it is more convenient just to call I don't think we should constrain ourselves by Matlab's syntax here at the expense of internal consistency or un-Julian style. Passing multiple optional arguments as an explicit array rather than as varargs is both un-idiomatic for Julia and is inconsistent with our I agree that we might as well allow an arbitrary norm to be specified via a If an algorithm doesn't support a certain keyword, e.g. I agree that you don't need Regarding In |
I do see your points about argument order - not sure I am convinced just yet, but I see your points ;) If we do make this change, it might be a good thing to just have Why don't you think we should implement non-adaptive algorithms? Because they're easy enough for each user to implement, and would take up space, or for some other reason? I think there might be merit in having things like I'll take a stab at these changes when I find some time, and see what comes of it. |
I just don't see non-adaptive algorithms as being useful in a general-purpose setting. Users know what accuracy they want, not what stepsize they want, and there doesn't seem to be much if any downside to variable-stepsize adaptive algorithms. Most users would be ill-advised to use a non-adaptive method, and I don't like the idea of putting in a method that is mostly a trap for the unwary. Moreover, every additional algorithm that is implemented increases the code complexity and maintenance effort, so it is a bad idea to include one unless it seems genuinely useful and non-redundant. (There seem to be plenty of adaptive symplectic integrators, so that appears to be an unrelated issue.) For pedagogical purposes, if you want to illustrate a toy ODE integrator for people learning Julia, the right thing to do is to put it in a blog post or similar, not into the production library. |
* renamed kw argument vecnorm to norm, with default * duck typing note: this has not been tested on systems of ODE's yet, as there are none of those in the test suite... * replaced with to get rid of warnings
Hi! What is the status of this PR? I just tried the API changes and they appear to be Ok. I think it would be great to have them merged, also because finding errors is much easier when the functions have a uniform interface. I am bit undecided about the "solver object", but maybe this would be worth a separate issue/PR? There are two minor things: you forgot to change Finally, FWIW, I agree with @stevengj that non-adaptive algorithms are mainly creating additional maintenance overhead. Once intermediate times are properly handled by |
@acroy Thanks for kicking the tires a bit! I'll take a look at your comments about If you'd like to provide a test case where Does anyone know of a good adaptive AND symplectic algorithm, that we could add here? I do agree that non-adaptive algorithms aren't really necessary to have in a library, but without any other symplectic algorithm we might as well keep something like a Verlet integrator here just to have an option for energy-conserving problems. |
Here is an example, which might also be used as a test for solving a system of ODEs
I get
The test might be
Regarding an adaptive symplectic integrator, SIAM J. Sci. Comput. 18, 239 (1997) might be a start? I might also have some more recent references somewhere ... Let's open a new issue for this and maybe ask in julia-users (I vaguely remember that some celestial mechanics related question showed up at some point)? |
I'd hate to not have an implementation of RK4, in no small part because I don't feel every simulation project that uses it should have to carry it around themselves. Fixed-step solvers are still the way to go for real-time, closed-loop PIL/HIL simulation tasks (and we use it for fast-time too so the PIL/HIL work can be validated.) |
@pao: Excuse my ignorance, but why do you need RK4 in that case? Is it because you want exactly 4 evaluations of the RHS? Otherwise, using |
There are no intermediate times. You're only integrating one time step into the future. Your system will have changed due to the influence of the control system for the next time step. (In Simulink, this is the At any rate, if people are seriously considering this it might be best as a separate issue. |
I also very often use fixed steppers for integrating over fixed grids - it would be useful to keep this built in, but it could be in a separate infrastructure. |
I think that "integrating" over fixed grids is mostly a separate problem; if there is no possibility of convergence or stepsize control, then you are really solving a discrete recurrence relation, not an ODE. (And e.g. if your fixed-grid came from some other discretization, e.g. a PDE discretization, then you want to use an integration scheme based on the order/type of your original discretization.) |
Yes, I agree. To provide context, I often propagate a field using a PDE using the appropriate specialist methods for that problem, but need to solve some auxiliary problem with those fields as part of the PDE RHS (for example, some coupled rate equations). To do that I use a fixed step (the step determined by the field grid, which is in turn determined by other aspects of the whole problem) ODE solver. I guess this is not the main use of the ODE package, and I can implement this elsewhere, but I wanted to point out that there are some use cases for such solvers. [Of course, if you have a better way to solve my problem, I will very happily listen to your advice!] |
I guess one could also use RK45 with a fixed-step size and return the error estimate together with the solution vector? Let's continue the discussion about that in #9 ... |
Regarding the API I would like to make another suggestion: if |
@acroy, I'm not sure I like the idea of assuming that integration ranges start at 0. Couldn't the user just use |
It's generally a bad idea for the type of the return value to depend on the value (as opposed to the type) of the arguments. This kind of type-instability causes bad performance to "leak" into the surrounding code. Hence I would strongly urge against having One possibility would be for the syntax to be:
I would also tend to prefer changing the argument order to |
@stevengj: Sounds very reasonable. One minor issue would be that your second |
The second variant could throw an error if the You could certainly have |
Is the |
At least we shouldn't worry too much about it now. Once the PR for the |
…solvers; see SciML#7. Tests adjusted accordingly.
Should we have a keyword |
@acroy Probably a good idea. |
About a month ago, I started some work on porting to Julia some code I wrote in Python to automatically calculate the sensitivity equations analytically for a system of differential equations. This is something I've found very useful when working on fitting ODE models to a set of timecourse data, since estimating the Jacobian using finite element methods is really numerically unstable, especially when the system is very stiff. The downside of the approach is that the individual differential equations have to be differentiable, and I've not found a good way of identifying the actual equations within the callable function, short of writing the function in a specific way that's easy to parse. |
@FedericoV Take a look at https://github.com/scidom/DualNumbers.jl. It uses a different approach to numerical differentiation that does not rely on a epsilon. PS. This seems rather off-topic for the API discussion. |
Umm, good point. Should I edit it out or leave it there for time being? |
@FedericoV : That sounds very interesting! At the moment our support for stiff is ODEs is very basic ( I think we should continue the discussion in a separate issue ... |
Just copy it over into a new issue. |
…solvers; see SciML#7. Tests adjusted accordingly.
…solvers; see SciML#7. Tests adjusted accordingly.
It seems that MATLAB doesn't allow to set @tlycken : If you don't mind, I will copy the summary of the API discussion from one of my comments above into the description of this PR to make it easier to spot. Or should we put it somewhere else? |
Summarizing will be great, wherever you decide to put it. Eventually I think we will want the reasoning behind the API in a |
@acroy I've been thinking about moving this discussion somewhere else for a while - moving your summary to some "cleaner" place (e.g. a new issue) is probably a good idea. Then we can close this PR (the changes here aren't going to make it into the repo anyway) and move all future discussion there, and keep updating the head of that issue when new decisions are made. @ivarne Documenting reasoning behind various API decisions is a great idea. I have no hard preferences on exactly how it's done, so if you think these old issues with discussions won't be "good enough" then |
Old issues contain way too much meta discussion when someone tries to evaluate the ODE solver capabilities in Julia, and it is hard to find exactly the information you are looking for. I use Markdown for github comments, but I don't have any preference. Readthedocs provides a nice soulution for |
It would be great to have a document containing a description of the API and maybe even some background material on the mathematics (does that work in Markdown or rst?). For now I would say having an issue which contains the latest decisions is most convenient. |
…solvers; see SciML#7. Tests adjusted accordingly.
I think this issue has played its part, so I'm closing it for housekeeping purposes. Discussions around API decisions can continue in #20, and discussions about documentation preferably in one or more separate issues. |
…solvers; see SciML#7. Tests adjusted accordingly.
I've started polishing the API for the existing solvers, and would like some comments both on the API decisions and on the implementations of them.
The first of these commits makes a few simple changes to the api:
it possible to run all the solvers for scalar equations, returning scalar results
ode23
andode45
can take tolerances as keyword arguments:ode23
takes two argumentsrtol
andatol
, andode45
takes one argumenttol
. I would rather both methods took the same arguments (preferrably by introducing relative and absolute tolerance inode45
), but I didn't want to change anything in the implementation.ode23
andode45
support non-standard vector norms for determining the error, by supplying a keyword argumentvecnorm
which is a function(x,y) -> norm(x,y)
in the vector space of the solution (see https://groups.google.com/d/msg/julia-users/PouO26Q5C-c/6UBWYBq7wAwJ for some discussion) The default is the standardnorm
function from Base.The second commit introduces the the notion of a "solver object" which can be re-used. It currently only handles very basic setup (no kwargs, for example), but it might be used like this:
In the implementation of this, I am especially uncertain on whether it's better to use symbols (
:ode23
) or direct references to the functions (ode23
) - look at the implementation to see what I mean. It could probably be prettier =)