malachite_q/rational_vector/arithmetic/abs_squared.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::Rational;
10use crate::rational_vector::RationalVector;
11use malachite_base::num::arithmetic::traits::{AbsSquared, Square};
12use malachite_nz::integer_vector::IntegerVector;
13use malachite_nz::natural::Natural;
14
15// The squared norm of the vector `numerators / denominator`: the squared norm of the integer
16// numerators over the square of the denominator, reduced once.
17fn abs_squared_over((numerators, denominator): (IntegerVector, Natural)) -> Rational {
18 Rational::from_naturals(numerators.abs_squared(), denominator.square())
19}
20
21impl AbsSquared for RationalVector {
22 type Output = Rational;
23
24 /// Computes the squared norm of a [`RationalVector`], the sum of the squares of its elements,
25 /// taking the vector by value.
26 ///
27 /// This is the dot product of the vector with itself, $\|v\|^2$. The squared norm of the
28 /// 0-dimensional vector is 0. The vector is written as integer numerators over a common
29 /// denominator, as in [`Dot`](malachite_base::num::arithmetic::traits::Dot), so that one
30 /// integer squared norm and one reduction suffice.
31 ///
32 /// $$
33 /// f(v) = \|v\|^2 = \sum_{i=0}^{n-1} v_i^2,
34 /// $$
35 ///
36 /// where $n$ is the dimension of $v$.
37 ///
38 /// # Worst-case complexity
39 /// $T(n, m) = O(nm \log m \log\log m)$
40 ///
41 /// $M(m) = O(m \log m)$
42 ///
43 /// where $T$ is time, $M$ is additional memory, $n$ is the dimension of the vector, and $m$ is
44 /// the largest number of significant bits of any element.
45 ///
46 /// # Examples
47 /// ```
48 /// use core::str::FromStr;
49 /// use malachite_base::num::arithmetic::traits::AbsSquared;
50 /// use malachite_q::rational_vector::RationalVector;
51 ///
52 /// let v = RationalVector::from_str("(1/2, -2/3)").unwrap();
53 /// assert_eq!(v.abs_squared().to_string(), "25/36");
54 /// let v = RationalVector::from_str("()").unwrap();
55 /// assert_eq!(v.abs_squared(), 0);
56 /// ```
57 #[inline]
58 fn abs_squared(self) -> Rational {
59 abs_squared_over(self.into_numerators_and_denominator())
60 }
61}
62
63impl AbsSquared for &RationalVector {
64 type Output = Rational;
65
66 /// Computes the squared norm of a [`RationalVector`], the sum of the squares of its elements,
67 /// taking the vector by reference.
68 ///
69 /// This is the dot product of the vector with itself, $\|v\|^2$. The squared norm of the
70 /// 0-dimensional vector is 0. The vector is written as integer numerators over a common
71 /// denominator, as in [`Dot`](malachite_base::num::arithmetic::traits::Dot), so that one
72 /// integer squared norm and one reduction suffice.
73 ///
74 /// $$
75 /// f(v) = \|v\|^2 = \sum_{i=0}^{n-1} v_i^2,
76 /// $$
77 ///
78 /// where $n$ is the dimension of $v$.
79 ///
80 /// # Worst-case complexity
81 /// $T(n, m) = O(nm \log m \log\log m)$
82 ///
83 /// $M(m) = O(m \log m)$
84 ///
85 /// where $T$ is time, $M$ is additional memory, $n$ is the dimension of the vector, and $m$ is
86 /// the largest number of significant bits of any element.
87 ///
88 /// # Examples
89 /// ```
90 /// use core::str::FromStr;
91 /// use malachite_base::num::arithmetic::traits::AbsSquared;
92 /// use malachite_q::rational_vector::RationalVector;
93 ///
94 /// let v = RationalVector::from_str("(1/2, -2/3)").unwrap();
95 /// assert_eq!((&v).abs_squared().to_string(), "25/36");
96 /// let v = RationalVector::from_str("()").unwrap();
97 /// assert_eq!((&v).abs_squared(), 0);
98 /// ```
99 #[inline]
100 fn abs_squared(self) -> Rational {
101 abs_squared_over(self.to_numerators_and_denominator())
102 }
103}