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;
38mod spaces;
39
40pub use anova::{frechet_anova, frechet_anova_space};
41pub use mean::{frechet_mean, frechet_variance};
42pub use regression::{
43    frechet_global_reg, frechet_global_reg_space, frechet_local_reg, frechet_local_reg_space,
44};
45pub use space::{wasserstein2_distance, MetricSpace, WassersteinDensitySpace};
46pub use spaces::{
47    CorrelationMatrixSpace, NetworkSpace, PointProcessSpace, SpdMatrixSpace, SpdMetric,
48    SphericalSpace,
49};
50
51use crate::matrix::FdMatrix;
52
53/// Result of global Fréchet regression ([`frechet_global_reg`]).
54///
55/// Predicts a conditional Fréchet-mean density response at each `xout` row via the
56/// Petersen–Müller global linear weight scheme.
57#[derive(Debug, Clone, PartialEq)]
58#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
59#[non_exhaustive]
60pub struct FrechetGlobalRegResult {
61    /// Predicted density responses, shape n_out × m (row i = prediction at `xout` row i).
62    pub predicted: FdMatrix,
63    /// The predictor values predictions were made at, shape n_out × p.
64    pub xout: FdMatrix,
65    /// Column means of the training predictors, length p.
66    pub x_bar: Vec<f64>,
67}
68
69/// Result of local (local-linear, kernel-weighted) Fréchet regression
70/// ([`frechet_local_reg`]).
71#[derive(Debug, Clone, PartialEq)]
72#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
73#[non_exhaustive]
74pub struct FrechetLocalRegResult {
75    /// Predicted density responses, shape n_out × m.
76    pub predicted: FdMatrix,
77    /// The predictor values predictions were made at, shape n_out × p.
78    pub xout: FdMatrix,
79    /// The kernel bandwidth used.
80    pub bandwidth: f64,
81}
82
83/// Result of a Fréchet ANOVA group-difference test ([`frechet_anova`]).
84///
85/// The Dubey–Müller `Tₙ` statistic with a primary seeded permutation p-value and
86/// a secondary asymptotic χ²(k−1) p-value.
87#[derive(Debug, Clone, PartialEq)]
88#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
89#[non_exhaustive]
90pub struct FrechetAnovaResult {
91    /// Dubey–Müller `Tₙ` test statistic.
92    pub statistic: f64,
93    /// Asymptotic χ²(k−1) p-value (secondary inference).
94    pub p_value_asymptotic: f64,
95    /// Seeded-permutation p-value (primary reported inference).
96    pub p_value_permutation: f64,
97    /// Number of permutations used.
98    pub n_perm: usize,
99    /// Per-group Fréchet variances V̂ₗ (length k).
100    pub group_frechet_variances: Vec<f64>,
101    /// Pooled Fréchet variance V̂ₚ.
102    pub pooled_frechet_variance: f64,
103    /// The Fₙ variance-contrast component.
104    pub fn_statistic: f64,
105    /// The Uₙ pairwise-dispersion component.
106    pub un_statistic: f64,
107    /// The group labels used (contiguous 0..k).
108    pub group_labels: Vec<usize>,
109}