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