use super::stats::Distribution;
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Deserialize, Serialize, Debug)]
pub struct ConfidenceInterval {
pub confidence_level: f64,
pub lower_bound: f64,
pub upper_bound: f64,
}
#[derive(Clone, PartialEq, Deserialize, Serialize, Debug)]
pub struct Estimate {
pub confidence_interval: ConfidenceInterval,
pub point_estimate: f64,
pub standard_error: f64,
}
pub fn build_estimates(
distributions: &Distributions,
points: &PointEstimates,
cl: f64,
) -> Estimates {
let to_estimate = |point_estimate, distribution: &Distribution<f64>| {
let (lb, ub) = distribution.confidence_interval(cl);
Estimate {
confidence_interval: ConfidenceInterval {
confidence_level: cl,
lower_bound: lb,
upper_bound: ub,
},
point_estimate,
standard_error: distribution.std_dev(None),
}
};
Estimates {
mean: to_estimate(points.mean, &distributions.mean),
median: to_estimate(points.median, &distributions.median),
median_abs_dev: to_estimate(points.median_abs_dev, &distributions.median_abs_dev),
slope: None,
std_dev: to_estimate(points.std_dev, &distributions.std_dev),
}
}
pub fn build_change_estimates(
distributions: &ChangeDistributions,
points: &ChangePointEstimates,
cl: f64,
) -> ChangeEstimates {
let to_estimate = |point_estimate, distribution: &Distribution<f64>| {
let (lb, ub) = distribution.confidence_interval(cl);
Estimate {
confidence_interval: ConfidenceInterval {
confidence_level: cl,
lower_bound: lb,
upper_bound: ub,
},
point_estimate,
standard_error: distribution.std_dev(None),
}
};
ChangeEstimates {
mean: to_estimate(points.mean, &distributions.mean),
median: to_estimate(points.median, &distributions.median),
}
}
pub struct PointEstimates {
pub mean: f64,
pub median: f64,
pub median_abs_dev: f64,
pub std_dev: f64,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Estimates {
pub mean: Estimate,
pub median: Estimate,
pub median_abs_dev: Estimate,
pub slope: Option<Estimate>,
pub std_dev: Estimate,
}
impl Estimates {
pub fn typical(&self) -> &Estimate {
self.slope.as_ref().unwrap_or(&self.mean)
}
}
pub struct Distributions {
pub mean: Distribution<f64>,
pub median: Distribution<f64>,
pub median_abs_dev: Distribution<f64>,
pub slope: Option<Distribution<f64>>,
pub std_dev: Distribution<f64>,
}
pub struct ChangePointEstimates {
pub mean: f64,
pub median: f64,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ChangeEstimates {
pub mean: Estimate,
pub median: Estimate,
}
pub struct ChangeDistributions {
pub mean: Distribution<f64>,
pub median: Distribution<f64>,
}