1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use crate::maximum::{Max, RollingMax};
use crate::minimum::{Min, RollingMin};
use crate::stats::Univariate;
use num::{Float, FromPrimitive};
use serde::{Deserialize, Serialize};
use std::ops::{AddAssign, SubAssign};
/// Running peak to peak (max - min).
/// # Examples
/// ```
/// use online_statistics::ptp::PeakToPeak;
/// use online_statistics::stats::Univariate;
/// let mut running_peak_to_peak: PeakToPeak<f64> = PeakToPeak::new();
/// for i in 1..10{
///     running_peak_to_peak.update(i as f64);
/// }
/// assert_eq!(running_peak_to_peak.get(), 8.0);
/// ```
///
#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)]
pub struct PeakToPeak<F: Float + FromPrimitive + AddAssign + SubAssign> {
    pub min: Min<F>,
    pub max: Max<F>,
}

impl<F: Float + FromPrimitive + AddAssign + SubAssign> PeakToPeak<F> {
    pub fn new() -> Self {
        Self {
            min: Min::new(),
            max: Max::new(),
        }
    }
}

impl<F: Float + FromPrimitive + AddAssign + SubAssign> Univariate<F> for PeakToPeak<F> {
    fn update(&mut self, x: F) {
        self.min.update(x);
        self.max.update(x);
    }
    fn get(&self) -> F {
        self.max.get() - self.min.get()
    }
}

/// Rolling peak to peak (max - min).
/// # Arguments
/// * `window_size` - Size of the rolling window.
/// # Examples
/// ```
/// use online_statistics::ptp::RollingPeakToPeak;
/// use online_statistics::stats::Univariate;
/// let mut rolling_peak_to_peak: RollingPeakToPeak<f64> = RollingPeakToPeak::new(3);
/// for i in 1..10{
///     rolling_peak_to_peak.update(i as f64);
/// }
/// assert_eq!(rolling_peak_to_peak.get(), 2.0);
/// ```
///
#[derive(Serialize, Deserialize)]
pub struct RollingPeakToPeak<F: Float + FromPrimitive + AddAssign + SubAssign> {
    pub min: RollingMin<F>,
    pub max: RollingMax<F>,
}

impl<F: Float + FromPrimitive + AddAssign + SubAssign> RollingPeakToPeak<F> {
    pub fn new(window_size: usize) -> Self {
        Self {
            min: RollingMin::new(window_size),
            max: RollingMax::new(window_size),
        }
    }
}

impl<F: Float + FromPrimitive + AddAssign + SubAssign> Univariate<F> for RollingPeakToPeak<F> {
    fn update(&mut self, x: F) {
        self.min.update(x);
        self.max.update(x);
    }
    fn get(&self) -> F {
        self.max.get() - self.min.get()
    }
}