@@ -6,18 +6,32 @@ The mode is the most frequently occurring value on the list.
66
77Reference: https://www.britannica.com/science/mean-median-and-mode
88
9- This program approximates the mean, median and mode of a finite sequence.
9+ There is also the geometric mean, often used in finance, which is much more suited for rates and other multiplicative
10+ relationships. The geometric mean is the Nth root of the product of a finite sequence of numbers.
11+
12+ This program approximates the mean, geometric mean, median and mode of a finite sequence.
1013Note: Floats sequences are not allowed for `mode` function.
1114" ]
1215use std:: collections:: HashMap ;
1316use std:: collections:: HashSet ;
1417
15- use num_traits:: Num ;
18+ use num_traits:: { Num , FromPrimitive , ToPrimitive , One } ;
1619
1720fn sum < T : Num + Copy > ( sequence : Vec < T > ) -> T {
1821 sequence. iter ( ) . fold ( T :: zero ( ) , |acc, x| acc + * x)
1922}
2023
24+ fn product < T : Num + Copy + One + FromPrimitive + ToPrimitive > ( sequence : & Vec < T > ) -> Option < f64 > {
25+ if sequence. is_empty ( ) {
26+ None
27+ } else {
28+ sequence. iter ( )
29+ . copied ( )
30+ . fold ( T :: one ( ) , |acc, x| acc * x)
31+ . to_f64 ( )
32+ }
33+ }
34+
2135/// # Argument
2236///
2337/// * `sequence` - A vector of numbers.
@@ -34,6 +48,22 @@ fn mean_of_two<T: Num + Copy>(a: T, b: T) -> T {
3448 ( a + b) / ( T :: one ( ) + T :: one ( ) )
3549}
3650
51+
52+ /// # Argument
53+ ///
54+ /// * `sequence` - A vector of numbers.
55+ /// Returns geometric mean of `sequence`.
56+ pub fn geometric_mean < T : Num + Copy + One + FromPrimitive + ToPrimitive > ( sequence : & Vec < T > ) -> Option < f64 > {
57+ if sequence. is_empty ( ) {
58+ return None ;
59+ }
60+ if sequence. iter ( ) . any ( |& x| x. to_f64 ( ) <= Some ( 0.0 ) ) {
61+ return None ;
62+ }
63+ let product_result = product ( sequence) ?;
64+ Some ( product_result. powf ( 1.0 / sequence. len ( ) as f64 ) )
65+ }
66+
3767/// # Argument
3868///
3969/// * `sequence` - A vector of numbers.
@@ -119,4 +149,62 @@ mod test {
119149 assert ! ( mean( Vec :: <f64 >:: new( ) ) . is_none( ) ) ;
120150 assert ! ( mean( Vec :: <i32 >:: new( ) ) . is_none( ) ) ;
121151 }
122- }
152+
153+ // Tests for product function
154+ // Empty Product is empty
155+ #[ test]
156+ fn test_product_empty ( ) {
157+ let sequence: Vec < i32 > = vec ! [ ] ;
158+ let result = product ( & sequence) ;
159+ assert_eq ! ( result, None ) ;
160+ }
161+
162+ // Product of a single value is the value
163+ #[ test]
164+ fn test_product_single_element ( ) {
165+ let sequence = vec ! [ 10 ] ;
166+ let result = product ( & sequence) ;
167+ assert_eq ! ( result, Some ( 10.0 ) ) ;
168+ }
169+ // Product generic test
170+ #[ test]
171+ fn test_product_floats ( ) {
172+ let sequence = vec ! [ 1.5 , 2.0 , 4.0 ] ;
173+ let result = product ( & sequence) ;
174+ assert_eq ! ( result, Some ( 12.0 ) ) ;
175+ }
176+
177+ // Tests for geometric mean function
178+ // Empty sequence returns nothing
179+ #[ test]
180+ fn test_geometric_mean_empty ( ) {
181+ let sequence: Vec < f64 > = vec ! [ ] ;
182+ let result = geometric_mean ( & sequence) ;
183+ assert_eq ! ( result, None ) ;
184+ }
185+
186+ // Geometric mean of a single value is the value itself.
187+ #[ test]
188+ fn test_geometric_mean_single_element ( ) {
189+ let sequence = vec ! [ 5.0 ] ;
190+ let result = geometric_mean ( & sequence) ;
191+ assert_eq ! ( result, Some ( 5.0 ) ) ;
192+ }
193+
194+ // Geometric means are not defined for negative values
195+ #[ test]
196+ fn test_geometric_mean_negative ( ) {
197+ let sequence = vec ! [ 1.0 , -3.0 , 2.0 ] ;
198+ let result = geometric_mean ( & sequence) ;
199+ assert_eq ! ( result, None ) ;
200+ }
201+
202+ // Geometric mean generic test
203+ #[ test]
204+ fn test_geometric_mean_floats ( ) {
205+ let sequence = vec ! [ 0.5 , 0.5 , 0.3 , 0.2 ] ;
206+ let result = geometric_mean ( & sequence) ;
207+ assert_eq ! ( result, Some ( 0.34996355115805833 ) ) ;
208+ }
209+
210+ }
0 commit comments