numerilib/stats/generic/
generic_lists.rs

1/// A module containing functions to work with Lists.
2pub struct Generic;
3
4impl Generic {
5    /// Calculates the mean of a list of numbers.
6    ///
7    /// The mean is calculated as the sum of all numbers divided by the count of numbers.
8    ///
9    /// # Parameters
10    ///
11    /// - `list`: A slice of numbers for which the mean will be calculated.
12    ///
13    /// # Returns
14    ///
15    /// The calculated mean.
16    ///
17    /// # Example
18    ///
19    /// ```rust
20    /// use numerilib::stats::Generic;
21    ///
22    /// let numbers = [3.0, 5.0, 8.0, 12.0, 15.0];
23    /// let mean = Generic::mean(&numbers);
24    ///
25    /// println!("Mean: {}", mean);
26    /// ```
27    /// <hr/>
28    pub fn mean(list: &[f64]) -> f64 {
29        let sum: f64 = list.iter().sum();
30        let count = list.len() as f64;
31
32        sum / count
33    }
34
35    /// Calculates the sum of a list of numbers.
36    ///
37    /// The sum is calculated as the total of all numbers in the list.
38    ///
39    /// # Parameters
40    ///
41    /// - `list`: A slice of numbers to be summed.
42    ///
43    /// # Returns
44    ///
45    /// The calculated sum.
46    ///
47    /// # Example
48    ///
49    /// ```rust
50    /// use numerilib::stats::Generic;
51    ///
52    /// let numbers = [3.0, 5.0, 8.0, 12.0, 15.0];
53    /// let sum = Generic::sum(&numbers);
54    ///
55    /// println!("Sum: {}", sum);
56    /// ```
57    /// <hr/>
58    pub fn sum(list: &[f64]) -> f64 {
59        list.iter().sum()
60    }
61
62    /// Calculates the sum of squared values in a list of numbers.
63    ///
64    /// Each number in the list is squared, and then the sum of these squared values is calculated.
65    ///
66    /// # Parameters
67    ///
68    /// - `list`: A slice of numbers for which the sum of squared values will be calculated.
69    ///
70    /// # Returns
71    ///
72    /// The calculated sum of squared values.
73    ///
74    /// # Example
75    ///
76    /// ```rust
77    /// use numerilib::stats::Generic;
78    ///
79    /// let numbers = [3.0, 5.0, 8.0, 12.0, 15.0];
80    /// let sum_squared = Generic::sum_squared(&numbers);
81    ///
82    /// println!("Sum of Squared Values: {}", sum_squared);
83    /// ```
84    /// <hr/>
85    pub fn sum_squared(list: &[f64]) -> f64 {
86        list.iter().map(|&x| x * x).sum()
87    }
88
89    /// Retrieves the number of elements in a list.
90    ///
91    /// This function returns the count of elements in the provided list.
92    ///
93    /// # Parameters
94    ///
95    /// - `list`: A slice of numbers for which the size will be determined.
96    ///
97    /// # Returns
98    ///
99    /// The size (count) of the list.
100    ///
101    /// # Example
102    ///
103    /// ```rust
104    /// use numerilib::stats::Generic;
105    ///
106    /// let numbers = [3.0, 5.0, 8.0, 12.0, 15.0];
107    /// let size = Generic::size(&numbers);
108    ///
109    /// println!("Size of List: {}", size);
110    /// ```
111    /// <hr/>
112    pub fn size(list: &[f64]) -> usize {
113        list.len()
114    }
115
116    /// Calculates the population variance of a list of numbers.
117    ///
118    /// The population variance is the average of the squared differences between each number
119    /// and the mean of the entire population.
120    ///
121    /// # Parameters
122    ///
123    /// - `list`: A slice of numbers for which the population variance will be calculated.
124    ///
125    /// # Returns
126    ///
127    /// The calculated population variance.
128    ///
129    /// # Example
130    ///
131    /// ```rust
132    /// use numerilib::stats::Generic;
133    ///
134    /// let numbers = [3.0, 5.0, 8.0, 12.0, 15.0];
135    /// let variance = Generic::population_variance(&numbers);
136    ///
137    /// println!("Population Variance: {}", variance);
138    /// ```
139    /// <hr/>
140    pub fn population_variance(list: &[f64]) -> f64 {
141        let mu = Self::mean(list);
142        let squared_deviations_sum = list.iter().map(|x| (x - mu).powi(2)).sum::<f64>();
143        squared_deviations_sum / Self::size(list) as f64
144    }
145
146    /// Calculates the sample variance of a list of numbers.
147    ///
148    /// The sample variance is an estimate of the variance within a sample from a larger population.
149    ///
150    /// # Parameters
151    ///
152    /// - `list`: A slice of numbers for which the sample variance will be calculated.
153    ///
154    /// # Returns
155    ///
156    /// The calculated sample variance.
157    ///
158    /// # Example
159    ///
160    /// ```rust
161    /// use numerilib::stats::Generic;
162    ///
163    /// let numbers = [3.0, 5.0, 8.0, 12.0, 15.0];
164    /// let sample_variance = Generic::sample_variance(&numbers);
165    ///
166    /// println!("Sample Variance: {}", sample_variance);
167    /// ```
168    /// <hr/>
169    pub fn sample_variance(list: &[f64]) -> f64 {
170        let mean = Self::mean(list);
171        let squared_deviations_sum = list.iter().map(|x| (x - mean).powi(2)).sum::<f64>();
172        squared_deviations_sum / (Self::size(list) - 1) as f64
173    }
174
175    /// Calculates the population standard deviation of a list of numbers.
176    ///
177    /// The population standard deviation is the square root of the population variance.
178    ///
179    /// # Parameters
180    ///
181    /// - `list`: A slice of numbers for which the population standard deviation will be calculated.
182    ///
183    /// # Returns
184    ///
185    /// The calculated population standard deviation.
186    ///
187    /// # Example
188    ///
189    /// ```rust
190    /// use numerilib::stats::Generic;
191    ///
192    /// let numbers = [3.0, 5.0, 8.0, 12.0, 15.0];
193    /// let population_sd = Generic::population_sd(&numbers);
194    ///
195    /// println!("Population Standard Deviation: {}", population_sd);
196    /// ```
197    /// <hr/>
198    pub fn population_sd(list: &[f64]) -> f64 {
199        Self::population_variance(list).sqrt()
200    }
201
202    /// Calculates the sample standard deviation of a list of numbers.
203    ///
204    /// The sample standard deviation is calculated using the sample variance.
205    ///
206    /// # Parameters
207    ///
208    /// - `list`: A slice of numbers for which the sample standard deviation will be calculated.
209    ///
210    /// # Returns
211    ///
212    /// The calculated sample standard deviation.
213    ///
214    /// # Example
215    ///
216    /// ```rust
217    /// use numerilib::stats::Generic;
218    ///
219    /// let numbers = [3.0, 5.0, 8.0, 12.0, 15.0];
220    /// let sd = Generic::sample_sd(&numbers);
221    ///
222    /// println!("Sample Standard Deviation: {}", sd);
223    /// ```
224    /// <hr/>
225    pub fn sample_sd(list: &[f64]) -> f64 {
226        Self::sample_variance(list).sqrt()
227    }
228
229    /// Calculates the five-number summary of a list of numbers.
230    ///
231    /// The five-number summary consists of the minimum, first quartile (Q1), median, third quartile (Q3),
232    /// and maximum of the given list of numbers.
233    ///
234    /// # Parameters
235    ///
236    /// - `list`: A slice of numbers for which the five-number summary will be calculated.
237    ///
238    /// # Returns
239    ///
240    /// A vector containing the minimum, Q1, median, Q3, and maximum.
241    ///
242    /// # Example
243    ///
244    /// ```rust
245    /// use numerilib::stats::Generic;
246    ///
247    /// let numbers = [3.0, 5.0, 8.0, 12.0, 15.0, 19.0, 21.0, 25.0, 28.0, 31.0];
248    /// let summary = Generic::five_number_summary(&numbers);
249    ///
250    /// println!("Five-Number Summary: {:?}", summary);
251    /// ```
252    /// <hr/>
253    pub fn five_number_summary(list: &[f64]) -> Vec<f64> {
254        let mut sorted_list = list.to_vec();
255        sorted_list.sort_by(|a, b| a.partial_cmp(b).unwrap());
256
257        let min = sorted_list[0];
258        let max = sorted_list[sorted_list.len() - 1];
259
260        let median_index = (sorted_list.len() as f64 / 2.0).floor() as usize;
261        let median = if sorted_list.len() % 2 == 0 {
262            (sorted_list[median_index - 1] + sorted_list[median_index]) / 2.0
263        } else {
264            sorted_list[median_index]
265        };
266
267        let lower_half = &sorted_list[..median_index];
268        let upper_half = &sorted_list[median_index + sorted_list.len() % 2..];
269
270        let q1_index = (lower_half.len() as f64 / 2.0).floor() as usize;
271        let q1 = if lower_half.len() % 2 == 0 {
272            (lower_half[q1_index - 1] + lower_half[q1_index]) / 2.0
273        } else {
274            lower_half[q1_index]
275        };
276
277        let q3_index = (upper_half.len() as f64 / 2.0).floor() as usize;
278        let q3 = if upper_half.len() % 2 == 0 {
279            (upper_half[q3_index - 1] + upper_half[q3_index]) / 2.0
280        } else {
281            upper_half[q3_index]
282        };
283
284        vec![min, q1, median, q3, max]
285    }
286}