malachite_base/unsigned_vector/mod.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::named::Named;
10use crate::num::basic::unsigneds::PrimitiveUnsigned;
11use crate::num::conversion::traits::ExactFrom;
12use crate::num::logic::traits::SignificantBits;
13use crate::vector::Vector;
14use alloc::vec;
15use alloc::vec::Vec;
16use core::fmt::{self, Debug, Formatter};
17use core::ops::Deref;
18
19/// Implementations of [`Index`](core::ops::Index) and [`IndexMut`](core::ops::IndexMut) for
20/// [`UnsignedVector`].
21pub mod access;
22/// Traits for arithmetic on [`UnsignedVector`]s.
23pub mod arithmetic;
24/// Implementations of [`Ord`] and [`PartialOrd`] for [`ShortlexUnsignedVector`] and
25/// [`ShortlexUnsignedVectorRef`], comparing two vectors by dimension and then lexicographically.
26pub mod comparison;
27/// Functions for converting an [`UnsignedVector`] to and from other types.
28pub mod conversion;
29/// Iterators that generate [`UnsignedVector`]s without repetition.
30pub mod exhaustive;
31/// An implementation of [`Extend`], for appending the elements produced by an iterator to an
32/// [`UnsignedVector`].
33pub mod extend;
34/// Traits for logic and bit manipulation on [`UnsignedVector`]s.
35pub mod logic;
36#[cfg(feature = "random")]
37/// Iterators that generate [`UnsignedVector`]s randomly.
38pub mod random;
39/// Implementations of [`SelectCoordinates`](crate::vector::SelectCoordinates) and
40/// [`SelectCoordinatesAssign`](crate::vector::SelectCoordinatesAssign), for selecting coordinates
41/// of an [`UnsignedVector`] by index.
42pub mod select_coordinates;
43
44/// A vector whose elements are primitive unsigned integers.
45///
46/// Its dimension is the number of elements, and the 0-dimensional vector has none. The field is
47/// public, since every [`Vec`] of `T`s is a valid vector: unlike a polynomial, a vector has no
48/// normal form to maintain, and two vectors are equal exactly when their elements are.
49///
50/// An `UnsignedVector` is serialized as the list of its elements.
51///
52/// # Examples
53/// ```
54/// use malachite_base::unsigned_vector::UnsignedVector;
55/// use malachite_base::vector::Vector;
56///
57/// let v = UnsignedVector {
58/// elements: vec![1u32, 2, 3],
59/// };
60/// assert_eq!(v.dimension(), 3);
61/// assert_eq!(v.to_string(), "(1, 2, 3)");
62/// ```
63#[derive(Clone, Eq, Hash, PartialEq)]
64#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
65#[cfg_attr(feature = "serde", serde(transparent))]
66pub struct UnsignedVector<T: PrimitiveUnsigned> {
67 pub elements: Vec<T>,
68}
69
70impl<T: PrimitiveUnsigned> Vector for UnsignedVector<T> {
71 type Element = T;
72 type ElementOutput<'a>
73 = T
74 where
75 Self: 'a;
76
77 /// Converts a slice to an [`UnsignedVector`], cloning the elements.
78 ///
79 /// The vector's dimension is the length of the slice. Every slice is a valid vector, so this
80 /// cannot fail; the empty slice gives the 0-dimensional vector.
81 ///
82 /// # Worst-case complexity
83 /// $T(n) = O(n)$
84 ///
85 /// $M(n) = O(n)$
86 ///
87 /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
88 ///
89 /// # Examples
90 /// ```
91 /// use malachite_base::unsigned_vector::UnsignedVector;
92 /// use malachite_base::vector::Vector;
93 ///
94 /// assert_eq!(
95 /// UnsignedVector::from_elements(&[1u32, 2]).to_string(),
96 /// "(1, 2)"
97 /// );
98 /// assert_eq!(UnsignedVector::<u32>::from_elements(&[]).to_string(), "()");
99 /// ```
100 #[inline]
101 fn from_elements(xs: &[T]) -> Self {
102 Self {
103 elements: xs.to_vec(),
104 }
105 }
106
107 /// Converts a [`Vec`] to an [`UnsignedVector`], taking ownership of it.
108 ///
109 /// The vector's dimension is the length of the [`Vec`]. Every [`Vec`] is a valid vector, so
110 /// this cannot fail, and nothing is copied or allocated.
111 ///
112 /// # Worst-case complexity
113 /// Constant time and additional memory.
114 ///
115 /// # Examples
116 /// ```
117 /// use malachite_base::unsigned_vector::UnsignedVector;
118 /// use malachite_base::vector::Vector;
119 ///
120 /// assert_eq!(
121 /// UnsignedVector::from_owned_elements(vec![1u32, 2]).to_string(),
122 /// "(1, 2)"
123 /// );
124 /// assert_eq!(
125 /// UnsignedVector::<u32>::from_owned_elements(Vec::new()).to_string(),
126 /// "()"
127 /// );
128 /// ```
129 #[inline]
130 fn from_owned_elements(xs: Vec<T>) -> Self {
131 Self { elements: xs }
132 }
133
134 /// Returns the zero vector of a given dimension: a vector of `dimension` zeros.
135 ///
136 /// # Worst-case complexity
137 /// $T(n) = O(n)$
138 ///
139 /// $M(n) = O(n)$
140 ///
141 /// where $T$ is time, $M$ is additional memory, and $n$ is `dimension`.
142 ///
143 /// # Panics
144 /// Panics if `dimension` is greater than [`usize::MAX`].
145 ///
146 /// # Examples
147 /// ```
148 /// use malachite_base::unsigned_vector::UnsignedVector;
149 /// use malachite_base::vector::Vector;
150 ///
151 /// assert_eq!(UnsignedVector::<u8>::zero(3).to_string(), "(0, 0, 0)");
152 /// assert_eq!(UnsignedVector::<u8>::zero(0).to_string(), "()");
153 /// ```
154 ///
155 /// This is equivalent to `_nmod_vec_init` from `nmod_vec.h`, FLINT 3.6.0, followed by
156 /// `_nmod_vec_zero`, since `_nmod_vec_init` leaves the elements uninitialized.
157 #[inline]
158 fn zero(dimension: u64) -> Self {
159 Self {
160 elements: vec![T::ZERO; usize::exact_from(dimension)],
161 }
162 }
163
164 /// Returns the standard basis vector $e_i$ of a given dimension: the vector whose element at
165 /// `index` is 1 and whose other elements are 0.
166 ///
167 /// Indices start at 0, as they do for [`Index`](core::ops::Index).
168 ///
169 /// # Worst-case complexity
170 /// $T(n) = O(n)$
171 ///
172 /// $M(n) = O(n)$
173 ///
174 /// where $T$ is time, $M$ is additional memory, and $n$ is `dimension`.
175 ///
176 /// # Panics
177 /// Panics if `index` is greater than or equal to `dimension`, or if `dimension` is greater than
178 /// [`usize::MAX`].
179 ///
180 /// # Examples
181 /// ```
182 /// use malachite_base::unsigned_vector::UnsignedVector;
183 /// use malachite_base::vector::Vector;
184 ///
185 /// assert_eq!(
186 /// UnsignedVector::<u8>::standard_basis_vector(3, 1).to_string(),
187 /// "(0, 1, 0)"
188 /// );
189 /// assert_eq!(
190 /// UnsignedVector::<u8>::standard_basis_vector(1, 0).to_string(),
191 /// "(1)"
192 /// );
193 /// ```
194 fn standard_basis_vector(dimension: u64, index: u64) -> Self {
195 assert!(
196 index < dimension,
197 "the index {index} is not less than the dimension {dimension}"
198 );
199 let mut v = Self::zero(dimension);
200 v.elements[usize::exact_from(index)] = T::ONE;
201 v
202 }
203
204 /// Appends an element to the end of an [`UnsignedVector`], increasing its dimension by 1.
205 ///
206 /// # Worst-case complexity
207 /// $T(n) = O(n)$
208 ///
209 /// $M(n) = O(n)$
210 ///
211 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`. The capacity
212 /// grows geometrically, so pushing $n$ elements onto an empty vector takes $O(n)$ time in
213 /// total.
214 ///
215 /// # Examples
216 /// ```
217 /// use core::str::FromStr;
218 /// use malachite_base::unsigned_vector::UnsignedVector;
219 /// use malachite_base::vector::Vector;
220 ///
221 /// let mut v = UnsignedVector::<u8>::from_str("(1, 2)").unwrap();
222 /// v.push(3);
223 /// assert_eq!(v.to_string(), "(1, 2, 3)");
224 ///
225 /// let mut v = UnsignedVector::<u8>::zero(0);
226 /// v.push(5);
227 /// assert_eq!(v.to_string(), "(5)");
228 /// ```
229 #[inline]
230 fn push(&mut self, x: T) {
231 self.elements.push(x);
232 }
233
234 /// Sets the dimension of an [`UnsignedVector`], removing elements from the end if the new
235 /// dimension is smaller, and appending zeros if it is larger.
236 ///
237 /// Reducing the dimension keeps the first `dimension` coordinates: it is the projection onto
238 /// them.
239 ///
240 /// # Worst-case complexity
241 /// $T(n) = O(n)$
242 ///
243 /// $M(n) = O(n)$
244 ///
245 /// where $T$ is time, $M$ is additional memory, and $n$ is the larger of `self.dimension()` and
246 /// `dimension`.
247 ///
248 /// # Panics
249 /// Panics if `dimension` is greater than [`usize::MAX`].
250 ///
251 /// # Examples
252 /// ```
253 /// use core::str::FromStr;
254 /// use malachite_base::unsigned_vector::UnsignedVector;
255 /// use malachite_base::vector::Vector;
256 ///
257 /// let mut v = UnsignedVector::<u8>::from_str("(1, 2, 3)").unwrap();
258 /// v.set_dimension(5);
259 /// assert_eq!(v.to_string(), "(1, 2, 3, 0, 0)");
260 /// v.set_dimension(2);
261 /// assert_eq!(v.to_string(), "(1, 2)");
262 /// v.set_dimension(0);
263 /// assert_eq!(v.to_string(), "()");
264 /// ```
265 #[inline]
266 fn set_dimension(&mut self, dimension: u64) {
267 self.elements.resize(usize::exact_from(dimension), T::ZERO);
268 }
269
270 /// Sets every element of an [`UnsignedVector`] to zero, keeping its dimension.
271 ///
272 /// Afterwards the vector equals [`zero`](Vector::zero) of the same dimension.
273 ///
274 /// # Worst-case complexity
275 /// $T(n) = O(n)$
276 ///
277 /// $M(n) = O(1)$
278 ///
279 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
280 ///
281 /// # Examples
282 /// ```
283 /// use core::str::FromStr;
284 /// use malachite_base::unsigned_vector::UnsignedVector;
285 /// use malachite_base::vector::Vector;
286 ///
287 /// let mut v = UnsignedVector::<u8>::from_str("(1, 2, 3)").unwrap();
288 /// v.set_zero();
289 /// assert_eq!(v.to_string(), "(0, 0, 0)");
290 ///
291 /// let mut v = UnsignedVector::<u8>::from_str("()").unwrap();
292 /// v.set_zero();
293 /// assert_eq!(v.to_string(), "()");
294 /// ```
295 ///
296 /// This is equivalent to `_nmod_vec_zero` from `nmod_vec.h`, FLINT 3.6.0.
297 #[inline]
298 fn set_zero(&mut self) {
299 self.elements.fill(T::ZERO);
300 }
301
302 /// Sorts the elements of an [`UnsignedVector`] in ascending order, keeping its dimension.
303 ///
304 /// Equal elements are indistinguishable, so the sort does not need to be stable, and an
305 /// unstable sort is used.
306 ///
307 /// # Worst-case complexity
308 /// $T(n) = O(n \log n)$
309 ///
310 /// $M(n) = O(1)$
311 ///
312 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`, assuming that
313 /// comparing two elements takes constant time; comparing large elements takes time proportional
314 /// to their sizes.
315 ///
316 /// # Examples
317 /// ```
318 /// use core::str::FromStr;
319 /// use malachite_base::unsigned_vector::UnsignedVector;
320 /// use malachite_base::vector::Vector;
321 ///
322 /// let mut v = UnsignedVector::<u8>::from_str("(3, 1, 2, 1)").unwrap();
323 /// v.sort();
324 /// assert_eq!(v.to_string(), "(1, 1, 2, 3)");
325 /// ```
326 #[inline]
327 fn sort(&mut self) {
328 self.elements.sort_unstable();
329 }
330
331 /// Returns an [`UnsignedVector`]'s elements as a [`Vec`], cloning them.
332 ///
333 /// # Worst-case complexity
334 /// $T(n) = O(n)$
335 ///
336 /// $M(n) = O(n)$
337 ///
338 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
339 ///
340 /// # Examples
341 /// ```
342 /// use core::str::FromStr;
343 /// use malachite_base::unsigned_vector::UnsignedVector;
344 /// use malachite_base::vector::Vector;
345 ///
346 /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
347 /// assert_eq!(v.to_elements(), [1, 2, 3]);
348 /// assert!(
349 /// UnsignedVector::<u32>::from_str("()")
350 /// .unwrap()
351 /// .to_elements()
352 /// .is_empty()
353 /// );
354 /// ```
355 #[inline]
356 fn to_elements(&self) -> Vec<T> {
357 self.elements.clone()
358 }
359
360 /// Returns an [`UnsignedVector`]'s elements as a [`Vec`], taking ownership of the
361 /// [`UnsignedVector`].
362 ///
363 /// Nothing is copied or allocated.
364 ///
365 /// # Worst-case complexity
366 /// Constant time and additional memory.
367 ///
368 /// # Examples
369 /// ```
370 /// use core::str::FromStr;
371 /// use malachite_base::unsigned_vector::UnsignedVector;
372 /// use malachite_base::vector::Vector;
373 ///
374 /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
375 /// assert_eq!(v.into_elements(), [1, 2, 3]);
376 /// assert!(
377 /// UnsignedVector::<u32>::from_str("()")
378 /// .unwrap()
379 /// .into_elements()
380 /// .is_empty()
381 /// );
382 /// ```
383 #[inline]
384 fn into_elements(self) -> Vec<T> {
385 self.elements
386 }
387
388 /// Returns a reference to an [`UnsignedVector`]'s elements, as a slice.
389 ///
390 /// # Worst-case complexity
391 /// Constant time and additional memory.
392 ///
393 /// # Examples
394 /// ```
395 /// use core::str::FromStr;
396 /// use malachite_base::unsigned_vector::UnsignedVector;
397 /// use malachite_base::vector::Vector;
398 ///
399 /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
400 /// assert_eq!(v.elements_ref(), [1, 2, 3]);
401 /// // A slice of the elements can be taken directly.
402 /// assert_eq!(&v.elements_ref()[1..], [2, 3]);
403 /// assert!(
404 /// UnsignedVector::<u32>::from_str("()")
405 /// .unwrap()
406 /// .elements_ref()
407 /// .is_empty()
408 /// );
409 /// ```
410 #[inline]
411 fn elements_ref(&self) -> &[T] {
412 &self.elements
413 }
414
415 /// Returns the dimension of an [`UnsignedVector`]: the number of its elements.
416 ///
417 /// # Worst-case complexity
418 /// Constant time and additional memory.
419 ///
420 /// # Examples
421 /// ```
422 /// use malachite_base::unsigned_vector::UnsignedVector;
423 /// use malachite_base::vector::Vector;
424 ///
425 /// assert_eq!(
426 /// UnsignedVector {
427 /// elements: vec![4u32, 5]
428 /// }
429 /// .dimension(),
430 /// 2
431 /// );
432 /// assert_eq!(
433 /// UnsignedVector::<u32> {
434 /// elements: Vec::new()
435 /// }
436 /// .dimension(),
437 /// 0
438 /// );
439 /// ```
440 #[inline]
441 fn dimension(&self) -> u64 {
442 u64::exact_from(self.elements.len())
443 }
444
445 /// Returns the pivot of an [`UnsignedVector`]: its first nonzero element.
446 ///
447 /// This is the element that leads the vector when it is a row of a matrix in echelon form. It
448 /// returns a copy of it, or `None` if every element is zero, which includes the 0-dimensional
449 /// vector.
450 ///
451 /// # Worst-case complexity
452 /// $T(n) = O(n)$
453 ///
454 /// $M(n) = O(1)$
455 ///
456 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
457 ///
458 /// # Examples
459 /// ```
460 /// use core::str::FromStr;
461 /// use malachite_base::unsigned_vector::UnsignedVector;
462 /// use malachite_base::vector::Vector;
463 ///
464 /// assert_eq!(
465 /// UnsignedVector::<u32>::from_str("(0, 0, 3, 0, 5)")
466 /// .unwrap()
467 /// .pivot(),
468 /// Some(3)
469 /// );
470 /// assert_eq!(
471 /// UnsignedVector::<u32>::from_str("(0, 0)").unwrap().pivot(),
472 /// None
473 /// );
474 /// assert_eq!(UnsignedVector::<u32>::from_str("()").unwrap().pivot(), None);
475 /// ```
476 #[inline]
477 fn pivot(&self) -> Option<T> {
478 self.elements.iter().find(|&&x| x != T::ZERO).copied()
479 }
480
481 /// Returns the index of the pivot of an [`UnsignedVector`]: the position of its first nonzero
482 /// element.
483 ///
484 /// Indices start at 0, as they do for [`Index`](core::ops::Index). Returns `None` if every
485 /// element is zero, which includes the 0-dimensional vector. When it returns `Some(i)`,
486 /// [`pivot`](Self::pivot) is the element at `i`.
487 ///
488 /// # Worst-case complexity
489 /// $T(n) = O(n)$
490 ///
491 /// $M(n) = O(1)$
492 ///
493 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
494 ///
495 /// # Examples
496 /// ```
497 /// use core::str::FromStr;
498 /// use malachite_base::unsigned_vector::UnsignedVector;
499 /// use malachite_base::vector::Vector;
500 ///
501 /// assert_eq!(
502 /// UnsignedVector::<u32>::from_str("(0, 0, 3, 0, 5)")
503 /// .unwrap()
504 /// .pivot_index(),
505 /// Some(2)
506 /// );
507 /// assert_eq!(
508 /// UnsignedVector::<u32>::from_str("(0, 0)")
509 /// .unwrap()
510 /// .pivot_index(),
511 /// None
512 /// );
513 /// assert_eq!(
514 /// UnsignedVector::<u32>::from_str("()").unwrap().pivot_index(),
515 /// None
516 /// );
517 /// ```
518 #[inline]
519 fn pivot_index(&self) -> Option<u64> {
520 self.elements
521 .iter()
522 .position(|&x| x != T::ZERO)
523 .map(u64::exact_from)
524 }
525
526 /// Returns the index of the largest element of an [`UnsignedVector`]: the first one, when
527 /// several are tied.
528 ///
529 /// Indices start at 0, as they do for [`Index`](core::ops::Index). Returns `None` for the
530 /// 0-dimensional vector.
531 ///
532 /// # Worst-case complexity
533 /// $T(n) = O(n)$
534 ///
535 /// $M(n) = O(1)$
536 ///
537 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
538 /// elements.
539 ///
540 /// # Examples
541 /// ```
542 /// use core::str::FromStr;
543 /// use malachite_base::unsigned_vector::UnsignedVector;
544 /// use malachite_base::vector::Vector;
545 ///
546 /// assert_eq!(
547 /// UnsignedVector::<u8>::from_str("(1, 3, 3, 2)")
548 /// .unwrap()
549 /// .height_index(),
550 /// Some(1)
551 /// );
552 /// assert_eq!(
553 /// UnsignedVector::<u8>::from_str("(5, 5)")
554 /// .unwrap()
555 /// .height_index(),
556 /// Some(0)
557 /// );
558 /// assert_eq!(
559 /// UnsignedVector::<u8>::from_str("()").unwrap().height_index(),
560 /// None
561 /// );
562 /// ```
563 #[inline]
564 fn height_index(&self) -> Option<u64> {
565 // `max_by` returns the last of several equal maxima, so iterating in reverse gives the
566 // first.
567 self.elements
568 .iter()
569 .enumerate()
570 .rev()
571 .max_by(|(_, x), (_, y)| x.cmp(y))
572 .map(|(i, _)| u64::exact_from(i))
573 }
574
575 /// Determines whether every element of an [`UnsignedVector`] is zero.
576 ///
577 /// The 0-dimensional vector, which has no elements, counts as zero.
578 ///
579 /// # Worst-case complexity
580 /// $T(n) = O(n)$
581 ///
582 /// $M(n) = O(1)$
583 ///
584 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
585 ///
586 /// # Examples
587 /// ```
588 /// use core::str::FromStr;
589 /// use malachite_base::unsigned_vector::UnsignedVector;
590 /// use malachite_base::vector::Vector;
591 ///
592 /// assert!(UnsignedVector::<u8>::from_str("(0, 0)").unwrap().is_zero());
593 /// assert!(UnsignedVector::<u8>::from_str("()").unwrap().is_zero());
594 /// assert!(
595 /// !UnsignedVector::<u8>::from_str("(0, 1, 0)")
596 /// .unwrap()
597 /// .is_zero()
598 /// );
599 /// ```
600 #[inline]
601 fn is_zero(&self) -> bool {
602 self.elements.iter().all(|&x| x == T::ZERO)
603 }
604
605 /// Determines whether an [`UnsignedVector`] is a standard basis vector, returning the index of
606 /// its 1 if it is.
607 ///
608 /// A standard basis vector has a single element equal to 1 and every other element 0. Returns
609 /// `None` for every other vector, including the zero vectors and the 0-dimensional vector.
610 ///
611 /// # Worst-case complexity
612 /// $T(n) = O(n)$
613 ///
614 /// $M(n) = O(1)$
615 ///
616 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
617 ///
618 /// # Examples
619 /// ```
620 /// use core::str::FromStr;
621 /// use malachite_base::unsigned_vector::UnsignedVector;
622 /// use malachite_base::vector::Vector;
623 ///
624 /// assert_eq!(
625 /// UnsignedVector::<u8>::from_str("(0, 1, 0)")
626 /// .unwrap()
627 /// .standard_basis_index(),
628 /// Some(1)
629 /// );
630 /// assert_eq!(
631 /// UnsignedVector::<u8>::from_str("(0, 2, 0)")
632 /// .unwrap()
633 /// .standard_basis_index(),
634 /// None
635 /// );
636 /// assert_eq!(
637 /// UnsignedVector::<u8>::from_str("(1, 0, 1)")
638 /// .unwrap()
639 /// .standard_basis_index(),
640 /// None
641 /// );
642 /// assert_eq!(
643 /// UnsignedVector::<u8>::from_str("(0, 0)")
644 /// .unwrap()
645 /// .standard_basis_index(),
646 /// None
647 /// );
648 /// ```
649 fn standard_basis_index(&self) -> Option<u64> {
650 let index = self.pivot_index()?;
651 let i = usize::exact_from(index);
652 if self.elements[i] == T::ONE && self.elements[i + 1..].iter().all(|&x| x == T::ZERO) {
653 Some(index)
654 } else {
655 None
656 }
657 }
658
659 /// Returns the number of significant bits of the height of an [`UnsignedVector`], together with
660 /// whether any of its elements is negative.
661 ///
662 /// Since no element is negative, the flag is always `false`. The bit count is the bit length of
663 /// the bitwise or of the elements.
664 ///
665 /// # Worst-case complexity
666 /// $T(n) = O(n)$
667 ///
668 /// $M(n) = O(1)$
669 ///
670 /// where $T$ is time, $M$ is additional memory, and $n$ is the number of elements.
671 ///
672 /// # Examples
673 /// ```
674 /// use core::str::FromStr;
675 /// use malachite_base::unsigned_vector::UnsignedVector;
676 /// use malachite_base::vector::Vector;
677 ///
678 /// assert_eq!(
679 /// UnsignedVector::<u8>::from_str("(1, 5, 2)")
680 /// .unwrap()
681 /// .max_bits(),
682 /// (3, false)
683 /// );
684 /// assert_eq!(
685 /// UnsignedVector::<u8>::from_str("()").unwrap().max_bits(),
686 /// (0, false)
687 /// );
688 /// ```
689 ///
690 /// This is equivalent to `_nmod_vec_max_bits` from `nmod_vec/max_bits.c`, FLINT 3.6.0, together
691 /// with the flag.
692 #[inline]
693 fn max_bits(&self) -> (u64, bool) {
694 let mut or = T::ZERO;
695 for &x in &self.elements {
696 or |= x;
697 }
698 (or.significant_bits(), false)
699 }
700
701 /// Returns the number of significant bits of the sum of the absolute values of the elements of
702 /// an [`UnsignedVector`] (its $\ell^1$ norm), together with the number of significant bits of
703 /// its height.
704 ///
705 /// The sum may not fit in a `T`, so the carries out of the top bit are counted; no wider type
706 /// is needed.
707 ///
708 /// # Worst-case complexity
709 /// $T(n) = O(n)$
710 ///
711 /// $M(n) = O(n)$
712 ///
713 /// where $T$ is time, $M$ is additional memory, and $n$ is the number of elements.
714 ///
715 /// # Examples
716 /// ```
717 /// use core::str::FromStr;
718 /// use malachite_base::unsigned_vector::UnsignedVector;
719 /// use malachite_base::vector::Vector;
720 ///
721 /// assert_eq!(
722 /// UnsignedVector::<u8>::from_str("(255, 255)")
723 /// .unwrap()
724 /// .sum_max_bits(),
725 /// (9, 8)
726 /// );
727 /// assert_eq!(
728 /// UnsignedVector::<u8>::from_str("()").unwrap().sum_max_bits(),
729 /// (0, 0)
730 /// );
731 /// ```
732 fn sum_max_bits(&self) -> (u64, u64) {
733 let mut sum = T::ZERO;
734 let mut carries = 0u64;
735 let mut or = T::ZERO;
736 for &x in &self.elements {
737 let overflow;
738 (sum, overflow) = sum.overflowing_add(x);
739 if overflow {
740 carries += 1;
741 }
742 or |= x;
743 }
744 // The sum is `carries` times 2^W plus `sum`.
745 let sum_bits = if carries == 0 {
746 sum.significant_bits()
747 } else {
748 T::WIDTH + carries.significant_bits()
749 };
750 (sum_bits, or.significant_bits())
751 }
752}
753
754macro_rules! impl_named_unsigned_vector {
755 ($t:ident, $name:expr) => {
756 impl Named for UnsignedVector<$t> {
757 /// The name of this type, with its element type spelled out.
758 const NAME: &'static str = $name;
759 }
760 };
761}
762impl_named_unsigned_vector!(u8, "UnsignedVector<u8>");
763impl_named_unsigned_vector!(u16, "UnsignedVector<u16>");
764impl_named_unsigned_vector!(u32, "UnsignedVector<u32>");
765impl_named_unsigned_vector!(u64, "UnsignedVector<u64>");
766impl_named_unsigned_vector!(u128, "UnsignedVector<u128>");
767impl_named_unsigned_vector!(usize, "UnsignedVector<usize>");
768
769/// `ShortlexUnsignedVector` is a wrapper around an [`UnsignedVector`], taking the
770/// [`UnsignedVector`] by value.
771///
772/// [`UnsignedVector`] does not implement [`Ord`], because no order on vectors is canonical: lex,
773/// graded lex, and the others all have their uses, and the order most natural mathematically,
774/// comparing vectors of the same dimension element by element, is only partial. Wrapping an
775/// [`UnsignedVector`] in a `ShortlexUnsignedVector` provides one total order: vectors are compared
776/// first by dimension and then, in case of a tie, lexicographically, by their elements from first
777/// to last. Its equality agrees with [`UnsignedVector`] equality.
778///
779/// Unlike lexicographic order on [`Vec`]s, this order puts every vector of a smaller dimension
780/// before every vector of a larger one, so that $(5) < (0, 0)$. It is a well-order: any nonempty
781/// set of vectors has a least element, the lexicographically least of those of the smallest
782/// dimension present.
783///
784/// `ShortlexUnsignedVector` owns its value. This is useful in many cases, for example if you want
785/// to use [`UnsignedVector`]s as keys in a [`BTreeMap`](alloc::collections::BTreeMap). In other
786/// situations, it is better to use [`ShortlexUnsignedVectorRef`], which only has a reference to its
787/// value.
788// Serialized as its inner `UnsignedVector`, since the wrapper adds no data of its own.
789#[derive(Clone, Eq, Hash, PartialEq)]
790#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
791#[cfg_attr(feature = "serde", serde(transparent))]
792pub struct ShortlexUnsignedVector<T: PrimitiveUnsigned>(pub UnsignedVector<T>);
793
794/// `ShortlexUnsignedVectorRef` is a wrapper around an [`UnsignedVector`], taking the
795/// [`UnsignedVector`] by reference.
796///
797/// See the [`ShortlexUnsignedVector`] documentation for details.
798#[derive(Clone, Eq, Hash, PartialEq)]
799pub struct ShortlexUnsignedVectorRef<'a, T: PrimitiveUnsigned>(pub &'a UnsignedVector<T>);
800
801impl<T: PrimitiveUnsigned> ShortlexUnsignedVector<T> {
802 /// Borrows a [`ShortlexUnsignedVector`] as a [`ShortlexUnsignedVectorRef`].
803 ///
804 /// # Worst-case complexity
805 /// Constant time and additional memory.
806 ///
807 /// # Examples
808 /// ```
809 /// use core::str::FromStr;
810 /// use malachite_base::unsigned_vector::{
811 /// ShortlexUnsignedVector, ShortlexUnsignedVectorRef, UnsignedVector,
812 /// };
813 ///
814 /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
815 /// let x = ShortlexUnsignedVector(v.clone());
816 /// assert_eq!(x.as_ref(), ShortlexUnsignedVectorRef(&v));
817 /// ```
818 pub const fn as_ref(&self) -> ShortlexUnsignedVectorRef<'_, T> {
819 ShortlexUnsignedVectorRef(&self.0)
820 }
821}
822
823impl<T: PrimitiveUnsigned> Deref for ShortlexUnsignedVector<T> {
824 type Target = UnsignedVector<T>;
825
826 /// Allows a [`ShortlexUnsignedVector`] to dereference to an [`UnsignedVector`].
827 ///
828 /// ```
829 /// use core::str::FromStr;
830 /// use malachite_base::unsigned_vector::{ShortlexUnsignedVector, UnsignedVector};
831 ///
832 /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
833 /// let x = ShortlexUnsignedVector(v.clone());
834 /// assert_eq!(*x, v);
835 /// ```
836 fn deref(&self) -> &UnsignedVector<T> {
837 &self.0
838 }
839}
840
841impl<T: PrimitiveUnsigned> Deref for ShortlexUnsignedVectorRef<'_, T> {
842 type Target = UnsignedVector<T>;
843
844 /// Allows a [`ShortlexUnsignedVectorRef`] to dereference to an [`UnsignedVector`].
845 ///
846 /// ```
847 /// use core::str::FromStr;
848 /// use malachite_base::unsigned_vector::{ShortlexUnsignedVectorRef, UnsignedVector};
849 ///
850 /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
851 /// let x = ShortlexUnsignedVectorRef(&v);
852 /// assert_eq!(*x, v);
853 /// ```
854 fn deref(&self) -> &UnsignedVector<T> {
855 self.0
856 }
857}
858
859impl<T: PrimitiveUnsigned> Debug for ShortlexUnsignedVector<T> {
860 /// Writes a [`ShortlexUnsignedVector`] as `ShortlexUnsignedVector(` followed by the vector and
861 /// `)`.
862 ///
863 /// # Examples
864 /// ```
865 /// use core::str::FromStr;
866 /// use malachite_base::strings::ToDebugString;
867 /// use malachite_base::unsigned_vector::{ShortlexUnsignedVector, UnsignedVector};
868 ///
869 /// let v = UnsignedVector::<u32>::from_str("(1, 2)").unwrap();
870 /// assert_eq!(
871 /// ShortlexUnsignedVector(v).to_debug_string(),
872 /// "ShortlexUnsignedVector((1, 2))"
873 /// );
874 /// ```
875 #[inline]
876 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
877 f.debug_tuple("ShortlexUnsignedVector")
878 .field(&self.0)
879 .finish()
880 }
881}
882
883impl<T: PrimitiveUnsigned> Debug for ShortlexUnsignedVectorRef<'_, T> {
884 /// Writes a [`ShortlexUnsignedVectorRef`] as `ShortlexUnsignedVectorRef(` followed by the
885 /// vector and `)`.
886 ///
887 /// # Examples
888 /// ```
889 /// use core::str::FromStr;
890 /// use malachite_base::strings::ToDebugString;
891 /// use malachite_base::unsigned_vector::{ShortlexUnsignedVectorRef, UnsignedVector};
892 ///
893 /// let v = UnsignedVector::<u32>::from_str("(1, 2)").unwrap();
894 /// assert_eq!(
895 /// ShortlexUnsignedVectorRef(&v).to_debug_string(),
896 /// "ShortlexUnsignedVectorRef((1, 2))"
897 /// );
898 /// ```
899 #[inline]
900 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
901 f.debug_tuple("ShortlexUnsignedVectorRef")
902 .field(self.0)
903 .finish()
904 }
905}