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;