pub(crate) mod l1;
pub(crate) mod l2;
mod tree;
use std::ops::Range;
use l2::{L2Cost1D, L2Cost2D};
use ndarray::{ArrayView1, ArrayView2};
use crate::cost::l1::{L1Cost1D, L1Cost2D};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum SegmentCostFunction {
#[default]
L1,
L2,
}
impl SegmentCostFunction {
#[cfg(feature = "rayon")]
#[inline]
pub(crate) const fn should_use_threading(self, iterations: usize) -> bool {
match self {
Self::L1 => iterations >= 32,
Self::L2 => iterations >= 512,
}
}
}
#[doc(hidden)]
pub enum Cost1D {
L1(L1Cost1D),
L2(L2Cost1D),
}
impl Cost1D {
#[inline]
pub(crate) fn precalculate(cost: SegmentCostFunction, signal: &ArrayView1<f64>) -> Self {
match cost {
SegmentCostFunction::L1 => Self::L1(L1Cost1D::precalculate(signal)),
SegmentCostFunction::L2 => Self::L2(L2Cost1D::precalculate(signal)),
}
}
#[inline]
pub(crate) fn loss(&self, total_loss: &mut f64, signal: &ArrayView1<f64>, range: Range<usize>) {
match self {
Self::L1(cost) => cost.loss(total_loss, signal, range),
Self::L2(cost) => cost.loss(total_loss, range),
}
}
}
#[doc(hidden)]
pub enum Cost2D {
L1(L1Cost2D),
L2(L2Cost2D),
}
impl Cost2D {
#[inline]
pub(crate) fn precalculate(cost: SegmentCostFunction, signal: &ArrayView2<f64>) -> Self {
match cost {
SegmentCostFunction::L1 => Self::L1(L1Cost2D::precalculate(signal)),
SegmentCostFunction::L2 => Self::L2(L2Cost2D::precalculate(signal)),
}
}
#[inline]
pub(crate) fn loss(&self, total_loss: &mut f64, signal: &ArrayView2<f64>, range: Range<usize>) {
match self {
Self::L1(cost) => cost.loss(total_loss, signal, range),
Self::L2(cost) => cost.loss(total_loss, range),
}
}
}