1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
pub use crate::error::EvaluatorError;
pub use crate::float_trait::Float;
pub use crate::time_series::TimeSeries;

use dyn_clonable::*;
pub use lazy_static::lazy_static;
pub use std::fmt::Debug;

#[derive(Clone, Debug, PartialEq)]
pub struct EvaluatorInfo {
    pub size: usize,
    pub min_ts_length: usize,
    pub t_required: bool,
    pub m_required: bool,
    pub w_required: bool,
    pub sorting_required: bool,
}

/// The trait each feature should implement
#[clonable]
pub trait FeatureEvaluator<T: Float>: Send + Sync + Clone + Debug {
    /// Should return the vector of feature values
    fn eval(&self, ts: &mut TimeSeries<T>) -> Result<Vec<T>, EvaluatorError>;

    fn eval_or_fill(&self, ts: &mut TimeSeries<T>, fill_value: T) -> Vec<T> {
        match self.eval(ts) {
            Ok(v) => v,
            Err(_) => vec![fill_value; self.size_hint()],
        }
    }

    /// Get feature evaluator meta-information
    fn get_info(&self) -> &EvaluatorInfo;

    /// Should return the vector of feature names. The length and feature order should
    /// correspond to `eval()` output
    fn get_names(&self) -> Vec<&str>;

    /// Should return the size of vectors returned by `eval()` and `get_names()`
    fn size_hint(&self) -> usize {
        self.get_info().size
    }

    /// Should return minimum time series length to successfully find feature value
    fn min_ts_length(&self) -> usize {
        self.get_info().min_ts_length
    }

    fn is_t_required(&self) -> bool {
        self.get_info().t_required
    }

    fn is_m_required(&self) -> bool {
        self.get_info().m_required
    }

    fn is_w_required(&self) -> bool {
        self.get_info().w_required
    }

    fn is_sorting_required(&self) -> bool {
        self.get_info().sorting_required
    }

    fn check_ts_length(&self, ts: &TimeSeries<T>) -> Result<usize, EvaluatorError> {
        let length = ts.lenu();
        if length < self.min_ts_length() {
            Err(EvaluatorError::ShortTimeSeries {
                actual: length,
                minimum: self.min_ts_length(),
            })
        } else {
            Ok(length)
        }
    }
}

pub type VecFE<T> = Vec<Box<dyn FeatureEvaluator<T>>>;

pub fn get_nonzero_m_std<T: Float>(ts: &mut TimeSeries<T>) -> Result<T, EvaluatorError> {
    let std = ts.m.get_std();
    if std.is_zero() {
        Err(EvaluatorError::FlatTimeSeries)
    } else {
        Ok(std)
    }
}

pub fn get_nonzero_m_std2<T: Float>(ts: &mut TimeSeries<T>) -> Result<T, EvaluatorError> {
    let std2 = ts.m.get_std2();
    if std2.is_zero() {
        Err(EvaluatorError::FlatTimeSeries)
    } else {
        Ok(std2)
    }
}

pub fn get_nonzero_reduced_chi2<T: Float>(ts: &mut TimeSeries<T>) -> Result<T, EvaluatorError> {
    let reduced_chi2 = ts.get_m_reduced_chi2();
    if reduced_chi2.is_zero() {
        Err(EvaluatorError::FlatTimeSeries)
    } else {
        Ok(reduced_chi2)
    }
}

pub struct TMWVectors<T> {
    pub t: Vec<T>,
    pub m: Vec<T>,
    pub w: Option<Vec<T>>,
}