use std::ops::{Add, Mul};
use crate::{Abs, Max, Poly, Sqrt};
impl<T> Poly<T>
where
T: Abs + Add<Output = T>,
{
#[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,
{
#[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,
{
#[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());
}
}