1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
//! Probability distributions: parameter structs plus their behaviour traits.
//!
//! This module defines the behaviour traits (`Pdf`/`Pmf`/`Cdf`/`Quantile`/
//! `Moments`/`Sample`) every distribution implements, plus the shared
//! `bisection_quantile` inverse-CDF solver and a small integer→float helper.
//! The plain-data parameter structs for each distribution live in [`types`] and
//! are re-exported here. Each concrete distribution lives in a subgroup folder
//! (`symmetric/`, `positive/`, `sampling/`, `discrete/`) and implements these
//! traits for its parameter struct, keeping the family uniform.
//!
//! The math is validated against committed `scipy.stats` golden fixtures by the
//! `distributions_equiv` integration suite within the documented tolerances
//! (pdf/cdf/ppf abs ≤ 1e-10, rel ≤ 1e-9 in tails; moments rel ≤ 1e-12).
//!
//! # Examples
//!
//! Build a distribution from its parameter struct and evaluate it through the
//! behaviour traits. Here the standard normal `N(0, 1)`: its density peaks at
//! `1/√(2π) ≈ 0.398_942` and its CDF is `0.5` at the mean.
//!
//! ```
//! use stats_claw::distributions::{Cdf, Moments, NormalDistribution, Pdf, Quantile};
//!
//! let n = NormalDistribution {
//! mean: 0.0,
//! standard_deviation: 1.0,
//! ..Default::default()
//! };
//!
//! assert!((n.pdf(0.0) - 0.398_942_280_401_432_7).abs() < 1e-12);
//! assert!((n.cdf(0.0) - 0.5).abs() < 1e-12);
//! assert!((n.quantile(0.5) - 0.0).abs() < 1e-9);
//! assert_eq!(n.mean(), Some(0.0));
//! assert_eq!(n.variance(), Some(1.0));
//! ```
use crateSplitMix64;
pub use *;
/// Continuous probability density at a point.
/// Discrete probability mass at an integer support point.
/// Cumulative distribution function.
/// Log-space cumulative and survival functions, for extreme-tail probabilities
/// that underflow to `0.0` (or saturate to `1.0`) in linear space.
///
/// Mirrors `scipy.stats.<dist>.logcdf` / `logsf`. The deep tail of a continuous
/// null distribution — where a statistical test's p-value lives — is exactly
/// where the linear [`Cdf`] loses all precision (`1 - cdf(x)` rounds to `0.0`
/// once `cdf(x) ≥ 1 - 2⁻⁵³`); these log-space evaluations stay finite and
/// accurate there, so a test can report an accurate log p-value.
/// Inverse cumulative distribution function (quantile / percent-point).
/// First two moments, reporting `None` where the moment is undefined (matching
/// scipy's NaN for e.g. Cauchy or the T distribution with low degrees of
/// freedom).
/// Draws a single variate from a seeded, reproducible RNG.
/// Generic inverse-CDF via bracketed bisection, for distributions whose quantile
/// has no closed form.
///
/// The bracket `[lo, hi]` must contain the target quantile and `cdf` must be
/// monotone non-decreasing on it. Two hundred halvings drive the residual well
/// below the round-trip tolerance for any double-precision bracket.
///
/// # Arguments
///
/// * `p` — target probability; `p ≤ 0` returns `lo`, `p ≥ 1` returns `hi`.
/// * `lo` — lower bracket bound (a value with `cdf(lo) ≤ p`).
/// * `hi` — upper bracket bound (a value with `cdf(hi) ≥ p`).
/// * `cdf` — the monotone CDF to invert.
///
/// # Returns
///
/// The bracket midpoint after convergence — an `x` with `cdf(x) ≈ p`.
pub
/// Converts a small non-negative count to `f64` losslessly by domain.
///
/// Distribution parameters that arrive as integers (degrees of freedom, trial
/// counts, support indices) are far below `i32::MAX`, so routing through
/// `i32::try_from` then the lossless `f64::from` is exact and avoids the banned
/// `as` cast. Values outside `i32` range saturate to `i32::MAX`/`MIN`, which the
/// supported parameter domains never reach.
///
/// # Arguments
///
/// * `n` — an integer parameter (e.g. degrees of freedom or trial count).
///
/// # Returns
///
/// `n` as an `f64`.
pub