rs_stats/lib.rs
1//! # rs-stats — Comprehensive Statistical Library
2//!
3//! `rs-stats` provides a complete, **panic-free** statistical toolkit for Rust:
4//! probability functions, 14 parametric distributions with fitting, automatic
5//! distribution detection, hypothesis testing, and regression analysis.
6//!
7//! All fallible operations return [`StatsResult<T>`] — a `Result<T, StatsError>`.
8//!
9//! ## Modules at a Glance
10//!
11//! | Module | Contents |
12//! |--------|----------|
13//! | [`distributions`] | 14 distributions + unified trait interface + auto-fit API |
14//! | [`hypothesis_tests`] | t-tests, ANOVA, chi-square, chi-square independence |
15//! | [`regression`] | Linear, multiple linear, decision trees |
16//! | [`prob`] | Mean, variance, std-dev, z-scores, erf, CDF helpers |
17//! | [`utils`] | Special functions (`ln_gamma`, incomplete gamma/beta), combinatorics |
18//!
19//! ## Medical Quick-Start
20//!
21//! ### Identify the distribution of a clinical measurement
22//!
23//! ```rust
24//! use rs_stats::{auto_fit, fit_all, Distribution};
25//! use rs_stats::distributions::lognormal::LogNormal;
26//!
27//! // CRP levels (mg/L) from an outpatient cohort — right-skewed biomarker
28//! let crp = vec![
29//! 0.8, 1.2, 1.5, 2.1, 2.4, 3.2, 3.9, 5.6, 9.7, 12.4,
30//! 22.3, 45.0, 88.0, 0.9, 1.3, 1.8, 0.7, 0.6, 0.5, 1.1,
31//! ];
32//!
33//! // One call: auto-detect type, fit all candidates, return the best (lowest AIC)
34//! let best = auto_fit(&crp).unwrap();
35//! println!("Best distribution: {} (AIC={:.2})", best.name, best.aic);
36//! // → Best distribution: LogNormal
37//!
38//! // Fit explicitly and answer clinical questions
39//! let crp_dist = LogNormal::fit(&crp).unwrap();
40//! let median = crp_dist.inverse_cdf(0.5).unwrap();
41//! let p_high = 1.0 - crp_dist.cdf(10.0).unwrap(); // P(CRP > 10 mg/L)
42//! println!("Median CRP = {:.2} mg/L", median);
43//! println!("P(CRP > 10 mg/L) = {:.1}%", p_high * 100.0);
44//! ```
45//!
46//! ### Compare two treatment arms
47//!
48//! ```rust
49//! use rs_stats::hypothesis_tests::t_test::two_sample_t_test;
50//!
51//! // Systolic blood pressure (mmHg) — control vs. treated
52//! let control = vec![128.0, 132.0, 125.0, 130.0, 129.0, 131.0];
53//! let treatment = vec![118.0, 122.0, 115.0, 120.0, 119.0, 121.0];
54//!
55//! let result = two_sample_t_test(&control, &treatment, false).unwrap();
56//! println!("t = {:.3}, p = {:.4}", result.t_statistic, result.p_value);
57//! if result.p_value < 0.05 {
58//! println!("→ Significant BP reduction (α = 0.05)");
59//! }
60//! ```
61//!
62//! ### Compute reference intervals from data
63//!
64//! ```rust
65//! use rs_stats::distributions::normal_distribution::Normal;
66//! use rs_stats::Distribution;
67//!
68//! // Haemoglobin (g/dL) in healthy adults — estimate the 95% reference interval
69//! let hgb = vec![13.5, 14.2, 13.8, 15.1, 14.5, 13.9, 14.8, 15.3, 14.0, 14.6];
70//! let dist = Normal::fit(&hgb).unwrap();
71//!
72//! let lower = dist.inverse_cdf(0.025).unwrap();
73//! let upper = dist.inverse_cdf(0.975).unwrap();
74//! println!("95% reference interval: [{:.2}, {:.2}] g/dL", lower, upper);
75//! ```
76//!
77//! ## Trait-Based Polymorphism
78//!
79//! Use `Box<dyn Distribution>` to work with distributions at runtime:
80//!
81//! ```rust
82//! use rs_stats::Distribution;
83//! use rs_stats::distributions::{
84//! normal_distribution::Normal,
85//! lognormal::LogNormal,
86//! };
87//!
88//! // Choose the distribution based on data characteristics
89//! fn best_model(skewed: bool) -> Box<dyn Distribution> {
90//! if skewed {
91//! Box::new(LogNormal::new(1.0, 0.5).unwrap())
92//! } else {
93//! Box::new(Normal::new(80.0, 10.0).unwrap())
94//! }
95//! }
96//!
97//! let model = best_model(true);
98//! println!("Mean = {:.2}", model.mean());
99//! println!("P95 = {:.2}", model.inverse_cdf(0.95).unwrap());
100//! ```
101pub mod distributions;
102pub mod error;
103pub mod hypothesis_tests;
104pub mod prob;
105pub mod regression;
106pub mod utils;
107
108// Re-export error types for convenience
109pub use error::{StatsError, StatsResult};
110
111// Re-export fitting API at the crate root for easy access
112pub use distributions::fitting::{
113 DataKind, FitResult, KsResult, auto_fit, detect_data_type, fit_all, fit_all_discrete, fit_best,
114 fit_best_discrete,
115};
116// Re-export traits for use without the full path
117pub use distributions::traits::{DiscreteDistribution, Distribution};