New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Weird behaviour due to defaults when using Implicit-Euler #156
Comments
Yep, your point makes sense. We should add a check for whether the solver is adaptive or not, and display an error message appropriately. |
Do you concur with the following changed logic? from diffrax import AbstractSolver, AbstractNonlinearSolver, NewtonNonlinearSolver
class AbstractImplicitSolver(AbstractSolver):
"""Indicates that this is an implicit differential equation solver, and as such
that it should take a nonlinear solver as an argument.
"""
nonlinear_solver: AbstractNonlinearSolver
class AbstractAdaptiveSolver(AbstractSolver):
"""Indicates that this solver provides error estimates, and that as such it may be
used with an adaptive step size controller.
"""
class AbstractImplicitAdaptiveSolver(AbstractImplicitSolver, AbstractAdaptiveSolver):
"""Indicates that this is an implicit differential equation solver that also
provides error estimates, and as such it may be used with an adaptive step
size controller and that it should take a nonlinear solver as an argument.
"""
nonlinear_solver: AbstractNonlinearSolver = NewtonNonlinearSolver() |
Hmm. I see what you're aiming for -- add a default nonlinear solver iff we're adaptive -- but I'd prefer to avoid adding abstract base classes with special behaviour for the intersection of two concepts. I think the change I'd propose here is actually a little more involved. I've thrown together a completely untested draft at #157. The TL;DR is that by default the Why this approach?
WDYT? |
I like it. The entire logic is then handled by the fact that (leaf) nodes of a pytree can be typed. Correct? class UseControllerAtol(eqx.Module):
pass
class UseControllerRtol(eqx.Module):
pass
# ...
def _replace_tol(x):
if isinstance(x, UseControllerAtol):
return stepsize_controller.atol
elif isinstance(x, UseControllerRtol):
return stepsize_controller.rtol
else:
return x
# solver is another `eqx.Module` (i.e. a pytree)
solver = jtu.tree_map(_replace_tol, solver) |
Pretty much. Although I've just spotted that I should have written (At the moment they're non-leaf nodes that just so happen not to have any child nodes.) |
Makes sense. |
When using
dfx.ImplicitEuler()
with everything set to default an error is raisedYou are then prompted to set these values in the stepsize-controller, because it is by default supposed to fallback to the values provided in
PIDController
.But
dfx.ImplicitEuler()
does not support adaptive step-sizing using aPIDController
.The solution is to use
Just something that feels a bit odd.
The text was updated successfully, but these errors were encountered: