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}