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

241 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Feature: PID Controller
## Overview
The PID (Proportional-Integral-Derivative) step size controller is an advanced adaptive time-stepping controller that provides better stability and efficiency than the basic PI controller, especially for difficult or oscillatory problems.
**Key Characteristics:**
- Three-term control: proportional, integral, and derivative components
- More stable than PI for challenging problems
- Standard in production ODE solvers
- Can prevent oscillatory step size behavior
## Why This Feature Matters
- **Robustness**: Handles difficult problems that cause PI controller to oscillate
- **Industry standard**: Used in MATLAB, Sundials, and other production solvers
- **Minimal overhead**: Small computational cost for significant stability improvement
- **Smooth stepping**: Reduces erratic step size changes
## Dependencies
- None (extends current controller infrastructure)
## Implementation Approach
### Mathematical Formulation
The PID controller determines the next step size based on error estimates from the current and previous steps:
```
h_{n+1} = h_n * (ε_n)^(-β₁) * (ε_{n-1})^(-β₂) * (ε_{n-2})^(-β₃)
```
Where:
- ε_i = error estimate at step i (normalized by tolerance)
- β₁ = proportional coefficient (typically ~0.3 to 0.5)
- β₂ = integral coefficient (typically ~0.04 to 0.1)
- β₃ = derivative coefficient (typically ~0.01 to 0.05)
Standard formula (Hairer & Wanner):
```
h_{n+1} = h_n * safety * (ε_n)^(-β₁/(k+1)) * (ε_{n-1})^(-β₂/(k+1)) * (h_n/h_{n-1})^(-β₃/(k+1))
```
Where k is the order of the method.
### Advantages Over PI
- **PI controller**: Uses only current and previous error (2 terms)
- **PID controller**: Also uses rate of change of error (3 terms)
- **Result**: Anticipates trends, prevents overshoot
### Implementation Design
```rust
pub struct PIDController {
// Coefficients
pub beta1: f64, // Proportional
pub beta2: f64, // Integral
pub beta3: f64, // Derivative
// Constraints
pub factor_min: f64, // qmax inverse
pub factor_max: f64, // qmin inverse
pub h_max: f64,
pub safety_factor: f64,
// State (error history)
pub err_old: f64, // ε_{n-1}
pub err_older: f64, // ε_{n-2}
pub h_old: f64, // h_{n-1}
// Next step guess
pub next_step_guess: TryStep,
}
```
## Implementation Tasks
### Core Controller
- [ ] Define `PIDController` struct
- [ ] Add beta1, beta2, beta3 coefficients
- [ ] Add constraint fields (factor_min, factor_max, h_max, safety)
- [ ] Add state fields (err_old, err_older, h_old)
- [ ] Add next_step_guess field
- [ ] Implement `Controller<D>` trait
- [ ] `determine_step()` method
- [ ] Handle first step (no history)
- [ ] Handle second step (partial history)
- [ ] Full PID formula for subsequent steps
- [ ] Apply safety factor and limits
- [ ] Update error history
- [ ] Return TryStep::Accepted or NotYetAccepted
- [ ] Constructor methods
- [ ] `new()` with all parameters
- [ ] `default()` with standard coefficients
- [ ] `for_order()` - scale coefficients by method order
- [ ] Helper methods
- [ ] `reset()` - clear history (for algorithm switching)
- [ ] Update state after accepted/rejected steps
### Standard Coefficient Sets
Different coefficient sets for different problem classes:
- [ ] **Default (H312)**:
- β₁ = 1/4, β₂ = 1/4, β₃ = 0
- Actually a PI controller with specific tuning
- Good general-purpose choice
- [ ] **H211**:
- β₁ = 1/6, β₂ = 1/6, β₃ = 0
- More conservative
- [ ] **Full PID (Gustafsson)**:
- β₁ = 0.49/(k+1)
- β₂ = 0.34/(k+1)
- β₃ = 0.10/(k+1)
- True PID behavior
### Integration
- [ ] Export PIDController in prelude
- [ ] Update Problem to accept any Controller trait
- [ ] Examples using PID controller
### Testing
- [ ] **Comparison test: Smooth problem**
- [ ] Run exponential decay with PI and PID
- [ ] Both should perform similarly
- [ ] Verify PID doesn't hurt performance
- [ ] **Oscillatory problem test**
- [ ] Problem that causes PI to oscillate step sizes
- [ ] Example: y'' + ω²y = 0 with varying ω
- [ ] PID should have smoother step size evolution
- [ ] Plot step size vs time for both
- [ ] **Step rejection handling**
- [ ] Verify history updated correctly after rejection
- [ ] Doesn't blow up or get stuck
- [ ] **Reset test**
- [ ] Algorithm switching scenario
- [ ] Verify reset() clears history appropriately
- [ ] **Coefficient tuning test**
- [ ] Try different β values
- [ ] Verify stability bounds
- [ ] Document which work best for which problems
### Benchmarking
- [ ] Add PID option to existing benchmarks
- [ ] Compare step count and function evaluations vs PI
- [ ] Measure overhead (should be negligible)
### Documentation
- [ ] Docstring explaining PID control
- [ ] When to prefer PID over PI
- [ ] Coefficient selection guidance
- [ ] Example comparing PI and PID behavior
## Testing Requirements
### Oscillatory Test Problem
Problem designed to expose step size oscillation:
```rust
// Prothero-Robinson equation
// y' = λ(y - φ(t)) + φ'(t)
// where φ(t) = sin(ωt), λ << 0 (stiff), ω moderate
//
// This problem can cause step size oscillation with PI
```
Expected: PID should maintain more stable step sizes.
### Step Size Stability Metric
Track standard deviation of log(h_i/h_{i-1}) over the integration:
- PI controller: may have σ > 0.5
- PID controller: should have σ < 0.3
## References
1. **PID Controllers for ODE**:
- Gustafsson, K., Lundh, M., and Söderlind, G. (1988)
- "A PI stepsize control for the numerical solution of ordinary differential equations"
- BIT Numerical Mathematics, 28, 270-287
2. **Implementation Details**:
- Hairer, E., Nørsett, S.P., and Wanner, G. (1993)
- "Solving Ordinary Differential Equations I", Section II.4
- PID controller discussion
3. **Coefficient Selection**:
- Söderlind, G. (2002)
- "Automatic Control and Adaptive Time-Stepping"
- Numerical Algorithms, 31, 281-310
4. **Julia Implementation**:
- `OrdinaryDiffEq.jl/lib/OrdinaryDiffEqCore/src/integrators/controllers.jl`
- Look for `PIDController`
## Complexity Estimate
**Effort**: Small (3-5 hours)
- Straightforward extension of PI controller
- Main work is getting coefficients right
- Testing requires careful problem selection
**Risk**: Low
- Well-understood algorithm
- Minimal code changes
- Easy to validate
## Success Criteria
- [ ] Implements full PID formula correctly
- [ ] Handles first/second step bootstrap
- [ ] Shows improved stability on oscillatory test problem
- [ ] Performance similar to PI on smooth problems
- [ ] Error history management correct after rejections
- [ ] Documentation complete with usage examples
- [ ] Coefficient sets match literature values
## Future Enhancements
- [ ] Automatic coefficient selection based on problem characteristics
- [ ] More sophisticated controllers (H0211b, predictive)
- [ ] Limiter functions to prevent extreme changes
- [ ] Per-algorithm default coefficients