dirtydata_runtime/nodes/
nonlinear.rs1use super::base::*;
2use dirtydata_core::types::ConfigSnapshot;
3
4pub struct LorenzNode {
5 state: [f32; 3],
6}
7
8impl LorenzNode {
9 pub fn new() -> Self { Self { state: [0.1, 0.0, 0.0] } }
10}
11
12impl DspNode for LorenzNode {
13 fn process(&mut self, _inputs: &[f32], outputs: &mut [[f32; 2]], config: &ConfigSnapshot, ctx: &ProcessContext) {
14 let sigma = config.get("sigma").and_then(|v| v.as_float()).unwrap_or(10.0) as f32;
15 let rho = config.get("rho").and_then(|v| v.as_float()).unwrap_or(28.0) as f32;
16 let beta = config.get("beta").and_then(|v| v.as_float()).unwrap_or(8.0/3.0) as f32;
17 let dt = 1.0 / ctx.sample_rate;
18 rk4_step_fixed(&mut self.state, dt, 0.0, |s, _| {
19 let dx = sigma * (s[1] - s[0]);
20 let dy = s[0] * (rho - s[2]) - s[1];
21 let dz = s[0] * s[1] - beta * s[2];
22 [dx, dy, dz]
23 });
24 outputs[0] = [self.state[0] * 0.05, self.state[1] * 0.05];
25 }
26}
27
28pub struct MackeyGlassNode {
29 history: std::collections::VecDeque<f32>,
30 current_x: f32,
31}
32
33impl MackeyGlassNode {
34 pub fn new() -> Self { Self { history: std::collections::VecDeque::from(vec![0.5; 1000]), current_x: 0.5 } }
35}
36
37impl DspNode for MackeyGlassNode {
38 fn process(&mut self, _inputs: &[f32], outputs: &mut [[f32; 2]], config: &ConfigSnapshot, ctx: &ProcessContext) {
39 let a = config.get("a").and_then(|v| v.as_float()).unwrap_or(0.2) as f32;
40 let b = config.get("b").and_then(|v| v.as_float()).unwrap_or(0.1) as f32;
41 let tau_samples = config.get("tau_samples").and_then(|v| v.as_float()).unwrap_or(300.0) as usize;
42 let x_tau = *self.history.get(self.history.len().saturating_sub(tau_samples)).unwrap_or(&0.5);
43 let dx = (a * x_tau) / (1.0 + x_tau.powi(10)) - b * self.current_x;
44 self.current_x += dx / ctx.sample_rate;
45 self.history.push_back(self.current_x);
46 if self.history.len() > 2000 { self.history.pop_front(); }
47 outputs[0] = [self.current_x, self.current_x];
48 }
49}
50
51pub struct GrayScottNode {
52 u: Vec<f32>,
53 v: Vec<f32>,
54}
55
56impl GrayScottNode {
57 pub fn new() -> Self { Self { u: vec![1.0; 100], v: vec![0.0; 100] } }
58}
59
60impl DspNode for GrayScottNode {
61 fn process(&mut self, _inputs: &[f32], outputs: &mut [[f32; 2]], _config: &ConfigSnapshot, _ctx: &ProcessContext) {
62 outputs[0] = [self.u[0], self.v[0]];
64 }
65}