Source code for lyapax.utils

"""Small helpers for demos/examples -- not part of the core LE engine."""
from __future__ import annotations

from typing import Callable

import jax
import jax.numpy as jnp


[docs] def simulate_trajectory( step_fn: Callable[[jnp.ndarray], jnp.ndarray], state0: jnp.ndarray, n_steps: int, dt: float | None = None, ) -> jnp.ndarray | tuple[jnp.ndarray, jnp.ndarray]: """Run ``step_fn`` for ``n_steps`` iterations via ``lax.scan`` (fast, compiled -- unlike a Python for-loop calling a JAX function repeatedly). Returns the trajectory including the initial state: shape ``(n_steps + 1, d)``. If ``dt`` is given, also returns the matching time axis as ``(t, traj)``, ``t = arange(n_steps + 1) * dt`` -- ``dt`` is otherwise opaque to ``step_fn`` (baked into its closure), so this is the only place that can hand it back to the caller. """ def body(state, _): new_state = step_fn(state) return new_state, new_state _, traj = jax.lax.scan(body, state0, None, length=n_steps) traj = jnp.concatenate([state0[None, :], traj], axis=0) if dt is None: return traj return jnp.arange(n_steps + 1) * dt, traj