use super::super::MatZq;
use crate::traits::MatrixDimensions;
use flint3_sys::fmpz_mod_mat_neg;
use std::ops::Neg;
impl Neg for MatZq {
type Output = MatZq;
fn neg(mut self) -> Self::Output {
unsafe {
fmpz_mod_mat_neg(
&mut self.matrix,
&self.matrix,
self.modulus.get_fmpz_mod_ctx_struct(),
)
};
self
}
}
impl Neg for &MatZq {
type Output = MatZq;
fn neg(self) -> Self::Output {
let mut out = MatZq::new(self.get_num_rows(), self.get_num_columns(), self.get_mod());
unsafe {
fmpz_mod_mat_neg(
&mut out.matrix,
&self.matrix,
self.modulus.get_fmpz_mod_ctx_struct(),
)
};
out
}
}
#[cfg(test)]
mod test_neg {
use super::MatZq;
use crate::integer::MatZ;
use std::str::FromStr;
#[test]
fn correct_small() {
let a = MatZq::from_str("[[1, -2, 0],[3, 4, -5]] mod 17").unwrap();
let b = MatZq::from_str("[[-1, 2, 0],[-3, -4, 5]] mod 17").unwrap();
let c = MatZq::new(2, 3, 17);
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 a = MatZq::from_str(&format!("[[{}, 1],[0, 2]] mod {}", i64::MAX, u64::MAX)).unwrap();
let b =
MatZq::from_str(&format!("[[-{}, -1],[0, -2]] mod {}", i64::MAX, u64::MAX)).unwrap();
assert_eq!(a, -(-&a));
assert_eq!(b, -&a);
assert_eq!(b, -a);
}
#[test]
fn reduced() {
let a = MatZq::from_str("[[1, 16, 0],[3, 8, 9]] mod 17").unwrap();
let cmp = MatZ::from_str("[[16, 1, 0],[14, 9, 8]]").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!(17, neg_a.get_mod());
}
}