polynomen 1.0.0

Polynomial library
Documentation
//! # Polynomials Norms
//!
//! l1-norm, l2-norm, l∞-norm.

use std::ops::{Add, Mul};

use crate::{Abs, Max, Poly, Sqrt};

impl<T> Poly<T>
where
    T: Abs + Add<Output = T>,
{
    /// Polynomial l1-norm: `||P||1 = ∑|a_k|`
    ///
    /// # Example
    /// ```
    /// use polynomen::poly;
    /// let p = poly!(12, -33, -21, -19, 15);
    /// assert_eq!(100, p.norm_1());
    /// ```
    #[must_use]
    pub fn norm_1(&self) -> T {
        self.map_reduce(Abs::abs, Add::add)
    }
}

impl<T> Poly<T>
where
    T: Abs + Add<Output = T> + Clone + Mul<Output = T> + Sqrt,
{
    /// Polynomial l2-norm: `||P||2 = √(∑|a_k|^2)`
    ///
    /// # Example
    /// ```
    /// use polynomen::poly;
    /// let p = poly!(3., -4.);
    /// assert_eq!(5., p.norm_2());
    /// ```
    #[must_use]
    pub fn norm_2(&self) -> T {
        self.map_reduce(|c| c.clone() * c.clone(), Add::add).sqrt()
    }
}

impl<T> Poly<T>
where
    T: Abs + Max,
{
    /// Polynomial l∞-norm: `||P||∞ = max|a_k|`
    ///
    /// # Example
    /// ```
    /// use polynomen::poly;
    /// let max = 69.;
    /// let p = poly!(3., -max, 0.4309, -2.930);
    /// assert_eq!(max, p.norm_inf());
    /// ```
    #[must_use]
    pub fn norm_inf(&self) -> T {
        self.map_reduce(Abs::abs, Max::max)
    }
}

#[cfg(test)]
mod tests {
    use crate::poly;

    #[test]
    fn l_1_norm() {
        let expected = 100;
        let p = poly!(12, -33, -21, -19, 15);
        assert_eq!(expected, p.norm_1());
    }

    #[test]
    #[allow(clippy::float_cmp)]
    fn l_2_norm() {
        let expected = 5.;
        let p = poly!(3., -4.);
        assert_eq!(expected, p.norm_2());
    }

    #[test]
    #[allow(clippy::float_cmp)]
    fn l_infinity_norm() {
        let max = 69.;
        let p = poly!(3., -max, 0.4309, -2.930);
        assert_eq!(max, p.norm_inf());
    }
}