@@ -196,9 +196,10 @@ impl<const D: usize> Matrix<D> {
196196 Ldlt :: factor ( self , tol)
197197 }
198198
199- /// Closed-form determinant for dimensions 1 –4, bypassing LU factorization.
199+ /// Closed-form determinant for dimensions 0 –4, bypassing LU factorization.
200200 ///
201- /// Returns `Some(det)` for `D` ∈ {1, 2, 3, 4}, `None` for larger matrices.
201+ /// Returns `Some(det)` for `D` ∈ {0, 1, 2, 3, 4}, `None` for D ≥ 5.
202+ /// `D = 0` returns `Some(1.0)` (empty product).
202203 /// This is a `const fn` (Rust 1.94+) and uses fused multiply-add (`mul_add`)
203204 /// for improved accuracy and performance.
204205 ///
@@ -212,6 +213,9 @@ impl<const D: usize> Matrix<D> {
212213 /// let m = Matrix::<2>::from_rows([[1.0, 2.0], [3.0, 4.0]]);
213214 /// assert!((m.det_direct().unwrap() - (-2.0)).abs() <= 1e-12);
214215 ///
216+ /// // D = 0 is the empty product.
217+ /// assert_eq!(Matrix::<0>::zero().det_direct(), Some(1.0));
218+ ///
215219 /// // D ≥ 5 returns None.
216220 /// assert!(Matrix::<5>::identity().det_direct().is_none());
217221 /// ```
@@ -239,33 +243,23 @@ impl<const D: usize> Matrix<D> {
239243 )
240244 }
241245 4 => {
242- // Cofactor expansion on first row → four 3×3 sub-determinants,
243- // each computed inline (closures are not const-compatible ).
246+ // Cofactor expansion on first row → four 3×3 sub-determinants.
247+ // Hoist the 6 unique 2×2 minors from rows 2–3 (each used twice ).
244248 let r = & self . rows ;
245249
246- // Minor M00: rows 1-3, cols 1-3
247- let m00_0 = r[ 2 ] [ 2 ] . mul_add ( r[ 3 ] [ 3 ] , -( r[ 2 ] [ 3 ] * r[ 3 ] [ 2 ] ) ) ;
248- let m00_1 = r[ 2 ] [ 1 ] . mul_add ( r[ 3 ] [ 3 ] , -( r[ 2 ] [ 3 ] * r[ 3 ] [ 1 ] ) ) ;
249- let m00_2 = r[ 2 ] [ 1 ] . mul_add ( r[ 3 ] [ 2 ] , -( r[ 2 ] [ 2 ] * r[ 3 ] [ 1 ] ) ) ;
250- let c00 = r[ 1 ] [ 1 ] . mul_add ( m00_0, ( -r[ 1 ] [ 2 ] ) . mul_add ( m00_1, r[ 1 ] [ 3 ] * m00_2) ) ;
251-
252- // Minor M01: rows 1-3, cols 0,2,3
253- let m01_0 = r[ 2 ] [ 2 ] . mul_add ( r[ 3 ] [ 3 ] , -( r[ 2 ] [ 3 ] * r[ 3 ] [ 2 ] ) ) ;
254- let m01_1 = r[ 2 ] [ 0 ] . mul_add ( r[ 3 ] [ 3 ] , -( r[ 2 ] [ 3 ] * r[ 3 ] [ 0 ] ) ) ;
255- let m01_2 = r[ 2 ] [ 0 ] . mul_add ( r[ 3 ] [ 2 ] , -( r[ 2 ] [ 2 ] * r[ 3 ] [ 0 ] ) ) ;
256- let c01 = r[ 1 ] [ 0 ] . mul_add ( m01_0, ( -r[ 1 ] [ 2 ] ) . mul_add ( m01_1, r[ 1 ] [ 3 ] * m01_2) ) ;
257-
258- // Minor M02: rows 1-3, cols 0,1,3
259- let m02_0 = r[ 2 ] [ 1 ] . mul_add ( r[ 3 ] [ 3 ] , -( r[ 2 ] [ 3 ] * r[ 3 ] [ 1 ] ) ) ;
260- let m02_1 = r[ 2 ] [ 0 ] . mul_add ( r[ 3 ] [ 3 ] , -( r[ 2 ] [ 3 ] * r[ 3 ] [ 0 ] ) ) ;
261- let m02_2 = r[ 2 ] [ 0 ] . mul_add ( r[ 3 ] [ 1 ] , -( r[ 2 ] [ 1 ] * r[ 3 ] [ 0 ] ) ) ;
262- let c02 = r[ 1 ] [ 0 ] . mul_add ( m02_0, ( -r[ 1 ] [ 1 ] ) . mul_add ( m02_1, r[ 1 ] [ 3 ] * m02_2) ) ;
263-
264- // Minor M03: rows 1-3, cols 0,1,2
265- let m03_0 = r[ 2 ] [ 1 ] . mul_add ( r[ 3 ] [ 2 ] , -( r[ 2 ] [ 2 ] * r[ 3 ] [ 1 ] ) ) ;
266- let m03_1 = r[ 2 ] [ 0 ] . mul_add ( r[ 3 ] [ 2 ] , -( r[ 2 ] [ 2 ] * r[ 3 ] [ 0 ] ) ) ;
267- let m03_2 = r[ 2 ] [ 0 ] . mul_add ( r[ 3 ] [ 1 ] , -( r[ 2 ] [ 1 ] * r[ 3 ] [ 0 ] ) ) ;
268- let c03 = r[ 1 ] [ 0 ] . mul_add ( m03_0, ( -r[ 1 ] [ 1 ] ) . mul_add ( m03_1, r[ 1 ] [ 2 ] * m03_2) ) ;
250+ // 2×2 minors: s_ij = r[2][i]*r[3][j] - r[2][j]*r[3][i]
251+ let s23 = r[ 2 ] [ 2 ] . mul_add ( r[ 3 ] [ 3 ] , -( r[ 2 ] [ 3 ] * r[ 3 ] [ 2 ] ) ) ; // cols 2,3
252+ let s13 = r[ 2 ] [ 1 ] . mul_add ( r[ 3 ] [ 3 ] , -( r[ 2 ] [ 3 ] * r[ 3 ] [ 1 ] ) ) ; // cols 1,3
253+ let s12 = r[ 2 ] [ 1 ] . mul_add ( r[ 3 ] [ 2 ] , -( r[ 2 ] [ 2 ] * r[ 3 ] [ 1 ] ) ) ; // cols 1,2
254+ let s03 = r[ 2 ] [ 0 ] . mul_add ( r[ 3 ] [ 3 ] , -( r[ 2 ] [ 3 ] * r[ 3 ] [ 0 ] ) ) ; // cols 0,3
255+ let s02 = r[ 2 ] [ 0 ] . mul_add ( r[ 3 ] [ 2 ] , -( r[ 2 ] [ 2 ] * r[ 3 ] [ 0 ] ) ) ; // cols 0,2
256+ let s01 = r[ 2 ] [ 0 ] . mul_add ( r[ 3 ] [ 1 ] , -( r[ 2 ] [ 1 ] * r[ 3 ] [ 0 ] ) ) ; // cols 0,1
257+
258+ // 3×3 cofactors via row 1 expansion using hoisted minors.
259+ let c00 = r[ 1 ] [ 1 ] . mul_add ( s23, ( -r[ 1 ] [ 2 ] ) . mul_add ( s13, r[ 1 ] [ 3 ] * s12) ) ;
260+ let c01 = r[ 1 ] [ 0 ] . mul_add ( s23, ( -r[ 1 ] [ 2 ] ) . mul_add ( s03, r[ 1 ] [ 3 ] * s02) ) ;
261+ let c02 = r[ 1 ] [ 0 ] . mul_add ( s13, ( -r[ 1 ] [ 1 ] ) . mul_add ( s03, r[ 1 ] [ 3 ] * s01) ) ;
262+ let c03 = r[ 1 ] [ 0 ] . mul_add ( s12, ( -r[ 1 ] [ 1 ] ) . mul_add ( s02, r[ 1 ] [ 2 ] * s01) ) ;
269263
270264 Some ( r[ 0 ] [ 0 ] . mul_add (
271265 c00,
0 commit comments