Method-of-moments / MLE fit returns $(\kappa, \theta, \sigma, \text{half-life})$. Use a few thousand samples for stability; winsorize heavy tails if needed.
## Kalman filtering (linear, EKF, UKF)
```python
importnumpyasnp
fromoptimizrimportLinearKalmanFilter
F=[[1.0,1.0],[0.0,1.0]]
H=[[1.0,0.0]]
Q=[[1e-4,0.0],[0.0,1e-4]]
R=[[1e-2]]
kf=LinearKalmanFilter(
f_matrix=F,
h_matrix=H,
q_matrix=Q,
r_matrix=R,
initial_state=[0.0,0.0],
initial_covariance=[[1.0,0.0],[0.0,1.0]],
)
kf.predict(control=[0.0,0.0])
kf.update(observation=[1.2])
state=kf.get_state()
```
- Interfaces: `LinearKalmanFilter`, `UnscentedKalmanFilter`, and `KalmanState` for batch `filter` and smoothing.
- Concept: prediction (dynamics prior) + correction (measurement residual); RTS smoother refines past states.
## Practical notes
- Rust backend (`optimizr._core`) must be present for control utilities; install from source if wheels are unavailable.
- Grids: for HJB, `n_points≈400` is stable; widen `n_std` for volatile spreads.
- Combine with Mean Field Games: see `mean_field_games.md` for population dynamics; use Kalman estimates as control inputs if needed.