1use super::super::Zq;
12use crate::{
13 error::MathError,
14 integer::Z,
15 macros::arithmetics::{
16 arithmetic_assign_between_types, arithmetic_assign_trait_borrowed_to_owned,
17 arithmetic_between_types_zq, arithmetic_trait_borrowed_to_owned,
18 arithmetic_trait_mixed_borrowed_owned,
19 },
20 traits::CompareBase,
21};
22use flint3_sys::{
23 fmpz, {fmpz_mod_sub, fmpz_mod_sub_fmpz, fmpz_mod_sub_si, fmpz_mod_sub_ui},
24};
25use std::ops::{Sub, SubAssign};
26
27impl SubAssign<&Zq> for Zq {
28 fn sub_assign(&mut self, other: &Self) {
55 if !self.compare_base(other) {
56 panic!("{}", self.call_compare_base_error(other).unwrap());
57 }
58
59 unsafe {
60 fmpz_mod_sub(
61 &mut self.value.value,
62 &self.value.value,
63 &other.value.value,
64 self.modulus.get_fmpz_mod_ctx_struct(),
65 )
66 };
67 }
68}
69impl SubAssign<i64> for Zq {
70 fn sub_assign(&mut self, other: i64) {
72 unsafe {
73 fmpz_mod_sub_si(
74 &mut self.value.value,
75 &self.value.value,
76 other,
77 self.modulus.get_fmpz_mod_ctx_struct(),
78 )
79 };
80 }
81}
82impl SubAssign<u64> for Zq {
83 fn sub_assign(&mut self, other: u64) {
85 unsafe {
86 fmpz_mod_sub_ui(
87 &mut self.value.value,
88 &self.value.value,
89 other,
90 self.modulus.get_fmpz_mod_ctx_struct(),
91 )
92 };
93 }
94}
95impl SubAssign<&Z> for Zq {
96 fn sub_assign(&mut self, other: &Z) {
98 unsafe {
99 fmpz_mod_sub_fmpz(
100 &mut self.value.value,
101 &self.value.value,
102 &other.value,
103 self.modulus.get_fmpz_mod_ctx_struct(),
104 )
105 };
106 }
107}
108
109arithmetic_assign_trait_borrowed_to_owned!(SubAssign, sub_assign, Zq, Zq);
110arithmetic_assign_trait_borrowed_to_owned!(SubAssign, sub_assign, Zq, Z);
111arithmetic_assign_between_types!(SubAssign, sub_assign, Zq, i64, i32 i16 i8);
112arithmetic_assign_between_types!(SubAssign, sub_assign, Zq, u64, u32 u16 u8);
113
114impl Sub for &Zq {
115 type Output = Zq;
116 fn sub(self, other: Self) -> Self::Output {
140 self.sub_safe(other).unwrap()
141 }
142}
143
144impl Zq {
145 pub fn sub_safe(&self, other: &Self) -> Result<Zq, MathError> {
167 if !self.compare_base(other) {
168 return Err(self.call_compare_base_error(other).unwrap());
169 }
170 let mut out_z = Z::ZERO;
171 unsafe {
172 fmpz_mod_sub(
173 &mut out_z.value,
174 &self.value.value,
175 &other.value.value,
176 self.modulus.get_fmpz_mod_ctx_struct(),
177 );
178 }
179
180 Ok(Self {
181 value: out_z,
182 modulus: self.modulus.clone(),
183 })
184 }
185}
186
187arithmetic_trait_borrowed_to_owned!(Sub, sub, Zq, Zq, Zq);
188arithmetic_trait_mixed_borrowed_owned!(Sub, sub, Zq, Zq, Zq);
189arithmetic_between_types_zq!(Sub, sub, Zq, i64 i32 i16 i8 u64 u32 u16 u8);
190
191impl Sub<&Z> for &Zq {
192 type Output = Zq;
193
194 fn sub(self, other: &Z) -> Self::Output {
217 let mut out: fmpz = 0;
218 unsafe {
219 fmpz_mod_sub_fmpz(
220 &mut out,
221 &self.value.value,
222 &other.value,
223 self.modulus.get_fmpz_mod_ctx_struct(),
224 );
225 }
226 Zq {
227 modulus: self.modulus.clone(),
228 value: Z { value: out },
229 }
230 }
231}
232
233arithmetic_trait_borrowed_to_owned!(Sub, sub, Zq, Z, Zq);
234arithmetic_trait_mixed_borrowed_owned!(Sub, sub, Zq, Z, Zq);
235
236#[cfg(test)]
237mod test_sub_assign {
238 use crate::{integer::Z, integer_mod_q::Zq};
239
240 #[test]
242 fn correct_small() {
243 let mut a: Zq = Zq::from((-1, 7));
244 let b = Zq::from((1, 7));
245 let c = Zq::from((-1, 7));
246
247 a -= &b;
248 assert_eq!(Zq::from((5, 7)), a);
249 a -= &c;
250 assert_eq!(Zq::from((6, 7)), a);
251 a -= &c;
252 assert_eq!(Zq::from((0, 7)), a);
253 a -= &c;
254 assert_eq!(Zq::from((1, 7)), a);
255 a -= &c;
256 assert_eq!(Zq::from((2, 7)), a);
257 a -= 2 * b;
258 assert_eq!(Zq::from((0, 7)), a);
259 }
260
261 #[test]
263 fn correct_large() {
264 let mut a = Zq::from((i64::MAX, u64::MAX));
265 let b = Zq::from((i64::MAX - 1, u64::MAX));
266
267 a -= b;
268 assert_eq!(Zq::from((1, u64::MAX)), a);
269 }
270
271 #[test]
273 fn availability() {
274 let mut a = Zq::from((3, 7));
275 let b = Zq::from((1, 7));
276 let c = Z::from(1);
277
278 a -= &b;
279 a -= b;
280 a -= &c;
281 a -= c;
282 a -= 1_u8;
283 a -= 1_u16;
284 a -= 1_u32;
285 a -= 1_u64;
286 a -= 1_i8;
287 a -= 1_i16;
288 a -= 1_i32;
289 a -= 1_i64;
290 }
291
292 #[test]
294 #[should_panic]
295 fn mismatching_moduli() {
296 let mut a = Zq::from((3, 7));
297 let b = Zq::from((1, 8));
298
299 a -= b;
300 }
301}
302
303#[cfg(test)]
304mod test_sub {
305 use super::Zq;
306
307 #[test]
309 fn sub() {
310 let a: Zq = Zq::from((11, 17));
311 let b: Zq = Zq::from((12, 17));
312 let c: Zq = a - b;
313 assert_eq!(c, Zq::from((16, 17)));
314 }
315
316 #[test]
318 fn sub_borrow() {
319 let a: Zq = Zq::from((10, 11));
320 let b: Zq = Zq::from((1, 11));
321 let c: Zq = &a - &b;
322 assert_eq!(c, Zq::from((9, 11)));
323 }
324
325 #[test]
327 fn sub_first_borrowed() {
328 let a: Zq = Zq::from((2, 11));
329 let b: Zq = Zq::from((5, 11));
330 let c: Zq = &a - b;
331 assert_eq!(c, Zq::from((-3, 11)));
332 }
333
334 #[test]
336 fn sub_second_borrowed() {
337 let a: Zq = Zq::from((12, 11));
338 let b: Zq = Zq::from((10, 11));
339 let c: Zq = a - &b;
340 assert_eq!(c, Zq::from((2, 11)));
341 }
342
343 #[test]
345 fn sub_large_numbers() {
346 let a: Zq = Zq::from((u32::MAX, u32::MAX - 58));
347 let b: Zq = Zq::from((i32::MAX, u32::MAX - 58));
348 let c: Zq = a - b;
349 assert_eq!(c, Zq::from((u32::MAX - (u32::MAX - 1) / 2, u32::MAX - 58)));
350 }
351
352 #[test]
354 #[should_panic]
355 fn sub_mismatching_modulus() {
356 let a: Zq = Zq::from((4, 11));
357 let b: Zq = Zq::from((1, 3));
358 let _c: Zq = a - b;
359 }
360
361 #[test]
363 fn sub_safe_is_err() {
364 let a: Zq = Zq::from((4, 11));
365 let b: Zq = Zq::from((1, 3));
366 assert!(&a.sub_safe(&b).is_err());
367 }
368}
369
370#[cfg(test)]
371mod test_sub_between_z_and_zq {
372 use super::Z;
373 use crate::integer_mod_q::Zq;
374
375 #[test]
377 fn sub() {
378 let a: Zq = Zq::from((4, 11));
379 let b: Z = Z::from(9);
380 let c: Zq = a - b;
381 assert_eq!(c, Zq::from((6, 11)));
382 }
383
384 #[test]
386 fn sub_borrow() {
387 let a: Zq = Zq::from((4, 11));
388 let b: Z = Z::from(9);
389 let c: Zq = &a - &b;
390 assert_eq!(c, Zq::from((6, 11)));
391 }
392
393 #[test]
395 fn sub_first_borrowed() {
396 let a: Zq = Zq::from((4, 11));
397 let b: Z = Z::from(9);
398 let c: Zq = &a - b;
399 assert_eq!(c, Zq::from((6, 11)));
400 }
401
402 #[test]
404 fn sub_second_borrowed() {
405 let a: Zq = Zq::from((4, 11));
406 let b: Z = Z::from(9);
407 let c: Zq = a - &b;
408 assert_eq!(c, Zq::from((6, 11)));
409 }
410
411 #[test]
413 fn sub_large_numbers() {
414 let a: Zq = Zq::from((i64::MAX, u64::MAX - 58));
415 let b: Zq = Zq::from((i64::MAX - 1, i64::MAX));
416 let c: Z = Z::from(u64::MAX);
417
418 let d: Zq = a - &c;
419 let e: Zq = b - c;
420
421 assert_eq!(d, Zq::from(((u64::MAX - 1) / 2 - 58, u64::MAX - 58)));
422 assert_eq!(e, Zq::from((-2, i64::MAX)));
423 }
424}
425
426#[cfg(test)]
427mod test_sub_between_types {
428 use crate::integer_mod_q::Zq;
429
430 #[test]
432 #[allow(clippy::op_ref)]
433 fn sub() {
434 let a: Zq = Zq::from((4, 11));
435 let b: u64 = 1;
436 let c: u32 = 1;
437 let d: u16 = 1;
438 let e: u8 = 1;
439 let f: i64 = 1;
440 let g: i32 = 1;
441 let h: i16 = 1;
442 let i: i8 = 1;
443
444 let _: Zq = &a - &b;
445 let _: Zq = &a - &c;
446 let _: Zq = &a - &d;
447 let _: Zq = &a - &e;
448 let _: Zq = &a - &f;
449 let _: Zq = &a - &g;
450 let _: Zq = &a - &h;
451 let _: Zq = &a - &i;
452
453 let _: Zq = &b - &a;
454 let _: Zq = &c - &a;
455 let _: Zq = &d - &a;
456 let _: Zq = &e - &a;
457 let _: Zq = &f - &a;
458 let _: Zq = &g - &a;
459 let _: Zq = &h - &a;
460 let _: Zq = &i - &a;
461
462 let _: Zq = &a - b;
463 let _: Zq = &a - c;
464 let _: Zq = &a - d;
465 let _: Zq = &a - e;
466 let _: Zq = &a - f;
467 let _: Zq = &a - g;
468 let _: Zq = &a - h;
469 let _: Zq = &a - i;
470
471 let _: Zq = &b - Zq::from((4, 11));
472 let _: Zq = &c - Zq::from((4, 11));
473 let _: Zq = &d - Zq::from((4, 11));
474 let _: Zq = &e - Zq::from((4, 11));
475 let _: Zq = &f - Zq::from((4, 11));
476 let _: Zq = &g - Zq::from((4, 11));
477 let _: Zq = &h - Zq::from((4, 11));
478 let _: Zq = &i - Zq::from((4, 11));
479
480 let _: Zq = Zq::from((4, 11)) - &b;
481 let _: Zq = Zq::from((4, 11)) - &c;
482 let _: Zq = Zq::from((4, 11)) - &d;
483 let _: Zq = Zq::from((4, 11)) - &e;
484 let _: Zq = Zq::from((4, 11)) - &f;
485 let _: Zq = Zq::from((4, 11)) - &g;
486 let _: Zq = Zq::from((4, 11)) - &h;
487 let _: Zq = Zq::from((4, 11)) - &i;
488
489 let _: Zq = b - &a;
490 let _: Zq = c - &a;
491 let _: Zq = d - &a;
492 let _: Zq = e - &a;
493 let _: Zq = f - &a;
494 let _: Zq = g - &a;
495 let _: Zq = h - &a;
496 let _: Zq = i - &a;
497
498 let _: Zq = Zq::from((4, 11)) - b;
499 let _: Zq = Zq::from((4, 11)) - c;
500 let _: Zq = Zq::from((4, 11)) - d;
501 let _: Zq = Zq::from((4, 11)) - e;
502 let _: Zq = Zq::from((4, 11)) - f;
503 let _: Zq = Zq::from((4, 11)) - g;
504 let _: Zq = Zq::from((4, 11)) - h;
505 let _: Zq = Zq::from((4, 11)) - i;
506
507 let _: Zq = b - Zq::from((4, 11));
508 let _: Zq = c - Zq::from((4, 11));
509 let _: Zq = d - Zq::from((4, 11));
510 let _: Zq = e - Zq::from((4, 11));
511 let _: Zq = f - Zq::from((4, 11));
512 let _: Zq = g - Zq::from((4, 11));
513 let _: Zq = h - Zq::from((4, 11));
514 let _: Zq = i - Zq::from((4, 11));
515 }
516}