Files
differential-equations/roadmap/features/12-auto-switching.md
Connor Johnstone e3788bf607 Added the roadmap
2025-10-23 16:47:48 -04:00

8.4 KiB
Raw Permalink Blame History

Feature: Auto-Switching & Stiffness Detection

Overview

Automatic algorithm switching detects when a problem transitions between stiff and non-stiff regimes and switches to the appropriate solver automatically. This is one of the most powerful features for robust, user-friendly ODE solving.

Key Characteristics:

  • Automatic stiffness detection via eigenvalue estimation
  • Seamless switching between non-stiff and stiff solvers
  • CompositeAlgorithm infrastructure
  • Configurable switching criteria
  • Basis for DefaultODEAlgorithm (solve without specifying algorithm)

Why This Feature Matters

  • User-friendly: User doesn't need to know if problem is stiff
  • Robustness: Handles problems with changing character
  • Efficiency: Uses fast explicit methods when possible, switches to implicit when needed
  • Production-ready: Essential for general-purpose library
  • Real problems: Many problems are "mildly stiff" or transiently stiff

Dependencies

Required

  • At least one stiff solver (Rosenbrock23 or FBDF)
  • At least two non-stiff solvers (have DP5, Tsit5)
  • BS3 recommended for completeness
  • Vern7 for high-accuracy non-stiff
  • Rodas4 or Rodas5P for high-accuracy stiff
  • Multiple controllers (PI, PID)

Implementation Approach

Stiffness Detection

Eigenvalue Estimation:

ρ = ||δf|| / ||δy||

Where:

  • δy = y_{n+1} - y_n
  • δf = f(t_{n+1}, y_{n+1}) - f(t_n, y_n)
  • ρ approximates spectral radius of Jacobian

Stiffness ratio:

S = |ρ * h| / stability_region_size

If S > tolerance (e.g., 1.0), problem is stiff.

Algorithm Switching Logic

  1. Detect stiffness every few steps
  2. Switch condition: Stiffness detected for N consecutive steps
  3. Switch back: Non-stiffness detected for M consecutive steps
  4. Hysteresis: N < M to avoid chattering

Typical values:

  • N = 3-5 (switch to stiff solver)
  • M = 25-50 (switch back to non-stiff)

CompositeAlgorithm Structure

pub struct CompositeAlgorithm<NonStiff, Stiff> {
    pub nonstiff_alg: NonStiff,
    pub stiff_alg: Stiff,
    pub choice_function: AutoSwitchCache,
}

pub struct AutoSwitchCache {
    pub current_algorithm: AlgorithmChoice,
    pub consecutive_stiff: usize,
    pub consecutive_nonstiff: usize,
    pub switch_to_stiff_threshold: usize,
    pub switch_to_nonstiff_threshold: usize,
    pub stiffness_tolerance: f64,
}

pub enum AlgorithmChoice {
    NonStiff,
    Stiff,
}

Implementation Challenges

  1. State transfer: When switching, need to transfer state cleanly
  2. Controller state: Each algorithm may have different controller state
  3. Interpolation: Dense output from previous algorithm
  4. First step: Which algorithm to start with?

Implementation Tasks

Core Infrastructure

  • Define CompositeAlgorithm struct

    • Generic over two integrator types
    • Store both algorithms
    • Store switching logic state
  • Define AutoSwitchCache

    • Current algorithm choice
    • Consecutive step counters
    • Thresholds
    • Stiffness tolerance
  • Implement switching logic

    • Eigenvalue estimation function
    • Stiffness detection
    • Decision to switch
    • Reset counters appropriately

Integrator Changes

  • Modify Problem to work with composite algorithms

    • May need IntegratorEnum or dynamic dispatch
    • Or: make Problem generic and handle in solve loop
  • State transfer mechanism

    • Transfer y, t from one integrator to other
    • Transfer/reset controller state
    • Clear interpolation data
  • Solve loop modifications

    • Check for switch every N steps
    • Perform switch if needed
    • Continue with new algorithm

Eigenvalue Estimation

  • Implement basic estimator

    • Track previous f evaluation
    • Compute ρ = ||δf|| / ||δy||
    • Update estimate smoothly (exponential moving average)
  • Handle edge cases

    • Very small ||δy||
    • First step (no history)
    • After callback event

Default Algorithm

  • AutoAlgSwitch function/constructor

    • Takes tuple of non-stiff algorithms
    • Takes tuple of stiff algorithms
    • Returns CompositeAlgorithm
    • With default switching parameters
  • DefaultODEAlgorithm (future)

    • Analyzes problem
    • Selects algorithms based on size, tolerance
    • Returns configured CompositeAlgorithm

Testing

  • Transiently stiff problem

    • Starts non-stiff, becomes stiff, then non-stiff again
    • Example: Van der Pol with time-varying μ
    • Verify switches at right times
    • Verify solution accuracy throughout
  • Always non-stiff problem

    • Should never switch to stiff solver
    • Verify minimal overhead
  • Always stiff problem

    • Should switch to stiff early
    • Stay on stiff solver
  • Chattering prevention

    • Problem near stiffness boundary
    • Verify doesn't switch back and forth rapidly
    • Hysteresis should prevent chattering
  • State transfer test

    • Switch mid-integration
    • Verify no discontinuity in solution
    • Interpolation works across switch
  • Comparison test

    • Run transient stiff problem three ways:
      • Auto-switching
      • Non-stiff only (should fail or be very slow)
      • Stiff only (should work but possibly slower)
    • Auto-switching should be nearly optimal

Benchmarking

  • ROBER problem (chemistry, transiently stiff)
  • HIRES problem (atmospheric chemistry)
  • Compare to manual algorithm selection
  • Measure switching overhead

Documentation

  • Explain stiffness detection
  • Document switching thresholds
  • When auto-switching helps vs hurts
  • Examples with different problem types
  • How to configure switching parameters

Testing Requirements

Transient Stiffness Test

Van der Pol oscillator with time-varying stiffness:

// μ(t) = 100 for t < 20
// μ(t) = 1 for 20 <= t < 40
// μ(t) = 100 for t >= 40

Expected behavior:

  • Start with non-stiff (or quickly switch to stiff)
  • Switch to non-stiff around t=20
  • Switch back to stiff around t=40
  • Solution remains accurate throughout

Track:

  • When switches occur
  • Number of switches
  • Total steps with each algorithm

ROBER Problem

Robertson chemical kinetics:

y1' = -0.04*y1 + 1e4*y2*y3
y2' = 0.04*y1 - 1e4*y2*y3 - 3e7*y2²
y3' = 3e7*y2²

Very stiff initially, becomes less stiff.

Expected: Should start with (or quickly switch to) stiff solver.

References

  1. Stiffness Detection:

    • Shampine, L.F. (1977)
    • "Stiffness and Non-stiff Differential Equation Solvers, II"
    • Applied Numerical Mathematics
  2. Auto-switching Algorithms:

    • Hairer & Wanner (1996), "Solving ODEs II", Section IV.3
    • Discussion of when to use stiff solvers
  3. Julia Implementation:

    • OrdinaryDiffEq.jl/lib/OrdinaryDiffEqDefault/src/default_alg.jl
    • AutoAlgSwitch and default_autoswitch functions
  4. MATLAB's ode45/ode15s switching:

    • MATLAB documentation on automatic solver selection

Complexity Estimate

Effort: Large (15-25 hours)

  • Composite algorithm infrastructure: 6-8 hours
  • Stiffness detection: 4-6 hours
  • Switching logic and state transfer: 5-8 hours
  • Testing and tuning: 4-6 hours

Risk: Medium-High

  • Complexity in state transfer
  • Getting switching criteria right requires tuning
  • Interaction with controllers needs care
  • Edge cases (callbacks during switch, etc.)

Success Criteria

  • Handles transiently stiff problems automatically
  • Switches at appropriate times
  • No chattering between algorithms
  • Solution accuracy maintained across switches
  • Overhead < 10% on problems that don't need switching
  • Performance within 20% of manual optimal selection
  • Documentation complete with examples
  • Robust to edge cases

Future Enhancements

  • More sophisticated stiffness detection

    • Multiple detection methods
    • Learning from past behavior
  • Multi-algorithm selection

    • More than 2 algorithms (low/medium/high accuracy)
    • Tolerance-based selection
  • Automatic tolerance selection

  • Problem analysis at start

    • Estimate problem size effect
    • Sparsity detection
    • Initial algorithm recommendation
  • DefaultODEAlgorithm with full analysis

    • Based on problem size, tolerance, mass matrix, etc.