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