patrick-kidger / patrick-kidger/diffrax
Why are step_ts and jump_ts treated differently here?
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.1k
- Forks
- 189
- Avg merge
- 3d 18h
- Merged PRs (30d)
- 1
Description
Hi Patrick,
Am I correct in saying that the only differences between step_ts and jump_ts are the following:
jump_tscannot be integers, but must be floats (so that you can doprevbeforeandnextafter)_clip_jump_tsalso returnsmade_jump, which is used to determine whether we need to do_t1 = nextafter(nextafter(t1)).
But in addition to those discrepancies, it seems Diffrax treats them differently in one other way as well, which I am not sure I understand. Namely, the line below uses prev_dt=prev_dt if the step was clipped due to a jump, but prev_dt=t1-t0 if the step was clipped due to step_ts. I don't see why we should make a distinction between these two cases.
I would go even further and say that the line should just say prev_dt=t1-t0 in all cases. This is because the error of the current step depends on t1-t0, rather than on prev_dt, so I feel like keeping prev_dt in controller state is not needed. Here is what could go wrong with the current setup:
Say prev_dt=0.1, but due to jump_ts it was clipped to t1-t0 = 0.01. Also assume that the error was large and the step gets rejected and assume that the controller computes factor=0.5. Then the next step-size proposal will be 0.05, which is bigger than the step that was just taken, so it will again be clipped by jump_ts to 0.01, resulting in an infinite loop. Instead the new step proposal should just be (t1-t0)*factor = 0.005, which would presumably result in a smaller error and move forward.
On the other hand if the step was clipped to a much smaller size than was intended (i.e. t1-t0 << prev_dt), then this will usually reflect in the error being small accordingly, resulting in a large factor. This means that (t1-t0)*factor would be again a reasonably large step-size proposal, whereas prev_dt*factor would be disproportionately massive.
Let me know if I missed something.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in diffrax/_step_size_controller/adaptive.py around line 561 and trace how step_ts, jump_ts, prev_dt, and the actual t1-t0 are passed through the adaptive controller. Reproduce the rejected-step and clipped jump_ts scenario described in the issue, then determine whether the proposal should use the actual step duration and verify that the controller avoids repeated clipping or an infinite loop.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100