pub struct MinMaxNormalizer { /* private fields */ }Expand description
Rolling min-max normalizer over a sliding window of Decimal observations.
§Example
use fin_stream::norm::MinMaxNormalizer;
use rust_decimal_macros::dec;
let mut norm = MinMaxNormalizer::new(4).unwrap();
norm.update(dec!(10));
norm.update(dec!(20));
norm.update(dec!(30));
norm.update(dec!(40));
// 40 is the current max; 10 is the current min
let v = norm.normalize(dec!(40)).unwrap();
assert!((v - 1.0).abs() < 1e-10);Implementations§
Source§impl MinMaxNormalizer
impl MinMaxNormalizer
Sourcepub fn new(window_size: usize) -> Result<Self, StreamError>
pub fn new(window_size: usize) -> Result<Self, StreamError>
Create a new normalizer with the given rolling window size.
§Errors
Returns StreamError::ConfigError if window_size == 0.
Sourcepub fn min_max(&mut self) -> Option<(Decimal, Decimal)>
pub fn min_max(&mut self) -> Option<(Decimal, Decimal)>
Return the current (min, max) of the window.
Returns None if the window is empty.
§Complexity: O(1) when the cache is clean; O(W) after an eviction.
Sourcepub fn normalize(&mut self, value: Decimal) -> Result<f64, StreamError>
pub fn normalize(&mut self, value: Decimal) -> Result<f64, StreamError>
Normalize value into [0.0, 1.0] using the current window.
The value is clamped so that even if value falls outside the window
range the result is always in [0.0, 1.0].
§Errors
Returns StreamError::NormalizationError if the window is empty (no
observations have been fed yet), or if the normalized Decimal cannot be
converted to f64.
§Complexity: O(1) when cache is clean; O(W) after an eviction.
Sourcepub fn denormalize(&mut self, normalized: f64) -> Result<Decimal, StreamError>
pub fn denormalize(&mut self, normalized: f64) -> Result<Decimal, StreamError>
Inverse of normalize: map a [0, 1] value back to
the original scale.
denormalized = normalized * (max - min) + min
Works outside [0, 1] for extrapolation, but returns
StreamError::NormalizationError if the window is empty.
Sourcepub fn range(&mut self) -> Option<Decimal>
pub fn range(&mut self) -> Option<Decimal>
Scale of the current window: max - min.
Returns None if the window is empty. Returns Decimal::ZERO when all
observations are identical (zero range → degenerate distribution).
Sourcepub fn clamp_to_window(&mut self, value: Decimal) -> Decimal
pub fn clamp_to_window(&mut self, value: Decimal) -> Decimal
Clamps value to the [min, max] range of the current window.
Returns value unchanged if the window is empty (no clamping possible).
Sourcepub fn midpoint(&mut self) -> Option<Decimal>
pub fn midpoint(&mut self) -> Option<Decimal>
Midpoint of the current window: (min + max) / 2.
Returns None if the window is empty.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if no observations have been added since construction or
the last reset.
Sourcepub fn window_size(&self) -> usize
pub fn window_size(&self) -> usize
The configured window size.
Sourcepub fn is_full(&self) -> bool
pub fn is_full(&self) -> bool
Returns true when the window holds exactly window_size observations.
At full capacity the normalizer has seen enough data for stable min/max estimates; before this point early observations dominate the range.
Sourcepub fn min(&mut self) -> Option<Decimal>
pub fn min(&mut self) -> Option<Decimal>
Current window minimum, or None if the window is empty.
Equivalent to self.min_max().map(|(min, _)| min) but avoids also
computing the max when only the min is needed.
Sourcepub fn max(&mut self) -> Option<Decimal>
pub fn max(&mut self) -> Option<Decimal>
Current window maximum, or None if the window is empty.
Equivalent to self.min_max().map(|(_, max)| max) but avoids also
computing the min when only the max is needed.
Sourcepub fn mean(&self) -> Option<Decimal>
pub fn mean(&self) -> Option<Decimal>
Returns the arithmetic mean of the current window observations.
Returns None if the window is empty.
Sourcepub fn normalize_batch(
&mut self,
values: &[Decimal],
) -> Result<Vec<f64>, StreamError>
pub fn normalize_batch( &mut self, values: &[Decimal], ) -> Result<Vec<f64>, StreamError>
Feed a slice of values into the window and return normalized forms of each.
Each value in values is first passed through update to
advance the rolling window, then normalized against the current window state.
The output has the same length as values.
§Errors
Propagates the first StreamError returned by normalize.
Sourcepub fn normalize_clamp(&mut self, value: Decimal) -> Result<f64, StreamError>
pub fn normalize_clamp(&mut self, value: Decimal) -> Result<f64, StreamError>
Normalize value and clamp the result to [0.0, 1.0].
Identical to normalize but silently clamps values
that fall outside the window’s observed range. Useful when applying a
learned normalizer to out-of-sample data without erroring on outliers.
§Errors
Returns StreamError::NormalizationError if the window is empty.
Sourcepub fn z_score(&self, value: Decimal) -> Option<f64>
pub fn z_score(&self, value: Decimal) -> Option<f64>
Compute the z-score of value relative to the current window.
z = (value - mean) / stddev
Returns None if the window has fewer than 2 observations, or if the
standard deviation is zero (all values identical).
Useful for detecting outliers and standardising features for ML models
when a bounded [0, 1] range is not required.
Sourcepub fn percentile_rank(&self, value: Decimal) -> Option<f64>
pub fn percentile_rank(&self, value: Decimal) -> Option<f64>
Returns the percentile rank of value within the current window.
The percentile rank is the fraction of window values that are <= value,
expressed in [0.0, 1.0]. Returns None if the window is empty.
Useful for identifying whether the current value is historically high or low relative to its recent context without requiring a min/max range.
Sourcepub fn count_above(&self, threshold: Decimal) -> usize
pub fn count_above(&self, threshold: Decimal) -> usize
Count of observations in the current window that are strictly above threshold.
Sourcepub fn fraction_above_mid(&mut self) -> Option<f64>
pub fn fraction_above_mid(&mut self) -> Option<f64>
Fraction of window values strictly above the midpoint (min + max) / 2.
Returns None if the window is empty. Returns 0.0 if all values are equal.
Sourcepub fn normalized_range(&mut self) -> Option<f64>
pub fn normalized_range(&mut self) -> Option<f64>
(max - min) / max as f64 — the range as a fraction of the maximum.
Measures how wide the window’s spread is relative to its peak. Returns
None if the window is empty or the maximum is zero.
Sourcepub fn ewma(&self, alpha: f64) -> Option<f64>
pub fn ewma(&self, alpha: f64) -> Option<f64>
Exponential weighted moving average of the current window values.
Applies alpha as the smoothing factor (most-recent weight), scanning oldest→newest.
alpha is clamped to (0, 1]. Returns None if the window is empty.
Sourcepub fn interquartile_range(&self) -> Option<Decimal>
pub fn interquartile_range(&self) -> Option<Decimal>
Interquartile range: Q3 (75th percentile) − Q1 (25th percentile) of the window.
Returns None if the window has fewer than 4 observations.
The IQR is a robust spread measure less sensitive to outliers than range or std dev.