From f191380a15c586e587facb9110c0af3e8cd44845 Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Sun, 2 Dec 2018 14:37:58 +0000 Subject: [PATCH 01/10] New module --- src/summary_statistics/mod.rs | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/summary_statistics/mod.rs diff --git a/src/summary_statistics/mod.rs b/src/summary_statistics/mod.rs new file mode 100644 index 00000000..50d66a63 --- /dev/null +++ b/src/summary_statistics/mod.rs @@ -0,0 +1 @@ +//! Summary statistics (e.g. mean, variance, etc.). From 3354d9042419c3f3de50c93caef9549025924d7a Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Sat, 5 Jan 2019 16:13:41 +0000 Subject: [PATCH 02/10] First implementation of mean and harmonic_mean --- src/lib.rs | 3 +- src/summary_statistics/means.rs | 70 +++++++++++++++++++++++++++++++++ src/summary_statistics/mod.rs | 1 + 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/summary_statistics/means.rs diff --git a/src/lib.rs b/src/lib.rs index 4a974d2d..f14124c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,4 +48,5 @@ mod maybe_nan; mod quantile; mod sort; mod correlation; -pub mod histogram; \ No newline at end of file +pub mod histogram; +pub mod summary_statistics; \ No newline at end of file diff --git a/src/summary_statistics/means.rs b/src/summary_statistics/means.rs new file mode 100644 index 00000000..c3fc1c1c --- /dev/null +++ b/src/summary_statistics/means.rs @@ -0,0 +1,70 @@ +use ndarray::{Data, Dimension, ArrayBase}; +use std::ops::{Add, Div}; +use num_traits::{FromPrimitive, Float, Zero}; + + +/// Extension trait for `ArrayBase` providing methods +/// to compute several summary statistics (e.g. mean, variance, etc.). +pub trait SummaryStatisticsExt + where + S: Data, + D: Dimension, +{ + fn mean(&self) -> A + where + A: Clone + FromPrimitive + Add + Div + Zero; + + fn harmonic_mean(&self) -> A + where + A: Float + FromPrimitive; +} + + +impl SummaryStatisticsExt for ArrayBase +where + S: Data, + D: Dimension, +{ + fn mean(&self) -> A + where + A: Clone + FromPrimitive + Add + Div + Zero + { + let n_elements = A::from_usize(self.len()) + .expect("Converting number of elements to `A` must not fail."); + self.sum() / n_elements + } + + fn harmonic_mean(&self) -> A + where + A: Float + FromPrimitive, + { + self.map(|x| x.recip()).mean().recip() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::f64; + use noisy_float::types::N64; + use ndarray::Array1; + + #[test] + fn test_mean_with_nan_values() { + let a = array![f64::NAN, 1.]; + assert!(a.mean().is_nan()); + } + + #[test] + fn test_mean_with_empty_array_of_floats() { + let a: Array1 = array![]; + assert!(a.mean().is_nan()); + } + + #[test] + #[should_panic] // This looks highly undesirable + fn test_mean_with_empty_array_of_noisy_floats() { + let a: Array1 = array![]; + assert!(a.mean().is_nan()); + } +} diff --git a/src/summary_statistics/mod.rs b/src/summary_statistics/mod.rs index 50d66a63..5446fece 100644 --- a/src/summary_statistics/mod.rs +++ b/src/summary_statistics/mod.rs @@ -1 +1,2 @@ //! Summary statistics (e.g. mean, variance, etc.). +pub mod means; \ No newline at end of file From 30fa4cf6ec7f6b0dc57a5698ea541d71c0690b90 Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Sat, 5 Jan 2019 16:25:24 +0000 Subject: [PATCH 03/10] Return a Result instead of panicking --- src/summary_statistics/means.rs | 43 ++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/summary_statistics/means.rs b/src/summary_statistics/means.rs index c3fc1c1c..5973fb16 100644 --- a/src/summary_statistics/means.rs +++ b/src/summary_statistics/means.rs @@ -1,6 +1,7 @@ use ndarray::{Data, Dimension, ArrayBase}; -use std::ops::{Add, Div}; use num_traits::{FromPrimitive, Float, Zero}; +use std::result::Result; +use std::ops::{Add, Div}; /// Extension trait for `ArrayBase` providing methods @@ -10,13 +11,13 @@ pub trait SummaryStatisticsExt S: Data, D: Dimension, { - fn mean(&self) -> A + fn mean(&self) -> Result where - A: Clone + FromPrimitive + Add + Div + Zero; + A: Clone + FromPrimitive + Add + Div + PartialEq + Zero; - fn harmonic_mean(&self) -> A + fn harmonic_mean(&self) -> Result where - A: Float + FromPrimitive; + A: Float + FromPrimitive + PartialEq; } @@ -25,20 +26,29 @@ where S: Data, D: Dimension, { - fn mean(&self) -> A + fn mean(&self) -> Result where - A: Clone + FromPrimitive + Add + Div + Zero + A: Clone + FromPrimitive + Add + Div + PartialEq + Zero { - let n_elements = A::from_usize(self.len()) - .expect("Converting number of elements to `A` must not fail."); - self.sum() / n_elements + let n_elements = self.len(); + if n_elements == 0 { + Err("The mean of an empty array is not defined.") + } else { + let n_elements = A::from_usize(n_elements) + .expect("Converting number of elements to `A` must not fail."); + Ok(self.sum() / n_elements) + } } - fn harmonic_mean(&self) -> A + fn harmonic_mean(&self) -> Result where - A: Float + FromPrimitive, + A: Float + FromPrimitive + PartialEq, { - self.map(|x| x.recip()).mean().recip() + if self.len() == 0 { + Err("The harmonic mean of an empty array is not defined.") + } else { + Ok(self.map(|x| x.recip()).mean()?.recip()) + } } } @@ -52,19 +62,18 @@ mod tests { #[test] fn test_mean_with_nan_values() { let a = array![f64::NAN, 1.]; - assert!(a.mean().is_nan()); + assert!(a.mean().unwrap().is_nan()); } #[test] fn test_mean_with_empty_array_of_floats() { let a: Array1 = array![]; - assert!(a.mean().is_nan()); + assert!(a.mean().is_err()); } #[test] - #[should_panic] // This looks highly undesirable fn test_mean_with_empty_array_of_noisy_floats() { let a: Array1 = array![]; - assert!(a.mean().is_nan()); + assert!(a.mean().is_err()); } } From 8a38fbe842b2c6d788d323507fb75d8e2cb7d3be Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Sat, 5 Jan 2019 16:44:59 +0000 Subject: [PATCH 04/10] Added documentation --- src/summary_statistics/means.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/summary_statistics/means.rs b/src/summary_statistics/means.rs index 5973fb16..a277492e 100644 --- a/src/summary_statistics/means.rs +++ b/src/summary_statistics/means.rs @@ -11,10 +11,32 @@ pub trait SummaryStatisticsExt S: Data, D: Dimension, { + /// Returns the [`arithmetic mean`] x̅ of all elements in the array: + /// + /// ```text + /// 1 n + /// x̅ = ― ∑ xᵢ + /// n i=1 + /// ``` + /// + /// If the array is empty, an `Err` is returned. + /// + /// [`arithmetic mean`]: https://en.wikipedia.org/wiki/Arithmetic_mean fn mean(&self) -> Result where A: Clone + FromPrimitive + Add + Div + PartialEq + Zero; + /// Returns the [`harmonic mean`] `HM(X)` of all elements in the array: + /// + /// ```text + /// n + /// HM(X) = n ( ∑ xᵢ⁻¹)⁻¹ + /// i=1 + /// ``` + /// + /// If the array is empty, an `Err` is returned. + /// + /// [`harmonic mean`]: https://en.wikipedia.org/wiki/Harmonic_mean fn harmonic_mean(&self) -> Result where A: Float + FromPrimitive + PartialEq; From 94929dc100dc7f43bfaf95d6e622deb480349a6d Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Sat, 5 Jan 2019 17:01:20 +0000 Subject: [PATCH 05/10] Improved test suite --- Cargo.toml | 1 + src/lib.rs | 3 +++ src/summary_statistics/means.rs | 32 +++++++++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d3a993c5..57795ce8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,4 @@ itertools = { version = "0.7.0", default-features = false } [dev-dependencies] quickcheck = "0.7" ndarray-rand = "0.9" +approx = "0.3" diff --git a/src/lib.rs b/src/lib.rs index f14124c7..a04250c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,9 @@ extern crate ndarray_rand; #[cfg(test)] #[macro_use(quickcheck)] extern crate quickcheck; +#[cfg(test)] +#[macro_use(abs_diff_eq)] +extern crate approx; pub use maybe_nan::{MaybeNan, MaybeNanExt}; pub use quantile::{interpolate, QuantileExt, Quantile1dExt}; diff --git a/src/summary_statistics/means.rs b/src/summary_statistics/means.rs index a277492e..75175e31 100644 --- a/src/summary_statistics/means.rs +++ b/src/summary_statistics/means.rs @@ -82,20 +82,46 @@ mod tests { use ndarray::Array1; #[test] - fn test_mean_with_nan_values() { + fn test_means_with_nan_values() { let a = array![f64::NAN, 1.]; assert!(a.mean().unwrap().is_nan()); + assert!(a.harmonic_mean().unwrap().is_nan()); } #[test] - fn test_mean_with_empty_array_of_floats() { + fn test_means_with_empty_array_of_floats() { let a: Array1 = array![]; assert!(a.mean().is_err()); + assert!(a.harmonic_mean().is_err()); } #[test] - fn test_mean_with_empty_array_of_noisy_floats() { + fn test_means_with_empty_array_of_noisy_floats() { let a: Array1 = array![]; assert!(a.mean().is_err()); + assert!(a.harmonic_mean().is_err()); + } + + #[test] + fn test_means_with_array_of_floats() { + let a: Array1 = array![ + 0.99889651, 0.0150731 , 0.28492482, 0.83819218, 0.48413156, + 0.80710412, 0.41762936, 0.22879429, 0.43997224, 0.23831807, + 0.02416466, 0.6269962 , 0.47420614, 0.56275487, 0.78995021, + 0.16060581, 0.64635041, 0.34876609, 0.78543249, 0.19938356, + 0.34429457, 0.88072369, 0.17638164, 0.60819363, 0.250392 , + 0.69912532, 0.78855523, 0.79140914, 0.85084218, 0.31839879, + 0.63381769, 0.22421048, 0.70760302, 0.99216018, 0.80199153, + 0.19239188, 0.61356023, 0.31505352, 0.06120481, 0.66417377, + 0.63608897, 0.84959691, 0.43599069, 0.77867775, 0.88267754, + 0.83003623, 0.67016118, 0.67547638, 0.65220036, 0.68043427 + ]; + // Computed using NumPy + let expected_mean = 0.5475494059146699; + // Computed using SciPy + let expected_harmonic_mean = 0.21790094950226022; + + abs_diff_eq!(a.mean().unwrap(), expected_mean, epsilon = f64::EPSILON); + abs_diff_eq!(a.harmonic_mean().unwrap(), expected_harmonic_mean, epsilon = f64::EPSILON); } } From 169931f77b8314b1bdc43cd8394d29cccf938b1a Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Sat, 5 Jan 2019 18:52:36 +0000 Subject: [PATCH 06/10] Implemented geometric mean --- src/summary_statistics/means.rs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/summary_statistics/means.rs b/src/summary_statistics/means.rs index 75175e31..cf71edbb 100644 --- a/src/summary_statistics/means.rs +++ b/src/summary_statistics/means.rs @@ -40,8 +40,22 @@ pub trait SummaryStatisticsExt fn harmonic_mean(&self) -> Result where A: Float + FromPrimitive + PartialEq; -} + /// Returns the [`geometric mean`] `GM(X)` of all elements in the array: + /// + /// ```text + /// n + /// GM(X) = ( Π xᵢ)^(1/n) + /// i=1 + /// ``` + /// + /// If the array is empty, an `Err` is returned. + /// + /// [`geometric mean`]: https://en.wikipedia.org/wiki/Geometric_mean + fn geometric_mean(&self) -> Result + where + A: Float + FromPrimitive + PartialEq; +} impl SummaryStatisticsExt for ArrayBase where @@ -72,6 +86,17 @@ where Ok(self.map(|x| x.recip()).mean()?.recip()) } } + + fn geometric_mean(&self) -> Result + where + A: Float + FromPrimitive + PartialEq, + { + if self.len() == 0 { + Err("The geometric mean of an empty array is not defined.") + } else { + Ok(self.map(|x| x.ln()).mean()?.exp()) + } + } } #[cfg(test)] @@ -86,6 +111,7 @@ mod tests { let a = array![f64::NAN, 1.]; assert!(a.mean().unwrap().is_nan()); assert!(a.harmonic_mean().unwrap().is_nan()); + assert!(a.geometric_mean().unwrap().is_nan()); } #[test] @@ -93,6 +119,7 @@ mod tests { let a: Array1 = array![]; assert!(a.mean().is_err()); assert!(a.harmonic_mean().is_err()); + assert!(a.geometric_mean().is_err()); } #[test] @@ -100,6 +127,7 @@ mod tests { let a: Array1 = array![]; assert!(a.mean().is_err()); assert!(a.harmonic_mean().is_err()); + assert!(a.geometric_mean().is_err()); } #[test] @@ -120,8 +148,11 @@ mod tests { let expected_mean = 0.5475494059146699; // Computed using SciPy let expected_harmonic_mean = 0.21790094950226022; + // Computed using SciPy + let expected_geometric_mean = 0.4345897639796527; abs_diff_eq!(a.mean().unwrap(), expected_mean, epsilon = f64::EPSILON); abs_diff_eq!(a.harmonic_mean().unwrap(), expected_harmonic_mean, epsilon = f64::EPSILON); + abs_diff_eq!(a.geometric_mean().unwrap(), expected_geometric_mean, epsilon = f64::EPSILON); } } From 46b0ea4f5b1b958579685fad47abfbc63541f363 Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Sat, 5 Jan 2019 19:02:57 +0000 Subject: [PATCH 07/10] Reorganized to only expose the extension trait, instead of the whole submodule tree --- src/lib.rs | 3 +- src/summary_statistics/means.rs | 54 +---------------------------- src/summary_statistics/mod.rs | 61 ++++++++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a04250c2..fad9cef8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,10 +46,11 @@ pub use quantile::{interpolate, QuantileExt, Quantile1dExt}; pub use sort::Sort1dExt; pub use correlation::CorrelationExt; pub use histogram::HistogramExt; +pub use summary_statistics::SummaryStatisticsExt; mod maybe_nan; mod quantile; mod sort; mod correlation; +mod summary_statistics; pub mod histogram; -pub mod summary_statistics; \ No newline at end of file diff --git a/src/summary_statistics/means.rs b/src/summary_statistics/means.rs index cf71edbb..36d6ea72 100644 --- a/src/summary_statistics/means.rs +++ b/src/summary_statistics/means.rs @@ -2,61 +2,9 @@ use ndarray::{Data, Dimension, ArrayBase}; use num_traits::{FromPrimitive, Float, Zero}; use std::result::Result; use std::ops::{Add, Div}; +use super::SummaryStatisticsExt; -/// Extension trait for `ArrayBase` providing methods -/// to compute several summary statistics (e.g. mean, variance, etc.). -pub trait SummaryStatisticsExt - where - S: Data, - D: Dimension, -{ - /// Returns the [`arithmetic mean`] x̅ of all elements in the array: - /// - /// ```text - /// 1 n - /// x̅ = ― ∑ xᵢ - /// n i=1 - /// ``` - /// - /// If the array is empty, an `Err` is returned. - /// - /// [`arithmetic mean`]: https://en.wikipedia.org/wiki/Arithmetic_mean - fn mean(&self) -> Result - where - A: Clone + FromPrimitive + Add + Div + PartialEq + Zero; - - /// Returns the [`harmonic mean`] `HM(X)` of all elements in the array: - /// - /// ```text - /// n - /// HM(X) = n ( ∑ xᵢ⁻¹)⁻¹ - /// i=1 - /// ``` - /// - /// If the array is empty, an `Err` is returned. - /// - /// [`harmonic mean`]: https://en.wikipedia.org/wiki/Harmonic_mean - fn harmonic_mean(&self) -> Result - where - A: Float + FromPrimitive + PartialEq; - - /// Returns the [`geometric mean`] `GM(X)` of all elements in the array: - /// - /// ```text - /// n - /// GM(X) = ( Π xᵢ)^(1/n) - /// i=1 - /// ``` - /// - /// If the array is empty, an `Err` is returned. - /// - /// [`geometric mean`]: https://en.wikipedia.org/wiki/Geometric_mean - fn geometric_mean(&self) -> Result - where - A: Float + FromPrimitive + PartialEq; -} - impl SummaryStatisticsExt for ArrayBase where S: Data, diff --git a/src/summary_statistics/mod.rs b/src/summary_statistics/mod.rs index 5446fece..fa78f3f7 100644 --- a/src/summary_statistics/mod.rs +++ b/src/summary_statistics/mod.rs @@ -1,2 +1,61 @@ //! Summary statistics (e.g. mean, variance, etc.). -pub mod means; \ No newline at end of file +use ndarray::{Data, Dimension}; +use num_traits::{FromPrimitive, Float, Zero}; +use std::result::Result; +use std::ops::{Add, Div}; + +/// Extension trait for `ArrayBase` providing methods +/// to compute several summary statistics (e.g. mean, variance, etc.). +pub trait SummaryStatisticsExt + where + S: Data, + D: Dimension, +{ + /// Returns the [`arithmetic mean`] x̅ of all elements in the array: + /// + /// ```text + /// 1 n + /// x̅ = ― ∑ xᵢ + /// n i=1 + /// ``` + /// + /// If the array is empty, an `Err` is returned. + /// + /// [`arithmetic mean`]: https://en.wikipedia.org/wiki/Arithmetic_mean + fn mean(&self) -> Result + where + A: Clone + FromPrimitive + Add + Div + PartialEq + Zero; + + /// Returns the [`harmonic mean`] `HM(X)` of all elements in the array: + /// + /// ```text + /// n + /// HM(X) = n ( ∑ xᵢ⁻¹)⁻¹ + /// i=1 + /// ``` + /// + /// If the array is empty, an `Err` is returned. + /// + /// [`harmonic mean`]: https://en.wikipedia.org/wiki/Harmonic_mean + fn harmonic_mean(&self) -> Result + where + A: Float + FromPrimitive + PartialEq; + + /// Returns the [`geometric mean`] `GM(X)` of all elements in the array: + /// + /// ```text + /// n + /// GM(X) = ( Π xᵢ)^(1/n) + /// i=1 + /// ``` + /// + /// If the array is empty, an `Err` is returned. + /// + /// [`geometric mean`]: https://en.wikipedia.org/wiki/Geometric_mean + fn geometric_mean(&self) -> Result + where + A: Float + FromPrimitive + PartialEq; +} + +mod means; + From d661ac0c9f63000d4a653f00e8f3df0f16fa474b Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Wed, 9 Jan 2019 08:30:13 +0000 Subject: [PATCH 08/10] Implement review comments --- src/summary_statistics/means.rs | 43 +++++++++++++-------------------- src/summary_statistics/mod.rs | 21 ++++++++++------ 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/summary_statistics/means.rs b/src/summary_statistics/means.rs index 36d6ea72..dd0d5337 100644 --- a/src/summary_statistics/means.rs +++ b/src/summary_statistics/means.rs @@ -1,6 +1,5 @@ use ndarray::{Data, Dimension, ArrayBase}; use num_traits::{FromPrimitive, Float, Zero}; -use std::result::Result; use std::ops::{Add, Div}; use super::SummaryStatisticsExt; @@ -10,46 +9,38 @@ where S: Data, D: Dimension, { - fn mean(&self) -> Result + fn mean(&self) -> Option where - A: Clone + FromPrimitive + Add + Div + PartialEq + Zero + A: Clone + FromPrimitive + Add + Div + Zero { let n_elements = self.len(); if n_elements == 0 { - Err("The mean of an empty array is not defined.") + None } else { let n_elements = A::from_usize(n_elements) .expect("Converting number of elements to `A` must not fail."); - Ok(self.sum() / n_elements) + Some(self.sum() / n_elements) } } - fn harmonic_mean(&self) -> Result + fn harmonic_mean(&self) -> Option where - A: Float + FromPrimitive + PartialEq, + A: Float + FromPrimitive, { - if self.len() == 0 { - Err("The harmonic mean of an empty array is not defined.") - } else { - Ok(self.map(|x| x.recip()).mean()?.recip()) - } + self.map(|x| x.recip()).mean().map(|x| x.recip()) } - fn geometric_mean(&self) -> Result + fn geometric_mean(&self) -> Option where - A: Float + FromPrimitive + PartialEq, + A: Float + FromPrimitive, { - if self.len() == 0 { - Err("The geometric mean of an empty array is not defined.") - } else { - Ok(self.map(|x| x.ln()).mean()?.exp()) - } + self.map(|x| x.ln()).mean().map(|x| x.exp()) } } #[cfg(test)] mod tests { - use super::*; + use super::SummaryStatisticsExt; use std::f64; use noisy_float::types::N64; use ndarray::Array1; @@ -65,17 +56,17 @@ mod tests { #[test] fn test_means_with_empty_array_of_floats() { let a: Array1 = array![]; - assert!(a.mean().is_err()); - assert!(a.harmonic_mean().is_err()); - assert!(a.geometric_mean().is_err()); + assert!(a.mean().is_none()); + assert!(a.harmonic_mean().is_none()); + assert!(a.geometric_mean().is_none()); } #[test] fn test_means_with_empty_array_of_noisy_floats() { let a: Array1 = array![]; - assert!(a.mean().is_err()); - assert!(a.harmonic_mean().is_err()); - assert!(a.geometric_mean().is_err()); + assert!(a.mean().is_none()); + assert!(a.harmonic_mean().is_none()); + assert!(a.geometric_mean().is_none()); } #[test] diff --git a/src/summary_statistics/mod.rs b/src/summary_statistics/mod.rs index fa78f3f7..536a5075 100644 --- a/src/summary_statistics/mod.rs +++ b/src/summary_statistics/mod.rs @@ -1,7 +1,6 @@ //! Summary statistics (e.g. mean, variance, etc.). use ndarray::{Data, Dimension}; use num_traits::{FromPrimitive, Float, Zero}; -use std::result::Result; use std::ops::{Add, Div}; /// Extension trait for `ArrayBase` providing methods @@ -21,10 +20,12 @@ pub trait SummaryStatisticsExt /// /// If the array is empty, an `Err` is returned. /// + /// **Panics** if `A::from_usize()` fails to convert the number of elements in the array. + /// /// [`arithmetic mean`]: https://en.wikipedia.org/wiki/Arithmetic_mean - fn mean(&self) -> Result + fn mean(&self) -> Option where - A: Clone + FromPrimitive + Add + Div + PartialEq + Zero; + A: Clone + FromPrimitive + Add + Div + Zero; /// Returns the [`harmonic mean`] `HM(X)` of all elements in the array: /// @@ -36,10 +37,12 @@ pub trait SummaryStatisticsExt /// /// If the array is empty, an `Err` is returned. /// + /// **Panics** if `A::from_usize()` fails to convert the number of elements in the array. + /// /// [`harmonic mean`]: https://en.wikipedia.org/wiki/Harmonic_mean - fn harmonic_mean(&self) -> Result + fn harmonic_mean(&self) -> Option where - A: Float + FromPrimitive + PartialEq; + A: Float + FromPrimitive; /// Returns the [`geometric mean`] `GM(X)` of all elements in the array: /// @@ -51,11 +54,13 @@ pub trait SummaryStatisticsExt /// /// If the array is empty, an `Err` is returned. /// + /// **Panics** if `A::from_usize()` fails to convert the number of elements in the array. + /// /// [`geometric mean`]: https://en.wikipedia.org/wiki/Geometric_mean - fn geometric_mean(&self) -> Result + fn geometric_mean(&self) -> Option where - A: Float + FromPrimitive + PartialEq; + A: Float + FromPrimitive; + } mod means; - From 9bd68240d8bd49d55d8fd69a0f177b17253204c3 Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Wed, 9 Jan 2019 08:32:26 +0000 Subject: [PATCH 09/10] Fixed documentation --- src/summary_statistics/mod.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/summary_statistics/mod.rs b/src/summary_statistics/mod.rs index 536a5075..ae05e709 100644 --- a/src/summary_statistics/mod.rs +++ b/src/summary_statistics/mod.rs @@ -18,7 +18,7 @@ pub trait SummaryStatisticsExt /// n i=1 /// ``` /// - /// If the array is empty, an `Err` is returned. + /// If the array is empty, `None` is returned. /// /// **Panics** if `A::from_usize()` fails to convert the number of elements in the array. /// @@ -30,12 +30,12 @@ pub trait SummaryStatisticsExt /// Returns the [`harmonic mean`] `HM(X)` of all elements in the array: /// /// ```text - /// n - /// HM(X) = n ( ∑ xᵢ⁻¹)⁻¹ - /// i=1 + /// ⎛ n ⎞⁻¹ + /// HM(X) = n ⎜ ∑ xᵢ⁻¹⎟ + /// ⎝i=1 ⎠ /// ``` /// - /// If the array is empty, an `Err` is returned. + /// If the array is empty, `None` is returned. /// /// **Panics** if `A::from_usize()` fails to convert the number of elements in the array. /// @@ -47,12 +47,12 @@ pub trait SummaryStatisticsExt /// Returns the [`geometric mean`] `GM(X)` of all elements in the array: /// /// ```text - /// n - /// GM(X) = ( Π xᵢ)^(1/n) - /// i=1 + /// ⎛ n ⎞¹⁄ₙ + /// GM(X) = ⎜ ∏ xᵢ⎟ + /// ⎝i=1 ⎠ /// ``` /// - /// If the array is empty, an `Err` is returned. + /// If the array is empty, `None` is returned. /// /// **Panics** if `A::from_usize()` fails to convert the number of elements in the array. /// From 291597ba079d9af32cbac6add88037279fee70db Mon Sep 17 00:00:00 2001 From: LukeMathWalker Date: Wed, 9 Jan 2019 09:01:49 +0000 Subject: [PATCH 10/10] Use Rust 1.31 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 666dc16b..c71c2f1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ addons: - libssl-dev cache: cargo rust: - - 1.30.0 + - 1.31.0 - stable - beta - nightly