qfall_math/integer/poly_over_z/arithmetic/neg.rs
1// Copyright 2026 Jan Niklas Siemer
2//
3// This file is part of qFALL-math
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! Implementation of the [`Neg`] trait for [`PolyOverZ`] values.
10
11use super::super::PolyOverZ;
12use flint3_sys::fmpz_poly_neg;
13use std::ops::Neg;
14
15impl Neg for PolyOverZ {
16 type Output = PolyOverZ;
17
18 /// Implements the [`Neg`] trait for [`PolyOverZ`] values.
19 /// [`Neg`] is implemented for both borrowed and owned [`PolyOverZ`].
20 ///
21 /// When called on owned [`PolyOverZ`] it will reuse the memory of `self`.
22 ///
23 /// Returns the additive inverse of `self` as a [`PolyOverZ`].
24 ///
25 /// # Examples
26 /// ```
27 /// use qfall_math::integer::PolyOverZ;
28 /// use std::str::FromStr;
29 ///
30 /// let a: PolyOverZ = PolyOverZ::from_str("3 1 -2 42").unwrap();
31 ///
32 /// let b: PolyOverZ = -&a;
33 /// let c: PolyOverZ = -a;
34 /// ```
35 fn neg(mut self) -> Self::Output {
36 unsafe { fmpz_poly_neg(&mut self.poly, &self.poly) };
37 self
38 }
39}
40
41impl Neg for &PolyOverZ {
42 type Output = PolyOverZ;
43
44 /// Documentation at [`PolyOverZ::neg`].
45 fn neg(self) -> Self::Output {
46 let mut out = PolyOverZ::default();
47 unsafe { fmpz_poly_neg(&mut out.poly, &self.poly) };
48 out
49 }
50}
51
52#[cfg(test)]
53mod test_neg {
54 use super::PolyOverZ;
55 use std::str::FromStr;
56
57 /// Ensure that `neg` works for small coefficients.
58 #[test]
59 fn correct_small() {
60 let a = PolyOverZ::from_str("4 1 -2 0 3").unwrap();
61 let b = PolyOverZ::from_str("4 -1 2 0 -3").unwrap();
62 let c = PolyOverZ::default();
63
64 assert_eq!(a, -(-&a));
65 assert_eq!(a, -&b);
66 assert_eq!(b, -&a);
67 assert_eq!(a, -b.clone());
68 assert_eq!(b, -a);
69 assert_eq!(c, -&c);
70 assert_eq!(c.clone(), -c);
71 }
72
73 /// Ensure that `neg` works for large coefficients.
74 #[test]
75 fn correct_large() {
76 let a = PolyOverZ::from_str(&format!("3 {} 0 {}", u64::MAX, i64::MIN)).unwrap();
77 let b =
78 PolyOverZ::from_str(&format!("3 -{} 0 {}", u64::MAX, i64::MAX as u64 + 1)).unwrap();
79
80 assert_eq!(a, -(-&a));
81 assert_eq!(b, -&a);
82 assert_eq!(b, -a);
83 }
84}