Skip to main content

quantwave_core/features/
griffiths_dominant_cycle.rs

1//! Griffiths Dominant Cycle feature extractor wrapper.
2//!
3//! Wraps the Griffiths spectral estimation dominant cycle detector.
4//! Returns the estimated dominant cycle length — a high-value stationary cycle feature for ML.
5//!
6//! Source: quantwave-core/src/indicators/griffiths_dominant_cycle.rs (returns f64 dominant cycle estimate)
7
8use crate::indicators::griffiths_dominant_cycle::GriffithsDominantCycle;
9use crate::traits::Next;
10
11#[derive(Debug, Clone, Copy, PartialEq)]
12pub struct GriffithsDominantCycleFeatures {
13    pub dominant_cycle: f64,
14}
15
16#[derive(Debug, Clone)]
17pub struct GriffithsDominantCycleFeatureExtractor {
18    inner: GriffithsDominantCycle,
19}
20
21impl GriffithsDominantCycleFeatureExtractor {
22    pub fn new(lower_bound: usize, upper_bound: usize, length: usize) -> Self {
23        Self {
24            inner: GriffithsDominantCycle::new(lower_bound, upper_bound, length),
25        }
26    }
27}
28
29impl Next<f64> for GriffithsDominantCycleFeatureExtractor {
30    type Output = GriffithsDominantCycleFeatures;
31
32    fn next(&mut self, input: f64) -> Self::Output {
33        let dc = self.inner.next(input);
34        GriffithsDominantCycleFeatures { dominant_cycle: dc }
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn test_griffiths_wrapper_basic() {
44        let mut ext = GriffithsDominantCycleFeatureExtractor::new(10, 40, 30);
45        for i in 0..100 {
46            let val = 100.0 + 5.0 * (i as f64 * 0.25).sin();
47            let f = ext.next(val);
48            if !f.dominant_cycle.is_nan() {
49                assert!(f.dominant_cycle > 5.0 && f.dominant_cycle < 50.0);
50            }
51        }
52    }
53}