use super::super::PolynomialRingZq;
use flint3_sys::fmpz_poly_neg;
use std::ops::Neg;
impl Neg for PolynomialRingZq {
type Output = PolynomialRingZq;
fn neg(mut self) -> Self::Output {
unsafe { fmpz_poly_neg(&mut self.poly.poly, &self.poly.poly) };
self.reduce();
self
}
}
impl Neg for &PolynomialRingZq {
type Output = PolynomialRingZq;
fn neg(self) -> Self::Output {
let mut out = PolynomialRingZq {
poly: -&self.poly,
modulus: self.modulus.clone(),
};
out.reduce();
out
}
}
#[cfg(test)]
mod test_neg {
use super::PolynomialRingZq;
use crate::integer::PolyOverZ;
use crate::integer_mod_q::ModulusPolynomialRingZq;
use std::str::FromStr;
#[test]
fn correct_small() {
let modulus = ModulusPolynomialRingZq::from_str("4 1 0 0 1 mod 17").unwrap();
let a = PolynomialRingZq::from((&PolyOverZ::from_str("3 1 -2 3").unwrap(), &modulus));
let b = PolynomialRingZq::from((&PolyOverZ::from_str("3 -1 2 -3").unwrap(), &modulus));
let c = PolynomialRingZq::from((&PolyOverZ::default(), &modulus));
assert_eq!(a, -(-&a));
assert_eq!(a, -&b);
assert_eq!(b, -&a);
assert_eq!(a, -b.clone());
assert_eq!(b, -a);
assert_eq!(c, -&c);
assert_eq!(c.clone(), -c);
}
#[test]
fn correct_large() {
let modulus =
ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap();
let a = PolynomialRingZq::from((
&PolyOverZ::from_str(&format!("3 {} 0 1", i64::MAX)).unwrap(),
&modulus,
));
let b = PolynomialRingZq::from((
&PolyOverZ::from_str(&format!("3 -{} 0 -1", i64::MAX)).unwrap(),
&modulus,
));
assert_eq!(a, -(-&a));
assert_eq!(b, -&a);
assert_eq!(b, -a);
}
#[test]
fn reduced() {
let modulus = ModulusPolynomialRingZq::from_str("4 1 0 0 1 mod 17").unwrap();
let a = PolynomialRingZq::from((&PolyOverZ::from_str("3 1 16 8").unwrap(), &modulus));
let cmp = PolyOverZ::from_str("3 16 1 9").unwrap();
let neg_a = -&a;
assert_eq!(cmp, neg_a.get_representative_least_nonnegative_residue());
assert_eq!(cmp, (-a).get_representative_least_nonnegative_residue());
assert_eq!(modulus, neg_a.get_mod());
}
}