qfall_math/integer/mat_poly_over_z/
trace.rs1use flint_sys::fmpz_poly_mat::fmpz_poly_mat_trace;
12
13use super::MatPolyOverZ;
14use crate::{error::MathError, integer::PolyOverZ, traits::MatrixDimensions};
15
16impl MatPolyOverZ {
17 pub fn trace(&self) -> Result<PolyOverZ, MathError> {
34 if self.get_num_rows() != self.get_num_columns() {
36 return Err(MathError::NoSquareMatrix(self.to_string()));
37 }
38
39 let mut out = PolyOverZ::default();
40 unsafe {
41 fmpz_poly_mat_trace(&mut out.poly, &self.matrix);
42 }
43 Ok(out)
44 }
45}
46
47#[cfg(test)]
48mod test_trace {
49 use crate::integer::{MatPolyOverZ, PolyOverZ};
50 use std::str::FromStr;
51
52 #[test]
54 fn trace_works() {
55 let mat_1 =
56 MatPolyOverZ::from_str("[[2 4 5, 1 2, 0],[1 2, 1 1, 0],[0, 3 1 2 3, 1 1]]")
57 .unwrap();
58 let mat_2 = MatPolyOverZ::from_str("[[2 -1 -1, 0],[0, 2 1 1]]").unwrap();
59
60 let trace_1 = mat_1.trace().unwrap();
61 let trace_2 = mat_2.trace().unwrap();
62
63 assert_eq!(PolyOverZ::from_str("2 6 5").unwrap(), trace_1);
64 assert_eq!(PolyOverZ::default(), trace_2);
65 }
66
67 #[test]
69 fn trace_large_values() {
70 let mat_1 = MatPolyOverZ::from_str(&format!(
71 "[[2 -1 {}, 1 5],[3 1 2 3, 1 {}]]",
72 i64::MAX,
73 i64::MAX
74 ))
75 .unwrap();
76 let mat_2 = MatPolyOverZ::from_str(&format!("[[1 {}]]", i64::MIN)).unwrap();
77 let mat_3 = MatPolyOverZ::from_str(&format!(
78 "[[1 {}, 1 5],[3 1 2 3, 1 {}]]",
79 i64::MIN,
80 i64::MAX
81 ))
82 .unwrap();
83
84 let trace_1 = mat_1.trace().unwrap();
85 let trace_2 = mat_2.trace().unwrap();
86 let trace_3 = mat_3.trace().unwrap();
87
88 assert_eq!(
89 PolyOverZ::from_str(&format!("2 {} {}", i64::MAX - 1, i64::MAX)).unwrap(),
90 trace_1
91 );
92 assert_eq!(PolyOverZ::from(i64::MIN), trace_2);
93 assert_eq!(PolyOverZ::from(-1), trace_3);
94 }
95
96 #[test]
98 fn trace_error_not_squared() {
99 let mat_1 = MatPolyOverZ::from_str("[[1 1, 0, 1 1],[0, 1 2, 1 3]]").unwrap();
100 let mat_2 = MatPolyOverZ::from_str("[[1 42, 0],[0, 3 17 9 8],[1 3, 0]]").unwrap();
101
102 assert!(mat_1.trace().is_err());
103 assert!(mat_2.trace().is_err());
104 }
105}