Skip to main content

ZScoreNormalizer

Struct ZScoreNormalizer 

Source
pub struct ZScoreNormalizer { /* private fields */ }
Expand description

Rolling z-score normalizer over a sliding window of Decimal observations.

Maps each new sample to its z-score: (x - mean) / std_dev. The rolling window maintains an O(1) mean and variance via incremental sum/sum-of-squares tracking, with O(W) recompute only when a value is evicted.

Returns 0.0 when the window has fewer than 2 observations (variance is 0).

§Example

use fin_stream::norm::ZScoreNormalizer;
use rust_decimal_macros::dec;

let mut norm = ZScoreNormalizer::new(5).unwrap();
for v in [dec!(10), dec!(20), dec!(30), dec!(40), dec!(50)] {
    norm.update(v);
}
// 30 is the mean; normalize returns 0.0
let z = norm.normalize(dec!(30)).unwrap();
assert!((z - 0.0).abs() < 1e-9);

Implementations§

Source§

impl ZScoreNormalizer

Source

pub fn new(window_size: usize) -> Result<Self, StreamError>

Create a new z-score normalizer with the given rolling window size.

§Errors

Returns StreamError::ConfigError if window_size == 0.

Source

pub fn update(&mut self, value: Decimal)

Add a new observation to the rolling window.

Evicts the oldest value when the window is full, adjusting running sums in O(1). No full recompute is needed unless eviction causes sum drift; the implementation recomputes exactly when necessary via recompute.

Source

pub fn normalize(&self, value: Decimal) -> Result<f64, StreamError>

Normalize value to a z-score using the current window’s mean and std dev.

Returns 0.0 if:

  • The window has fewer than 2 observations (std dev undefined).
  • The standard deviation is effectively zero (all window values identical).
§Errors

Returns StreamError::NormalizationError if the window is empty.

§Complexity: O(1)
Source

pub fn mean(&self) -> Option<Decimal>

Current rolling mean of the window, or None if the window is empty.

Source

pub fn std_dev(&self) -> Option<f64>

Current population standard deviation of the window.

Returns None if the window is empty. Returns Some(0.0) if fewer than 2 observations are present (undefined variance, treated as zero) or if all values are identical.

Source

pub fn reset(&mut self)

Reset the normalizer, clearing all observations and sums.

Source

pub fn len(&self) -> usize

Number of observations currently in the window.

Source

pub fn is_empty(&self) -> bool

Returns true if no observations have been added since construction or reset.

Source

pub fn window_size(&self) -> usize

The configured window size.

Source

pub fn is_full(&self) -> bool

Returns true when the window holds exactly window_size observations.

At full capacity the z-score calculation is stable; before this point the window may not be representative of the underlying distribution.

Source

pub fn sum(&self) -> Option<Decimal>

Running sum of all values currently in the window.

Returns None if the window is empty. Useful for deriving a rolling mean without calling normalize.

Source

pub fn variance(&self) -> Option<Decimal>

Current population variance of the window.

Computed as E[X²] − (E[X])² from running sums in O(1). Returns None if fewer than 2 observations are present (variance undefined).

Source

pub fn std_dev_f64(&self) -> Option<f64>

Standard deviation of the current window as f64.

Returns None if the window has fewer than 2 observations.

Source

pub fn variance_f64(&self) -> Option<f64>

Current window variance as f64 (convenience wrapper around variance).

Returns None if the window has fewer than 2 observations.

Source

pub fn normalize_batch( &mut self, values: &[Decimal], ) -> Result<Vec<f64>, StreamError>

Feed a slice of values into the window and return z-scores for each.

Each value is first passed through update to advance the rolling window, then normalized. The output has the same length as values.

§Errors

Propagates the first StreamError returned by normalize.

Source

pub fn is_outlier(&self, value: Decimal, z_threshold: f64) -> bool

Returns true if value is an outlier: its z-score exceeds z_threshold in magnitude.

Returns false when the window has fewer than 2 observations (z-score undefined). A typical threshold is 2.0 (95th percentile) or 3.0 (99.7th percentile).

Source

pub fn percentile_rank(&self, value: Decimal) -> Option<f64>

Percentile rank: fraction of window observations that are ≤ value.

Returns None if the window is empty. Range: [0.0, 1.0].

Source

pub fn running_min(&self) -> Option<Decimal>

Minimum value seen in the current window.

Returns None when the window is empty.

Source

pub fn running_max(&self) -> Option<Decimal>

Maximum value seen in the current window.

Returns None when the window is empty.

Source

pub fn window_range(&self) -> Option<Decimal>

Range of values in the current window: running_max − running_min.

Returns None when the window is empty.

Source

pub fn coefficient_of_variation(&self) -> Option<f64>

Coefficient of variation: std_dev / |mean|.

A dimensionless measure of relative dispersion. Returns None when the window has fewer than 2 observations or when the mean is zero.

Source

pub fn sample_variance(&self) -> Option<f64>

Population variance of the current window: std_dev².

Returns None when the window is empty (same conditions as std_dev).

Source

pub fn window_mean_f64(&self) -> Option<f64>

Current window mean as f64.

A convenience over calling mean() and then converting to f64. Returns None when the window is empty.

Source

pub fn is_near_mean(&self, value: Decimal, sigma_tolerance: f64) -> bool

Returns true if value is within sigma_tolerance standard deviations of the window mean (inclusive).

Equivalent to |z_score(value)| <= sigma_tolerance. Returns false when the window has fewer than 2 observations (z-score undefined).

Source

pub fn window_sum(&self) -> Decimal

Sum of all values currently in the window as Decimal.

Returns Decimal::ZERO on an empty window.

Source

pub fn window_sum_f64(&self) -> f64

Sum of all values currently in the window as f64.

Returns 0.0 on an empty window.

Source

pub fn window_max_f64(&self) -> Option<f64>

Maximum value currently in the window as f64.

Returns None when the window is empty.

Source

pub fn window_min_f64(&self) -> Option<f64>

Minimum value currently in the window as f64.

Returns None when the window is empty.

Source

pub fn window_span_f64(&self) -> Option<f64>

Difference between the window maximum and minimum, as f64.

Returns None if the window is empty.

Source

pub fn kurtosis(&self) -> Option<f64>

Excess kurtosis of the window: (Σ((x-mean)⁴/n) / std_dev⁴) - 3.

Returns None if the window has fewer than 4 observations or std dev is zero. A normal distribution has excess kurtosis of 0; positive values indicate heavier tails (leptokurtic); negative values indicate lighter tails (platykurtic).

Source

pub fn is_extreme(&self, value: Decimal, sigma: f64) -> bool

Returns true if the z-score of value exceeds sigma in absolute terms.

Convenience wrapper around normalize for alert logic. Returns false if the normalizer window is empty or std-dev is zero.

Source

pub fn latest(&self) -> Option<Decimal>

The most recently added value, or None if the window is empty.

Source

pub fn median(&self) -> Option<Decimal>

Median of the current window, or None if empty.

Source

pub fn percentile(&self, value: Decimal) -> Option<f64>

Empirical percentile of value within the current window: fraction of values ≤ value.

Returns a value in [0.0, 1.0]. Returns None if the window is empty.

Source

pub fn ema_z_score( value: Decimal, alpha: f64, ema_mean: &mut f64, ema_var: &mut f64, ) -> Option<f64>

Stateless EMA z-score helper: updates running ema_mean and ema_var and returns the z-score (value - ema_mean) / sqrt(ema_var).

alpha ∈ (0, 1] controls smoothing speed (higher = faster adaptation). Initialize ema_mean = 0.0 and ema_var = 0.0 before first call. Returns None if value cannot be converted to f64 or variance is still zero.

Source

pub fn z_score_of_latest(&self) -> Option<f64>

Z-score of the most recently added value.

Returns None if the window is empty or std-dev is zero.

Source

pub fn ema_of_z_scores(&self, alpha: f64) -> Option<f64>

Exponential moving average of z-scores for all values in the current window.

alpha is the smoothing factor (0 < alpha ≤ 1). Higher alpha gives more weight to recent z-scores. Returns None if the window has fewer than 2 observations.

Source

pub fn add_observation(&mut self, value: Decimal) -> &mut Self

Chainable alias for update: feeds value into the window and returns &mut Self.

Source

pub fn deviation_from_mean(&self, value: Decimal) -> Option<f64>

Signed deviation of value from the window mean, as f64.

Returns None if the window is empty.

Source

pub fn trim_outliers(&self, sigma: f64) -> Vec<Decimal>

Returns a Vec of window values that are within sigma standard deviations of the mean.

Useful for robust statistics after removing extreme outliers. Returns all values if std-dev is zero (no outliers possible), empty vec if window is empty.

Source

pub fn rolling_zscore_batch(&mut self, values: &[Decimal]) -> Vec<Option<f64>>

Batch normalize: returns z-scores for each value as if they were added one-by-one.

Each z-score uses only the window state after incorporating that value. The internal state is modified; call reset() if you need to restore it. Returns None entries where normalization fails (window warming up or zero std-dev).

Source

pub fn rolling_mean_change(&self) -> Option<f64>

Change in mean between the first half and second half of the current window.

Splits the window in two, computes the mean of each half, and returns second_half_mean - first_half_mean as f64. Returns None if the window has fewer than 2 observations.

Source

pub fn count_positive_z_scores(&self) -> usize

Count of window values whose z-score is strictly positive (above the mean).

Returns 0 if the window is empty or all values are equal (z-scores are all 0).

Source

pub fn is_mean_stable(&self, threshold: f64) -> bool

Returns true if the absolute change between first-half and second-half window means is below threshold. A stable mean indicates the distribution is not trending.

Returns false if the window has fewer than 2 observations.

Source

pub fn above_threshold_count(&self, z_threshold: f64) -> usize

Count of window values whose absolute z-score exceeds z_threshold.

Returns 0 if the window has fewer than 2 observations or std-dev is zero.

Source

pub fn mad(&self) -> Option<Decimal>

Median Absolute Deviation (MAD) of the current window.

MAD = median(|x_i - median(window)|). Returns None if the window is empty.

Source

pub fn robust_z_score(&self, value: Decimal) -> Option<f64>

Robust z-score: (value - median) / MAD.

More resistant to outliers than the standard z-score. Returns None when the window is empty or MAD is zero.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more