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
use crate::evaluator::*; use crate::straight_line_fit::fit_straight_line; macro_const! { const DOC: &str = r#" Slope, its error and reduced $\chi^2$ of the light curve in the linear fit Least squares fit of the linear stochastic model with Gaussian noise described by observation errors $\{\delta_i\}$: $$ m_i = c + \mathrm{slope}\,t_i + \delta_i \varepsilon_i $$ where $c$ is a constant, $\{\varepsilon_i\}$ are standard distributed random variables. Feature values are $\mathrm{slope}$, $\sigma_\mathrm{slope}$ and $\frac{\sum{((m_i - c - \mathrm{slope}\,t_i) / \delta_i)^2}}{N - 2}$. - Depends on: **time**, **magnitude**, **magnitude error** - Minimum number of observations: **3** - Number of features: **3** "#; } #[doc = DOC!()] #[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema)] pub struct LinearFit {} impl LinearFit { pub fn new() -> Self { Self {} } pub fn doc() -> &'static str { DOC } } lazy_info!( LINEAR_FIT_INFO, size: 3, min_ts_length: 3, t_required: true, m_required: true, w_required: true, sorting_required: true, ); impl<T> FeatureEvaluator<T> for LinearFit where T: Float, { fn eval(&self, ts: &mut TimeSeries<T>) -> Result<Vec<T>, EvaluatorError> { self.check_ts_length(ts)?; let result = fit_straight_line(ts, true); Ok(vec![ result.slope, T::sqrt(result.slope_sigma2), result.reduced_chi2, ]) } fn get_info(&self) -> &EvaluatorInfo { &LINEAR_FIT_INFO } fn get_names(&self) -> Vec<&str> { vec![ "linear_fit_slope", "linear_fit_slope_sigma", "linear_fit_reduced_chi2", ] } fn get_descriptions(&self) -> Vec<&str> { vec![ "slope of linear fit", "error of slope of linear fit", "linear fit quality (reduced chi2)", ] } } #[cfg(test)] #[allow(clippy::unreadable_literal)] #[allow(clippy::excessive_precision)] mod tests { use super::*; use crate::tests::*; check_feature!(LinearFit); feature_test!( linear_fit, [LinearFit::default()], [1.0544186045473263, 0.7963978113902943, 0.013781209302325587], [0.0_f32, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0], [0.0_f32, 0.01, 0.04, 0.09, 0.16, 0.25, 0.36, 0.49, 0.64, 0.81, 1.0], [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0], ); }