mathhook_core/algebra/
diagonal_matrix_tests.rs

1//! Comprehensive tests for DiagonalMatrix mathematical properties and optimizations
2//!
3//! Tests verify that diagonal matrix operations maintain perfect mathematical accuracy
4//! and leverage O(n) memory optimizations.
5
6#[cfg(test)]
7mod tests {
8    use crate::core::expression::Expression;
9    use crate::matrices::operations::MatrixOperations;
10
11    /// Test diagonal matrix creation and basic properties
12    #[test]
13    fn test_diagonal_matrix_creation() {
14        let diag = Expression::diagonal_matrix(vec![
15            Expression::integer(2),
16            Expression::integer(3),
17            Expression::integer(5),
18        ]);
19
20        // Test dimensions
21        assert_eq!(diag.matrix_dimensions(), Some((3, 3)));
22        assert!(diag.is_matrix());
23
24        // Test diagonal property
25        assert!(diag.is_diagonal());
26        assert!(!diag.is_identity_matrix());
27        assert!(!diag.is_zero_matrix());
28    }
29
30    /// Test diagonal matrix addition optimizations
31    #[test]
32    fn test_diagonal_matrix_addition() {
33        let diag1 = Expression::diagonal_matrix(vec![
34            Expression::integer(1),
35            Expression::integer(2),
36            Expression::integer(3),
37        ]);
38        let diag2 = Expression::diagonal_matrix(vec![
39            Expression::integer(4),
40            Expression::integer(5),
41            Expression::integer(6),
42        ]);
43
44        // D1 + D2 should be diagonal with element-wise addition
45        let result = diag1.matrix_add(&diag2);
46        let expected = Expression::diagonal_matrix(vec![
47            Expression::integer(5), // 1 + 4
48            Expression::integer(7), // 2 + 5
49            Expression::integer(9), // 3 + 6
50        ]);
51
52        assert_eq!(result, expected);
53        assert!(result.is_diagonal());
54    }
55
56    /// Test diagonal matrix + identity matrix optimization
57    #[test]
58    fn test_diagonal_plus_identity() {
59        let diag = Expression::diagonal_matrix(vec![
60            Expression::integer(2),
61            Expression::integer(3),
62            Expression::integer(4),
63        ]);
64        let identity = Expression::identity_matrix(3);
65
66        // D + I should add 1 to each diagonal element
67        let result = diag.matrix_add(&identity);
68        let expected = Expression::diagonal_matrix(vec![
69            Expression::integer(3), // 2 + 1
70            Expression::integer(4), // 3 + 1
71            Expression::integer(5), // 4 + 1
72        ]);
73
74        assert_eq!(result, expected);
75        assert!(result.is_diagonal());
76
77        // Test commutativity: I + D = D + I
78        let result2 = identity.matrix_add(&diag);
79        assert_eq!(result, result2);
80    }
81
82    /// Test diagonal matrix optimization from dense matrix
83    #[test]
84    fn test_diagonal_matrix_optimization() {
85        // Create a dense matrix that is actually diagonal
86        let dense = Expression::matrix(vec![
87            vec![
88                Expression::integer(2),
89                Expression::integer(0),
90                Expression::integer(0),
91            ],
92            vec![
93                Expression::integer(0),
94                Expression::integer(3),
95                Expression::integer(0),
96            ],
97            vec![
98                Expression::integer(0),
99                Expression::integer(0),
100                Expression::integer(4),
101            ],
102        ]);
103
104        // Should be optimized to diagonal matrix
105        let optimized = dense;
106        let expected = Expression::diagonal_matrix(vec![
107            Expression::integer(2),
108            Expression::integer(3),
109            Expression::integer(4),
110        ]);
111
112        assert_eq!(optimized, expected);
113        assert!(optimized.is_diagonal());
114    }
115
116    /// Test diagonal matrix with zero elements
117    #[test]
118    fn test_diagonal_matrix_with_zeros() {
119        let diag = Expression::diagonal_matrix(vec![
120            Expression::integer(2),
121            Expression::integer(0), // Zero on diagonal
122            Expression::integer(3),
123        ]);
124
125        // Should remain diagonal (not optimized to zero matrix)
126        assert!(diag.is_diagonal());
127        assert!(!diag.is_zero_matrix());
128
129        // Determinant should be zero (has zero on diagonal)
130        let det = diag.matrix_determinant();
131        assert_eq!(det, Expression::integer(0));
132
133        // Trace should be sum including zero
134        let trace = diag.matrix_trace();
135        assert_eq!(trace, Expression::integer(5)); // 2 + 0 + 3
136    }
137}