ndarray_linalg/
norm.rs

1//! Norm of vectors
2
3use ndarray::*;
4use num_traits::Zero;
5
6use super::types::*;
7
8/// Define norm as a metric linear space (not as a matrix)
9///
10/// For operator norms, see opnorm module
11pub trait Norm {
12    type Output;
13    /// rename of `norm_l2`
14    fn norm(&self) -> Self::Output {
15        self.norm_l2()
16    }
17    /// L-1 norm
18    fn norm_l1(&self) -> Self::Output;
19    /// L-2 norm
20    fn norm_l2(&self) -> Self::Output;
21    /// maximum norm
22    fn norm_max(&self) -> Self::Output;
23}
24
25impl<A, D> Norm for ArrayRef<A, D>
26where
27    A: Scalar + Lapack,
28    D: Dimension,
29{
30    type Output = A::Real;
31    fn norm_l1(&self) -> Self::Output {
32        self.iter().map(|x| x.abs()).sum()
33    }
34    fn norm_l2(&self) -> Self::Output {
35        self.iter().map(|x| x.square()).sum::<A::Real>().sqrt()
36    }
37    fn norm_max(&self) -> Self::Output {
38        self.iter().fold(A::Real::zero(), |f, &val| {
39            let v = val.abs();
40            if f > v {
41                f
42            } else {
43                v
44            }
45        })
46    }
47}
48
49pub enum NormalizeAxis {
50    Row = 0,
51    Column = 1,
52}
53
54/// normalize in L2 norm
55pub fn normalize<A, S>(
56    mut m: ArrayBase<S, Ix2>,
57    axis: NormalizeAxis,
58) -> (ArrayBase<S, Ix2>, Vec<A::Real>)
59where
60    A: Scalar + Lapack,
61    S: DataMut<Elem = A>,
62{
63    let mut ms = Vec::new();
64    for mut v in m.axis_iter_mut(Axis(axis as usize)) {
65        let n = v.norm();
66        ms.push(n);
67        v.map_inplace(|x| *x /= A::from_real(n))
68    }
69    (m, ms)
70}