qfall_math/rational/poly_over_q/arithmetic/
div_scalar.rs1use super::super::PolyOverQ;
12use crate::integer::Z;
13use crate::macros::arithmetics::{
14 arithmetic_assign_between_types, arithmetic_assign_trait_borrowed_to_owned,
15 arithmetic_trait_borrowed_to_owned, arithmetic_trait_mixed_borrowed_owned,
16};
17use crate::macros::for_others::implement_for_others;
18use crate::rational::Q;
19use flint_sys::fmpq_poly::{
20 fmpq_poly_scalar_div_fmpq, fmpq_poly_scalar_div_fmpz, fmpq_poly_scalar_div_si,
21 fmpq_poly_scalar_div_ui,
22};
23use std::ops::{Div, DivAssign};
24
25impl Div<&Z> for &PolyOverQ {
26 type Output = PolyOverQ;
27 fn div(self, scalar: &Z) -> Self::Output {
53 assert!(!scalar.is_zero(), "Tried to divide {self} by zero.");
54
55 let mut out = PolyOverQ::default();
56 unsafe {
57 fmpq_poly_scalar_div_fmpz(&mut out.poly, &self.poly, &scalar.value);
58 }
59 out
60 }
61}
62
63arithmetic_trait_borrowed_to_owned!(Div, div, PolyOverQ, Z, PolyOverQ);
64arithmetic_trait_mixed_borrowed_owned!(Div, div, PolyOverQ, Z, PolyOverQ);
65
66implement_for_others!(Z, PolyOverQ, PolyOverQ, Div Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
67
68impl Div<&Q> for &PolyOverQ {
69 type Output = PolyOverQ;
70 fn div(self, scalar: &Q) -> Self::Output {
95 assert!(!scalar.is_zero(), "Tried to divide {self} by zero.");
96
97 let mut out = PolyOverQ::default();
98 unsafe {
99 fmpq_poly_scalar_div_fmpq(&mut out.poly, &self.poly, &scalar.value);
100 }
101 out
102 }
103}
104
105arithmetic_trait_borrowed_to_owned!(Div, div, PolyOverQ, Q, PolyOverQ);
106arithmetic_trait_mixed_borrowed_owned!(Div, div, PolyOverQ, Q, PolyOverQ);
107
108implement_for_others!(Q, PolyOverQ, PolyOverQ, Div Scalar for f32 f64);
109
110impl DivAssign<&Q> for PolyOverQ {
111 fn div_assign(&mut self, scalar: &Q) {
135 assert!(!scalar.is_zero(), "Tried to divide {self} by zero.");
136
137 unsafe { fmpq_poly_scalar_div_fmpq(&mut self.poly, &self.poly, &scalar.value) }
138 }
139}
140
141impl DivAssign<&Z> for PolyOverQ {
142 fn div_assign(&mut self, scalar: &Z) {
144 assert!(!scalar.is_zero(), "Tried to divide {self} by zero.");
145
146 unsafe { fmpq_poly_scalar_div_fmpz(&mut self.poly, &self.poly, &scalar.value) };
147 }
148}
149
150impl DivAssign<u64> for PolyOverQ {
151 fn div_assign(&mut self, scalar: u64) {
153 assert!(scalar != 0, "Tried to divide {self} by zero.");
154
155 unsafe { fmpq_poly_scalar_div_ui(&mut self.poly, &self.poly, scalar) };
156 }
157}
158
159impl DivAssign<i64> for PolyOverQ {
160 fn div_assign(&mut self, scalar: i64) {
162 assert!(scalar != 0, "Tried to divide {self} by zero.");
163
164 unsafe { fmpq_poly_scalar_div_si(&mut self.poly, &self.poly, scalar) };
165 }
166}
167
168arithmetic_assign_trait_borrowed_to_owned!(DivAssign, div_assign, PolyOverQ, Q);
169arithmetic_assign_trait_borrowed_to_owned!(DivAssign, div_assign, PolyOverQ, Z);
170arithmetic_assign_between_types!(DivAssign, div_assign, PolyOverQ, u64, u32 u16 u8);
171arithmetic_assign_between_types!(DivAssign, div_assign, PolyOverQ, i64, i32 i16 i8);
172arithmetic_assign_between_types!(DivAssign, div_assign, PolyOverQ, Q, f64 f32);
173
174#[cfg(test)]
175mod test_mul_z {
176 use super::PolyOverQ;
177 use crate::integer::Z;
178 use std::str::FromStr;
179
180 #[test]
182 fn borrowed_correctness() {
183 let poly_1 = PolyOverQ::from_str(&format!("3 1 4/5 {}", (i64::MAX as u64) * 2)).unwrap();
184 let poly_2 = PolyOverQ::from_str(&format!("3 1/2 2/5 {}", i64::MAX)).unwrap();
185 let integer = Z::from(2);
186
187 let poly_1 = &poly_1 / &integer;
188
189 assert_eq!(poly_2, poly_1);
190 }
191
192 #[test]
194 fn availability() {
195 let poly = PolyOverQ::from_str("3 1/2 2 3/8").unwrap();
196 let z = Z::from(2);
197
198 _ = poly.clone() / z.clone();
199 _ = poly.clone() / 2i8;
200 _ = poly.clone() / 2u8;
201 _ = poly.clone() / 2i16;
202 _ = poly.clone() / 2u16;
203 _ = poly.clone() / 2i32;
204 _ = poly.clone() / 2u32;
205 _ = poly.clone() / 2i64;
206 _ = poly.clone() / 2u64;
207
208 _ = &poly / &z;
209 _ = &poly / z.clone();
210 _ = poly.clone() / &z;
211 _ = &poly / 2i8;
212 }
213}
214
215#[cfg(test)]
216mod test_mul_q {
217 use crate::{
218 integer::Z,
219 rational::{PolyOverQ, Q},
220 };
221 use std::str::FromStr;
222
223 #[test]
225 fn borrowed_correctness() {
226 let poly_1 = PolyOverQ::from_str(&format!("3 1 2 {}", (i64::MAX as u64) * 2)).unwrap();
227 let poly_2 = poly_1.clone();
228 let poly_3 = PolyOverQ::from_str(&format!("3 1/2 1 {}", i64::MAX)).unwrap();
229 let rational = Q::from((1, 2));
230
231 let poly_1 = &poly_1 * &rational;
232 let poly_2 = &rational * &poly_2;
233
234 assert_eq!(poly_3, poly_1);
235 assert_eq!(poly_3, poly_2);
236 }
237
238 #[test]
240 fn availability() {
241 let poly = PolyOverQ::from_str("3 1/2 2 3/7").unwrap();
242 let q = Q::from((1, 2));
243
244 _ = poly.clone() / q.clone();
245 _ = &poly / &q;
246 _ = &poly / q.clone();
247 _ = &poly / 2.0_f32;
248 _ = &poly / 2.0_f64;
249 }
250
251 #[test]
253 #[should_panic]
254 fn div_0() {
255 let poly = PolyOverQ::from_str("3 1/2 2 3/7").unwrap();
256 let integer = Z::from(0);
257
258 let _ = &poly / &integer;
259 }
260}
261
262#[cfg(test)]
263mod test_div_assign {
264 use crate::integer::Z;
265 use crate::rational::{PolyOverQ, Q};
266 use std::str::FromStr;
267
268 #[test]
270 fn consistency() {
271 let mut a = PolyOverQ::from_str("3 1/2 2 3/7").unwrap();
272 let b = Q::from((1, i32::MAX));
273 let cmp = &a / &b;
274
275 a /= b;
276
277 assert_eq!(cmp, a);
278 }
279
280 #[test]
282 fn availability() {
283 let mut a = PolyOverQ::from_str("3 1/2 2 3/7").unwrap();
284 let b = Z::from(2);
285 let c = Q::from((2, 3));
286
287 a /= &b;
288 a /= b;
289 a /= &c;
290 a /= c;
291 a /= 1_u8;
292 a /= 1_u16;
293 a /= 1_u32;
294 a /= 1_u64;
295 a /= 1_i8;
296 a /= 1_i16;
297 a /= 1_i32;
298 a /= 1_i64;
299 a /= 1_f32;
300 a /= 1_f64;
301 }
302
303 #[test]
305 #[should_panic]
306 fn div_0() {
307 let mut a = PolyOverQ::from_str("3 1/2 2 3/7").unwrap();
308 let b = Q::from((0, i32::MAX));
309
310 a /= b;
311 }
312}