tea_core/agg.rs
1use num_traits::Zero;
2use tea_dtype::{BoolType, Cast, IntoCast, IsNone, Number};
3
4use crate::prelude::{EPS, IterBasic};
5
6pub trait AggValidBasic<T: IsNone>: IntoIterator<Item = T> + Sized {
7 #[inline]
8 /// count the number of valid elements in the vector.
9 #[deprecated(since = "0.3.0", note = "Please use count_valid instead")]
10 fn count(self) -> usize {
11 self.vfold_n((), |(), _| {}).0
12 }
13
14 #[inline]
15 /// Counts the number of valid (non-None) elements in the iterator.
16 ///
17 /// This method iterates through all elements and counts those that are not None.
18 ///
19 /// # Returns
20 ///
21 /// Returns the count of valid elements as a `usize`.
22 ///
23 /// # Examples
24 ///
25 /// ```
26 /// use tea_core::prelude::*;
27 ///
28 /// let vec = vec![Some(1), None, Some(2), None, Some(3)];
29 /// assert_eq!(vec.count_valid(), 3);
30 /// ```
31 fn count_valid(self) -> usize {
32 self.vfold_n((), |(), _| {}).0
33 }
34
35 #[inline]
36 /// Finds the first valid (non-None) element in the iterator.
37 ///
38 /// This method iterates through the elements and returns the first one that is not None.
39 ///
40 /// # Returns
41 ///
42 /// Returns an `Option<T>`:
43 /// - `Some(T)` if a valid element is found
44 /// - `None` if no valid elements are found (i.e., all elements are None or the iterator is empty)
45 ///
46 /// # Examples
47 ///
48 /// ```
49 /// use tea_core::prelude::*;
50 ///
51 /// let vec = vec![None, Some(1), None, Some(2), Some(3)];
52 /// assert_eq!(vec.vfirst(), Some(Some(1)));
53 ///
54 /// let empty_vec: Vec<Option<i32>> = vec![];
55 /// assert_eq!(empty_vec.vfirst(), None);
56 /// ```
57 fn vfirst(self) -> Option<T> {
58 self.into_iter().find(|v| v.not_none())
59 }
60
61 #[inline]
62 /// Finds the last valid (non-None) element in the iterator.
63 ///
64 /// This method iterates through the elements in reverse order and returns the first non-None element encountered.
65 ///
66 /// # Returns
67 ///
68 /// Returns an `Option<T>`:
69 /// - `Some(T)` if a valid element is found
70 /// - `None` if no valid elements are found (i.e., all elements are None or the iterator is empty)
71 ///
72 /// # Examples
73 ///
74 /// ```
75 /// use tea_core::prelude::*;
76 ///
77 /// let vec = vec![Some(1), None, Some(2), None, Some(3)];
78 /// assert_eq!(vec.vlast(), Some(Some(3)));
79 ///
80 /// let empty_vec: Vec<Option<i32>> = vec![];
81 /// assert_eq!(empty_vec.vlast(), None);
82 /// ```
83 ///
84 /// # Note
85 ///
86 /// This method requires the iterator to be double-ended.
87 fn vlast(self) -> Option<T>
88 where
89 Self::IntoIter: DoubleEndedIterator,
90 {
91 self.into_iter().rev().find(|v| v.not_none())
92 }
93
94 #[inline]
95 /// Counts the number of `None` values in the iterator.
96 ///
97 /// This method iterates through all elements and counts those that are `None`.
98 ///
99 /// # Returns
100 ///
101 /// Returns the count of `None` values as a `usize`.
102 ///
103 /// # Examples
104 ///
105 /// ```
106 /// use tea_core::prelude::*;
107 ///
108 /// let vec = vec![Some(1), None, Some(2), None, Some(3)];
109 /// assert_eq!(vec.count_none(), 2);
110 /// ```
111 fn count_none(self) -> usize {
112 let mut n = 0;
113 self.into_iter().for_each(|v| {
114 if v.is_none() {
115 n += 1;
116 }
117 });
118 n
119 }
120
121 #[inline]
122 /// Counts the number of occurrences of a specific value in the iterator.
123 ///
124 /// This method iterates through all elements and counts those that match the given value.
125 /// It handles both `Some` and `None` values.
126 ///
127 /// # Arguments
128 ///
129 /// * `value` - The value to count occurrences of. It can be either `Some(T::Inner)` or `None`.
130 ///
131 /// # Returns
132 ///
133 /// Returns the count of occurrences as a `usize`.
134 ///
135 /// # Examples
136 ///
137 /// ```
138 /// use tea_core::prelude::*;
139 ///
140 /// let vec = vec![Some(1), None, Some(2), Some(1), None, Some(3)];
141 /// assert_eq!(vec.titer().vcount_value(Some(1)), 2);
142 /// assert_eq!(vec.titer().vcount_value(None), 2);
143 /// assert_eq!(vec.vcount_value(Some(4)), 0);
144 /// ```
145 fn vcount_value(self, value: T) -> usize
146 where
147 T::Inner: PartialEq,
148 {
149 if value.not_none() {
150 let value = value.unwrap();
151 self.vfold(0, |acc, x| if x.unwrap() == value { acc + 1 } else { acc })
152 } else {
153 self.into_iter()
154 .fold(0, |acc, x| if x.is_none() { acc + 1 } else { acc })
155 }
156 }
157
158 #[inline]
159 /// Checks if any valid (non-None) element in the iterator satisfies the given condition.
160 ///
161 /// This method iterates through all elements and returns `true` if any element is not None and satisfies the condition.
162 ///
163 /// # Returns
164 ///
165 /// Returns a `bool`:
166 /// - `true` if any valid element satisfies the condition
167 /// - `false` if no valid elements satisfy the condition or the iterator is empty
168 fn vany(self) -> bool
169 where
170 T::Inner: BoolType,
171 {
172 self.vfold(false, |acc, x| acc || x.unwrap().bool_())
173 }
174
175 #[inline]
176 /// Checks if all valid (non-None) elements in the iterator satisfy the given condition.
177 ///
178 /// This method iterates through all elements and returns `true` if all elements are not None and satisfy the condition.
179 ///
180 /// # Returns
181 ///
182 /// Returns a `bool`:
183 /// - `true` if all valid elements satisfy the condition
184 /// - `false` if any valid element does not satisfy the condition or the iterator is empty
185 ///
186 /// # Examples
187 ///
188 /// ```
189 /// use tea_core::prelude::*;
190 ///
191 /// let vec = vec![Some(true), Some(true), Some(false)];
192 /// assert_eq!(vec.vall(), false);
193 ///
194 /// let vec = vec![Some(true), Some(true), Some(true)];
195 /// assert_eq!(vec.vall(), true);
196 ///
197 /// let empty_vec: Vec<Option<bool>> = vec![];
198 /// assert_eq!(empty_vec.vall(), true); // All elements are None, so it satisfies the condition
199 /// ```
200 fn vall(self) -> bool
201 where
202 T::Inner: BoolType,
203 {
204 self.vfold(true, |acc, x| acc && x.unwrap().bool_())
205 }
206
207 #[inline]
208 /// Returns the sum of all valid elements in the vector.
209 ///
210 /// This method iterates through all elements, summing up the valid (non-None) values.
211 ///
212 /// # Returns
213 ///
214 /// Returns an `Option<T::Inner>`:
215 /// - `Some(sum)` if there is at least one valid element
216 /// - `None` if there are no valid elements or the vector is empty
217 ///
218 /// # Type Parameters
219 ///
220 /// - `T::Inner`: Must implement the `Zero` trait to provide a zero value for initialization
221 ///
222 /// # Examples
223 ///
224 /// ```
225 /// use tea_core::prelude::*;
226 ///
227 /// let vec = vec![Some(1), Some(2), None, Some(3)];
228 /// assert_eq!(vec.vsum(), Some(6));
229 ///
230 /// let empty_vec: Vec<Option<i32>> = vec![];
231 /// assert_eq!(empty_vec.vsum(), None);
232 ///
233 /// let all_none_vec: Vec<Option<f64>> = vec![None, None, None];
234 /// assert_eq!(all_none_vec.vsum(), None);
235 /// ```
236 fn vsum(self) -> Option<T::Inner>
237 where
238 T::Inner: Zero,
239 {
240 let (n, sum) = self.vfold_n(T::Inner::zero(), |acc, x| acc + x);
241 if n >= 1 { Some(sum) } else { None }
242 }
243
244 #[inline]
245 /// Calculates the mean (average) of all valid elements in the vector.
246 ///
247 /// This method iterates through all elements, summing up the valid (non-None) values
248 /// and counting the number of valid elements. It then calculates the mean by dividing
249 /// the sum by the count.
250 ///
251 /// # Returns
252 ///
253 /// Returns an `f64`:
254 /// - The calculated mean if there is at least one valid element
255 /// - `f64::NAN` if there are no valid elements or the vector is empty
256 ///
257 /// # Type Parameters
258 ///
259 /// - `T::Inner`: Must implement the `Number` trait to support arithmetic operations
260 ///
261 /// # Examples
262 ///
263 /// ```
264 /// use tea_core::prelude::*;
265 ///
266 /// let vec = vec![Some(1), Some(2), None, Some(3)];
267 /// assert_eq!(vec.vmean(), 2.0);
268 ///
269 /// let empty_vec: Vec<Option<i32>> = vec![];
270 /// assert!(empty_vec.vmean().is_nan());
271 ///
272 /// let all_none_vec: Vec<Option<f64>> = vec![None, None, None];
273 /// assert!(all_none_vec.vmean().is_nan());
274 /// ```
275 fn vmean(self) -> f64
276 where
277 T::Inner: Number,
278 {
279 let (n, sum) = self.vfold_n(T::Inner::zero(), |acc, x| acc + x);
280 if n >= 1 {
281 sum.f64() / n as f64
282 } else {
283 f64::NAN
284 }
285 }
286
287 /// Calculates the mean and variance of all valid elements in the vector.
288 ///
289 /// This method iterates through all elements, computing the sum and sum of squares
290 /// of valid (non-None) values. It then calculates the mean and variance using these values.
291 ///
292 /// # Arguments
293 ///
294 /// * `min_periods` - The minimum number of valid observations required to calculate the result.
295 ///
296 /// # Returns
297 ///
298 /// Returns a tuple of two `f64` values:
299 /// - The first element is the calculated mean
300 /// - The second element is the calculated variance
301 /// - Both elements are `f64::NAN` if there are fewer valid elements than `min_periods`
302 ///
303 /// # Type Parameters
304 ///
305 /// - `T::Inner`: Must implement the `Number` trait to support arithmetic operations
306 ///
307 /// # Examples
308 ///
309 /// ```
310 /// use tea_core::prelude::*;
311 ///
312 /// let vec = vec![Some(1), Some(2), None, Some(3)];
313 /// let (mean, var) = vec.vmean_var(1);
314 /// assert_eq!(mean, 2.0);
315 /// assert!((var - 1.0).abs() < EPS);
316 ///
317 /// let empty_vec: Vec<Option<i32>> = vec![];
318 /// let (mean, var) = empty_vec.vmean_var(1);
319 /// assert!(mean.is_nan() && var.is_nan());
320 /// ```
321 fn vmean_var(self, min_periods: usize) -> (f64, f64)
322 where
323 T::Inner: Number,
324 {
325 let (mut m1, mut m2) = (0., 0.);
326 let n = self.vapply_n(|v| {
327 let v = v.f64();
328 m1 += v;
329 m2 += v * v;
330 });
331 if n < min_periods {
332 return (f64::NAN, f64::NAN);
333 }
334 let n_f64 = n.f64();
335 m1 /= n_f64; // E(x)
336 m2 /= n_f64; // E(x^2)
337 m2 -= m1.powi(2); // variance = E(x^2) - (E(x))^2
338 if m2 <= EPS {
339 (m1, 0.)
340 } else if n >= 2 {
341 (m1, m2 * n_f64 / (n - 1).f64())
342 } else {
343 (f64::NAN, f64::NAN)
344 }
345 }
346
347 /// Calculates the variance of the data.
348 ///
349 /// This method computes the variance of the non-null values in the collection.
350 ///
351 /// # Arguments
352 ///
353 /// * `min_periods` - The minimum number of non-null values required to calculate the variance.
354 /// If the number of non-null values is less than `min_periods`, the method returns `f64::NAN`.
355 ///
356 /// # Returns
357 ///
358 /// Returns an `f64` representing the variance of the data. If there are fewer valid elements
359 /// than `min_periods`, returns `f64::NAN`.
360 ///
361 /// # Examples
362 ///
363 /// ```
364 /// use tea_core::prelude::*;
365 ///
366 /// let vec = vec![Some(1), Some(2), None, Some(3)];
367 /// let var = vec.vvar(1);
368 /// assert!((var - 1.0).abs() < EPS);
369 ///
370 /// let empty_vec: Vec<Option<i32>> = vec![];
371 /// let var = empty_vec.vvar(1);
372 /// assert!(var.is_nan());
373 /// ```
374 #[inline]
375 fn vvar(self, min_periods: usize) -> f64
376 where
377 T::Inner: Number,
378 {
379 self.vmean_var(min_periods).1
380 }
381
382 /// Calculates the standard deviation of the data.
383 ///
384 /// This method computes the standard deviation of the non-null values in the collection.
385 ///
386 /// # Arguments
387 ///
388 /// * `min_periods` - The minimum number of non-null values required to calculate the standard deviation.
389 /// If the number of non-null values is less than `min_periods`, the method returns `f64::NAN`.
390 ///
391 /// # Returns
392 ///
393 /// Returns an `f64` representing the standard deviation of the data. If there are fewer valid elements
394 /// than `min_periods`, returns `f64::NAN`.
395 ///
396 /// # Examples
397 ///
398 /// ```
399 /// use tea_core::prelude::*;
400 ///
401 /// let vec = vec![Some(1), Some(2), None, Some(3)];
402 /// let std = vec.vstd(1);
403 /// assert!((std - 1.0).abs() < EPS);
404 ///
405 /// let empty_vec: Vec<Option<i32>> = vec![];
406 /// let std = empty_vec.vstd(1);
407 /// assert!(std.is_nan());
408 /// ```
409 #[inline]
410 fn vstd(self, min_periods: usize) -> f64
411 where
412 T::Inner: Number,
413 {
414 self.vvar(min_periods).sqrt()
415 }
416
417 /// Calculates the skewness of the data.
418 ///
419 /// Skewness is a measure of the asymmetry of the probability distribution of a real-valued random variable about its mean.
420 ///
421 /// # Arguments
422 ///
423 /// * `min_periods` - The minimum number of non-null values required to calculate the skewness.
424 /// If the number of non-null values is less than `min_periods`, the method returns `f64::NAN`.
425 ///
426 /// # Returns
427 ///
428 /// Returns an `f64` representing the skewness of the data. If there are fewer valid elements
429 /// than `min_periods`, or if the number of elements is less than 3, returns `f64::NAN`.
430 ///
431 /// # Examples
432 ///
433 /// ```
434 /// use tea_core::prelude::*;
435 ///
436 /// let vec = vec![Some(1), Some(2), Some(3), Some(4), Some(5)];
437 /// let skew = vec.vskew(1);
438 /// assert!((skew - 0.0).abs() < EPS);
439 ///
440 /// let empty_vec: Vec<Option<i32>> = vec![];
441 /// let skew = empty_vec.vskew(1);
442 /// assert!(skew.is_nan());
443 /// ```
444 fn vskew(self, min_periods: usize) -> f64
445 where
446 T::Inner: Number,
447 {
448 let (mut m1, mut m2, mut m3) = (0., 0., 0.);
449 let n = self.vapply_n(|v| {
450 let v = v.f64();
451 m1 += v;
452 let v2 = v * v;
453 m2 += v2;
454 m3 += v2 * v;
455 });
456 if n < min_periods {
457 return f64::NAN;
458 }
459 let mut res = if n >= 3 {
460 let n_f64 = n.f64();
461 m1 /= n_f64; // Ex
462 m2 /= n_f64; // Ex^2
463 let var = m2 - m1.powi(2);
464 if var <= EPS {
465 0.
466 } else {
467 let std = var.sqrt(); // var^2
468 m3 /= n_f64; // Ex^3
469 let mean_std = m1 / std; // mean / std
470 m3 / std.powi(3) - 3_f64 * mean_std - mean_std.powi(3)
471 }
472 } else {
473 f64::NAN
474 };
475 if res.not_none() && res != 0. {
476 let adjust = (n * (n - 1)).f64().sqrt() / (n - 2).f64();
477 res *= adjust;
478 }
479 res
480 }
481
482 /// Returns the maximum value in the vector.
483 ///
484 /// This method iterates through the vector and returns the maximum value.
485 /// If the vector is empty or contains only `None` values, it returns `None`.
486 ///
487 /// # Examples
488 ///
489 /// ```
490 /// use tea_core::prelude::*;
491 ///
492 /// let vec = vec![Some(1), Some(5), Some(3), Some(2), Some(4)];
493 /// assert_eq!(vec.vmax(), Some(5));
494 ///
495 /// let empty_vec: Vec<Option<i32>> = vec![];
496 /// assert_eq!(empty_vec.vmax(), None);
497 ///
498 /// let none_vec: Vec<Option<i32>> = vec![None, None, None];
499 /// assert_eq!(none_vec.vmax(), None);
500 /// ```
501 #[inline]
502 fn vmax(self) -> Option<T::Inner>
503 where
504 T::Inner: Number,
505 {
506 self.vfold(None, |acc, x| match acc.to_opt() {
507 None => Some(x.unwrap()),
508 Some(v) => Some(v.max_with(x.unwrap())),
509 })
510 }
511
512 /// Returns the minimum value in the vector.
513 ///
514 /// This method iterates through the vector and returns the minimum value.
515 /// If the vector is empty or contains only `None` values, it returns `None`.
516 ///
517 /// # Examples
518 ///
519 /// ```
520 /// use tea_core::prelude::*;
521 ///
522 /// let vec = vec![Some(1), Some(5), Some(3), Some(2), Some(4)];
523 /// assert_eq!(vec.vmin(), Some(1));
524 ///
525 /// let empty_vec: Vec<Option<i32>> = vec![];
526 /// assert_eq!(empty_vec.vmin(), None);
527 ///
528 /// let none_vec: Vec<Option<i32>> = vec![None, None, None];
529 /// assert_eq!(none_vec.vmin(), None);
530 /// ```
531 #[inline]
532 fn vmin(self) -> Option<T::Inner>
533 where
534 T::Inner: Number,
535 {
536 self.vfold(None, |acc, x| match acc {
537 None => Some(x.unwrap()),
538 Some(v) => Some(v.min_with(x.unwrap())),
539 })
540 }
541
542 /// Returns the index of the maximum value in the vector.
543 ///
544 /// This method iterates through the vector and returns the index of the maximum value.
545 /// If the vector is empty or contains only `None` values, it returns `None`.
546 ///
547 /// # Examples
548 ///
549 /// ```
550 /// use tea_core::prelude::*;
551 ///
552 /// let vec = vec![Some(1), Some(5), Some(3), Some(2), Some(4)];
553 /// assert_eq!(vec.vargmax(), Some(1)); // Index of 5
554 ///
555 /// let empty_vec: Vec<Option<i32>> = vec![];
556 /// assert_eq!(empty_vec.vargmax(), None);
557 ///
558 /// let none_vec: Vec<Option<i32>> = vec![None, None, None];
559 /// assert_eq!(none_vec.vargmax(), None);
560 /// ```
561 #[inline]
562 fn vargmax(self) -> Option<usize>
563 where
564 T::Inner: PartialOrd,
565 {
566 use std::cmp::Ordering;
567 let mut max = None;
568 let mut max_idx = None;
569 let mut current_idx = 0;
570 self.into_iter().for_each(|v| {
571 if v.not_none() {
572 let v = v.unwrap();
573 if let Some(max_value) = &max {
574 // None is smaller than any value
575 if let Some(Ordering::Greater) = v.partial_cmp(max_value) {
576 max = Some(v);
577 max_idx = Some(current_idx);
578 }
579 } else {
580 max = Some(v);
581 max_idx = Some(current_idx);
582 }
583 }
584 current_idx += 1;
585 });
586 max_idx
587 }
588
589 /// Returns the index of the minimum value in the vector.
590 ///
591 /// This method iterates through the vector and returns the index of the minimum value.
592 /// If the vector is empty or contains only `None` values, it returns `None`.
593 ///
594 /// # Examples
595 ///
596 /// ```
597 /// use tea_core::prelude::*;
598 ///
599 /// let vec = vec![Some(3), Some(1), Some(4), Some(2), Some(5)];
600 /// assert_eq!(vec.vargmin(), Some(1)); // Index of 1
601 ///
602 /// let empty_vec: Vec<Option<i32>> = vec![];
603 /// assert_eq!(empty_vec.vargmin(), None);
604 ///
605 /// let none_vec: Vec<Option<i32>> = vec![None, None, None];
606 /// assert_eq!(none_vec.vargmin(), None);
607 /// ```
608 #[inline]
609 fn vargmin(self) -> Option<usize>
610 where
611 T::Inner: PartialOrd,
612 {
613 use std::cmp::Ordering;
614 let mut min = None;
615 let mut min_idx = None;
616 let mut current_idx = 0;
617 self.into_iter().for_each(|v| {
618 if v.not_none() {
619 let v = v.unwrap();
620 if let Some(min_value) = &min {
621 if let Some(Ordering::Less) = v.partial_cmp(min_value) {
622 min = Some(v);
623 min_idx = Some(current_idx);
624 }
625 } else {
626 min = Some(v);
627 min_idx = Some(current_idx);
628 }
629 }
630 current_idx += 1;
631 });
632 min_idx
633 }
634
635 /// Calculates the covariance between two vectors.
636 ///
637 /// This method computes the covariance between the elements of `self` and `other`.
638 ///
639 /// # Arguments
640 ///
641 /// * `other` - An iterator over the second vector of values.
642 /// * `min_periods` - The minimum number of pairs of non-None values required to have a valid result.
643 ///
644 /// # Returns
645 ///
646 /// Returns the covariance as `T::Cast<f64>`. If there are fewer valid pairs than `min_periods`,
647 /// or if the computation results in NaN, returns `None`.
648 ///
649 /// # Type Parameters
650 ///
651 /// * `V2` - The type of the iterator for the second vector.
652 /// * `T2` - The type of elements in the second vector, which must implement `IsNone`.
653 fn vcov<V2: IntoIterator<Item = T2>, T2: IsNone>(
654 self,
655 other: V2,
656 min_periods: usize,
657 ) -> T::Cast<f64>
658 where
659 T::Inner: Number,
660 T2::Inner: Number,
661 {
662 let (mut sum_a, mut sum_b, mut sum_ab) = (0., 0., 0.);
663 let mut n = 0;
664 let min_periods = min_periods.max_with(2);
665 self.into_iter().zip(other).for_each(|(va, vb)| {
666 if va.not_none() && vb.not_none() {
667 n += 1;
668 let (va, vb) = (va.unwrap().f64(), vb.unwrap().f64());
669 sum_a += va;
670 sum_b += vb;
671 sum_ab += va * vb;
672 }
673 });
674 if n >= min_periods {
675 let res = (sum_ab - (sum_a * sum_b) / n as f64) / (n - 1) as f64;
676 res.into_cast::<T>()
677 } else {
678 T::Cast::<f64>::none()
679 }
680 }
681
682 /// Calculates the Pearson correlation coefficient between two vectors.
683 ///
684 /// This method computes the Pearson correlation coefficient between the elements of `self` and `other`.
685 ///
686 /// # Arguments
687 ///
688 /// * `other` - An iterator over the second vector of values.
689 /// * `min_periods` - The minimum number of pairs of non-None values required to have a valid result.
690 ///
691 /// # Returns
692 ///
693 /// Returns the Pearson correlation coefficient as type `O`. If there are fewer valid pairs than `min_periods`,
694 /// or if the computation results in NaN (e.g., due to zero variance), returns `NaN`.
695 ///
696 /// # Type Parameters
697 ///
698 /// * `O` - The output type for the correlation coefficient.
699 /// * `V2` - The type of the iterator for the second vector.
700 /// * `T2` - The type of elements in the second vector, which must implement `IsNone`.
701 fn vcorr_pearson<O, V2: IntoIterator<Item = T2>, T2: IsNone>(
702 self,
703 other: V2,
704 min_periods: usize,
705 ) -> O
706 where
707 T::Inner: Number,
708 T2::Inner: Number,
709 f64: Cast<O>,
710 {
711 let (mut sum_a, mut sum2_a, mut sum_b, mut sum2_b, mut sum_ab) = (0., 0., 0., 0., 0.);
712 let mut n = 0;
713 let min_periods = min_periods.max_with(2);
714 self.into_iter().zip(other).for_each(|(va, vb)| {
715 if va.not_none() && vb.not_none() {
716 n += 1;
717 let (va, vb) = (va.unwrap().f64(), vb.unwrap().f64());
718 sum_a += va;
719 sum2_a += va * va;
720 sum_b += vb;
721 sum2_b += vb * vb;
722 sum_ab += va * vb;
723 }
724 });
725 if n >= min_periods {
726 let n = n.f64();
727 let mean_a = sum_a / n;
728 let mut var_a = sum2_a / n;
729 let mean_b = sum_b / n;
730 let mut var_b = sum2_b / n;
731 var_a -= mean_a.powi(2);
732 var_b -= mean_b.powi(2);
733 if (var_a > EPS) & (var_b > EPS) {
734 let exy = sum_ab / n;
735 let exey = sum_a * sum_b / (n * n);
736 let res = (exy - exey) / (var_a * var_b).sqrt();
737 res.cast()
738 } else {
739 f64::NAN.cast()
740 }
741 } else {
742 f64::NAN.cast()
743 }
744 }
745}
746
747pub trait AggBasic: IntoIterator + Sized {
748 /// Counts the occurrences of a specific value in the iterator.
749 ///
750 /// This method iterates over the elements of the collection and counts
751 /// how many times the specified `value` appears.
752 ///
753 /// # Arguments
754 ///
755 /// * `self` - The iterator to count values from.
756 /// * `value` - The value to count occurrences of.
757 ///
758 /// # Returns
759 ///
760 /// Returns the number of times the specified `value` appears in the iterator.
761 ///
762 /// # Type Parameters
763 ///
764 /// * `Self::Item` - The type of items in the iterator, which must implement `PartialEq`.
765 ///
766 /// # Examples
767 ///
768 /// ```
769 /// use tea_core::prelude::*;
770 ///
771 /// let numbers = vec![1, 2, 3, 2, 4, 2];
772 /// assert_eq!(numbers.titer().count_value(2), 3);
773 /// assert_eq!(numbers.count_value(5), 0);
774 /// ```
775 #[inline]
776 fn count_value(self, value: Self::Item) -> usize
777 where
778 Self::Item: PartialEq,
779 {
780 self.into_iter()
781 .fold(0, |acc, x| if x == value { acc + 1 } else { acc })
782 }
783
784 /// Checks if any element in the iterator satisfies a condition.
785 ///
786 /// This method returns `true` if at least one element in the iterator
787 /// evaluates to `true` when converted to a boolean value.
788 ///
789 /// # Returns
790 ///
791 /// Returns `true` if any element is `true`, `false` otherwise.
792 ///
793 /// # Type Parameters
794 ///
795 /// * `Self::Item` - The type of items in the iterator, which must implement `BoolType`.
796 ///
797 /// # Examples
798 ///
799 /// ```
800 /// use tea_core::prelude::*;
801 ///
802 /// let values = vec![false, false, true, false];
803 /// assert_eq!(values.any(), true);
804 ///
805 /// let empty: Vec<bool> = vec![];
806 /// assert_eq!(empty.any(), false);
807 /// ```
808 #[inline]
809 fn any(self) -> bool
810 where
811 Self::Item: BoolType,
812 {
813 Iterator::any(&mut self.into_iter(), |x| x.bool_())
814 }
815
816 /// Checks if all elements in the iterator satisfy a condition.
817 ///
818 /// This method returns `true` if all elements in the iterator
819 /// evaluate to `true` when converted to a boolean value.
820 ///
821 /// # Returns
822 ///
823 /// Returns `true` if all elements are `true`, `false` otherwise.
824 ///
825 /// # Type Parameters
826 ///
827 /// * `Self::Item` - The type of items in the iterator, which must implement `BoolType`.
828 ///
829 /// # Examples
830 ///
831 /// ```
832 /// use tea_core::prelude::*;
833 ///
834 /// let values = vec![true, true, true];
835 /// assert_eq!(values.all(), true);
836 ///
837 /// let mixed = vec![true, false, true];
838 /// assert_eq!(mixed.all(), false);
839 ///
840 /// let empty: Vec<bool> = vec![];
841 /// assert_eq!(empty.all(), true);
842 /// ```
843 #[inline]
844 fn all(self) -> bool
845 where
846 Self::Item: BoolType,
847 {
848 Iterator::all(&mut self.into_iter(), |x| x.bool_())
849 }
850
851 #[inline]
852 /// Returns the first element of the iterator.
853 /// If the iterator is empty, returns None.
854 fn first(self) -> Option<Self::Item> {
855 self.into_iter().next()
856 }
857
858 #[inline]
859 /// Returns the last element of the iterator.
860 /// If the iterator is empty, returns None.
861 fn last(self) -> Option<Self::Item>
862 where
863 Self::IntoIter: DoubleEndedIterator,
864 {
865 self.into_iter().rev().first()
866 }
867
868 #[inline]
869 /// Returns the sum of all elements in the vector.
870 fn n_sum(self) -> (usize, Option<Self::Item>)
871 where
872 Self::Item: Zero,
873 {
874 let mut n = 0;
875 let sum = self.into_iter().fold(Self::Item::zero(), |acc, x| {
876 n += 1;
877 acc + x
878 });
879 if n >= 1 { (n, Some(sum)) } else { (n, None) }
880 }
881
882 #[inline]
883 /// Returns the sum of all elements in the vector.
884 fn sum(self) -> Option<Self::Item>
885 where
886 Self::Item: Zero,
887 {
888 self.n_sum().1
889 }
890
891 /// Returns the mean of all elements in the iterator.
892 ///
893 /// This method calculates the arithmetic mean of all elements in the iterator.
894 /// It first computes the sum and count of all elements using the `n_sum` method,
895 /// then divides the sum by the count to get the mean.
896 ///
897 /// # Type Parameters
898 ///
899 /// - `Self::Item`: Must implement `Zero` and be castable to `f64`.
900 ///
901 /// # Returns
902 ///
903 /// - `Some(f64)`: The mean value if the iterator is not empty.
904 /// - `None`: If the iterator is empty.
905 ///
906 /// # Examples
907 ///
908 /// ```
909 /// use tea_core::prelude::*;
910 ///
911 /// let numbers = vec![1.0, 2.0, 3.0, 4.0, 5.0];
912 /// assert_eq!(numbers.titer().mean(), Some(3.0));
913 ///
914 /// let empty: Vec<f64> = vec![];
915 /// assert_eq!(empty.titer().mean(), None);
916 /// ```
917 #[inline]
918 fn mean(self) -> Option<f64>
919 where
920 Self::Item: Zero + Cast<f64>,
921 {
922 let (len, sum) = self.n_sum();
923 sum.map(|v| v.cast() / len as f64)
924 }
925
926 /// Returns the maximum element in the iterator.
927 ///
928 /// This method iterates through all elements and returns the maximum value.
929 ///
930 /// # Type Parameters
931 ///
932 /// - `Self::Item`: Must implement the `Number` trait.
933 ///
934 /// # Returns
935 ///
936 /// - `Some(Self::Item)`: The maximum value if the iterator is not empty.
937 /// - `None`: If the iterator is empty.
938 ///
939 /// # Examples
940 ///
941 /// ```
942 /// use tea_core::prelude::*;
943 /// use std::iter::empty;
944 ///
945 /// let numbers = vec![1, 5, 3, 2, 4];
946 /// assert_eq!(AggBasic::max(numbers.titer()), Some(5));
947 ///
948 /// let empty: Vec<i32> = vec![];
949 /// assert_eq!(AggBasic::max(empty.titer()), None);
950 /// ```
951 #[inline]
952 fn max(self) -> Option<Self::Item>
953 where
954 Self::Item: Number,
955 {
956 self.into_iter().fold(None, |acc, x| match acc {
957 None => Some(x),
958 Some(v) => Some(v.max_with(x)),
959 })
960 }
961
962 /// Returns the minimum element in the iterator.
963 ///
964 /// This method iterates through all elements and returns the minimum value.
965 ///
966 /// # Type Parameters
967 ///
968 /// - `Self::Item`: Must implement the `Number` trait.
969 ///
970 /// # Returns
971 ///
972 /// - `Some(Self::Item)`: The minimum value if the iterator is not empty.
973 /// - `None`: If the iterator is empty.
974 ///
975 /// # Examples
976 ///
977 /// ```
978 /// use tea_core::prelude::*;
979 /// use std::iter::empty;
980 /// let numbers = vec![5, 1, 3, 2, 4];
981 /// assert_eq!(AggBasic::min(numbers.titer()), Some(1));
982 ///
983 /// let empty: Vec<i32> = vec![];
984 /// assert_eq!(AggBasic::min(empty.titer()), None);
985 /// ```
986 #[inline]
987 fn min(self) -> Option<Self::Item>
988 where
989 Self::Item: Number,
990 {
991 self.into_iter().fold(None, |acc, x| match acc {
992 None => Some(x),
993 Some(v) => Some(v.min_with(x)),
994 })
995 }
996
997 /// Returns the index of the maximum element in the iterator.
998 ///
999 /// This method iterates through all elements and returns the index of the maximum value.
1000 ///
1001 /// # Type Parameters
1002 ///
1003 /// - `Self::Item`: Must implement `PartialOrd`.
1004 ///
1005 /// # Returns
1006 ///
1007 /// - `Some(usize)`: The index of the maximum value if the iterator is not empty.
1008 /// - `None`: If the iterator is empty.
1009 ///
1010 /// # Examples
1011 ///
1012 /// ```
1013 /// use tea_core::prelude::*;
1014 ///
1015 /// let numbers = vec![1, 5, 3, 2, 4];
1016 /// assert_eq!(numbers.titer().argmax(), Some(1));
1017 ///
1018 /// let empty: Vec<i32> = vec![];
1019 /// assert_eq!(empty.titer().argmax(), None);
1020 /// ```
1021 #[inline]
1022 fn argmax(self) -> Option<usize>
1023 where
1024 Self::Item: PartialOrd,
1025 {
1026 use std::cmp::Ordering;
1027 let mut max = None;
1028 let mut max_idx = None;
1029 let mut current_idx = 0;
1030 self.into_iter().for_each(|v| {
1031 if let Some(max_value) = &max {
1032 if let Some(Ordering::Greater) = v.partial_cmp(max_value) {
1033 max = Some(v);
1034 max_idx = Some(current_idx);
1035 }
1036 } else {
1037 max = Some(v);
1038 max_idx = Some(current_idx);
1039 }
1040 current_idx += 1;
1041 });
1042 max_idx
1043 }
1044
1045 /// Returns the index of the minimum element in the iterator.
1046 ///
1047 /// This method iterates through all elements and returns the index of the minimum value.
1048 ///
1049 /// # Type Parameters
1050 ///
1051 /// - `Self::Item`: Must implement `PartialOrd`.
1052 ///
1053 /// # Returns
1054 ///
1055 /// - `Some(usize)`: The index of the minimum value if the iterator is not empty.
1056 /// - `None`: If the iterator is empty.
1057 ///
1058 /// # Examples
1059 ///
1060 /// ```
1061 /// use tea_core::prelude::*;
1062 ///
1063 /// let numbers = vec![5, 1, 3, 2, 4];
1064 /// assert_eq!(numbers.titer().argmin(), Some(1));
1065 ///
1066 /// let empty: Vec<i32> = vec![];
1067 /// assert_eq!(empty.titer().argmin(), None);
1068 /// ```
1069 #[inline]
1070 fn argmin(self) -> Option<usize>
1071 where
1072 Self::Item: PartialOrd,
1073 {
1074 use std::cmp::Ordering;
1075 let mut min = None;
1076 let mut min_idx = None;
1077 let mut current_idx = 0;
1078 self.into_iter().for_each(|v| {
1079 if let Some(min_value) = &min {
1080 if let Some(Ordering::Less) = v.partial_cmp(min_value) {
1081 min = Some(v);
1082 min_idx = Some(current_idx);
1083 }
1084 } else {
1085 min = Some(v);
1086 min_idx = Some(current_idx);
1087 }
1088 current_idx += 1;
1089 });
1090 min_idx
1091 }
1092}
1093
1094impl<I: IntoIterator> AggBasic for I {}
1095impl<I: IntoIterator<Item = T>, T: IsNone> AggValidBasic<T> for I {}
1096
1097#[cfg(test)]
1098mod tests {
1099 use super::*;
1100 use crate::prelude::*;
1101 #[test]
1102 fn test_sum() {
1103 let data: Vec<i32> = vec![];
1104 assert_eq!(AggBasic::sum(data.titer()), None);
1105 let data = vec![1, 2, 3, 4, 5];
1106 assert_eq!(AggBasic::sum(data.titer()), Some(15));
1107 assert_eq!(data.titer().mean(), Some(3.));
1108 assert_eq!(data.titer().vsum(), Some(15));
1109 assert_eq!(data.opt().vmean(), 3.);
1110 let data = vec![1., f64::NAN, 3.];
1111 assert!(AggBasic::sum(data.titer()).unwrap().is_nan());
1112 assert_eq!(data.titer().vsum(), Some(4.));
1113 assert_eq!(AggValidBasic::vsum(&data.opt()), Some(4.));
1114 assert_eq!(data.opt().vmean(), 2.);
1115 // #[cfg(feature = "ndarray")]
1116 // {
1117 // use ndarray::prelude::*;
1118 // let arr = arr0(1.);
1119 // assert_eq!(arr.titer().vsum(), Some(1.));
1120 // assert_eq!(arr.titer().vmean(), Some(1.))
1121 // }
1122 }
1123
1124 #[test]
1125 fn test_cmp() {
1126 let data = vec![1., 3., f64::NAN, 2., 5.];
1127 assert_eq!(AggBasic::max(data.titer()), Some(5.));
1128 assert_eq!(AggBasic::min(data.titer()), Some(1.));
1129 assert_eq!(data.opt().vmax(), Some(5.));
1130 assert_eq!(data.opt().vmin(), Some(1.));
1131 let data: Vec<_> = data.opt().collect_trusted_vec1();
1132 assert_eq!(data.titer().vmax(), Some(5.));
1133 assert_eq!(data.vmin(), Some(1.));
1134 let data = vec![Some(1.), Some(2.), None, Some(3.)];
1135 assert_eq!(data.titer().vmin(), Some(1.));
1136 }
1137
1138 #[test]
1139 fn test_count() {
1140 let data = vec![1., 2., f64::NAN, 2., f64::NAN, f64::NAN];
1141 assert_eq!(data.opt().count_valid(), 3);
1142 assert_eq!(data.opt().count_none(), 3);
1143 assert_eq!(data.titer().count_value(1.), 1);
1144 assert_eq!(data.titer().count_value(2.), 2);
1145 assert_eq!(data.titer().vcount_value(1.), 1);
1146 assert_eq!(data.titer().vcount_value(f64::NAN), 3);
1147 assert_eq!((data.opt().vcount_value(Some(2.))), 2);
1148 assert_eq!((data.opt().vcount_value(None)), 3);
1149 }
1150
1151 #[test]
1152 fn test_bool() {
1153 let data = vec![true, false, false, false];
1154 assert!(data.titer().any());
1155 assert!(data.titer().vany());
1156 assert!(data.opt().vany());
1157 let data = vec![false, false, false, false];
1158 assert!(!data.titer().any());
1159 assert!(!data.titer().vany());
1160 assert!(!data.opt().vany());
1161 let data = vec![true, true, true, true];
1162 assert!(data.titer().all());
1163 assert!(data.titer().vall());
1164 assert!(data.opt().vall());
1165 let data = vec![true, false, true, true];
1166 assert!(!data.titer().all());
1167 assert!(!data.titer().vall());
1168 assert!(!data.opt().vall());
1169 }
1170
1171 #[test]
1172 fn test_argmax_and_argmin() {
1173 let data = vec![2, 1, 3, -3];
1174 assert_eq!(data.titer().vargmax(), Some(2));
1175 assert_eq!(data.titer().vargmin(), Some(3));
1176 assert_eq!(data.titer().argmax(), Some(2));
1177 assert_eq!(data.titer().argmin(), Some(3));
1178 let data = vec![Some(5.), Some(2.), None, Some(1.), Some(-3.), Some(4.)];
1179 assert_eq!(data.titer().vargmax(), Some(0));
1180 assert_eq!(data.titer().vargmin(), Some(4));
1181 }
1182}