Added support for multiterm (imex solvers) - #307
Conversation
| Checked structurally (not via `isinstance(..., ImExDrift)`) because the | ||
| concrete `ImExDrift` class lives in `state_evolution.py`, which imports | ||
| from `core.py`, which imports from this module -- importing it here | ||
| would cycle. |
There was a problem hiding this comment.
This doesn't seem like a good reason to create a dummy class. Can you take a look to see what sort of file refactor / creation would be needed to avoid this circular import issue?
| raise NotImplementedError() | ||
|
|
||
|
|
||
| type _Drift = Callable[ |
There was a problem hiding this comment.
How about models/types.py?
There was a problem hiding this comment.
just trying to think about big picture organization...dynestyx/types.py are pretty high-level types, so seems weird to drop ImExDrift there.
There was a problem hiding this comment.
actually, I guess models/core.py is already mostly a "types.py" file.
There was a problem hiding this comment.
How about models/drifts.py and include Drift, AffineDrift, and ImExDrift there?
There was a problem hiding this comment.
I'm going to be a bit verbose to make sure I understand things correctly, let me know if I'm off track.
Right now incheckers.py, we use _validate_continuous_state_evolution to check that we are not using both an ImExDrift AND a state_evolution.potential term (because we decided that combining these two is ambiguous), raising an error if so.
I think adding a drifts.py with Drift, AffineDrift, ImExDrift, Potential (?) and importing them into checkers.py could make sense.
One thing I'm not completely sure about is that diffusion.py is imported at the level of core.py, one level down so there is a difference between the two (and I would naively assume that they would mirror each other, I don't know if this is a concern). I could see if there is a way of checking the ImExDrift vs Potential at the level of core.py but it's definitely more complicated.
I want to add that I believe that we have 3 choices:
- add the check in
checkers.py, in_validate_continuous_state_evolution. - add the check in
core.py, inContinuousTimeStateEvolution(doing it during class instantiation( - add the check in
odes.py, in_solve
I'm not a fan of 3, because the error will be raised much later.
There was a problem hiding this comment.
I think it makes sense to include Potential too!
Not sure I understand the concern about diffusions.py. Both drifts.py and diffusions.py would be leaf modules imported by core.py; and checkers.py would additionally import ImExDrift
That should be OK? want to understand the complication here
There was a problem hiding this comment.
I'm just wanted to make sure that it was fine that checkers.py depends on drifts.py but not on diffusions.py is fine. I might be overthinking this, if it's not an issue, then will implement.
There was a problem hiding this comment.
yeah, checkers.py COULD depend on diffusions.py if we needed it to though right?
We just don't do any diffusion checks
dirfts.py now includes potential, drift, imexdrift. pure leaf file imported by checkers.py amd core.py
|
There now is a |
There was a problem hiding this comment.
I guess this file path should change to models/drifts/drift.md
There was a problem hiding this comment.
I guess this file path should change to models/drifts/potential.md
Yeah looks reasonable---I guess you need to change some of the docs .md file paths accordingly though |
|
@MatthieuDarcy I did a quick iteration with Codex, which picked up 2 issues:
|
|
Also, the reaction diffusion notebook kinda uses IMEX at the end, but it doesn't show any plots or justify the choice |
I fixed both.
|
|
Yeah looks good, thanks! |
|
Actually nevermind, ODE solvers can also be labelled as |
|
FYI I updated the PR to merge to main + made a merge commit, since the previous base branch landed on main. |
mattlevine22
left a comment
There was a problem hiding this comment.
I'm happy with this PR, so approving it.
Would recommend updating the end of the notebook with a plot of the pde solution that used the imex solver though.
changed the order added a drifts section (similar to diffusion)
|
@mattlevine22 I modified some of the API documentation in The order is changed (it seemed a bit random, I tried to have more coherent order). There now is a dedicated I updated the notebook with a plot and added a justification for using Imex. Let me know what you think, didn't want to merge without your approval. |
| class AffineDrift(eqx.Module): | ||
| """ | ||
| Affine drift function for continuous-time models. | ||
|
|
||
| This implements an affine map of the form | ||
|
|
||
| $$f(x, u, t) = A x + B u + b,$$ | ||
|
|
||
| where $A \\in \\mathbb{R}^{d_x \\times d_x}$, $B \\in \\mathbb{R}^{d_x \\times d_u}$ | ||
| (optional), and $b \\in \\mathbb{R}^{d_x}$ (optional). The time argument $t$ | ||
| is accepted for compatibility with the `Drift` protocol but is not used. | ||
|
|
||
| This is commonly used as the drift term $\\mu(x_t, u_t, t)$ inside | ||
| `ContinuousTimeStateEvolution`, and is a building block for LTI models such as | ||
| `LTI_continuous`. | ||
|
|
||
| Attributes: | ||
| A (jax.Array): Drift matrix with shape $(d_x, d_x)$. | ||
| B (jax.Array | None): Optional control matrix with shape $(d_x, d_u)$. | ||
| b (jax.Array | None): Optional additive bias with shape $(d_x,)$. | ||
| """ |
There was a problem hiding this comment.
I think we have enough (even if the total number is small) users and this is a common enough class that we should be keeping this API entrypoint with a deprecation warning that it will be removed in v0.5.0.
There was a problem hiding this comment.
state_evolution.py now imports AffineDrift from drifts.pyso this restores the API entrypoint (with a warning).
|
Sorry I realized afterwards that Matt had approved it already lol. But these are tiny, I'm happy for it to be merged afterwards :) |
Co-authored-by: Dan Waxman <dan.waxman1@gmail.com>
Requires
diffrax==0.7.2which is only possible when CD-Dynamax is updated, so marking this as a draft in the meantime.#304