qfall_math/rational/mat_q/norm.rs
1// Copyright © 2025 Niklas Siemer
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! This module includes functionality to compute several norms
10//! defined on matrices.
11
12use super::MatQ;
13use crate::{
14 rational::Q,
15 traits::{MatrixDimensions, MatrixGetSubmatrix},
16};
17
18impl MatQ {
19 /// Outputs the squared l_{2, ∞}-norm, i.e. it computes the squared Euclidean
20 /// norm of each column of the matrix and returns the largest one.
21 ///
22 /// # Examples
23 /// ```
24 /// use qfall_math::rational::{MatQ, Q};
25 /// use std::str::FromStr;
26 ///
27 /// let mat = MatQ::from_str("[[2, 3],[-2/1, 0]]").unwrap();
28 ///
29 /// let eucl_norm = mat.norm_l_2_infty_sqrd();
30 ///
31 /// // 3^2 + 0^2 = 9
32 /// assert_eq!(Q::from(9), eucl_norm);
33 /// ```
34 pub fn norm_l_2_infty_sqrd(&self) -> Q {
35 let mut max_sqrd_norm = Q::ZERO;
36 for i in 0..self.get_num_columns() {
37 let column = unsafe { self.get_column_unchecked(i) };
38 let sqrd_norm = column.norm_eucl_sqrd().unwrap();
39 if sqrd_norm > max_sqrd_norm {
40 max_sqrd_norm = sqrd_norm;
41 }
42 }
43 max_sqrd_norm
44 }
45
46 /// Outputs the l_{2, ∞}-norm, i.e. it computes the Euclidean
47 /// norm of each column of the matrix and returns the largest one.
48 ///
49 /// # Examples
50 /// ```
51 /// use qfall_math::rational::{Q, MatQ};
52 /// use std::str::FromStr;
53 ///
54 /// let mat = MatQ::from_str("[[4/2, 3],[2, 0]]").unwrap();
55 ///
56 /// let eucl_norm = mat.norm_l_2_infty();
57 ///
58 /// // sqrt(3^2 + 0^2) = 3
59 /// assert_eq!(Q::from(3), eucl_norm);
60 /// ```
61 pub fn norm_l_2_infty(&self) -> Q {
62 self.norm_l_2_infty_sqrd().sqrt()
63 }
64
65 /// Outputs the l_{∞, ∞}-norm, i.e. it computes the ∞-norm
66 /// of each column of the matrix and returns the largest one.
67 ///
68 /// # Examples
69 /// ```
70 /// use qfall_math::rational::{MatQ, Q};
71 /// use std::str::FromStr;
72 ///
73 /// let mat = MatQ::from_str("[[2, 6/2],[2, 0]]").unwrap();
74 ///
75 /// let eucl_norm = mat.norm_l_infty_infty();
76 ///
77 /// // max{2, 3} = 3
78 /// assert_eq!(Q::from(3), eucl_norm);
79 /// ```
80 pub fn norm_l_infty_infty(&self) -> Q {
81 let mut max_norm = Q::ZERO;
82 for i in 0..self.get_num_columns() {
83 let column = unsafe { self.get_column_unchecked(i) };
84 let norm = column.norm_infty().unwrap();
85 if norm > max_norm {
86 max_norm = norm;
87 }
88 }
89 max_norm
90 }
91}
92
93#[cfg(test)]
94mod test_matrix_norms {
95 use super::{MatQ, Q};
96 use std::str::FromStr;
97
98 /// Ensures that the squared l_{2, ∞}-norm is correctly computed.
99 #[test]
100 fn norm_sqrd_l_2_infty() {
101 let mat = MatQ::from_str("[[3, -2/1, 5],[-10/2, -6, 2],[4/-1, 0/1, 0],[2, 0, 1]]").unwrap();
102
103 let sqrd_norm = mat.norm_l_2_infty_sqrd();
104
105 assert_eq!(Q::from(54), sqrd_norm);
106 }
107
108 /// Ensures that the l_{2, ∞}-norm is correctly computed.
109 #[test]
110 fn norm_l_2_infty() {
111 let mat = MatQ::from_str("[[-2, -2/1],[-2, 3/-1],[-2, 0],[2, 0]]").unwrap();
112
113 let norm = mat.norm_l_2_infty();
114
115 assert_eq!(Q::from(4), norm);
116 }
117
118 /// Ensures that the l_{∞, ∞}-norm is correctly computed.
119 #[test]
120 fn norm_l_infty_infty() {
121 let mat = MatQ::from_str("[[-4/2, 3/1],[2, -5],[-2, 0]]").unwrap();
122
123 let infty_norm = mat.norm_l_infty_infty();
124
125 assert_eq!(Q::from(5), infty_norm);
126 }
127}