use super::{MatrixErrorType, Scalar};
use crate::{Centering, Normalization, Scaling};
pub trait ColumnStats<F: Scalar>: MatrixErrorType {
fn normalization_stats(
&self,
spec: Normalization,
) -> Result<crate::NormalizationStats<F>, Self::Error> {
let centers = match spec.center {
Centering::None => None,
Centering::Mean => Some(self.col_means()?),
Centering::Min => Some(self.col_mins()?),
};
let scales = match spec.scale {
Scaling::None => None,
Scaling::Sd => Some(self.col_sds()?),
Scaling::Range => Some(self.col_ranges()?),
Scaling::L1 => Some(match ¢ers {
Some(c) => self.col_l1_centered(c)?,
None => self.col_l1()?,
}),
Scaling::L2 => Some(match ¢ers {
Some(c) => self.col_l2_centered(c)?,
None => self.col_l2()?,
}),
Scaling::MaxAbs => Some(match ¢ers {
Some(c) => self.col_maxabs_centered(c)?,
None => self.col_maxabs()?,
}),
};
Ok((centers, scales))
}
fn col_means(&self) -> Result<Vec<F>, Self::Error>;
fn col_sds(&self) -> Result<Vec<F>, Self::Error>;
fn col_mins(&self) -> Result<Vec<F>, Self::Error>;
fn col_ranges(&self) -> Result<Vec<F>, Self::Error>;
fn col_maxabs(&self) -> Result<Vec<F>, Self::Error>;
fn col_l1(&self) -> Result<Vec<F>, Self::Error>;
fn col_l2(&self) -> Result<Vec<F>, Self::Error>;
fn col_l2_centered(&self, centers: &[F]) -> Result<Vec<F>, Self::Error>;
fn col_l1_centered(&self, centers: &[F]) -> Result<Vec<F>, Self::Error>;
fn col_maxabs_centered(&self, centers: &[F]) -> Result<Vec<F>, Self::Error>;
}
impl<M, F> ColumnStats<F> for &M
where
M: ColumnStats<F> + ?Sized,
F: Scalar,
{
fn normalization_stats(
&self,
spec: Normalization,
) -> Result<crate::NormalizationStats<F>, Self::Error> {
(**self).normalization_stats(spec)
}
fn col_means(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_means()
}
fn col_sds(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_sds()
}
fn col_mins(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_mins()
}
fn col_ranges(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_ranges()
}
fn col_maxabs(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_maxabs()
}
fn col_l1(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_l1()
}
fn col_l2(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_l2()
}
fn col_l2_centered(&self, centers: &[F]) -> Result<Vec<F>, Self::Error> {
(**self).col_l2_centered(centers)
}
fn col_l1_centered(&self, centers: &[F]) -> Result<Vec<F>, Self::Error> {
(**self).col_l1_centered(centers)
}
fn col_maxabs_centered(&self, centers: &[F]) -> Result<Vec<F>, Self::Error> {
(**self).col_maxabs_centered(centers)
}
}
impl<M, F> ColumnStats<F> for &mut M
where
M: ColumnStats<F> + ?Sized,
F: Scalar,
{
fn normalization_stats(
&self,
spec: Normalization,
) -> Result<crate::NormalizationStats<F>, Self::Error> {
(**self).normalization_stats(spec)
}
fn col_means(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_means()
}
fn col_sds(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_sds()
}
fn col_mins(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_mins()
}
fn col_ranges(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_ranges()
}
fn col_maxabs(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_maxabs()
}
fn col_l1(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_l1()
}
fn col_l2(&self) -> Result<Vec<F>, Self::Error> {
(**self).col_l2()
}
fn col_l2_centered(&self, centers: &[F]) -> Result<Vec<F>, Self::Error> {
(**self).col_l2_centered(centers)
}
fn col_l1_centered(&self, centers: &[F]) -> Result<Vec<F>, Self::Error> {
(**self).col_l1_centered(centers)
}
fn col_maxabs_centered(&self, centers: &[F]) -> Result<Vec<F>, Self::Error> {
(**self).col_maxabs_centered(centers)
}
}