Skip to content

Commit 3298cd5

Browse files
LukeMathWalkerjturner314
authored andcommitted
Add mean method
1 parent c569f75 commit 3298cd5

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ serde = { version = "1.0", optional = true }
4747
defmac = "0.2"
4848
quickcheck = { version = "0.7.2", default-features = false }
4949
rawpointer = "0.1"
50+
approx = "0.3"
5051

5152
[features]
5253
# Enable blas usage

src/numeric/impl_numeric.rs

+27
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,33 @@ impl<A, S, D> ArrayBase<S, D>
4646
sum
4747
}
4848

49+
/// Returns the [arithmetic mean] x̅ of all elements in the array:
50+
///
51+
/// ```text
52+
/// 1 n
53+
/// x̅ = ― ∑ xᵢ
54+
/// n i=1
55+
/// ```
56+
///
57+
/// If the array is empty, `None` is returned.
58+
///
59+
/// **Panics** if `A::from_usize()` fails to convert the number of elements in the array.
60+
///
61+
/// [arithmetic mean]: https://en.wikipedia.org/wiki/Arithmetic_mean
62+
pub fn mean(&self) -> Option<A>
63+
where
64+
A: Clone + FromPrimitive + Add<Output=A> + Div<Output=A> + Zero
65+
{
66+
let n_elements = self.len();
67+
if n_elements == 0 {
68+
None
69+
} else {
70+
let n_elements = A::from_usize(n_elements)
71+
.expect("Converting number of elements to `A` must not fail.");
72+
Some(self.sum() / n_elements)
73+
}
74+
}
75+
4976
/// Return the sum of all elements in the array.
5077
///
5178
/// *This method has been renamed to `.sum()` and will be deprecated in the

tests/numeric.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
extern crate approx;
2+
use std::f64;
3+
use ndarray::{Array1, array};
4+
use approx::abs_diff_eq;
5+
6+
#[test]
7+
fn test_mean_with_nan_values() {
8+
let a = array![f64::NAN, 1.];
9+
assert!(a.mean().unwrap().is_nan());
10+
}
11+
12+
#[test]
13+
fn test_mean_with_empty_array_of_floats() {
14+
let a: Array1<f64> = array![];
15+
assert!(a.mean().is_none());
16+
}
17+
18+
#[test]
19+
fn test_mean_with_array_of_floats() {
20+
let a: Array1<f64> = array![
21+
0.99889651, 0.0150731 , 0.28492482, 0.83819218, 0.48413156,
22+
0.80710412, 0.41762936, 0.22879429, 0.43997224, 0.23831807,
23+
0.02416466, 0.6269962 , 0.47420614, 0.56275487, 0.78995021,
24+
0.16060581, 0.64635041, 0.34876609, 0.78543249, 0.19938356,
25+
0.34429457, 0.88072369, 0.17638164, 0.60819363, 0.250392 ,
26+
0.69912532, 0.78855523, 0.79140914, 0.85084218, 0.31839879,
27+
0.63381769, 0.22421048, 0.70760302, 0.99216018, 0.80199153,
28+
0.19239188, 0.61356023, 0.31505352, 0.06120481, 0.66417377,
29+
0.63608897, 0.84959691, 0.43599069, 0.77867775, 0.88267754,
30+
0.83003623, 0.67016118, 0.67547638, 0.65220036, 0.68043427
31+
];
32+
// Computed using NumPy
33+
let expected_mean = 0.5475494059146699;
34+
abs_diff_eq!(a.mean().unwrap(), expected_mean, epsilon = f64::EPSILON);
35+
}

0 commit comments

Comments
 (0)