Skip to main content

qfall_math/rational/poly_over_q/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 [`PolyOverQ`] values.
10
11use super::super::PolyOverQ;
12use flint3_sys::fmpq_poly_neg;
13use std::ops::Neg;
14
15impl Neg for PolyOverQ {
16    type Output = PolyOverQ;
17
18    /// Implements the [`Neg`] trait for [`PolyOverQ`] values.
19    /// [`Neg`] is implemented for both borrowed and owned [`PolyOverQ`].
20    ///
21    /// When called on owned [`PolyOverQ`] it will reuse the memory of `self`.
22    ///
23    /// Returns the additive inverse of `self` as a [`PolyOverQ`].
24    ///
25    /// # Examples
26    /// ```
27    /// use qfall_math::rational::PolyOverQ;
28    /// use std::str::FromStr;
29    ///
30    /// let a: PolyOverQ = PolyOverQ::from_str("3  1/2 -2 42").unwrap();
31    ///
32    /// let b: PolyOverQ = -&a;
33    /// let c: PolyOverQ = -a;
34    /// ```
35    fn neg(mut self) -> Self::Output {
36        unsafe { fmpq_poly_neg(&mut self.poly, &self.poly) };
37        self
38    }
39}
40
41impl Neg for &PolyOverQ {
42    type Output = PolyOverQ;
43
44    /// Documentation at [`PolyOverQ::neg`].
45    fn neg(self) -> Self::Output {
46        let mut out = PolyOverQ::default();
47        unsafe { fmpq_poly_neg(&mut out.poly, &self.poly) };
48        out
49    }
50}
51
52#[cfg(test)]
53mod test_neg {
54    use super::PolyOverQ;
55    use std::str::FromStr;
56
57    /// Ensure that `neg` works for small coefficients.
58    #[test]
59    fn correct_small() {
60        let a = PolyOverQ::from_str("4  1/2 -2 0 3/7").unwrap();
61        let b = PolyOverQ::from_str("4  -1/2 2 0 -3/7").unwrap();
62        let c = PolyOverQ::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 = PolyOverQ::from_str(&format!("3  {} 0 1/{}", u64::MAX, i64::MAX)).unwrap();
77        let b = PolyOverQ::from_str(&format!("3  -{} 0 -1/{}", u64::MAX, i64::MAX)).unwrap();
78
79        assert_eq!(a, -(-&a));
80        assert_eq!(b, -&a);
81        assert_eq!(b, -a);
82    }
83}