Skip to main content

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}