patrick-kidger / patrick-kidger/diffrax

Event and PIDController: event doesn't always occure

Open
#507 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
Python
Stars
2.1k
Forks
189
Avg merge
3d 18h
Merged PRs (30d)
1

Description

First, I want to thank you for your amazing library. You have done a massive work which are very useful for my research.


diffrax 0.6.0
optimistix 0.0.7
jax 0.4.30

When using PID controler and Event functionnality are used simultaneously, I found that the event will not always raised due to the difference of complexity between the event function and the ode function. For example, If the ode function si very simple (straight line), the pid controler will allow to have large steps. Large step can miss the event condition if there is two changes of signs between this two steps.

To avoid this issue, I found that integrate the event condition in the ode function can correct the issue in my particular usecase. Is there a more mathematical grounded method to resolve this issue?

A small python example:

import jax
import jax.numpy as jnp
import jax.random as random


jax.config.update("jax_enable_x64", True)

import diffrax
import optimistix as optx


def event(x, high_pres=False,coeff=1.0):
    x = jnp.concatenate([jnp.ones((1, 1)) * x, jnp.zeros((1, 1))], axis=1)

    #  event_condition = (2.5 - y) . (5.0 - y) . (0.0 - y)
    event_condition = lambda t, y, args, **kwargs: (-y[0, 0] + 2.5) * (-y[0, 0] + 5.0) * (-y[0, 0] + 0.0)
  
    # dx/dt = [1, 0]
    # adding the event condition: dx/dt = [1, 0, | event_condition(t, x) | * coeff ]
    # coeff used to defined if the event condition is taken into account or not  
    ode_fun = lambda t, x_, args: jnp.concatenate([jnp.ones((1,1)), jnp.zeros((1,1)), coeff * jnp.expand_dims(jnp.expand_dims(jnp.abs(event_condition(t, x_, args)),axis=0),axis=0)],axis=1)

    fun = diffrax.ODETerm(ode_fun)

    if high_pres:
        stepsize_controller = diffrax.PIDController(rtol=1E-14, atol=1E-14)
    else:
        stepsize_controller = diffrax.PIDController(rtol=1E-8, atol=1E-8)

    solver = diffrax.Dopri8() 
    root_finder = optx.Bisection(1E-10, 1E-10)

    t1 = 10

    sol = diffrax.diffeqsolve(
        fun,
        solver,
        0.0,
        t1,
        None,
        jnp.concatenate([x, jnp.zeros((1,1))],axis=1),
        stepsize_controller=stepsize_controller,
        max_steps=None, 
        event=diffrax.Event(event_condition, root_finder),
        throw=False
    )

    event_occurred = diffrax.RESULTS.event_occurred == sol.result

    t_result = sol.ts
    x_last = sol.ys[0][:,:2]

    print(event_occurred, x_last, t_result)
    print(sol.result)

event(0.5, high_pres=True, coeff=0.0) # -> with high precision (1E-14), the event is detected
event(0.5, high_pres=False, coeff=0.0) # -> with "low" precision (1E-8), the event is not detected
event(0.5, high_pres=False, coeff=1.0) # -> with "low" precision (1E-8) and take into account the event condition on the ode terms, the event is detected

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided Python example with the stated diffrax, optimistix, and JAX versions, comparing PIDController settings and event outcomes. Investigate the interaction between Event root detection and large adaptive steps; done means establishing a mathematically grounded resolution and demonstrating reliable detection for the reported case.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.