fraug/augmenters/
time_warp.rs1use super::base::Augmenter;
2use rand::{Rng, rng};
3use tracing:: {info, info_span};
4
5pub struct RandomTimeWarpAugmenter {
11 pub name: String,
12 pub window_size: usize,
14 pub speed_ratio_range: (f64, f64),
16 p: f64,
17}
18
19impl RandomTimeWarpAugmenter {
20 pub fn new(window_size: usize, speed_ratio_range: (f64, f64)) -> Self {
23 RandomTimeWarpAugmenter {
24 name: "RandomTimeWarpAugmenter".to_string(),
25 window_size,
26 speed_ratio_range,
27 p: 1.0,
28 }
29 }
30
31 fn warp_series(series: &[f64],speed_ratio_range: (f64, f64),rng: &mut impl Rng)-> Vec<f64> {
32 let len = series.len();
33 if len < 2 { return series.to_vec(); }
34
35 let warp_ratio = rng.random_range(speed_ratio_range.0..=speed_ratio_range.1);
37
38 let times: Vec<f64> = (0..len).map(|i| (i as f64) / warp_ratio).collect();
39
40 times.into_iter().map(|t| {
41 let t = t.clamp(0.0, (len - 1) as f64);
42 let lo = t.floor() as usize;
43 let hi = t.ceil() as usize;
44 if lo == hi {
45 series[lo]
46 } else {
47 let w = t - lo as f64;
48 series[lo] * (1.0 - w) + series[hi] * w
49 }
50 }).collect()
51 }
52}
53
54impl Augmenter for RandomTimeWarpAugmenter {
55 fn augment_one(&self, x: &[f64]) -> Vec<f64> {
56 let span = info_span!("", step = "augment_one");
57 let _enter = span.enter();
58 let mut rng = rng();
59 let mut series = x.to_vec();
60 let len = series.len();
61
62 let (window_start, window_end) = if self.window_size == 0 || self.window_size >= len {
63 (0, len-1)
64 } else {
65 let start_index = rng.random_range(0..len - self.window_size);
66 (start_index, start_index + self.window_size)
67 };
68 info!("window selected from : {:?} to {:?} ", window_start, window_end);
69 let warped_series = Self::warp_series(
70 &series[window_start..=window_end],
71 self.speed_ratio_range,
72 &mut rng,
73 );
74 info!("Warped series: {:?}", warped_series);
75 series[window_start..=window_end].copy_from_slice(&warped_series);
76
77 series
78 }
79
80 fn get_probability(&self) -> f64 {
81 self.p
82 }
83
84 fn set_probability(&mut self, probability: f64) {
85 self.p = probability;
86 }
87
88 fn get_name(&self) -> String{
89 self.name.clone()
90 }
91}