qfall_math/rational/mat_q/
cmp.rs1use super::MatQ;
12use crate::{
13 integer::MatZ,
14 macros::{compare_base::compare_base_default, for_others::implement_trait_reverse},
15 rational::Q,
16 traits::{CompareBase, MatrixDimensions, MatrixGetEntry},
17};
18use flint_sys::{
19 fmpq_mat::{fmpq_mat_equal, fmpq_mat_set_fmpz_mat_div_fmpz},
20 fmpz::fmpz,
21};
22
23impl PartialEq for MatQ {
24 fn eq(&self, other: &Self) -> bool {
53 unsafe { fmpq_mat_equal(&self.matrix, &other.matrix) != 0 }
54 }
55}
56
57impl Eq for MatQ {}
60
61impl PartialEq<MatZ> for MatQ {
62 fn eq(&self, other: &MatZ) -> bool {
97 let num_rows = self.get_num_rows();
98 let num_cols = self.get_num_columns();
99
100 if num_rows != other.get_num_rows() || num_cols != other.get_num_columns() {
101 return false;
102 }
103
104 for i in 0..num_rows {
105 for j in 0..num_cols {
106 if unsafe { self.get_entry_unchecked(i, j) != other.get_entry_unchecked(i, j) } {
107 return false;
108 }
109 }
110 }
111
112 true
113 }
114}
115
116impl MatQ {
117 pub fn equal(self, other: MatZ) -> bool {
118 let mut other_matq = MatQ::new(other.get_num_rows(), other.get_num_columns());
119 unsafe { fmpq_mat_set_fmpz_mat_div_fmpz(&mut other_matq.matrix, &other.matrix, &fmpz(1)) };
120 1 != unsafe { fmpq_mat_equal(&other_matq.matrix, &self.matrix) }
121 }
122}
123
124implement_trait_reverse!(PartialEq, eq, MatZ, MatQ, bool);
125
126compare_base_default!(MatQ for MatQ MatZ);
127impl<Rational: Into<Q>> CompareBase<Rational> for MatQ {}
128
129#[cfg(test)]
131mod test_partial_eq {
132 use super::MatQ;
133 use crate::{rational::Q, traits::MatrixSetEntry};
134 use std::str::FromStr;
135
136 #[test]
138 fn equality_between_instantiations() {
139 let a = MatQ::from_str("[[0, 1/2],[0/2, 0]]").unwrap();
140 let mut b = MatQ::new(2, 2);
141 b.set_entry(0, 1, Q::from((2, 4))).unwrap();
142
143 assert_eq!(a, b);
144 }
145
146 #[test]
148 fn equality_for_large_and_small_entries() {
149 let mat_str_1 = &format!(
150 "[[{}/{}, {}/{}, 1],[-10, 10, 0],[0, 1, -10]]",
151 i64::MIN,
152 i64::MIN + 1,
153 i64::MAX,
154 i64::MAX - 1
155 );
156
157 let mat_str_2 = &format!(
159 "[[{}/{}, {}/{}, 1],[-20/2, 20/2, 0/2],[0, 1, -10]]",
160 i64::MIN,
161 i64::MIN + 1,
162 i64::MAX,
163 i64::MAX - 1
164 );
165
166 let a = MatQ::from_str(mat_str_1).unwrap();
167 let b = MatQ::from_str(mat_str_1).unwrap();
168 let c = MatQ::from_str(mat_str_2).unwrap();
169
170 assert_eq!(&a, &b);
171 assert_eq!(&a, &c);
172 }
173
174 #[test]
176 fn not_equal() {
177 let a = MatQ::from_str(&format!("[[{}, {}],[-10, 10]]", i64::MIN, i64::MAX)).unwrap();
178 let b = MatQ::from_str(&format!("[[0, {}],[-10, 10]]", i64::MAX)).unwrap();
179 let c =
180 MatQ::from_str(&format!("[[{}, {}],[-10, 10],[0, 0]]", i64::MIN, i64::MAX)).unwrap();
181 let d = MatQ::from_str(&format!("[[{}, {}]]", i64::MIN, i64::MAX)).unwrap();
182 let e = MatQ::from_str("[[0]]").unwrap();
183
184 assert_ne!(&a, &b);
185 assert_ne!(&a, &c);
186 assert_ne!(&a, &d);
187 assert_ne!(&a, &e);
188 assert_ne!(&b, &c);
189 assert_ne!(&b, &d);
190 assert_ne!(&b, &e);
191 assert_ne!(&c, &d);
192 assert_ne!(&c, &e);
193 assert_ne!(&d, &e);
194 }
195}
196
197#[cfg(test)]
199mod test_partial_eq_q_other {
200 use super::MatQ;
201 use crate::integer::MatZ;
202 use std::str::FromStr;
203
204 #[test]
206 #[allow(clippy::op_ref)]
207 fn availability() {
208 let q = MatQ::from_str("[[1, 2],[3, 4]]").unwrap();
209 let z = MatZ::from_str("[[1, 2],[3, 4]]").unwrap();
210
211 assert!(q == z);
212 assert!(z == q);
213 assert!(&q == &z);
214 assert!(&z == &q);
215 }
216
217 #[test]
219 fn equal_large() {
220 let q = MatQ::from_str(&format!("[[1,2],[3,{}]]", u64::MAX)).unwrap();
221 let z = MatZ::from_str(&format!("[[1,2],[3,{}]]", u64::MAX)).unwrap();
222
223 assert!(q == z);
224 }
225}
226
227#[cfg(test)]
229mod test_compare_base {
230 use crate::{
231 integer::{MatZ, Z},
232 rational::{MatQ, Q},
233 traits::CompareBase,
234 };
235 use std::str::FromStr;
236
237 #[test]
240 fn availability() {
241 let one_1 = MatQ::from_str("[[2,5,-7/3],[2,3,4]]").unwrap();
242
243 assert!(one_1.compare_base(&MatZ::new(1, 1)));
244 assert!(one_1.compare_base(&MatQ::new(1, 1)));
245 assert!(one_1.compare_base(&Z::ONE));
246 assert!(one_1.compare_base(&Q::ONE));
247 assert!(one_1.compare_base(&0_i8));
248 assert!(one_1.compare_base(&0_i16));
249 assert!(one_1.compare_base(&0_i32));
250 assert!(one_1.compare_base(&0_i64));
251 assert!(one_1.compare_base(&0_u8));
252 assert!(one_1.compare_base(&0_u16));
253 assert!(one_1.compare_base(&0_u32));
254 assert!(one_1.compare_base(&0_u64));
255 assert!(one_1.compare_base(&0.5_f32));
256 assert!(one_1.compare_base(&0.5_f64));
257
258 assert!(one_1.call_compare_base_error(&MatZ::new(1, 1)).is_none());
259 assert!(one_1.call_compare_base_error(&MatQ::new(1, 1)).is_none());
260 assert!(one_1.call_compare_base_error(&Z::ONE).is_none());
261 assert!(one_1.call_compare_base_error(&Q::ONE).is_none());
262 assert!(one_1.call_compare_base_error(&0_i8).is_none());
263 assert!(one_1.call_compare_base_error(&0_i16).is_none());
264 assert!(one_1.call_compare_base_error(&0_i32).is_none());
265 assert!(one_1.call_compare_base_error(&0_i64).is_none());
266 assert!(one_1.call_compare_base_error(&0_u8).is_none());
267 assert!(one_1.call_compare_base_error(&0_u16).is_none());
268 assert!(one_1.call_compare_base_error(&0_u32).is_none());
269 assert!(one_1.call_compare_base_error(&0_u64).is_none());
270 assert!(one_1.call_compare_base_error(&0.5_f32).is_none());
271 assert!(one_1.call_compare_base_error(&0.5_f64).is_none());
272 }
273}