statrs/statistics/
statistics.rs

1/// Enumeration of possible tie-breaking strategies
2/// when computing ranks
3#[derive(Debug, Copy, Clone)]
4pub enum RankTieBreaker {
5    /// Replaces ties with their mean
6    Average,
7    /// Replace ties with their minimum
8    Min,
9    /// Replace ties with their maximum
10    Max,
11    /// Permutation with increasing values at each index of ties
12    First,
13}
14
15/// The `Statistics` trait provides a host of statistical utilities for
16/// analyzing
17/// data sets
18pub trait Statistics<T> {
19    /// Returns the minimum value in the data
20    ///
21    /// # Remarks
22    ///
23    /// Returns `f64::NAN` if data is empty or an entry is `f64::NAN`
24    ///
25    /// # Examples
26    ///
27    /// ```
28    /// use std::f64;
29    /// use statrs::statistics::Statistics;
30    ///
31    /// let x = &[];
32    /// assert!(Statistics::min(x).is_nan());
33    ///
34    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
35    /// assert!(Statistics::min(y).is_nan());
36    ///
37    /// let z = &[0.0, 3.0, -2.0];
38    /// assert_eq!(Statistics::min(z), -2.0);
39    /// ```
40    fn min(self) -> T;
41
42    /// Returns the maximum value in the data
43    ///
44    /// # Remarks
45    ///
46    /// Returns `f64::NAN` if data is empty or an entry is `f64::NAN`
47    ///
48    /// # Examples
49    ///
50    /// ```
51    /// use std::f64;
52    /// use statrs::statistics::Statistics;
53    ///
54    /// let x = &[];
55    /// assert!(Statistics::max(x).is_nan());
56    ///
57    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
58    /// assert!(Statistics::max(y).is_nan());
59    ///
60    /// let z = &[0.0, 3.0, -2.0];
61    /// assert_eq!(Statistics::max(z), 3.0);
62    /// ```
63    fn max(self) -> T;
64
65    /// Returns the minimum absolute value in the data
66    ///
67    /// # Remarks
68    ///
69    /// Returns `f64::NAN` if data is empty or an entry is `f64::NAN`
70    ///
71    /// # Examples
72    ///
73    /// ```
74    /// use std::f64;
75    /// use statrs::statistics::Statistics;
76    ///
77    /// let x = &[];
78    /// assert!(x.abs_min().is_nan());
79    ///
80    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
81    /// assert!(y.abs_min().is_nan());
82    ///
83    /// let z = &[0.0, 3.0, -2.0];
84    /// assert_eq!(z.abs_min(), 0.0);
85    /// ```
86    fn abs_min(self) -> T;
87
88    /// Returns the maximum absolute value in the data
89    ///
90    /// # Remarks
91    ///
92    /// Returns `f64::NAN` if data is empty or an entry is `f64::NAN`
93    ///
94    /// # Examples
95    ///
96    /// ```
97    /// use std::f64;
98    /// use statrs::statistics::Statistics;
99    ///
100    /// let x = &[];
101    /// assert!(x.abs_max().is_nan());
102    ///
103    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
104    /// assert!(y.abs_max().is_nan());
105    ///
106    /// let z = &[0.0, 3.0, -2.0, -8.0];
107    /// assert_eq!(z.abs_max(), 8.0);
108    /// ```
109    fn abs_max(self) -> T;
110
111    /// Evaluates the sample mean, an estimate of the population
112    /// mean.
113    ///
114    /// # Remarks
115    ///
116    /// Returns `f64::NAN` if data is empty or an entry is `f64::NAN`
117    ///
118    /// # Examples
119    ///
120    /// ```
121    /// #[macro_use]
122    /// extern crate statrs;
123    ///
124    /// use std::f64;
125    /// use statrs::statistics::Statistics;
126    ///
127    /// # fn main() {
128    /// let x = &[];
129    /// assert!(x.mean().is_nan());
130    ///
131    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
132    /// assert!(y.mean().is_nan());
133    ///
134    /// let z = &[0.0, 3.0, -2.0];
135    /// assert_almost_eq!(z.mean(), 1.0 / 3.0, 1e-15);
136    /// # }
137    /// ```
138    fn mean(self) -> T;
139
140    /// Evaluates the geometric mean of the data
141    ///
142    /// # Remarks
143    ///
144    /// Returns `f64::NAN` if data is empty or an entry is `f64::NAN`.
145    /// Returns `f64::NAN` if an entry is less than `0`. Returns `0`
146    /// if no entry is less than `0` but there are entries equal to `0`.
147    ///
148    /// # Examples
149    ///
150    /// ```
151    /// #[macro_use]
152    /// extern crate statrs;
153    ///
154    /// use std::f64;
155    /// use statrs::statistics::Statistics;
156    ///
157    /// # fn main() {
158    /// let x = &[];
159    /// assert!(x.geometric_mean().is_nan());
160    ///
161    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
162    /// assert!(y.geometric_mean().is_nan());
163    ///
164    /// let mut z = &[0.0, 3.0, -2.0];
165    /// assert!(z.geometric_mean().is_nan());
166    ///
167    /// z = &[0.0, 3.0, 2.0];
168    /// assert_eq!(z.geometric_mean(), 0.0);
169    ///
170    /// z = &[1.0, 2.0, 3.0];
171    /// // test value from online calculator, could be more accurate
172    /// assert_almost_eq!(z.geometric_mean(), 1.81712, 1e-5);
173    /// # }
174    /// ```
175    fn geometric_mean(self) -> T;
176
177    /// Evaluates the harmonic mean of the data
178    ///
179    /// # Remarks
180    ///
181    /// Returns `f64::NAN` if data is empty or an entry is `f64::NAN`, or if
182    /// any value
183    /// in data is less than `0`. Returns `0` if there are no values less than
184    /// `0` but
185    /// there exists values equal to `0`.
186    ///
187    /// # Examples
188    ///
189    /// ```
190    /// #[macro_use]
191    /// extern crate statrs;
192    ///
193    /// use std::f64;
194    /// use statrs::statistics::Statistics;
195    ///
196    /// # fn main() {
197    /// let x = &[];
198    /// assert!(x.harmonic_mean().is_nan());
199    ///
200    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
201    /// assert!(y.harmonic_mean().is_nan());
202    ///
203    /// let mut z = &[0.0, 3.0, -2.0];
204    /// assert!(z.harmonic_mean().is_nan());
205    ///
206    /// z = &[0.0, 3.0, 2.0];
207    /// assert_eq!(z.harmonic_mean(), 0.0);
208    ///
209    /// z = &[1.0, 2.0, 3.0];
210    /// // test value from online calculator, could be more accurate
211    /// assert_almost_eq!(z.harmonic_mean(), 1.63636, 1e-5);
212    /// # }
213    /// ```
214    fn harmonic_mean(self) -> T;
215
216    /// Estimates the unbiased population variance from the provided samples
217    ///
218    /// # Remarks
219    ///
220    /// On a dataset of size `N`, `N-1` is used as a normalizer (Bessel's
221    /// correction).
222    ///
223    /// Returns `f64::NAN` if data has less than two entries or if any entry is
224    /// `f64::NAN`
225    ///
226    /// # Examples
227    ///
228    /// ```
229    /// use std::f64;
230    /// use statrs::statistics::Statistics;
231    ///
232    /// let x = &[];
233    /// assert!(x.variance().is_nan());
234    ///
235    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
236    /// assert!(y.variance().is_nan());
237    ///
238    /// let z = &[0.0, 3.0, -2.0];
239    /// assert_eq!(z.variance(), 19.0 / 3.0);
240    /// ```
241    fn variance(self) -> T;
242
243    /// Estimates the unbiased population standard deviation from the provided
244    /// samples
245    ///
246    /// # Remarks
247    ///
248    /// On a dataset of size `N`, `N-1` is used as a normalizer (Bessel's
249    /// correction).
250    ///
251    /// Returns `f64::NAN` if data has less than two entries or if any entry is
252    /// `f64::NAN`
253    ///
254    /// # Examples
255    ///
256    /// ```
257    /// use std::f64;
258    /// use statrs::statistics::Statistics;
259    ///
260    /// let x = &[];
261    /// assert!(x.std_dev().is_nan());
262    ///
263    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
264    /// assert!(y.std_dev().is_nan());
265    ///
266    /// let z = &[0.0, 3.0, -2.0];
267    /// assert_eq!(z.std_dev(), (19f64 / 3.0).sqrt());
268    /// ```
269    fn std_dev(self) -> T;
270
271    /// Evaluates the population variance from a full population.
272    ///
273    /// # Remarks
274    ///
275    /// On a dataset of size `N`, `N` is used as a normalizer and would thus
276    /// be biased if applied to a subset
277    ///
278    /// Returns `f64::NAN` if data is empty or an entry is `f64::NAN`
279    ///
280    /// # Examples
281    ///
282    /// ```
283    /// use std::f64;
284    /// use statrs::statistics::Statistics;
285    ///
286    /// let x = &[];
287    /// assert!(x.population_variance().is_nan());
288    ///
289    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
290    /// assert!(y.population_variance().is_nan());
291    ///
292    /// let z = &[0.0, 3.0, -2.0];
293    /// assert_eq!(z.population_variance(), 38.0 / 9.0);
294    /// ```
295    fn population_variance(self) -> T;
296
297    /// Evaluates the population standard deviation from a full population.
298    ///
299    /// # Remarks
300    ///
301    /// On a dataset of size `N`, `N` is used as a normalizer and would thus
302    /// be biased if applied to a subset
303    ///
304    /// Returns `f64::NAN` if data is empty or an entry is `f64::NAN`
305    ///
306    /// # Examples
307    ///
308    /// ```
309    /// use std::f64;
310    /// use statrs::statistics::Statistics;
311    ///
312    /// let x = &[];
313    /// assert!(x.population_std_dev().is_nan());
314    ///
315    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
316    /// assert!(y.population_std_dev().is_nan());
317    ///
318    /// let z = &[0.0, 3.0, -2.0];
319    /// assert_eq!(z.population_std_dev(), (38f64 / 9.0).sqrt());
320    /// ```
321    fn population_std_dev(self) -> T;
322
323    /// Estimates the unbiased population covariance between the two provided
324    /// samples
325    ///
326    /// # Remarks
327    ///
328    /// On a dataset of size `N`, `N-1` is used as a normalizer (Bessel's
329    /// correction).
330    ///
331    /// Returns `f64::NAN` if data has less than two entries or if any entry is
332    /// `f64::NAN`
333    ///
334    /// # Panics
335    ///
336    /// If the two sample containers do not contain the same number of elements
337    ///
338    /// # Examples
339    ///
340    /// ```
341    /// #[macro_use]
342    /// extern crate statrs;
343    ///
344    /// use std::f64;
345    /// use statrs::statistics::Statistics;
346    ///
347    /// # fn main() {
348    /// let x = &[];
349    /// assert!(x.covariance(&[]).is_nan());
350    ///
351    /// let y1 = &[0.0, f64::NAN, 3.0, -2.0];
352    /// let y2 = &[-5.0, 4.0, 10.0, f64::NAN];
353    /// assert!(y1.covariance(y2).is_nan());
354    ///
355    /// let z1 = &[0.0, 3.0, -2.0];
356    /// let z2 = &[-5.0, 4.0, 10.0];
357    /// assert_almost_eq!(z1.covariance(z2), -5.5, 1e-14);
358    /// # }
359    /// ```
360    fn covariance(self, other: Self) -> T;
361
362    /// Evaluates the population covariance between the two provider populations
363    ///
364    /// # Remarks
365    ///
366    /// On a dataset of size `N`, `N` is used as a normalizer and would thus be
367    /// biased if applied to a subset
368    ///
369    /// Returns `f64::NAN` if data is empty or any entry is `f64::NAN`
370    ///
371    /// # Panics
372    ///
373    /// If the two sample containers do not contain the same number of elements
374    ///
375    /// # Examples
376    ///
377    /// ```
378    /// #[macro_use]
379    /// extern crate statrs;
380    ///
381    /// use std::f64;
382    /// use statrs::statistics::Statistics;
383    ///
384    /// # fn main() {
385    /// let x = &[];
386    /// assert!(x.population_covariance(&[]).is_nan());
387    ///
388    /// let y1 = &[0.0, f64::NAN, 3.0, -2.0];
389    /// let y2 = &[-5.0, 4.0, 10.0, f64::NAN];
390    /// assert!(y1.population_covariance(y2).is_nan());
391    ///
392    /// let z1 = &[0.0, 3.0, -2.0];
393    /// let z2 = &[-5.0, 4.0, 10.0];
394    /// assert_almost_eq!(z1.population_covariance(z2), -11.0 / 3.0, 1e-14);
395    /// # }
396    /// ```
397    fn population_covariance(self, other: Self) -> T;
398
399    /// Estimates the quadratic mean (Root Mean Square) of the data
400    ///
401    /// # Remarks
402    ///
403    /// Returns `f64::NAN` if data is empty or any entry is `f64::NAN`
404    ///
405    /// # Examples
406    ///
407    /// ```
408    /// #[macro_use]
409    /// extern crate statrs;
410    ///
411    /// use std::f64;
412    /// use statrs::statistics::Statistics;
413    ///
414    /// # fn main() {
415    /// let x = &[];
416    /// assert!(x.quadratic_mean().is_nan());
417    ///
418    /// let y = &[0.0, f64::NAN, 3.0, -2.0];
419    /// assert!(y.quadratic_mean().is_nan());
420    ///
421    /// let z = &[0.0, 3.0, -2.0];
422    /// // test value from online calculator, could be more accurate
423    /// assert_almost_eq!(z.quadratic_mean(), 2.08167, 1e-5);
424    /// # }
425    /// ```
426    fn quadratic_mean(self) -> T;
427}