qfall_math/integer_mod_q/mat_zq/
ownership.rs1use super::MatZq;
15use crate::integer::Z;
16use crate::traits::MatrixDimensions;
17use flint_sys::fmpz_mod_mat::{fmpz_mod_mat_clear, fmpz_mod_mat_init_set};
18
19impl Clone for MatZq {
20 fn clone(&self) -> Self {
32 let mut out = MatZq::new(
33 self.get_num_rows(),
34 self.get_num_columns(),
35 Z::from(self.get_mod()),
36 );
37 unsafe {
38 fmpz_mod_mat_init_set(&mut out.matrix, &self.matrix);
39 }
40 out
41 }
42}
43
44impl Drop for MatZq {
45 fn drop(&mut self) {
67 unsafe { fmpz_mod_mat_clear(&mut self.matrix) }
68 }
69}
70
71#[cfg(test)]
73mod test_clone {
74 use super::MatZq;
75 use crate::integer::Z;
76 use crate::traits::{MatrixDimensions, MatrixGetEntry};
77 use std::str::FromStr;
78
79 #[test]
81 #[allow(clippy::redundant_clone)]
82 fn keep_alive() {
83 let a: MatZq;
84 let str_1 = "[[1, 2, 3],[3, 4, 5]] mod 6";
85 {
86 let b = MatZq::from_str(str_1).unwrap();
87
88 a = b.clone();
89 }
90
91 assert_eq!(a.get_num_rows(), 2);
92 assert_eq!(a.get_num_columns(), 3);
93
94 assert_eq!(MatrixGetEntry::<Z>::get_entry(&a, 0, 0).unwrap(), 1);
95 assert_eq!(MatrixGetEntry::<Z>::get_entry(&a, 0, 1).unwrap(), 2);
96 assert_eq!(MatrixGetEntry::<Z>::get_entry(&a, 0, 2).unwrap(), 3);
97 assert_eq!(MatrixGetEntry::<Z>::get_entry(&a, 1, 0).unwrap(), 3);
98 assert_eq!(MatrixGetEntry::<Z>::get_entry(&a, 1, 1).unwrap(), 4);
99 assert_eq!(MatrixGetEntry::<Z>::get_entry(&a, 1, 2).unwrap(), 5);
100 }
101
102 #[test]
104 fn entries_stored_separately() {
105 let a: MatZq;
106 let string = format!("[[{}, {}],[-10, 0]] mod {}", i64::MAX, i64::MIN, u64::MAX);
107 let b = MatZq::from_str(&string).unwrap();
108
109 a = b.clone();
110
111 assert_ne!(
112 MatrixGetEntry::<Z>::get_entry(&a, 0, 0).unwrap().value.0,
113 MatrixGetEntry::<Z>::get_entry(&b, 0, 0).unwrap().value.0
114 );
115 assert_ne!(
116 MatrixGetEntry::<Z>::get_entry(&a, 0, 1).unwrap().value.0,
117 MatrixGetEntry::<Z>::get_entry(&b, 0, 1).unwrap().value.0
118 );
119 assert_ne!(
120 MatrixGetEntry::<Z>::get_entry(&a, 1, 0).unwrap().value.0,
121 MatrixGetEntry::<Z>::get_entry(&b, 1, 0).unwrap().value.0
122 );
123 assert_eq!(
124 MatrixGetEntry::<Z>::get_entry(&a, 1, 1).unwrap().value.0,
125 MatrixGetEntry::<Z>::get_entry(&b, 1, 1).unwrap().value.0
126 ); }
128
129 #[test]
131 #[allow(clippy::redundant_clone)]
132 fn modulus_applied() {
133 let string = String::from("[[1, 2],[4, 5]] mod 4");
134 let b = MatZq::from_str(&string).unwrap();
135
136 let a = b.clone();
137
138 assert_eq!(MatrixGetEntry::<Z>::get_entry(&a, 1, 1).unwrap(), 1);
139 assert_eq!(MatrixGetEntry::<Z>::get_entry(&a, 1, 0).unwrap(), 0);
140 }
141
142 #[test]
144 fn modulus_storage() {
145 let string = format!("[[{}, {}],[-10, 0]] mod {}", i64::MAX, i64::MIN, u64::MAX);
146 let b = MatZq::from_str(&string).unwrap();
147
148 let a = b.clone();
149
150 assert_ne!(a.matrix.mod_[0].0, b.matrix.mod_[0].0);
151 }
152}
153
154#[cfg(test)]
156mod test_drop {
157 use super::MatZq;
158 use crate::integer::Z;
159 use crate::traits::MatrixGetEntry;
160 use std::collections::HashSet;
161 use std::str::FromStr;
162
163 fn create_and_drop_matzq() -> (i64, i64, i64) {
166 let string = format!("[[{}, {}]] mod {}", i64::MAX, i64::MIN, u64::MAX);
167 let a = MatZq::from_str(&string).unwrap();
168
169 let storage_mod = a.matrix.mod_[0].0;
170 let storage_0 = MatrixGetEntry::<Z>::get_entry(&a, 0, 0).unwrap().value.0;
171 let storage_1 = MatrixGetEntry::<Z>::get_entry(&a, 0, 1).unwrap().value.0;
172
173 (storage_mod, storage_0, storage_1)
174 }
175
176 #[test]
178 fn free_memory() {
179 let mut set = HashSet::new();
180
181 for _i in 0..5 {
182 let (a, b, c) = create_and_drop_matzq();
183 set.insert(a);
184 set.insert(b);
185 set.insert(c);
186 }
187
188 assert!(set.len() < 15);
189 }
190}