Skip to main content

antecedent_data/
reference.rs

1//! Reference-point policies for temporal sample alignment.
2//!
3//! SPDX-License-Identifier: MIT OR Apache-2.0
4
5/// How lag-aligned samples choose their contemporaneous origin row.
6#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Default)]
7pub enum ReferencePointPolicy {
8    /// Origin at row `max_lag` so every lag in `0..=max_lag` is in-bounds
9    /// (default stationary series alignment).
10    #[default]
11    SeriesOrigin,
12    /// Absolute origin row; effective samples are
13    /// `origin_row .. series_len` clipped so lags stay in-bounds.
14    AbsoluteOrigin {
15        /// Row treated as contemporaneous lag-0.
16        origin_row: usize,
17    },
18}
19
20impl ReferencePointPolicy {
21    /// Base contemporaneous row and effective sample count for a series.
22    ///
23    /// # Errors
24    ///
25    /// Empty series, `max_lag` too large, or origin out of range.
26    pub fn base_and_n(
27        self,
28        series_len: usize,
29        max_lag: u32,
30    ) -> Result<(usize, usize), crate::error::DataError> {
31        use crate::error::DataError;
32        if series_len == 0 {
33            return Err(DataError::InvalidArgument { message: "empty time series".into() });
34        }
35        let max_lag_usize = max_lag as usize;
36        if max_lag_usize >= series_len {
37            return Err(DataError::InvalidArgument {
38                message: "max_lag must be strictly less than series length".into(),
39            });
40        }
41        match self {
42            Self::SeriesOrigin => {
43                let base = max_lag_usize;
44                Ok((base, series_len - base))
45            }
46            Self::AbsoluteOrigin { origin_row } => {
47                if origin_row < max_lag_usize || origin_row >= series_len {
48                    return Err(DataError::InvalidArgument {
49                        message: "absolute origin must satisfy max_lag <= origin < series_len"
50                            .into(),
51                    });
52                }
53                Ok((origin_row, series_len - origin_row))
54            }
55        }
56    }
57}