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}