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