1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/******************************************************************************
* Copyright 2019 Manuel Simon
* This file is part of the norman library.
*
* Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
* https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
* <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
* option. This file may not be copied, modified, or distributed
* except according to those terms.
*****************************************************************************/
//! Implementations of the `Norm` and `Distance` traits on various
//! types.
//!
//! Below you find a detailed description of how these traits are implemented
//! on different types.
//!
//! # Primitive types
//!
//! Primitive integer and floating point types only implement `Norm<Abs>`.
//! For unsigned types, the norm function simply returns the original value,
//! for signed types, it returns the absolute value.
//!
//! # Complex numbers
//!
//! For `Complex<T>`, the `Norm` and `Distance` traits
//! are implemented if `T` implements [`Float`](num_traits::Float).
//! `Norm<Abs>` calculates the euclidean norm;
//! they also implement `Norm<Sup>`, which calculates the maximum
//! of the absolute values of real and imaginary part.
//!
//! # Vector types
//!
//! On types that represent vectors, the `Norm` trait is implemented
//! if the elements of the collection implement `Norm<Abs>`.
//!
//! For a vector of the form `[x_1, …, x_n]`, the supremum norm
//! will return the maximum of the Abs-norms of the `x_i`, i.e.
//! `max_(1≤i≤n) x_i.norm(Abs::new())`.
//!
//! The _p_-norms will return the _p_-th root of the sum of the
//! _p_-th powers of the Abs-norms of the `x_i`, i.e.
//! `(sum_(1≤i≤n) x_i.norm(Abs::new()).pow(p)).pow(1/p)`.
//!
//! Higher dimensional arrays of ndarray are simply considered
//! like single long vectors containing all the elements. Decent
//! operator norms of matrices (with their own norm descriptors)
//! will follow in a later release.
//!
//! The `Distance` trait calculates the norm of the difference
//! between two vectors. It is implemented if the elements of the collection
//! implement `Distance<Abs>` with an output that implements `PartialOrd`.
//! For `ndarray::ArrayBase` it will try
//! to broadcast the vectors together. If this fails, the function panics.
//!
//! ## Numerical edge cases for floating point elements
//!
//! NaNs in vectors are ignored, except if the vector contains only NaNs.
//! In this case, `norm` returns NaN.
//!
//! If the norm of one element of a vector is infinite, the norm of
//! the vector will be infinite, too.
//!
//! For _p_-norms there is however a special case: If the norms of all
//! elements are finite, but the _p_-the power of an element is infinite,
//! (which will usually only occur for a very high _p_), the supremum norm is returned.
//! This is done because the supremum norm is usually a better approximation to the _p_-norm
//! for high _ps_ than just returning Inf would be.
//!
//! ### Example
//!
//! ```
//! use ndarray::Array1;
//!
//! use norman::Norm;
//! use norman::desc::PNorm;
//!
//! let a = Array1::from(vec![2.0f32, std::f32::INFINITY, 3.0]);
//! assert_eq!(a.norm(PNorm::new(3)), std::f32::INFINITY);
//!
//! let b = Array1::from(vec![2.0f32, -4.0, 3.0]);
//! // 4^10000 is to high to be represented as an f32, but since the norms
//! // of all elements of b are finite, the _p_-norm falls back to calculating
//! // the supremum norm.
//! assert_eq!(b.norm(PNorm::new(10000)), 4.0);
//! ```