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