use std::f64::consts::PI;
pub fn sine_wave(n: usize, frequency: f64, amplitude: f64) -> Vec<f64> {
(0..n)
.map(|i| amplitude * (2.0 * PI * frequency * i as f64 / n as f64).sin())
.collect()
}
pub fn random_walk(n: usize, seed: u64) -> Vec<f64> {
let mut rng_state = seed;
let mut value = 0.0;
let mut result = Vec::with_capacity(n);
for _ in 0..n {
rng_state = rng_state.wrapping_mul(1664525).wrapping_add(1013904223);
let step = if (rng_state & 1) == 0 { 1.0 } else { -1.0 };
value += step;
result.push(value);
}
result
}
pub fn trend_with_noise(n: usize, trend: f64, noise_amplitude: f64, seed: u64) -> Vec<f64> {
let mut rng_state = seed;
(0..n)
.map(|i| {
rng_state = rng_state.wrapping_mul(1664525).wrapping_add(1013904223);
let noise = (rng_state as f64 / u64::MAX as f64 - 0.5) * noise_amplitude;
i as f64 * trend + noise
})
.collect()
}
pub fn multi_frequency(n: usize, frequencies: &[f64]) -> Vec<f64> {
(0..n)
.map(|i| {
frequencies
.iter()
.map(|&f| (2.0 * PI * f * i as f64 / n as f64).sin())
.sum()
})
.collect()
}
pub fn logistic_map(n: usize, r: f64, x0: f64) -> Vec<f64> {
let mut result = Vec::with_capacity(n);
let mut x = x0;
for _ in 0..n {
result.push(x);
x = r * x * (1.0 - x);
}
result
}
pub fn step_function(n: usize, levels: &[f64]) -> Vec<f64> {
let regime_length = n / levels.len();
let mut result = Vec::with_capacity(n);
for (i, &level) in levels.iter().enumerate() {
let start = i * regime_length;
let end = if i == levels.len() - 1 {
n
} else {
(i + 1) * regime_length
};
for _ in start..end {
result.push(level);
}
}
result
}
pub fn sawtooth(n: usize, period: usize) -> Vec<f64> {
(0..n)
.map(|i| (i % period) as f64 / period as f64)
.collect()
}
pub fn square_wave(n: usize, period: usize) -> Vec<f64> {
(0..n)
.map(|i| if (i / (period / 2)).is_multiple_of(2) { 1.0 } else { -1.0 })
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sine_wave() {
let data = sine_wave(100, 1.0, 1.0);
assert_eq!(data.len(), 100);
assert!(data[0].abs() < 0.1); }
#[test]
fn test_random_walk() {
let data1 = random_walk(100, 42);
let data2 = random_walk(100, 42);
assert_eq!(data1, data2); }
#[test]
fn test_logistic_map() {
let data = logistic_map(100, 3.9, 0.5);
assert_eq!(data.len(), 100);
assert!(data.iter().all(|&x| (0.0..=1.0).contains(&x)));
}
}