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}