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,
}
#[clonable]
pub trait FeatureEvaluator<T: Float>: Send + Sync + Clone + Debug {
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()],
}
}
fn get_info(&self) -> &EvaluatorInfo;
fn get_names(&self) -> Vec<&str>;
fn size_hint(&self) -> usize {
self.get_info().size
}
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>>,
}