qfall_math/integer/mat_z/
determinant.rs1use super::MatZ;
12use crate::{error::MathError, integer::Z, traits::MatrixDimensions};
13use flint_sys::fmpz_mat::fmpz_mat_det;
14
15impl MatZ {
16 pub fn det(&self) -> Result<Z, MathError> {
33 if self.get_num_rows() != self.get_num_columns() {
34 return Err(MathError::MismatchingMatrixDimension(
35 "The matrix is not square".to_string(),
36 ));
37 }
38
39 let mut det = Z::default();
40 unsafe {
41 fmpz_mat_det(&mut det.value, &self.matrix);
42 }
43 Ok(det)
44 }
45}
46
47#[cfg(test)]
48mod test_determinant {
49 use crate::integer::{MatZ, Z};
50 use std::str::FromStr;
51
52 #[test]
54 fn determinant_works() {
55 let mat_1 = MatZ::from_str("[[5, 2],[2, 1]]").unwrap();
56 let mat_2 = MatZ::from_str(&format!("[[{}, 0],[0, 1]]", i64::MAX)).unwrap();
57 let mat_3 = MatZ::from_str(&format!("[[{}]]", i64::MIN)).unwrap();
58 let mat_4 = MatZ::from_str("[[0, 0],[0, 1]]").unwrap();
59 let mat_5 = MatZ::from_str("[[6, 0, 1],[0, 1, 0],[1, 2, 3]]").unwrap();
60
61 let det_1 = mat_1.det().unwrap();
62 let det_2 = mat_2.det().unwrap();
63 let det_3 = mat_3.det().unwrap();
64 let det_4 = mat_4.det().unwrap();
65 let det_5 = mat_5.det().unwrap();
66
67 let cmp_1 = Z::ONE;
68 let cmp_2 = Z::from(i64::MAX);
69 let cmp_3 = Z::from(i64::MIN);
70 let cmp_4 = Z::ZERO;
71 let cmp_5 = Z::from(17);
72
73 assert_eq!(cmp_1, det_1);
74 assert_eq!(cmp_2, det_2);
75 assert_eq!(cmp_3, det_3);
76 assert_eq!(cmp_4, det_4);
77 assert_eq!(cmp_5, det_5);
78 }
79
80 #[test]
82 fn not_square_error() {
83 let mat_1 = MatZ::from_str("[[5],[2]]").unwrap();
84 let mat_2 = MatZ::from_str("[[2, 0],[0, 1],[8, -6]]").unwrap();
85
86 assert!(mat_1.det().is_err());
87 assert!(mat_2.det().is_err());
88 }
89}