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}