pub mod missing_data;
pub mod builtin;
pub use self::missing_data::MissingDataHandler;
pub use self::builtin::BuiltinFeature;
use std::collections::HashMap;
pub type FeatureFn<T> = fn(&[Option<T>], usize) -> Option<T>;
pub trait Feature<T>: Send + Sync {
fn compute(&self, series: &[Option<T>], index: usize, handler: &dyn MissingDataHandler<T>) -> Option<T>;
fn name(&self) -> &str;
fn requires_neighbors(&self) -> bool {
false
}
fn window_size(&self) -> Option<usize> {
None
}
}
pub struct FeatureSet<T> {
pub(crate) features: Vec<Box<dyn Feature<T> + Send + Sync>>,
pub(crate) functions: HashMap<String, FeatureFn<T>>,
pub(crate) missing_strategy: missing_data::MissingDataStrategy,
}
impl<T> FeatureSet<T> {
pub fn new() -> Self {
Self {
features: Vec::new(),
functions: HashMap::new(),
missing_strategy: missing_data::MissingDataStrategy::ZeroFill,
}
}
pub fn add_builtin(mut self, builtin: BuiltinFeature) -> Self
where
T: Copy + PartialOrd + std::ops::Add<Output = T> + std::ops::Sub<Output = T>
+ std::ops::Mul<Output = T> + std::ops::Div<Output = T> + From<f64> + Into<f64> + Send + Sync,
{
self.features.push(Box::new(builtin));
self
}
pub fn add_function(mut self, name: &str, f: FeatureFn<T>) -> Self {
self.functions.insert(name.to_string(), f);
self
}
}
impl<T> Default for FeatureSet<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> FeatureSet<T> {
pub fn with_missing_data_strategy(mut self, strategy: missing_data::MissingDataStrategy) -> Self {
self.missing_strategy = strategy;
self
}
pub fn len(&self) -> usize {
self.features.len() + self.functions.len()
}
pub fn is_empty(&self) -> bool {
self.features.is_empty() && self.functions.is_empty()
}
}