malachite_nz/integer_vector/arithmetic/div_exact.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::integer::Integer;
10use crate::integer_vector::IntegerVector;
11use crate::natural::Natural;
12use malachite_base::num::arithmetic::traits::{DivExact, DivExactAssign, NegAssign};
13use malachite_base::num::basic::traits::{One, Zero};
14
15impl DivExact<Integer> for IntegerVector {
16 type Output = Self;
17
18 /// Divides every element of an [`IntegerVector`] by an [`Integer`], taking the vector by value
19 /// and the Integer by value. Every element must be exactly divisible by the [`Integer`].
20 ///
21 /// If some element is not exactly divisible by `c`, this function may panic or return a
22 /// meaningless result. Dividing by 1 returns the vector unchanged, and dividing by $-1$ negates
23 /// it.
24 ///
25 /// $f(v, c) = v/c$.
26 ///
27 /// # Worst-case complexity
28 /// $T(n) = O(n \log n \log\log n)$
29 ///
30 /// $M(n) = O(n \log n)$
31 ///
32 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
33 /// elements and of `c`.
34 ///
35 /// # Panics
36 /// Panics if `c` is zero.
37 ///
38 /// # Examples
39 /// See [here](super::div_exact#div_exact).
40 ///
41 /// This is equivalent to `_fmpz_vec_scalar_divexact_fmpz` from `fmpz_vec/scalar_divexact.c`,
42 /// FLINT 3.6.0.
43 #[inline]
44 fn div_exact(mut self, c: Integer) -> Self {
45 self.div_exact_assign(&c);
46 self
47 }
48}
49
50impl DivExact<&Integer> for IntegerVector {
51 type Output = Self;
52
53 /// Divides every element of an [`IntegerVector`] by an [`Integer`], taking the vector by value
54 /// and the Integer by reference. Every element must be exactly divisible by the [`Integer`].
55 ///
56 /// If some element is not exactly divisible by `c`, this function may panic or return a
57 /// meaningless result. Dividing by 1 returns the vector unchanged, and dividing by $-1$ negates
58 /// it.
59 ///
60 /// $f(v, c) = v/c$.
61 ///
62 /// # Worst-case complexity
63 /// $T(n) = O(n \log n \log\log n)$
64 ///
65 /// $M(n) = O(n \log n)$
66 ///
67 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
68 /// elements and of `c`.
69 ///
70 /// # Panics
71 /// Panics if `c` is zero.
72 ///
73 /// # Examples
74 /// See [here](super::div_exact#div_exact).
75 ///
76 /// This is equivalent to `_fmpz_vec_scalar_divexact_fmpz` from `fmpz_vec/scalar_divexact.c`,
77 /// FLINT 3.6.0.
78 #[inline]
79 fn div_exact(mut self, c: &Integer) -> Self {
80 self.div_exact_assign(c);
81 self
82 }
83}
84
85impl DivExact<Integer> for &IntegerVector {
86 type Output = IntegerVector;
87
88 /// Divides every element of an [`IntegerVector`] by an [`Integer`], taking the vector by
89 /// reference and the Integer by value. Every element must be exactly divisible by the
90 /// [`Integer`].
91 ///
92 /// If some element is not exactly divisible by `c`, this function may panic or return a
93 /// meaningless result. Dividing by 1 returns the vector unchanged, and dividing by $-1$ negates
94 /// it.
95 ///
96 /// $f(v, c) = v/c$.
97 ///
98 /// # Worst-case complexity
99 /// $T(n) = O(n \log n \log\log n)$
100 ///
101 /// $M(n) = O(n \log n)$
102 ///
103 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
104 /// elements and of `c`.
105 ///
106 /// # Panics
107 /// Panics if `c` is zero.
108 ///
109 /// # Examples
110 /// See [here](super::div_exact#div_exact).
111 ///
112 /// This is equivalent to `_fmpz_vec_scalar_divexact_fmpz` from `fmpz_vec/scalar_divexact.c`,
113 /// FLINT 3.6.0.
114 #[inline]
115 fn div_exact(self, c: Integer) -> IntegerVector {
116 self.div_exact(&c)
117 }
118}
119
120impl DivExact<&Integer> for &IntegerVector {
121 type Output = IntegerVector;
122
123 /// Divides every element of an [`IntegerVector`] by an [`Integer`], taking the vector by
124 /// reference and the Integer by reference. Every element must be exactly divisible by the
125 /// [`Integer`].
126 ///
127 /// If some element is not exactly divisible by `c`, this function may panic or return a
128 /// meaningless result. Dividing by 1 returns the vector unchanged, and dividing by $-1$ negates
129 /// it.
130 ///
131 /// $f(v, c) = v/c$.
132 ///
133 /// # Worst-case complexity
134 /// $T(n) = O(n \log n \log\log n)$
135 ///
136 /// $M(n) = O(n \log n)$
137 ///
138 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
139 /// elements and of `c`.
140 ///
141 /// # Panics
142 /// Panics if `c` is zero.
143 ///
144 /// # Examples
145 /// See [here](super::div_exact#div_exact).
146 ///
147 /// This is equivalent to `_fmpz_vec_scalar_divexact_fmpz` from `fmpz_vec/scalar_divexact.c`,
148 /// FLINT 3.6.0.
149 fn div_exact(self, c: &Integer) -> IntegerVector {
150 IntegerVector {
151 elements: match *c {
152 integer_zero!() => panic!("division by zero"),
153 integer_one!() => self.elements.clone(),
154 integer_negative_one!() => self.elements.iter().map(|x| -x).collect(),
155 _ => self.elements.iter().map(|x| x.div_exact(c)).collect(),
156 },
157 }
158 }
159}
160
161impl DivExactAssign<Integer> for IntegerVector {
162 /// Divides every element of an [`IntegerVector`] by an [`Integer`], in place, taking the
163 /// Integer by value. Every element must be exactly divisible by the [`Integer`].
164 ///
165 /// If some element is not exactly divisible by `c`, this function may panic or return a
166 /// meaningless result. Dividing by 1 returns the vector unchanged, and dividing by $-1$ negates
167 /// it.
168 ///
169 /// $v \gets v/c$.
170 ///
171 /// # Worst-case complexity
172 /// $T(n) = O(n \log n \log\log n)$
173 ///
174 /// $M(n) = O(n \log n)$
175 ///
176 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
177 /// elements and of `c`.
178 ///
179 /// # Panics
180 /// Panics if `c` is zero.
181 ///
182 /// # Examples
183 /// See [here](super::div_exact#div_exact_assign).
184 ///
185 /// This is equivalent to `_fmpz_vec_scalar_divexact_fmpz` from `fmpz_vec/scalar_divexact.c`,
186 /// FLINT 3.6.0.
187 #[inline]
188 fn div_exact_assign(&mut self, c: Integer) {
189 self.div_exact_assign(&c);
190 }
191}
192
193impl DivExactAssign<&Integer> for IntegerVector {
194 /// Divides every element of an [`IntegerVector`] by an [`Integer`], in place, taking the
195 /// Integer by reference. Every element must be exactly divisible by the [`Integer`].
196 ///
197 /// If some element is not exactly divisible by `c`, this function may panic or return a
198 /// meaningless result. Dividing by 1 returns the vector unchanged, and dividing by $-1$ negates
199 /// it.
200 ///
201 /// $v \gets v/c$.
202 ///
203 /// # Worst-case complexity
204 /// $T(n) = O(n \log n \log\log n)$
205 ///
206 /// $M(n) = O(n \log n)$
207 ///
208 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
209 /// elements and of `c`.
210 ///
211 /// # Panics
212 /// Panics if `c` is zero.
213 ///
214 /// # Examples
215 /// See [here](super::div_exact#div_exact_assign).
216 ///
217 /// This is equivalent to `_fmpz_vec_scalar_divexact_fmpz` from `fmpz_vec/scalar_divexact.c`,
218 /// FLINT 3.6.0.
219 fn div_exact_assign(&mut self, c: &Integer) {
220 match *c {
221 integer_zero!() => panic!("division by zero"),
222 integer_one!() => {}
223 integer_negative_one!() => {
224 for x in &mut self.elements {
225 x.neg_assign();
226 }
227 }
228 _ => {
229 for x in &mut self.elements {
230 x.div_exact_assign(c);
231 }
232 }
233 }
234 }
235}