Added the roadmap
This commit is contained in:
240
roadmap/features/04-pid-controller.md
Normal file
240
roadmap/features/04-pid-controller.md
Normal file
@@ -0,0 +1,240 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user