Skip to main content

malachite_base/unsigned_vector/arithmetic/
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
9/// Implementations of [`CanonicalPrimitivePart`](
10/// crate::num::arithmetic::traits::CanonicalPrimitivePart), [`CanonicalPrimitivePartAssign`](
11/// crate::num::arithmetic::traits::CanonicalPrimitivePartAssign), and
12/// [`ContentAndCanonicalPrimitivePart`](
13/// crate::num::arithmetic::traits::ContentAndCanonicalPrimitivePart), which, for a vector with
14/// non-negative elements, are the same as the primitive part.
15pub mod canonical_primitive_part;
16/// Implementations of [`Content`](crate::num::arithmetic::traits::Content),
17/// [`PrimitivePart`](crate::num::arithmetic::traits::PrimitivePart),
18/// [`PrimitivePartAssign`](crate::num::arithmetic::traits::PrimitivePartAssign), and
19/// [`ContentAndPrimitivePart`](crate::num::arithmetic::traits::ContentAndPrimitivePart), which
20/// compute the GCD of a vector's elements and the vector divided by it.
21pub mod content;
22/// Implementations of [`ContentChained`](crate::num::arithmetic::traits::ContentChained), which
23/// computes the GCD of a number and a vector's elements.
24pub mod content_chained;
25/// Exact division of a vector by a scalar, by implementations of
26/// [`DivExact`](crate::num::arithmetic::traits::DivExact) and
27/// [`DivExactAssign`](crate::num::arithmetic::traits::DivExactAssign).
28///
29/// # div_exact
30/// ```
31/// use core::str::FromStr;
32/// use malachite_base::num::arithmetic::traits::DivExact;
33/// use malachite_base::unsigned_vector::UnsignedVector;
34///
35/// assert_eq!(
36///     UnsignedVector::<u8>::from_str("()")
37///         .unwrap()
38///         .div_exact(5)
39///         .to_string(),
40///     "()"
41/// );
42/// assert_eq!(
43///     UnsignedVector::<u8>::from_str("(0, 6, 255)")
44///         .unwrap()
45///         .div_exact(1)
46///         .to_string(),
47///     "(0, 6, 255)"
48/// );
49/// assert_eq!(
50///     (&UnsignedVector::<u8>::from_str("(0, 6, 255)").unwrap())
51///         .div_exact(3)
52///         .to_string(),
53///     "(0, 2, 85)"
54/// );
55/// assert_eq!(
56///     (&UnsignedVector::<u64>::from_str("(18446744073709551614, 4)").unwrap())
57///         .div_exact(2)
58///         .to_string(),
59///     "(9223372036854775807, 2)"
60/// );
61/// ```
62///
63/// # div_exact_assign
64/// ```
65/// use core::str::FromStr;
66/// use malachite_base::num::arithmetic::traits::DivExactAssign;
67/// use malachite_base::unsigned_vector::UnsignedVector;
68///
69/// let mut v = UnsignedVector::<u8>::from_str("(0, 6, 255)").unwrap();
70/// v.div_exact_assign(3);
71/// assert_eq!(v.to_string(), "(0, 2, 85)");
72/// ```
73pub mod div_exact;
74/// Dividing every element of a vector by a scalar and rounding each quotient, by implementations of
75/// [`EntrywiseDivRound`](crate::num::arithmetic::traits::EntrywiseDivRound) and
76/// [`EntrywiseDivRoundAssign`](crate::num::arithmetic::traits::EntrywiseDivRoundAssign).
77///
78/// # entrywise_div_round
79/// ```
80/// use core::str::FromStr;
81/// use malachite_base::num::arithmetic::traits::EntrywiseDivRound;
82/// use malachite_base::rounding_modes::RoundingMode::*;
83/// use malachite_base::unsigned_vector::UnsignedVector;
84///
85/// assert_eq!(
86///     UnsignedVector::<u8>::from_str("(1, 2, 3, 5)")
87///         .unwrap()
88///         .entrywise_div_round(2u8, Floor)
89///         .to_string(),
90///     "(0, 1, 1, 2)"
91/// );
92/// assert_eq!(
93///     (&UnsignedVector::<u8>::from_str("(1, 2, 3, 5)").unwrap())
94///         .entrywise_div_round(2u8, Ceiling)
95///         .to_string(),
96///     "(1, 1, 2, 3)"
97/// );
98/// assert_eq!(
99///     (&UnsignedVector::<u8>::from_str("(1, 2, 3, 5)").unwrap())
100///         .entrywise_div_round(2u8, Nearest)
101///         .to_string(),
102///     "(0, 1, 2, 2)"
103/// );
104/// assert_eq!(
105///     UnsignedVector::<u8>::from_str("(3, 6, 255)")
106///         .unwrap()
107///         .entrywise_div_round(3u8, Exact)
108///         .to_string(),
109///     "(1, 2, 85)"
110/// );
111/// ```
112///
113/// # entrywise_div_round_assign
114/// ```
115/// use core::str::FromStr;
116/// use malachite_base::num::arithmetic::traits::EntrywiseDivRoundAssign;
117/// use malachite_base::rounding_modes::RoundingMode::*;
118/// use malachite_base::unsigned_vector::UnsignedVector;
119///
120/// let mut v = UnsignedVector::<u8>::from_str("(1, 2, 3, 5)").unwrap();
121/// v.entrywise_div_round_assign(2u8, Nearest);
122/// assert_eq!(v.to_string(), "(0, 1, 2, 2)");
123/// ```
124pub mod entrywise_div_round;
125/// Right-shifting a vector (dividing it by a power of 2) and rounding every element, by
126/// implementations of [`EntrywiseShrRound`](crate::num::arithmetic::traits::EntrywiseShrRound) and
127/// [`EntrywiseShrRoundAssign`](crate::num::arithmetic::traits::EntrywiseShrRoundAssign).
128///
129/// # entrywise_shr_round
130/// ```
131/// use core::str::FromStr;
132/// use malachite_base::num::arithmetic::traits::EntrywiseShrRound;
133/// use malachite_base::rounding_modes::RoundingMode::*;
134/// use malachite_base::unsigned_vector::UnsignedVector;
135///
136/// let v = UnsignedVector::<u8>::from_str("(1, 2, 3, 5)").unwrap();
137/// assert_eq!(
138///     (&v).entrywise_shr_round(1u8, Floor).to_string(),
139///     "(0, 1, 1, 2)"
140/// );
141/// assert_eq!(
142///     (&v).entrywise_shr_round(1u16, Ceiling).to_string(),
143///     "(1, 1, 2, 3)"
144/// );
145/// // Ties round to even.
146/// assert_eq!(
147///     (&v).entrywise_shr_round(1u32, Nearest).to_string(),
148///     "(0, 1, 2, 2)"
149/// );
150/// assert_eq!(
151///     UnsignedVector::<u8>::from_str("(4, 8, 12)")
152///         .unwrap()
153///         .entrywise_shr_round(2u64, Exact)
154///         .to_string(),
155///     "(1, 2, 3)"
156/// );
157/// // Shifting by at least the width rounds every element to 0 or 1.
158/// assert_eq!(
159///     UnsignedVector::<u8>::from_str("(255, 128, 127)")
160///         .unwrap()
161///         .entrywise_shr_round(8u8, Nearest)
162///         .to_string(),
163///     "(1, 0, 0)"
164/// );
165/// assert_eq!(
166///     UnsignedVector::<u8>::from_str("(255, 1, 0)")
167///         .unwrap()
168///         .entrywise_shr_round(100u128, Ceiling)
169///         .to_string(),
170///     "(1, 1, 0)"
171/// );
172/// ```
173///
174/// # entrywise_shr_round_assign
175/// ```
176/// use core::str::FromStr;
177/// use malachite_base::num::arithmetic::traits::EntrywiseShrRoundAssign;
178/// use malachite_base::rounding_modes::RoundingMode::*;
179/// use malachite_base::unsigned_vector::UnsignedVector;
180///
181/// let mut v = UnsignedVector::<u8>::from_str("(1, 2, 3, 5)").unwrap();
182/// v.entrywise_shr_round_assign(1u8, Nearest);
183/// assert_eq!(v.to_string(), "(0, 1, 2, 2)");
184///
185/// let mut v = UnsignedVector::<u8>::from_str("(1, 2, 3, 5)").unwrap();
186/// v.entrywise_shr_round_assign(1u32, Up);
187/// assert_eq!(v.to_string(), "(1, 1, 2, 3)");
188/// ```
189pub mod entrywise_shr_round;
190/// An implementation of [`Height`](crate::num::arithmetic::traits::Height), the largest height of
191/// any element.
192pub mod height;
193/// Implementations of [`ModAbsSquared`](crate::num::arithmetic::traits::ModAbsSquared), the squared
194/// norm of a vector modulo a number.
195pub mod mod_abs_squared;
196/// Implementations of [`ModAdd`](crate::num::arithmetic::traits::ModAdd) and
197/// [`ModAddAssign`](crate::num::arithmetic::traits::ModAddAssign), for adding vectors modulo a
198/// number.
199pub mod mod_add;
200/// Implementations of [`ModAddMul`](crate::num::arithmetic::traits::ModAddMul) and
201/// [`ModAddMulAssign`](crate::num::arithmetic::traits::ModAddMulAssign), for adding a scalar
202/// multiple of one vector to another modulo a number.
203pub mod mod_add_mul;
204/// Implementations of [`ModAddMulShl`](crate::num::arithmetic::traits::ModAddMulShl) and
205/// [`ModAddMulShlAssign`](crate::num::arithmetic::traits::ModAddMulShlAssign), for adding a scalar
206/// multiple of one vector, shifted left, to another modulo a number.
207pub mod mod_add_mul_shl;
208/// Implementations of [`ModDot`](crate::num::arithmetic::traits::ModDot), the dot product of two
209/// vectors modulo a number, accumulating the sum before reducing it once.
210pub mod mod_dot;
211/// Implementations of [`ModElementProduct`](crate::num::arithmetic::traits::ModElementProduct), the
212/// product of the elements modulo a number.
213pub mod mod_element_product;
214/// Implementations of [`ModElementSum`](crate::num::arithmetic::traits::ModElementSum), the sum of
215/// the elements modulo a number.
216pub mod mod_element_sum;
217/// An implementation of [`ModIsReduced`](crate::num::arithmetic::traits::ModIsReduced), which
218/// checks whether every element of a vector is less than a given modulus.
219pub mod mod_is_reduced;
220/// Implementations of [`ModMul`](crate::num::arithmetic::traits::ModMul) and
221/// [`ModMulAssign`](crate::num::arithmetic::traits::ModMulAssign), for multiplying a vector by a
222/// scalar modulo a number.
223pub mod mod_mul;
224/// Implementations of [`ModNeg`](crate::num::arithmetic::traits::ModNeg) and
225/// [`ModNegAssign`](crate::num::arithmetic::traits::ModNegAssign), for negating a vector modulo a
226/// number.
227pub mod mod_neg;
228/// Implementations of [`Mod`](crate::num::arithmetic::traits::Mod),
229/// [`ModAssign`](crate::num::arithmetic::traits::ModAssign), [`Rem`](core::ops::Rem), and
230/// [`RemAssign`](core::ops::RemAssign), traits for reducing every element of a vector modulo a
231/// number.
232pub mod mod_op;
233/// Implementations of [`ModPowerOf2`](crate::num::arithmetic::traits::ModPowerOf2) and
234/// [`ModPowerOf2Assign`](crate::num::arithmetic::traits::ModPowerOf2Assign), which reduce every
235/// element of a vector modulo a power of 2.
236pub mod mod_power_of_2;
237/// Implementations of
238/// [`ModPowerOf2AbsSquared`](crate::num::arithmetic::traits::ModPowerOf2AbsSquared), the squared
239/// norm of a vector modulo a power of 2.
240pub mod mod_power_of_2_abs_squared;
241/// Implementations of [`ModPowerOf2Add`](crate::num::arithmetic::traits::ModPowerOf2Add) and
242/// [`ModPowerOf2AddAssign`](crate::num::arithmetic::traits::ModPowerOf2AddAssign), for adding
243/// vectors modulo a power of 2.
244pub mod mod_power_of_2_add;
245/// Implementations of [`ModPowerOf2AddMul`](crate::num::arithmetic::traits::ModPowerOf2AddMul) and
246/// [`ModPowerOf2AddMulAssign`](crate::num::arithmetic::traits::ModPowerOf2AddMulAssign), for adding
247/// a scalar multiple of one vector to another modulo a power of 2.
248pub mod mod_power_of_2_add_mul;
249/// Implementations of
250/// [`ModPowerOf2AddMulShl`](crate::num::arithmetic::traits::ModPowerOf2AddMulShl) and
251/// [`ModPowerOf2AddMulShlAssign`](crate::num::arithmetic::traits::ModPowerOf2AddMulShlAssign), for
252/// adding a scalar multiple of one vector, shifted left, to another modulo a power of 2.
253pub mod mod_power_of_2_add_mul_shl;
254/// Implementations of [`ModPowerOf2Dot`](crate::num::arithmetic::traits::ModPowerOf2Dot), the dot
255/// product of two vectors modulo a power of 2.
256pub mod mod_power_of_2_dot;
257/// An implementation of
258/// [`ModPowerOf2ElementProduct`](crate::num::arithmetic::traits::ModPowerOf2ElementProduct), the
259/// product of the elements modulo a power of 2.
260pub mod mod_power_of_2_element_product;
261/// An implementation of
262/// [`ModPowerOf2ElementSum`](crate::num::arithmetic::traits::ModPowerOf2ElementSum), the sum of the
263/// elements modulo a power of 2.
264pub mod mod_power_of_2_element_sum;
265/// An implementation of
266/// [`ModPowerOf2IsReduced`](crate::num::arithmetic::traits::ModPowerOf2IsReduced), which checks
267/// whether every element of a vector is less than a given power of 2.
268pub mod mod_power_of_2_is_reduced;
269/// Implementations of [`ModPowerOf2Mul`](crate::num::arithmetic::traits::ModPowerOf2Mul) and
270/// [`ModPowerOf2MulAssign`](crate::num::arithmetic::traits::ModPowerOf2MulAssign), for multiplying
271/// a vector by a scalar modulo a power of 2.
272pub mod mod_power_of_2_mul;
273/// Implementations of [`ModPowerOf2Neg`](crate::num::arithmetic::traits::ModPowerOf2Neg) and
274/// [`ModPowerOf2NegAssign`](crate::num::arithmetic::traits::ModPowerOf2NegAssign), for negating a
275/// vector modulo a power of 2.
276pub mod mod_power_of_2_neg;
277/// Implementations of [`ModPowerOf2Shl`](crate::num::arithmetic::traits::ModPowerOf2Shl) and
278/// [`ModPowerOf2ShlAssign`](crate::num::arithmetic::traits::ModPowerOf2ShlAssign), for
279/// left-shifting a vector (multiplying it by a power of 2) modulo another power of 2.
280///
281/// # mod_power_of_2_shl
282/// ```
283/// use core::str::FromStr;
284/// use malachite_base::num::arithmetic::traits::ModPowerOf2Shl;
285/// use malachite_base::unsigned_vector::UnsignedVector;
286///
287/// let v = UnsignedVector::<u8>::from_str("(5, 1, 3)").unwrap();
288/// assert_eq!(
289///     v.clone().mod_power_of_2_shl(1u8, 3).to_string(),
290///     "(2, 2, 6)"
291/// );
292/// // Shifting by at least the power zeroes every element, keeping the dimension.
293/// assert_eq!(v.mod_power_of_2_shl(3u32, 3).to_string(), "(0, 0, 0)");
294/// assert_eq!(
295///     (&UnsignedVector::<u8>::from_str("(1, 128, 1)").unwrap())
296///         .mod_power_of_2_shl(1u64, 8)
297///         .to_string(),
298///     "(2, 0, 2)"
299/// );
300/// assert_eq!(
301///     (&UnsignedVector::<u64>::from_str("(1, 1)").unwrap())
302///         .mod_power_of_2_shl(63u128, 64)
303///         .to_string(),
304///     "(9223372036854775808, 9223372036854775808)"
305/// );
306/// ```
307///
308/// # mod_power_of_2_shl_assign
309/// ```
310/// use core::str::FromStr;
311/// use malachite_base::num::arithmetic::traits::ModPowerOf2ShlAssign;
312/// use malachite_base::unsigned_vector::UnsignedVector;
313///
314/// let mut v = UnsignedVector::<u8>::from_str("(5, 1, 3)").unwrap();
315/// v.mod_power_of_2_shl_assign(1u8, 3);
316/// assert_eq!(v.to_string(), "(2, 2, 6)");
317///
318/// let mut v = UnsignedVector::<u8>::from_str("(5, 1, 3)").unwrap();
319/// v.mod_power_of_2_shl_assign(3u32, 3);
320/// assert_eq!(v.to_string(), "(0, 0, 0)");
321/// ```
322pub mod mod_power_of_2_shl;
323/// Implementations of [`ModPowerOf2Sub`](crate::num::arithmetic::traits::ModPowerOf2Sub) and
324/// [`ModPowerOf2SubAssign`](crate::num::arithmetic::traits::ModPowerOf2SubAssign), for subtracting
325/// vectors modulo a power of 2.
326pub mod mod_power_of_2_sub;
327/// Implementations of [`ModPowerOf2SubMul`](crate::num::arithmetic::traits::ModPowerOf2SubMul) and
328/// [`ModPowerOf2SubMulAssign`](crate::num::arithmetic::traits::ModPowerOf2SubMulAssign), for
329/// subtracting a scalar multiple of one vector from another modulo a power of 2.
330pub mod mod_power_of_2_sub_mul;
331/// Implementations of
332/// [`ModPowerOf2SubMulShl`](crate::num::arithmetic::traits::ModPowerOf2SubMulShl) and
333/// [`ModPowerOf2SubMulShlAssign`](crate::num::arithmetic::traits::ModPowerOf2SubMulShlAssign), for
334/// subtracting a scalar multiple of one vector, shifted left, from another modulo a power of 2.
335pub mod mod_power_of_2_sub_mul_shl;
336/// Implementations of [`ModPowerOf2Sum`](crate::num::arithmetic::traits::ModPowerOf2Sum), for
337/// adding up vectors entry by entry modulo a power of 2.
338pub mod mod_power_of_2_sum;
339/// Implementations of [`ModShl`](crate::num::arithmetic::traits::ModShl) and
340/// [`ModShlAssign`](crate::num::arithmetic::traits::ModShlAssign), for left-shifting a vector
341/// (multiplying it by a power of 2) modulo a number.
342///
343/// # mod_shl
344/// ```
345/// use core::str::FromStr;
346/// use malachite_base::num::arithmetic::traits::ModShl;
347/// use malachite_base::unsigned_vector::UnsignedVector;
348///
349/// let v = UnsignedVector::<u8>::from_str("(5, 1, 3)").unwrap();
350/// assert_eq!(v.clone().mod_shl(1u8, 7).to_string(), "(3, 2, 6)");
351/// // The modulus need not be odd, so elements can become zero, keeping the dimension.
352/// assert_eq!(v.mod_shl(3u32, 8).to_string(), "(0, 0, 0)");
353/// assert_eq!(
354///     (&UnsignedVector::<u8>::from_str("(1, 2)").unwrap())
355///         .mod_shl(8u64, 255)
356///         .to_string(),
357///     "(1, 2)"
358/// );
359/// ```
360///
361/// # mod_shl_assign
362/// ```
363/// use core::str::FromStr;
364/// use malachite_base::num::arithmetic::traits::ModShlAssign;
365/// use malachite_base::unsigned_vector::UnsignedVector;
366///
367/// let mut v = UnsignedVector::<u8>::from_str("(5, 1, 3)").unwrap();
368/// v.mod_shl_assign(1u8, 7);
369/// assert_eq!(v.to_string(), "(3, 2, 6)");
370/// ```
371pub mod mod_shl;
372/// Implementations of [`ModSub`](crate::num::arithmetic::traits::ModSub) and
373/// [`ModSubAssign`](crate::num::arithmetic::traits::ModSubAssign), for subtracting vectors modulo a
374/// number.
375pub mod mod_sub;
376/// Implementations of [`ModSubMul`](crate::num::arithmetic::traits::ModSubMul) and
377/// [`ModSubMulAssign`](crate::num::arithmetic::traits::ModSubMulAssign), for subtracting a scalar
378/// multiple of one vector from another modulo a number.
379pub mod mod_sub_mul;
380/// Implementations of [`ModSubMulShl`](crate::num::arithmetic::traits::ModSubMulShl) and
381/// [`ModSubMulShlAssign`](crate::num::arithmetic::traits::ModSubMulShlAssign), for subtracting a
382/// scalar multiple of one vector, shifted left, from another modulo a number.
383pub mod mod_sub_mul_shl;
384/// Implementations of [`ModSum`](crate::num::arithmetic::traits::ModSum), for adding up vectors
385/// entry by entry modulo a number.
386pub mod mod_sum;
387/// Implementations of [`Div`](core::ops::Div) and [`DivAssign`](core::ops::DivAssign), for dividing
388/// a vector by a scalar.
389///
390/// # div
391/// ```
392/// use core::str::FromStr;
393/// use malachite_base::unsigned_vector::UnsignedVector;
394///
395/// assert_eq!(
396///     (UnsignedVector::<u8>::from_str("()").unwrap() / 5u8).to_string(),
397///     "()"
398/// );
399/// assert_eq!(
400///     (UnsignedVector::<u8>::from_str("(0, 7, 255)").unwrap() / 1u8).to_string(),
401///     "(0, 7, 255)"
402/// );
403/// assert_eq!(
404///     (&UnsignedVector::<u8>::from_str("(0, 7, 255)").unwrap() / 2u8).to_string(),
405///     "(0, 3, 127)"
406/// );
407/// assert_eq!(
408///     (&UnsignedVector::<u8>::from_str("(0, 7, 255)").unwrap() / 255u8).to_string(),
409///     "(0, 0, 1)"
410/// );
411/// ```
412///
413/// # div_assign
414/// ```
415/// use core::str::FromStr;
416/// use malachite_base::unsigned_vector::UnsignedVector;
417///
418/// let mut v = UnsignedVector::<u8>::from_str("(0, 7, 255)").unwrap();
419/// v /= 2u8;
420/// assert_eq!(v.to_string(), "(0, 3, 127)");
421/// ```
422pub mod scalar_div;
423/// Right-shifting a vector (dividing it by a power of 2 and taking the floor), by implementations
424/// of [`Shr`](core::ops::Shr) and [`ShrAssign`](core::ops::ShrAssign).
425///
426/// # shr
427/// ```
428/// use core::str::FromStr;
429/// use malachite_base::unsigned_vector::UnsignedVector;
430///
431/// assert_eq!(
432///     (UnsignedVector::<u8>::from_str("()").unwrap() >> 10u8).to_string(),
433///     "()"
434/// );
435/// assert_eq!(
436///     (UnsignedVector::<u8>::from_str("(1, 2, 3, 5)").unwrap() >> 0u16).to_string(),
437///     "(1, 2, 3, 5)"
438/// );
439/// assert_eq!(
440///     (UnsignedVector::<u8>::from_str("(1, 2, 3, 5)").unwrap() >> 1u32).to_string(),
441///     "(0, 1, 1, 2)"
442/// );
443/// assert_eq!(
444///     (&UnsignedVector::<u8>::from_str("(255, 128)").unwrap() >> 7u64).to_string(),
445///     "(1, 1)"
446/// );
447/// // Shifting by at least the width zeroes every element, keeping the dimension.
448/// assert_eq!(
449///     (&UnsignedVector::<u8>::from_str("(255, 128)").unwrap() >> 8u128).to_string(),
450///     "(0, 0)"
451/// );
452/// assert_eq!(
453///     (UnsignedVector::<u64>::from_str("(18446744073709551615, 1)").unwrap() >> 63usize)
454///         .to_string(),
455///     "(1, 0)"
456/// );
457/// ```
458///
459/// # shr_assign
460/// ```
461/// use core::str::FromStr;
462/// use malachite_base::unsigned_vector::UnsignedVector;
463///
464/// let mut v = UnsignedVector::<u8>::from_str("(1, 2, 3, 5)").unwrap();
465/// v >>= 1u8;
466/// assert_eq!(v.to_string(), "(0, 1, 1, 2)");
467///
468/// let mut v = UnsignedVector::<u8>::from_str("(255, 128)").unwrap();
469/// v >>= 200u32;
470/// assert_eq!(v.to_string(), "(0, 0)");
471/// ```
472pub mod shr;