mod confidence;
mod piecewise;
mod robust;
mod seasonal;
mod spline;
pub use confidence::*;
pub use piecewise::*;
pub use robust::*;
pub use seasonal::*;
pub use spline::*;
use scirs2_core::ndarray::{Array1, Array2};
use scirs2_core::numeric::{Float, FromPrimitive};
use std::fmt::Debug;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SplineType {
Cubic,
NaturalCubic,
BSpline,
PSpline,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KnotPlacementStrategy {
Uniform,
Quantile,
Custom,
}
#[derive(Debug, Clone)]
pub struct SplineTrendOptions {
pub spline_type: SplineType,
pub num_knots: usize,
pub knot_placement: KnotPlacementStrategy,
pub knot_positions: Option<Vec<usize>>,
pub extrapolate: bool,
pub degree: usize,
pub lambda: f64,
}
impl Default for SplineTrendOptions {
fn default() -> Self {
SplineTrendOptions {
spline_type: SplineType::Cubic,
num_knots: 10,
knot_placement: KnotPlacementStrategy::Uniform,
knot_positions: None,
extrapolate: false,
degree: 3,
lambda: 1.0,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RobustFilterMethod {
HodrickPrescott,
L1Filter,
Whittaker,
}
#[derive(Debug, Clone)]
pub struct RobustFilterOptions {
pub method: RobustFilterMethod,
pub lambda: f64,
pub order: usize,
pub max_iter: usize,
pub tol: f64,
pub weight_function: WeightFunction,
pub tuning_parameter: f64,
}
impl Default for RobustFilterOptions {
fn default() -> Self {
RobustFilterOptions {
method: RobustFilterMethod::HodrickPrescott,
lambda: 1600.0,
order: 2,
max_iter: 100,
tol: 1e-6,
weight_function: WeightFunction::Bisquare,
tuning_parameter: 4.685,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WeightFunction {
Huber,
Bisquare,
Andrews,
Cauchy,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BreakpointMethod {
BinarySegmentation,
PELT,
BottomUp,
Custom,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BreakpointCriterion {
AIC,
BIC,
RSS,
ModifiedBIC,
}
#[derive(Debug, Clone)]
pub struct PiecewiseTrendOptions {
pub breakpoint_method: BreakpointMethod,
pub criterion: BreakpointCriterion,
pub min_segment_length: usize,
pub max_breakpoints: Option<usize>,
pub custom_breakpoints: Option<Vec<usize>>,
pub penalty: Option<f64>,
pub segment_model: SegmentModelType,
pub allow_discontinuities: bool,
}
impl Default for PiecewiseTrendOptions {
fn default() -> Self {
PiecewiseTrendOptions {
breakpoint_method: BreakpointMethod::BinarySegmentation,
criterion: BreakpointCriterion::BIC,
min_segment_length: 10,
max_breakpoints: None,
custom_breakpoints: None,
penalty: None,
segment_model: SegmentModelType::Linear,
allow_discontinuities: true,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SegmentModelType {
Constant,
Linear,
Quadratic,
Cubic,
Spline,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConfidenceIntervalMethod {
Bootstrap,
Parametric,
Prediction,
}
#[derive(Debug, Clone)]
pub struct ConfidenceIntervalOptions {
pub method: ConfidenceIntervalMethod,
pub level: f64,
pub num_bootstrap: usize,
pub block_bootstrap: bool,
pub block_length: usize,
pub include_observation_noise: bool,
pub estimate_noise_variance: bool,
pub noise_variance: Option<f64>,
}
impl Default for ConfidenceIntervalOptions {
fn default() -> Self {
ConfidenceIntervalOptions {
method: ConfidenceIntervalMethod::Bootstrap,
level: 0.95,
num_bootstrap: 1000,
block_bootstrap: true,
block_length: 10,
include_observation_noise: true,
estimate_noise_variance: true,
noise_variance: None,
}
}
}
#[derive(Debug, Clone)]
pub struct TrendWithConfidenceInterval<F: Float> {
pub trend: Array1<F>,
pub lower: Array1<F>,
pub upper: Array1<F>,
}
pub(crate) fn create_difference_matrix<F>(n: usize, order: usize) -> Array2<F>
where
F: Float + FromPrimitive + Debug,
{
let mut d = Array2::<F>::zeros((n - 1, n));
for i in 0..(n - 1) {
d[[i, i]] = F::one();
d[[i, i + 1]] = -F::one();
}
if order > 1 {
let d_lower = create_difference_matrix::<F>(n - 1, order - 1);
let mut d_higher = Array2::<F>::zeros((n - order, n));
for i in 0..(n - order) {
for j in 0..n {
let mut sum = F::zero();
for k in 0..(n - 1) {
if j < n - 1 {
sum = sum + d_lower[[i, k]] * d[[k, j]];
}
}
d_higher[[i, j]] = sum;
}
}
return d_higher;
}
d
}