solow_robust/lib.rs
1//! # solow-robust
2//!
3//! Robust linear regression by M-estimation, matching the reference's robust
4//! linear model (RLM).
5//!
6//! The estimator minimizes `Σ ρ((yᵢ − xᵢ·β) / σ)` for a robust criterion `ρ`
7//! using iteratively reweighted least squares (IRLS), re-estimating the scale
8//! `σ` from the residuals at each step.
9//!
10//! ```
11//! use ndarray::{Array1, Array2};
12//! use solow_robust::{norms::TukeyBiweight, Rlm};
13//!
14//! // A noisy line near y = 2 + 0.5·x with a gross outlier at the last point.
15//! let x: Vec<f64> = (1..=10).map(|i| i as f64).collect();
16//! let y = Array1::from(vec![
17//! 2.6, 3.1, 3.4, 4.1, 4.4, 5.1, 5.4, 6.1, 6.4, 100.0,
18//! ]);
19//! let exog =
20//! Array2::from_shape_fn((10, 2), |(i, j)| if j == 0 { 1.0 } else { x[i] });
21//! let res = Rlm::new(y, exog, TukeyBiweight::default())
22//! .unwrap()
23//! .fit()
24//! .unwrap();
25//! assert!(res.converged);
26//! // The redescending norm fully rejects the outlier ...
27//! assert_eq!(res.weights[9], 0.0);
28//! // ... so the slope stays close to the clean trend rather than ~10.
29//! assert!((res.params[1] - 0.5).abs() < 0.05);
30//! ```
31//!
32//! ## Components
33//!
34//! * [`norms`] — robust criterion functions ([`norms::HuberT`],
35//! [`norms::TukeyBiweight`], [`norms::AndrewWave`], [`norms::LeastSquares`]).
36//! * [`scale`] — robust scale estimators ([`scale::mad`], [`scale::Huber`],
37//! [`scale::HuberScale`]).
38//! * [`Rlm`] / [`RlmResults`] — the model and its fitted result.
39
40pub mod norms;
41pub mod norms_ext;
42pub mod scale;
43
44mod rlm;
45
46pub use norms_ext::{Hampel, RamsayE, TrimmedMean};
47pub use rlm::{Conv, Rlm, RlmResults, ScaleEst};