Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions diffrax/solver/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,20 +187,21 @@ class AbstractWrappedSolver(AbstractSolver):


class HalfSolver(AbstractWrappedSolver, AbstractAdaptiveSDESolver):
"""Wraps another solver, trading cost in order to provide error estimates. (These
error estimates mean that the solver can be used with an adaptive step size
controller, like [`diffrax.PIDController`][].)
"""Wraps another solver, trading cost in order to provide error estimates. (That
is, it means the solver can be used with an adaptive step size controller,
regardless of whether the underlying solver supports adaptive step sizing.)

For every step of the wrapped solver, it does this by also making two half-steps,
and comparing the results. (Hence the name "HalfSolver".)
and comparing the results between the full step and the two half steps. Hence the
name "HalfSolver".

As such each step costs 3 times the computational cost of the wrapped solver.

!!! tip

Many solvers already provided error estimates, making `HalfSolver` primarily
Many solvers already provide error estimates, making `HalfSolver` primarily
useful when using a solver that doesn't provide error estimates -- e.g.
[`diffrax.Euler`][] -- in particular this is common when solving SDEs.
[`diffrax.Euler`][] -- such solvers are most common when solving SDEs.
"""

@property
Expand Down
5 changes: 3 additions & 2 deletions diffrax/solver/dopri5.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,19 @@ class Dopri5(AbstractERK):
volume={6},
pages={19--26}
}
```

However (despite the name), the Butcher tableau used here is actually due to
Shampine:

```bibtex
@article{
@article{shampine1986some,
author={Lawrence F. Shampine},
journal={Mathematics of Computation},
number={173},
pages={135--150},
publisher={American Mathematical Society},
title={Some Practical Runge-Kutta Formulas},
title={Some Practical {R}unge-{K}utta Formulas},
volume={46},
year={1986},
doi={https://doi.org/10.2307/2008219}
Expand Down
2 changes: 2 additions & 0 deletions diffrax/solver/leapfrog_midpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class LeapfrogMidpoint(AbstractSolver):

??? cite "Reference"

```bibtex
@article{shampine2009stability,
title={Stability of the leapfrog/midpoint method},
author={L. F. Shampine},
Expand All @@ -36,6 +37,7 @@ class LeapfrogMidpoint(AbstractSolver):
pages={293-298},
year={2009},
}
```
"""

term_structure = jax.tree_structure(0)
Expand Down
12 changes: 6 additions & 6 deletions diffrax/solver/milstein.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class StratonovichMilstein(AbstractStratonovichSolver):

!!! warning

Requires commutative noise. Note that this commutativity condition is not
checked.
"""
Requires [commutative noise](https://docs.kidger.site/diffrax/usage/how-to-choose-a-solver/#stochastic-differential-equations).
Note that this commutativity condition is not checked.
""" # noqa: E501

term_structure = jax.tree_structure((0, 0))
interpolation_cls = LocalLinearInterpolation
Expand Down Expand Up @@ -79,9 +79,9 @@ class ItoMilstein(AbstractItoSolver):

!!! warning

Requires commutative noise. Note that this commutativity condition is not
checked.
"""
Requires [commutative noise](https://docs.kidger.site/diffrax/usage/how-to-choose-a-solver/#stochastic-differential-equations).
Note that this commutativity condition is not checked.
""" # noqa: E501

term_structure = jax.tree_structure((0, 0))
interpolation_cls = LocalLinearInterpolation
Expand Down
7 changes: 4 additions & 3 deletions docs/api/solver.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Solvers

The complete list of solvers, categorised by type, is as follows.
The complete list of solvers, categorised by type, is as follows. See also [How to choose a solver](../usage/how-to-choose-a-solver.md).

!!! info "Term structure"

Expand Down Expand Up @@ -106,8 +106,9 @@ The complete list of solvers, categorised by type, is as follows.

The state of the system (the initial value of which is given by `y0` to [`diffrax.diffeqsolve`][]) must be a 2-tuple (of PyTrees). The terms (given by the value of `terms` to [`diffrax.diffeqsolve`][]) must be a 2-tuple of `AbstractTerms`.

Letting `v, w = y0` and `f, g = terms`, then `v` is updated according to
`f(t, w, args) * dt` and `w` is updated according to `g(t, v, args) * dt`.
Letting `v, w = y0` and `f, g = terms`, then `v` is updated according to `f(t, w, args) * dt` and `w` is updated according to `g(t, v, args) * dt`.

See also this [Wikipedia page](https://en.wikipedia.org/wiki/Semi-implicit_Euler_method#Setting).

::: diffrax.SemiImplicitEuler
selection:
Expand Down
8 changes: 7 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@ If this page has caught your interest, then have a look at the [Getting Started]

!!! help

Both Diffrax and its documentation are very new! If anything is unclear, or if you have any suggestions, then please open an issue or pull request on [GitHub](https://github.com/patrick-kidger/diffrax).
Both Diffrax and its documentation are very new! If:

- anything is unclear;
- you have any suggestions;
- you need any more features;

then please open an issue or pull request on [GitHub](https://github.com/patrick-kidger/diffrax).
8 changes: 3 additions & 5 deletions docs/usage/how-to-choose-a-solver.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ See also the [Stiff ODE example](../examples/stiff_ode.ipynb).

## Stochastic differential equations

!!! info

SDE solvers are relatively specialised depending on the type of problem. Each solver will converge to either the Itô solution or the Stratonovich solution. In addition some solvers require "commutative noise".
SDE solvers are relatively specialised depending on the type of problem. Each solver will converge to either the Itô solution or the Stratonovich solution. In addition some solvers require "commutative noise".

??? info "Commutative noise"

Expand Down Expand Up @@ -83,7 +81,7 @@ $\mathrm{d}y(t) = μ(t, y(t))\mathrm{d}t + σ(t, y(t))\mathrm{d}w(t)$

Then the diffusion matrix $σ$ is said to be additive if $σ(t, y) = σ(t)$. That is to say if the diffusion is independent of $y$.

In this case then the Itô solution and the Stratonovich solution coincide, and mathematically speaking the choice of Itô vs Stratonovich is unimportant. (In addition, additive noise is commutative niose.)
In this case then the Itô solution and the Stratonovich solution coincide, and mathematically speaking the choice of Itô vs Stratonovich is unimportant.

- The cheapest (but least accurate) solver is [`diffrax.Euler`][].
- Otherwise [`diffrax.Heun`][] is a good choice. It gets first-order strong convergence and second-order weak convergence.
Expand All @@ -100,7 +98,7 @@ If the control is differentiable (e.g. an interpolation of discrete data) and is
vector_field = ...
control = ...
term = ControlTerm(vector_field, control)
term.to_ode()
term = term.to_ode()
```

Then use any of the ODE solvers as discussed above.
Expand Down