Skip to main content

malachite_base/unsigned_vector/arithmetic/
canonical_primitive_part.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::num::arithmetic::traits::{
10    CanonicalPrimitivePart, CanonicalPrimitivePartAssign, ContentAndCanonicalPrimitivePart,
11    ContentAndPrimitivePart, PrimitivePart, PrimitivePartAssign,
12};
13use crate::num::basic::unsigneds::PrimitiveUnsigned;
14use crate::unsigned_vector::UnsignedVector;
15
16impl<T: PrimitiveUnsigned> CanonicalPrimitivePart for UnsignedVector<T> {
17    type Output = Self;
18
19    /// Computes the canonical primitive part of an [`UnsignedVector`], taking the vector by value.
20    ///
21    /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
22    /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
23    ///
24    /// # Worst-case complexity
25    /// $T(n) = O(n)$
26    ///
27    /// $M(n) = O(1)$
28    ///
29    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
30    ///
31    /// # Examples
32    /// ```
33    /// use core::str::FromStr;
34    /// use malachite_base::num::arithmetic::traits::CanonicalPrimitivePart;
35    /// use malachite_base::unsigned_vector::UnsignedVector;
36    ///
37    /// let v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
38    /// assert_eq!(v.canonical_primitive_part().to_string(), "(3, 2, 5)");
39    /// ```
40    #[inline]
41    fn canonical_primitive_part(self) -> Self {
42        self.primitive_part()
43    }
44}
45
46impl<T: PrimitiveUnsigned> CanonicalPrimitivePart for &UnsignedVector<T> {
47    type Output = UnsignedVector<T>;
48
49    /// Computes the canonical primitive part of an [`UnsignedVector`], taking the vector by
50    /// reference.
51    ///
52    /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
53    /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
54    ///
55    /// # Worst-case complexity
56    /// $T(n) = O(n)$
57    ///
58    /// $M(n) = O(n)$
59    ///
60    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
61    ///
62    /// # Examples
63    /// ```
64    /// use core::str::FromStr;
65    /// use malachite_base::num::arithmetic::traits::CanonicalPrimitivePart;
66    /// use malachite_base::unsigned_vector::UnsignedVector;
67    ///
68    /// let v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
69    /// assert_eq!((&v).canonical_primitive_part().to_string(), "(3, 2, 5)");
70    /// ```
71    #[inline]
72    fn canonical_primitive_part(self) -> UnsignedVector<T> {
73        self.primitive_part()
74    }
75}
76
77impl<T: PrimitiveUnsigned> CanonicalPrimitivePartAssign for UnsignedVector<T> {
78    /// Replaces an [`UnsignedVector`] with its canonical primitive part.
79    ///
80    /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
81    /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
82    ///
83    /// # Worst-case complexity
84    /// $T(n) = O(n)$
85    ///
86    /// $M(n) = O(1)$
87    ///
88    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
89    ///
90    /// # Examples
91    /// ```
92    /// use core::str::FromStr;
93    /// use malachite_base::num::arithmetic::traits::CanonicalPrimitivePartAssign;
94    /// use malachite_base::unsigned_vector::UnsignedVector;
95    ///
96    /// let mut v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
97    /// v.canonical_primitive_part_assign();
98    /// assert_eq!(v.to_string(), "(3, 2, 5)");
99    /// ```
100    #[inline]
101    fn canonical_primitive_part_assign(&mut self) {
102        self.primitive_part_assign();
103    }
104}
105
106impl<T: PrimitiveUnsigned> ContentAndCanonicalPrimitivePart for UnsignedVector<T> {
107    type Content = T;
108    type CanonicalPrimitivePart = Self;
109
110    /// Computes the content and the canonical primitive part of an [`UnsignedVector`] together,
111    /// taking the vector by value.
112    ///
113    /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
114    /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
115    ///
116    /// # Worst-case complexity
117    /// $T(n) = O(n)$
118    ///
119    /// $M(n) = O(1)$
120    ///
121    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
122    ///
123    /// # Examples
124    /// ```
125    /// use core::str::FromStr;
126    /// use malachite_base::num::arithmetic::traits::ContentAndCanonicalPrimitivePart;
127    /// use malachite_base::unsigned_vector::UnsignedVector;
128    ///
129    /// let v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
130    /// let (content, primitive_part) = v.content_and_canonical_primitive_part();
131    /// assert_eq!(content, 2);
132    /// assert_eq!(primitive_part.to_string(), "(3, 2, 5)");
133    /// ```
134    #[inline]
135    fn content_and_canonical_primitive_part(self) -> (T, Self) {
136        self.content_and_primitive_part()
137    }
138}
139
140impl<T: PrimitiveUnsigned> ContentAndCanonicalPrimitivePart for &UnsignedVector<T> {
141    type Content = T;
142    type CanonicalPrimitivePart = UnsignedVector<T>;
143
144    /// Computes the content and the canonical primitive part of an [`UnsignedVector`] together,
145    /// taking the vector by reference.
146    ///
147    /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
148    /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
149    ///
150    /// # Worst-case complexity
151    /// $T(n) = O(n)$
152    ///
153    /// $M(n) = O(n)$
154    ///
155    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
156    ///
157    /// # Examples
158    /// ```
159    /// use core::str::FromStr;
160    /// use malachite_base::num::arithmetic::traits::ContentAndCanonicalPrimitivePart;
161    /// use malachite_base::unsigned_vector::UnsignedVector;
162    ///
163    /// let v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
164    /// let (content, primitive_part) = (&v).content_and_canonical_primitive_part();
165    /// assert_eq!(content, 2);
166    /// assert_eq!(primitive_part.to_string(), "(3, 2, 5)");
167    /// ```
168    #[inline]
169    fn content_and_canonical_primitive_part(self) -> (T, UnsignedVector<T>) {
170        self.content_and_primitive_part()
171    }
172}