conspire/math/tensor/norm/
mod.rs1#[cfg(test)]
2mod test;
3
4use super::{Quantity, Scalar, Tensor};
5
6#[derive(Clone, Copy, Debug, Default)]
8pub enum Norm {
9 Chebyshev,
10 #[default]
11 Euclidean,
12 Manhattan,
13 Minkowski(Scalar),
14}
15
16impl Norm {
17 pub fn apply<T: Tensor>(&self, t: &T) -> Quantity<T::Unit> {
19 match self {
20 Self::Chebyshev => t.norm_inf(),
21 Self::Euclidean => t.norm(),
22 Self::Manhattan => t.norm_l1(),
23 Self::Minkowski(p) => t.norm_p(*p),
24 }
25 }
26 pub fn measure<T: Tensor>(&self, t: &T) -> Scalar {
28 self.apply(t).value()
29 }
30 pub fn over(&self, values: impl Iterator<Item = Scalar>) -> Scalar {
32 match self {
33 Self::Chebyshev => values.fold(0.0, |largest: Scalar, value| largest.max(value.abs())),
34 Self::Euclidean => values.map(|value| value * value).sum::<Scalar>().sqrt(),
35 Self::Manhattan => values.map(|value| value.abs()).sum(),
36 Self::Minkowski(p) => values
37 .map(|value| value.abs().powf(*p))
38 .sum::<Scalar>()
39 .powf(1.0 / p),
40 }
41 }
42}