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