qfall_math/integer_mod_q/mat_zq/
properties.rs1use super::MatZq;
12use crate::{
13 integer::Z,
14 traits::{MatrixDimensions, MatrixGetEntry},
15};
16use flint3_sys::{
17 fmpz_mat_is_one, {fmpz_mod_mat_is_square, fmpz_mod_mat_is_zero},
18};
19
20impl MatZq {
21 pub fn is_identity(&self) -> bool {
43 unsafe { 1 == fmpz_mat_is_one(&self.matrix) }
44 }
45
46 pub fn is_square(&self) -> bool {
59 1 == unsafe { fmpz_mod_mat_is_square(&self.matrix, self.modulus.get_fmpz_mod_ctx_struct()) }
60 }
61
62 pub fn is_zero(&self) -> bool {
75 1 == unsafe { fmpz_mod_mat_is_zero(&self.matrix, self.modulus.get_fmpz_mod_ctx_struct()) }
76 }
77
78 pub fn is_symmetric(&self) -> bool {
90 if !self.is_square() {
91 return false;
92 }
93 for row in 0..self.get_num_rows() {
94 for column in 0..row {
95 if unsafe {
96 MatrixGetEntry::<Z>::get_entry_unchecked(self, row, column)
97 != MatrixGetEntry::<Z>::get_entry_unchecked(self, column, row)
98 } {
99 return false;
100 }
101 }
102 }
103 true
104 }
105}
106
107#[cfg(test)]
108mod test_is_identity {
109 use super::MatZq;
110 use std::str::FromStr;
111
112 #[test]
114 fn identity_detection() {
115 let ident_1 = MatZq::from_str("[[1, 0],[0, 1]] mod 7").unwrap();
116 let ident_2 = MatZq::from_str("[[1, 0],[0, 1],[0, 0]] mod 7").unwrap();
117
118 assert!(ident_1.is_identity());
119 assert!(ident_2.is_identity());
120 }
121
122 #[test]
124 fn identity_rejection() {
125 let small = MatZq::from_str("[[0, 0],[2, 0]] mod 17").unwrap();
126 let large = MatZq::from_str(&format!(
127 "[[1, 0],[0, {}]] mod {}",
128 (u128::MAX - 1) / 2 + 2,
129 u128::MAX
130 ))
131 .unwrap(); assert!(!small.is_identity());
134 assert!(!large.is_identity());
135 }
136}
137
138#[cfg(test)]
139mod test_is_zero {
140 use super::MatZq;
141 use std::str::FromStr;
142
143 #[test]
145 fn zero_detection() {
146 let zero_1 = MatZq::from_str("[[0, 0],[0, 0]] mod 7").unwrap();
147 let zero_2 = MatZq::from_str("[[0, 0],[0, 0],[0, 0],[0, 0]] mod 7").unwrap();
148
149 assert!(zero_1.is_zero());
150 assert!(zero_2.is_zero());
151 }
152
153 #[test]
155 fn zero_rejection() {
156 let small = MatZq::from_str("[[0, 0],[2, 0]] mod 7").unwrap();
157 let large = MatZq::from_str(&format!(
158 "[[0, 0],[{}, 0]] mod {}",
159 (u128::MAX - 1) / 2 + 1,
160 u128::MAX
161 ))
162 .unwrap();
163
164 assert!(!small.is_zero());
165 assert!(!large.is_zero());
166 }
167}
168
169#[cfg(test)]
170mod test_is_square {
171 use super::MatZq;
172 use std::str::FromStr;
173
174 #[test]
176 fn square_detection() {
177 let square_1 = MatZq::from_str("[[0, 4],[0, 0]] mod 10").unwrap();
178 let square_2 = MatZq::from_str("[[0, 6, 4],[0, 0, 1],[4, 6, 1]] mod 7").unwrap();
179
180 assert!(square_1.is_square());
181 assert!(square_2.is_square());
182 }
183
184 #[test]
186 fn sqaure_rejection() {
187 let small = MatZq::from_str("[[0, 0, 4],[2, 0, 1]] mod 7").unwrap();
188 let large = MatZq::from_str(&format!(
189 "[[9, 0],[{}, 0],[1, 4]] mod {}",
190 (u128::MAX - 1) / 2 + 1,
191 u128::MAX
192 ))
193 .unwrap();
194
195 assert!(!small.is_square());
196 assert!(!large.is_square());
197 }
198}
199
200#[cfg(test)]
201mod test_is_symmetric {
202 use super::MatZq;
203 use std::str::FromStr;
204
205 #[test]
207 fn symmetric_rejection() {
208 let mat_2x3 = MatZq::from_str("[[0, 5, 4],[2, 0, 1]] mod 17").unwrap();
209 let mat_2x2 = MatZq::from_str("[[9, 0],[127, 0]] mod 17").unwrap();
210
211 assert!(!mat_2x3.is_symmetric());
212 assert!(!mat_2x2.is_symmetric());
213 }
214
215 #[test]
217 fn symmetric_detection() {
218 let mat_2x2 = MatZq::from_str(&format!(
219 "[[2, {}],[{}, {}]] mod {}",
220 i64::MAX,
221 i64::MAX,
222 u64::MIN,
223 u64::MAX
224 ))
225 .unwrap();
226
227 assert!(mat_2x2.is_symmetric());
228 }
229}