qfall_math/integer_mod_q/mat_polynomial_ring_zq/
default.rs1use super::MatPolynomialRingZq;
12use crate::{integer::MatPolyOverZ, integer_mod_q::ModulusPolynomialRingZq};
13use std::fmt::Display;
14
15impl MatPolynomialRingZq {
16 pub fn new(
42 num_rows: impl TryInto<i64> + Display,
43 num_cols: impl TryInto<i64> + Display,
44 modulus: impl Into<ModulusPolynomialRingZq>,
45 ) -> Self {
46 let matrix = MatPolyOverZ::new(num_rows, num_cols);
47
48 MatPolynomialRingZq {
51 matrix,
52 modulus: modulus.into(),
53 }
54 }
55
56 pub fn identity(
81 num_rows: impl TryInto<i64> + Display,
82 num_cols: impl TryInto<i64> + Display,
83 modulus: impl Into<ModulusPolynomialRingZq>,
84 ) -> Self {
85 let matrix = MatPolyOverZ::identity(num_rows, num_cols);
86 MatPolynomialRingZq::from((matrix, modulus))
87 }
88}
89
90#[cfg(test)]
91mod test_new {
92 use crate::{
93 integer::PolyOverZ,
94 integer_mod_q::{MatPolynomialRingZq, ModulusPolynomialRingZq, PolyOverZq},
95 traits::MatrixGetEntry,
96 };
97 use std::str::FromStr;
98
99 const LARGE_PRIME: u64 = u64::MAX - 58;
100
101 #[test]
103 fn initialization() {
104 let poly_mod = PolyOverZq::from_str("3 1 0 1 mod 17").unwrap();
105 let modulus = ModulusPolynomialRingZq::from(&poly_mod);
106
107 let _ = MatPolynomialRingZq::new(2, 2, &modulus);
108 }
109
110 #[test]
112 fn entry_zero() {
113 let poly_mod = PolyOverZq::from_str("3 1 0 1 mod 17").unwrap();
114 let modulus = ModulusPolynomialRingZq::from(&poly_mod);
115
116 let matrix = MatPolynomialRingZq::new(2, 2, &modulus);
117
118 let entry_1: PolyOverZ = matrix.get_entry(0, 0).unwrap();
119 let entry_2: PolyOverZ = matrix.get_entry(0, 1).unwrap();
120 let entry_3: PolyOverZ = matrix.get_entry(1, 0).unwrap();
121 let entry_4: PolyOverZ = matrix.get_entry(1, 1).unwrap();
122
123 assert_eq!(PolyOverZ::default(), entry_1);
124 assert_eq!(PolyOverZ::default(), entry_2);
125 assert_eq!(PolyOverZ::default(), entry_3);
126 assert_eq!(PolyOverZ::default(), entry_4);
127 }
128
129 #[should_panic]
131 #[test]
132 fn error_zero_num_cols() {
133 let poly_mod = PolyOverZq::from_str("3 1 0 1 mod 17").unwrap();
134 let modulus = ModulusPolynomialRingZq::from(&poly_mod);
135
136 let _ = MatPolynomialRingZq::new(1, 0, &modulus);
137 }
138
139 #[should_panic]
141 #[test]
142 fn error_zero_num_rows() {
143 let poly_mod = PolyOverZq::from_str("3 1 0 1 mod 17").unwrap();
144 let modulus = ModulusPolynomialRingZq::from(&poly_mod);
145
146 let _ = MatPolynomialRingZq::new(0, 1, &modulus);
147 }
148
149 #[test]
151 fn large_modulus() {
152 let poly_mod =
153 PolyOverZq::from_str(&format!("3 1 {} 1 mod {LARGE_PRIME}", i64::MAX)).unwrap();
154 let modulus = ModulusPolynomialRingZq::from(&poly_mod);
155
156 let _ = MatPolynomialRingZq::new(2, 2, &modulus);
157 }
158}
159
160#[cfg(test)]
161mod test_identity {
162 use crate::{
163 integer::PolyOverZ,
164 integer_mod_q::{MatPolynomialRingZq, ModulusPolynomialRingZq},
165 traits::{MatrixDimensions, MatrixGetEntry},
166 };
167 use std::str::FromStr;
168
169 #[test]
171 fn identity() {
172 let modulus = ModulusPolynomialRingZq::from_str("3 1 0 1 mod 17").unwrap();
173 let matrix = MatPolynomialRingZq::identity(10, 10, &modulus);
174
175 for i in 0..matrix.get_num_rows() {
176 for j in 0..matrix.get_num_columns() {
177 let entry: PolyOverZ = matrix.get_entry(i, j).unwrap();
178 if i != j {
179 assert!(entry.is_zero());
180 } else {
181 assert!(entry.is_one());
182 }
183 }
184 }
185 }
186
187 #[test]
189 fn non_square_works() {
190 let modulus = ModulusPolynomialRingZq::from_str("3 1 0 1 mod 17").unwrap();
191 let matrix = MatPolynomialRingZq::identity(10, 7, &modulus);
192
193 for i in 0..10 {
194 for j in 0..7 {
195 let entry: PolyOverZ = matrix.get_entry(i, j).unwrap();
196 if i != j {
197 assert!(entry.is_zero());
198 } else {
199 assert!(entry.is_one());
200 }
201 }
202 }
203
204 let matrix = MatPolynomialRingZq::identity(7, 10, &modulus);
205
206 for i in 0..7 {
207 for j in 0..10 {
208 let entry: PolyOverZ = matrix.get_entry(i, j).unwrap();
209 if i != j {
210 assert!(entry.is_zero());
211 } else {
212 assert!(entry.is_one());
213 }
214 }
215 }
216 }
217
218 #[test]
220 fn modulus_large() {
221 let modulus =
222 ModulusPolynomialRingZq::from_str(&format!("4 1 0 {} 1 mod {}", i64::MAX, u64::MAX))
223 .unwrap();
224 let matrix = MatPolynomialRingZq::identity(10, 10, &modulus);
225
226 for i in 0..10 {
227 for j in 0..10 {
228 let entry: PolyOverZ = matrix.get_entry(i, j).unwrap();
229 if i != j {
230 assert!(entry.is_zero());
231 } else {
232 assert!(entry.is_one());
233 }
234 }
235 }
236 }
237
238 #[should_panic]
240 #[test]
241 fn no_rows() {
242 let modulus = ModulusPolynomialRingZq::from_str("3 1 0 1 mod 17").unwrap();
243 let _ = MatPolynomialRingZq::identity(0, 7, &modulus);
244 }
245
246 #[should_panic]
248 #[test]
249 fn no_columns() {
250 let modulus = ModulusPolynomialRingZq::from_str("3 1 0 1 mod 17").unwrap();
251 let _ = MatPolynomialRingZq::identity(7, 0, &modulus);
252 }
253}