pub mod adev;
pub mod oadev;
use crate::noise::detect::noise_id;
use crate::enums::{*};
use crate::utils::ms;
use crate::dev_result::{*};
pub trait DevEngine{
fn dev(&self) -> DevType;
fn preferred_noise_id_metod(&self) -> NoiseId;
fn compute_one(&self, xs: &[f64], m: usize, tau0: f64) -> f64;
fn compute_many(&self, xs: &[f64], ms: &[usize], tau0: f64) -> Vec<f64>{
ms.iter().map(|m| self.compute_one(&xs,*m, tau0)).collect()
}
fn m_max(&self, n: usize) -> usize;
fn compute(&self, xs: &[f64], tau0: f64, afs: &Afs, noise_id_method: NoiseId) -> DevResult{
let ms = ms::generate_ms(xs.len(), self.m_max(xs.len()), &afs);
let taus = ms.iter().map(|m| (*m as f64)*tau0).collect::<Vec<_>>();
let devs = self.compute_many(&xs, &ms, tau0);
let noise_id_method_final = match noise_id_method{
NoiseId::Default => self.preferred_noise_id_metod(),
_ => noise_id_method.clone()
};
let alphas = ms.iter().map(|m| noise_id(&xs, *m, tau0, noise_id_method_final.clone())).collect::<Vec<f64>>();
let ns = ms.iter().map(|m| self.ns(xs.len(),*m)).collect::<Vec<usize>>();
let edfs = alphas.iter().zip(ms.iter()).map(|(alpha,m)| self.edf(*alpha,xs.len(),*m)).collect::<Vec<f64>>();
let cis = edfs.iter()
.map(|edf| self.ci_factor(*edf,0.025))
.zip(devs.iter())
.map(|(cif,dev)| (cif.0*dev,cif.1*dev))
.collect::<Vec<(_,_)>>();
DevResultBuilder::default()
.dev(Some(self.dev()))
.taus(Some(taus))
.devs(Some(devs))
.ns(Some(ns))
.alphas(Some(alphas))
.edfs(Some(edfs))
.cis(Some(cis))
.noise_id(Some(noise_id_method_final))
.build().unwrap()
}
fn ns(&self, n: usize, m: usize) -> usize;
fn edf(&self, alpha: f64, n: usize, m: usize) -> f64;
fn ci_factor(&self, edf: f64, p: f64) -> (f64,f64);
}