norman/implementation/
num_complex.rs

1/******************************************************************************
2 * Copyright 2019 Manuel Simon
3 * This file is part of the norman library.
4 *
5 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
8 * option. This file may not be copied, modified, or distributed
9 * except according to those terms.
10 *****************************************************************************/
11
12//! Implementations of norms for the complex number types in [`num_complex`].
13
14use num_traits::Float;
15use num_complex::Complex;
16
17use crate::{Norm, Distance};
18use crate::desc::{Abs, Sup};
19
20impl<T: Float> Norm<Abs> for Complex<T> {
21    type Output = T;
22    /// Calculates the usual euclidean norm of the complex number.
23    fn norm(&self, _desc: Abs) -> T {
24        Complex::norm(&self)
25    }
26}
27
28impl<T: Float> Norm<Sup> for Complex<T> {
29    type Output = T;
30    /// Calculates the supremum norm of the complex number,
31    /// i.e. the maximum of the absolute values of real and imaginary part.
32    fn norm(&self, _desc: Sup) -> T {
33        self.re.abs().max(self.im.abs())
34    }
35}
36
37impl<T: Float> Distance<Abs> for Complex<T> {
38    type Output = T;
39    /// Calculates the usual euclidean norm of the complex number.
40    fn distance(&self, other: &Self, _desc: Abs) -> T {
41        Complex::norm(&(self - other))
42    }
43}
44
45impl<T: Float> Distance<Sup> for Complex<T> {
46    type Output = T;
47    /// Calculates the supremum norm of the complex number,
48    /// i.e. the maximum of the absolute values of real and imaginary part.
49    fn distance(&self, other: &Self, _desc: Sup) -> T {
50        (self.re - other.re).abs().max((self.im - other.im).abs())
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use num_complex::Complex;
57
58    use crate::{Norm, Distance};
59    use crate::desc::{Abs, Sup};
60
61    #[test]
62    fn complex_norm() {
63        assert_eq!(Norm::norm(&Complex::new( 3.0f32, -4.0f32), Abs::new()), 5.0);
64        assert_eq!(Norm::norm(&Complex::new(-4.0f64, -3.0f64), Abs::new()), 5.0);
65    }
66
67    #[test]
68    fn complex_sup_norm() {
69        assert_eq!(Norm::norm(&Complex::new( 4.0f32, -8.0f32), Sup::new()), 8.0);
70        assert_eq!(Norm::norm(&Complex::new( 3.0f32, -1.0f32), Sup::new()), 3.0);
71    }
72
73    #[test]
74    fn complex_distance() {
75        assert_eq!(Distance::distance(
76            &Complex::new( 3.0f32, -4.0f32),
77            &Complex::new( 3.0f32,  3.0f32),
78            Abs::new()
79            ), 7.0);
80        assert_eq!(Distance::distance(
81            &Complex::new( 5.0f32,  0.0f32),
82            &Complex::new( 1.0f32,  3.0f32),
83            Abs::new()
84            ), 5.0);
85    }
86}