]>
git.proxmox.com Git - proxmox-backup.git/blob - src/tools/statistics.rs
1 //! Helpers for common statistics tasks
2 use num_traits
::NumAssignRef
;
3 use num_traits
::cast
::ToPrimitive
;
5 /// Calculates the sum of a list of numbers
7 /// # use proxmox_backup::tools::statistics::sum;
8 /// # use num_traits::cast::ToPrimitive;
10 /// assert_eq!(sum(&[0,1,2,3,4,5]), 15);
11 /// assert_eq!(sum(&[-1,1,-2,2]), 0);
12 /// assert!((sum(&[0.0, 0.1,0.2]).to_f64().unwrap() - 0.3).abs() < 0.001);
13 /// assert!((sum(&[0.0, -0.1,0.2]).to_f64().unwrap() - 0.1).abs() < 0.001);
15 pub fn sum
<T
>(list
: &[T
]) -> T
17 T
: NumAssignRef
+ ToPrimitive
19 let mut sum
= T
::zero();
26 /// Calculates the mean of a variable x
28 /// # use proxmox_backup::tools::statistics::mean;
30 /// assert!((mean(&[0,1,2,3,4,5]).unwrap() - 2.5).abs() < 0.001);
31 /// assert_eq!(mean::<u64>(&[]), None)
33 pub fn mean
<T
>(list
: &[T
]) -> Option
<f64>
35 T
: NumAssignRef
+ ToPrimitive
41 Some(sum(list
).to_f64()?
/(list
.len() as f64))
44 /// Calculates the variance of a variable x
46 /// # use proxmox_backup::tools::statistics::variance;
48 /// assert!((variance(&[1,2,3,4]).unwrap() - 1.25).abs() < 0.001);
49 /// assert_eq!(variance::<u64>(&[]), None)
51 pub fn variance
<T
>(list
: &[T
]) -> Option
<f64>
53 T
: NumAssignRef
+ ToPrimitive
55 covariance(list
, list
)
58 /// Calculates the (non-corrected) covariance of two variables x,y
59 pub fn covariance
<X
, Y
> (x
: &[X
], y
: &[Y
]) -> Option
<f64>
61 X
: NumAssignRef
+ ToPrimitive
,
62 Y
: NumAssignRef
+ ToPrimitive
,
66 if len_x
== 0 || len_y
== 0 || len_x
!= len_y
{
70 let mean_x
= mean(x
)?
;
71 let mean_y
= mean(y
)?
;
73 let covariance
: f64 = (0..len_x
).map(|i
| {
74 let x
= x
[i
].to_f64().unwrap_or(0.0);
75 let y
= y
[i
].to_f64().unwrap_or(0.0);
76 (x
- mean_x
)*(y
- mean_y
)
79 Some(covariance
/(len_x
as f64))
82 /// Returns the factors `(a,b)` of a linear regression `y = a + bx`
83 /// for the variables `[x,y]` or `None` if the lists are not the same length
85 /// # use proxmox_backup::tools::statistics::linear_regression;
87 /// let x = &[0,1,2,3,4];
88 /// let y = &[-4,-2,0,2,4];
89 /// let (a,b) = linear_regression(x,y).unwrap();
90 /// assert!((a - -4.0).abs() < 0.001);
91 /// assert!((b - 2.0).abs() < 0.001);
93 pub fn linear_regression
<X
, Y
> (x
: &[X
], y
: &[Y
]) -> Option
<(f64, f64)>
95 X
: NumAssignRef
+ ToPrimitive
,
96 Y
: NumAssignRef
+ ToPrimitive
100 if len_x
== 0 || len_y
== 0 || len_x
!= len_y
{
104 let mean_x
= mean(x
)?
;
105 let mean_y
= mean(y
)?
;
107 let mut covariance
= 0.0;
108 let mut variance
= 0.0;
111 let x
= x
[i
].to_f64()?
;
112 let y
= y
[i
].to_f64()?
;
114 let x_mean_x
= x
- mean_x
;
116 covariance
+= x_mean_x
*(y
- mean_y
);
117 variance
+= x_mean_x
* x_mean_x
;
120 let beta
= covariance
/variance
;
121 let alpha
= mean_y
- beta
*mean_x
;