Skip to main content

fdars_core/frechet/
mod.rs

1//! Fréchet / object-data regression and statistics (FRE-01).
2//!
3//! Metric-space (object-data) regression and statistics in the style of the R
4//! `frechet` package: a [`MetricSpace`] abstraction (distance + weighted-Fréchet-
5//! mean solver) with a 1D-Wasserstein (density-response) backend
6//! ([`WassersteinDensitySpace`]) as the first concrete space, the sample Fréchet
7//! [`frechet_mean`] / [`frechet_variance`], the 1D 2-Wasserstein distance
8//! ([`wasserstein2_distance`]), global and local (kernel-weighted) Fréchet
9//! regression over Euclidean predictors, density-response regression, and a
10//! Fréchet ANOVA group-difference test.
11//!
12//! # R baselines
13//!
14//! * Global / local Fréchet regression — `frechet::GloWassReg` / `LocWassReg`
15//!   (Petersen & Müller 2019, *Annals of Statistics* 47(2)).
16//! * Fréchet ANOVA — `frechet::DenANOVA` (Dubey & Müller 2019, *Biometrika* 106(4)).
17//!
18//! # Reuse & conventions
19//!
20//! The density backend reuses DENS-01's quantile/Wasserstein machinery
21//! ([`crate::density_fda`]) rather than re-deriving it. All public functions
22//! return `Result<_, FdarError>` and validate inputs at entry (never panic).
23//! Any permutation path uses per-thread seeded RNG
24//! (`StdRng::seed_from_u64(seed + k)`) with a default of 999 replications. Result
25//! structs derive `Debug, Clone, PartialEq` and are serde-gated.
26//!
27//! # Divergence
28//!
29//! Global/local Fréchet regression weights can be negative; where R uses an
30//! `osqp` quadratic program to enforce a monotone predicted quantile, this crate
31//! uses a zero-dependency sort-based isotonic projection (see the regression
32//! submodule).
33
34mod anova;
35mod mean;
36mod regression;
37mod space;
38
39pub use anova::frechet_anova;
40pub use mean::{frechet_mean, frechet_variance};
41pub use regression::{frechet_global_reg, frechet_local_reg};
42pub use space::{wasserstein2_distance, MetricSpace, WassersteinDensitySpace};
43
44use crate::matrix::FdMatrix;
45
46/// Result of global Fréchet regression ([`frechet_global_reg`]).
47///
48/// Predicts a conditional Fréchet-mean density response at each `xout` row via the
49/// Petersen–Müller global linear weight scheme.
50#[derive(Debug, Clone, PartialEq)]
51#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
52#[non_exhaustive]
53pub struct FrechetGlobalRegResult {
54    /// Predicted density responses, shape n_out × m (row i = prediction at `xout` row i).
55    pub predicted: FdMatrix,
56    /// The predictor values predictions were made at, shape n_out × p.
57    pub xout: FdMatrix,
58    /// Column means of the training predictors, length p.
59    pub x_bar: Vec<f64>,
60}
61
62/// Result of local (local-linear, kernel-weighted) Fréchet regression
63/// ([`frechet_local_reg`]).
64#[derive(Debug, Clone, PartialEq)]
65#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
66#[non_exhaustive]
67pub struct FrechetLocalRegResult {
68    /// Predicted density responses, shape n_out × m.
69    pub predicted: FdMatrix,
70    /// The predictor values predictions were made at, shape n_out × p.
71    pub xout: FdMatrix,
72    /// The kernel bandwidth used.
73    pub bandwidth: f64,
74}
75
76/// Result of a Fréchet ANOVA group-difference test ([`frechet_anova`]).
77///
78/// The Dubey–Müller `Tₙ` statistic with a primary seeded permutation p-value and
79/// a secondary asymptotic χ²(k−1) p-value.
80#[derive(Debug, Clone, PartialEq)]
81#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
82#[non_exhaustive]
83pub struct FrechetAnovaResult {
84    /// Dubey–Müller `Tₙ` test statistic.
85    pub statistic: f64,
86    /// Asymptotic χ²(k−1) p-value (secondary inference).
87    pub p_value_asymptotic: f64,
88    /// Seeded-permutation p-value (primary reported inference).
89    pub p_value_permutation: f64,
90    /// Number of permutations used.
91    pub n_perm: usize,
92    /// Per-group Fréchet variances V̂ₗ (length k).
93    pub group_frechet_variances: Vec<f64>,
94    /// Pooled Fréchet variance V̂ₚ.
95    pub pooled_frechet_variance: f64,
96    /// The Fₙ variance-contrast component.
97    pub fn_statistic: f64,
98    /// The Uₙ pairwise-dispersion component.
99    pub un_statistic: f64,
100    /// The group labels used (contiguous 0..k).
101    pub group_labels: Vec<usize>,
102}