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}