Skip to main content

dsfb_database/grammar/
envelope.rs

1//! Drift / slew envelope semantics.
2//!
3//! The DSFB-native interpretation of *drift* is the EMA-smoothed residual
4//! magnitude `s_k = ρ s_k + (1−ρ)|r_k|`; *slew* is the instantaneous
5//! residual magnitude `|r_k|`. An envelope is a deterministic threshold band
6//! over both: when `s_k > drift_threshold` we are in the drift phase; when
7//! additionally `|r_k| > slew_threshold` we are at a boundary breach.
8//!
9//! These are the same definitions used in the `dsfb-semiconductor` and
10//! `dsfb-oil-gas` companion crates; we restate them here for clarity rather
11//! than re-import to avoid a cross-crate coupling that would make
12//! `dsfb-database` harder to publish independently.
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum Envelope {
16    /// Below drift threshold; residual is within the noise envelope.
17    Stable,
18    /// EMA over drift threshold; persistent low-amplitude excursion.
19    Drift,
20    /// Slew over slew threshold; an instantaneous boundary breach.
21    Boundary,
22}
23
24pub fn classify(ema: f64, instant: f64, drift_threshold: f64, slew_threshold: f64) -> Envelope {
25    let abs_e = ema.abs();
26    let abs_i = instant.abs();
27    if abs_i >= slew_threshold {
28        Envelope::Boundary
29    } else if abs_e >= drift_threshold {
30        Envelope::Drift
31    } else {
32        Envelope::Stable
33    }
34}