Design & Architecture¶
Project Structure¶
kalbee/
├── __init__.py # Top-level exports
├── modules/
│ ├── filters/
│ │ ├── base.py # BaseFilter ABC
│ │ ├── kf_filter.py # Kalman Filter
│ │ ├── ekf_filter.py # Extended KF
│ │ ├── ukf_filter.py # Unscented KF
│ │ ├── particle_filter.py # Particle Filter
│ │ ├── enkf_filter.py # Ensemble KF
│ │ ├── information_filter.py # Information Filter
│ │ ├── abg_filter.py # Alpha-Beta-Gamma
│ │ ├── adaptive_kf.py # Adaptive KF
│ │ └── auto_filter.py # Factory
│ ├── smoothers/
│ │ └── rts_smoother.py # RTS Smoother
│ └── utils/
│ └── metrics.py # RMSE, NEES, NIS
├── experiments/
│ ├── signals.py # Signal generators
│ ├── runner.py # Experiment runner
│ └── results.py # Results container
└── tests/
└── test_*.py # 58 tests
Design Principles¶
1. Common Interface via BaseFilter¶
Every filter inherits from BaseFilter and implements:
class BaseFilter(ABC):
def predict(self, dt: float = 1.0, **kwargs) -> np.ndarray: ...
def update(self, measurement: np.ndarray, **kwargs) -> np.ndarray: ...
def measure(self, state=None) -> np.ndarray: ...
This means you can swap filters without changing calling code.
2. Numerical Stability¶
- Joseph form for covariance updates in KF and EKF
- Symmetry enforcement after every covariance update:
P = (P + P.T) / 2 - Cholesky fallback in UKF sigma point generation
3. Extensibility¶
Add a new filter by:
- Create
kalbee/modules/filters/my_filter.py - Inherit from
BaseFilter - Implement
predict()andupdate() - Register in
__init__.pyandAutoFilter
from kalbee.modules.filters.base import BaseFilter
class MyFilter(BaseFilter):
def predict(self, dt=1.0, **kwargs):
# Your predict logic
return self.state
def update(self, measurement, **kwargs):
# Your update logic
return self.state
Dependencies¶
| Package | Why |
|---|---|
numpy |
Core matrix operations |
scipy |
Cholesky decomposition (UKF) |
Filter Comparison¶
| Filter | Linear | Non-linear | Non-Gaussian | Jacobians | Complexity |
|---|---|---|---|---|---|
| KF | ✅ | ❌ | ❌ | Not needed | \(O(n^3)\) |
| EKF | ✅ | ✅ | ❌ | Required | \(O(n^3)\) |
| UKF | ✅ | ✅ | ❌ | Not needed | \(O(n^3)\) |
| PF | ✅ | ✅ | ✅ | Not needed | \(O(Nn^2)\) |
| EnKF | ✅ | ✅ | ❌ | Not needed | \(O(Nn^2)\) |
| IF | ✅ | ❌ | ❌ | Not needed | \(O(n^3)\) |
| ABG | ✅ | ❌ | ❌ | Not needed | \(O(1)\) |
| AKF | ✅ | ❌ | ❌ | Not needed | \(O(n^3)\) |