qfall_math/integer_mod_q/mat_zq/arithmetic/
neg.rs1use super::super::MatZq;
12use crate::traits::MatrixDimensions;
13use flint3_sys::fmpz_mod_mat_neg;
14use std::ops::Neg;
15
16impl Neg for MatZq {
17 type Output = MatZq;
18
19 fn neg(mut self) -> Self::Output {
37 unsafe {
38 fmpz_mod_mat_neg(
39 &mut self.matrix,
40 &self.matrix,
41 self.modulus.get_fmpz_mod_ctx_struct(),
42 )
43 };
44 self
45 }
46}
47
48impl Neg for &MatZq {
49 type Output = MatZq;
50
51 fn neg(self) -> Self::Output {
53 let mut out = MatZq::new(self.get_num_rows(), self.get_num_columns(), self.get_mod());
54 unsafe {
55 fmpz_mod_mat_neg(
56 &mut out.matrix,
57 &self.matrix,
58 self.modulus.get_fmpz_mod_ctx_struct(),
59 )
60 };
61 out
62 }
63}
64
65#[cfg(test)]
66mod test_neg {
67 use super::MatZq;
68 use crate::integer::MatZ;
69 use std::str::FromStr;
70
71 #[test]
73 fn correct_small() {
74 let a = MatZq::from_str("[[1, -2, 0],[3, 4, -5]] mod 17").unwrap();
75 let b = MatZq::from_str("[[-1, 2, 0],[-3, -4, 5]] mod 17").unwrap();
76 let c = MatZq::new(2, 3, 17);
77
78 assert_eq!(a, -(-&a));
79 assert_eq!(a, -&b);
80 assert_eq!(b, -&a);
81 assert_eq!(a, -b.clone());
82 assert_eq!(b, -a);
83 assert_eq!(c, -&c);
84 assert_eq!(c.clone(), -c);
85 }
86
87 #[test]
89 fn correct_large() {
90 let a = MatZq::from_str(&format!("[[{}, 1],[0, 2]] mod {}", i64::MAX, u64::MAX)).unwrap();
91 let b =
92 MatZq::from_str(&format!("[[-{}, -1],[0, -2]] mod {}", i64::MAX, u64::MAX)).unwrap();
93
94 assert_eq!(a, -(-&a));
95 assert_eq!(b, -&a);
96 assert_eq!(b, -a);
97 }
98
99 #[test]
102 fn reduced() {
103 let a = MatZq::from_str("[[1, 16, 0],[3, 8, 9]] mod 17").unwrap();
104 let cmp = MatZ::from_str("[[16, 1, 0],[14, 9, 8]]").unwrap();
105
106 let neg_a = -&a;
107
108 assert_eq!(cmp, neg_a.get_representative_least_nonnegative_residue());
109 assert_eq!(cmp, (-a).get_representative_least_nonnegative_residue());
110 assert_eq!(17, neg_a.get_mod());
111 }
112}