/** * Constant-delay delay differential equation (DDE) solver via the method of steps. * * Solves * * y'(t) = f(t, y(t), [y(t−τ₁), y(t−τ₂), …]) on t ∈ [t0, T] * * with a **history function** `φ(t)` giving `y(t)` for `t ≤ t0` (the initial state * is `y(t0) = φ(t0)`). The `τ_k` are fixed positive **constant delays**. * * ## Method — method of steps + continuous extension (Bellen–Zennaro) * * The system is integrated with the adaptive **BS23** (Bogacki–Shampine 3(2)) * embedded Runge–Kutta pair — the same explicit pair MATLAB's `dde23` uses. At each * RK stage the delayed argument `y(t − τ_k)` is obtained from * * - the **history function** `φ` when `t − τ_k ≤ t0`, or * - a **cubic-Hermite dense-output interpolant** of the already-computed solution * otherwise (a C¹, O(h⁴) continuous extension built from the stored per-step * `(t, y, y')` data — consistent with BS23's order). * * ### The step cap (standard MOS constraint) * * Each step is **capped at `h ≤ min(τ)`**. With that cap every delayed argument * `t_stage − τ_k` lies in `[t0, t_n]` (already-accepted history), so the delayed * value is always available and the method stays fully **explicit** — no implicit * coupling of the current step to itself. Adaptive error control still chooses `h` * freely within that cap. * * ### Discontinuity propagation * * `y'` is generically discontinuous at `t0` (the history need not satisfy the DDE), * and that low-order discontinuity propagates to `t0 + τ_k`, `t0 + 2τ_k`, …. The * integrator **lands exactly on each `t0 + m·τ_k` breakpoint** (the step is trimmed * so it never *crosses* one), so no dense-output interval straddles a derivative * jump and the smoothing order increases past each breakpoint as it should. * * Plain-number state only (the interpolation and error norms are numeric). * * @packageDocumentation */ /** * Forcing function `y'(t) = f(t, y, yDelayed)`. * - `y` is the current state (`number[]`; a length-1 array for a scalar DDE). * - `yDelayed[k]` is `y(t − τ_k)` in the same shape as `y`, one entry per delay. * Returns the derivative vector (a bare number is accepted for a scalar DDE). */ export type DDEForcing = (t: number, y: number[], yDelayed: number[][]) => number[] | number; /** * History `φ(t)` giving `y(t)` for `t ≤ t0`. Either a function `(t) => state` * (state as `number[]` or scalar `number`), or a constant (`number` / `number[]`) * used for all `t ≤ t0`. The initial state is `φ(t0)`. */ export type DDEHistory = ((t: number) => number[] | number) | number | number[]; /** Options for {@link solveDDE} (mirrors the `solveODE` option shape). */ export interface SolveDDEOptions { /** Relative tolerance for the adaptive local-error control (default `1e-6`). */ tol?: number; /** Absolute tolerance (default `tol · 1e-3`). */ atol?: number; /** Initial step size (default: Hairer heuristic, capped to `min(τ)`). */ firstStep?: number; /** Minimum step size (a hard floor; below it a step is force-accepted). */ minStep?: number; /** Maximum step size (further capped by `min(τ)` and the next breakpoint). */ maxStep?: number; /** Maximum number of accepted steps (default `1e5`). */ maxIter?: number; } /** * Solution returned by {@link solveDDE}. * * `y` is `number[][]` (one state vector per accepted time) when the history/initial * state is a vector, and unwrapped to `number[]` when it is a scalar. */ export interface DDESolution { /** Accepted output times, `t[0] = t0`, last entry `= T`. */ t: number[]; /** State at each accepted time (`number[]` for a scalar DDE, else `number[][]`). */ y: number[][] | number[]; /** * Dense-output evaluator: the cubic-Hermite continuous extension `y(t)` for any * `t ∈ [t0, T]` (clamped to that range). Returns the state in the same shape as * `y` (scalar for a scalar DDE). C¹ and O(h⁴) between accepted steps. */ yInterp: (t: number) => number[] | number; } /** * Solve the constant-delay DDE `y'(t) = f(t, y(t), [y(t−τ₁), …])` on `[tspan[0], * tspan[1]]` with a history `φ` and delays `τ_k`, by the method of steps (adaptive * BS23 + cubic-Hermite continuous extension, step capped at `min(τ)`). * * @param f Forcing `f(t, y, yDelayed) → y'`. `yDelayed[k] = y(t − τ_k)`. * @param tspan `[t0, T]` (forward integration; `T > t0`). * @param history `φ(t)` for `t ≤ t0` — a function or a constant. `y(t0) = φ(t0)`. * @param delays Positive constant delays `τ_k` (at least one). * @param options See {@link SolveDDEOptions}. * @returns `{ t, y, yInterp }` — `y` unwrapped to `number[]` for a scalar DDE. * * @example * // y'(t) = −y(t−1), history φ ≡ 1 on t ≤ 0. Method-of-steps solution: * // [0,1]: 1 − t, [1,2]: t²/2 − 2t + 3/2, … * const sol = solveDDE((t, y, yd) => [-yd[0][0]], [0, 3], 1, [1]); * sol.yInterp(2.5); // dense output at t = 2.5 */ export declare function solveDDE(f: DDEForcing, tspan: [number, number] | number[], history: DDEHistory, delays: number[], options?: SolveDDEOptions): DDESolution; //# sourceMappingURL=solveDDE.d.ts.map