@@ -5,17 +5,21 @@ extern crate num_traits;
55
66use ndarray:: * ;
77use ndarray_linalg:: * ;
8- use num_traits:: { One , Zero } ;
8+ use num_traits:: { Float , One , Zero } ;
99
1010#[ test]
1111fn deth_empty ( ) {
1212 macro_rules! deth_empty {
1313 ( $elem: ty) => {
1414 let a: Array2 <$elem> = Array2 :: zeros( ( 0 , 0 ) ) ;
1515 assert_eq!( a. factorizeh( ) . unwrap( ) . deth( ) , One :: one( ) ) ;
16+ assert_eq!( a. factorizeh( ) . unwrap( ) . sln_deth( ) , ( One :: one( ) , Zero :: zero( ) ) ) ;
1617 assert_eq!( a. factorizeh( ) . unwrap( ) . deth_into( ) , One :: one( ) ) ;
18+ assert_eq!( a. factorizeh( ) . unwrap( ) . sln_deth_into( ) , ( One :: one( ) , Zero :: zero( ) ) ) ;
1719 assert_eq!( a. deth( ) . unwrap( ) , One :: one( ) ) ;
18- assert_eq!( a. deth_into( ) . unwrap( ) , One :: one( ) ) ;
20+ assert_eq!( a. sln_deth( ) . unwrap( ) , ( One :: one( ) , Zero :: zero( ) ) ) ;
21+ assert_eq!( a. clone( ) . deth_into( ) . unwrap( ) , One :: one( ) ) ;
22+ assert_eq!( a. sln_deth_into( ) . unwrap( ) , ( One :: one( ) , Zero :: zero( ) ) ) ;
1923 }
2024 }
2125 deth_empty ! ( f64 ) ;
@@ -30,7 +34,9 @@ fn deth_zero() {
3034 ( $elem: ty) => {
3135 let a: Array2 <$elem> = Array2 :: zeros( ( 1 , 1 ) ) ;
3236 assert_eq!( a. deth( ) . unwrap( ) , Zero :: zero( ) ) ;
33- assert_eq!( a. deth_into( ) . unwrap( ) , Zero :: zero( ) ) ;
37+ assert_eq!( a. sln_deth( ) . unwrap( ) , ( Zero :: zero( ) , Float :: neg_infinity( ) ) ) ;
38+ assert_eq!( a. clone( ) . deth_into( ) . unwrap( ) , Zero :: zero( ) ) ;
39+ assert_eq!( a. sln_deth_into( ) . unwrap( ) , ( Zero :: zero( ) , Float :: neg_infinity( ) ) ) ;
3440 }
3541 }
3642 deth_zero ! ( f64 ) ;
@@ -45,7 +51,9 @@ fn deth_zero_nonsquare() {
4551 ( $elem: ty, $shape: expr) => {
4652 let a: Array2 <$elem> = Array2 :: zeros( $shape) ;
4753 assert!( a. deth( ) . is_err( ) ) ;
48- assert!( a. deth_into( ) . is_err( ) ) ;
54+ assert!( a. sln_deth( ) . is_err( ) ) ;
55+ assert!( a. clone( ) . deth_into( ) . is_err( ) ) ;
56+ assert!( a. sln_deth_into( ) . is_err( ) ) ;
4957 }
5058 }
5159 for & shape in & [ ( 1 , 2 ) . into_shape ( ) , ( 1 , 2 ) . f ( ) ] {
@@ -62,11 +70,39 @@ fn deth() {
6270 ( $elem: ty, $rows: expr, $atol: expr) => {
6371 let a: Array2 <$elem> = random_hermite( $rows) ;
6472 println!( "a = \n {:?}" , a) ;
65- let det = a. eigvalsh( UPLO :: Upper ) . unwrap( ) . iter( ) . product( ) ;
73+
74+ // Compute determinant from eigenvalues.
75+ let ( sign, ln_det) = a. eigvalsh( UPLO :: Upper ) . unwrap( ) . iter( ) . fold(
76+ ( <$elem as AssociatedReal >:: Real :: one( ) , <$elem as AssociatedReal >:: Real :: zero( ) ) ,
77+ |( sign, ln_det) , eigval| ( sign * eigval. signum( ) , ln_det + eigval. abs( ) . ln( ) )
78+ ) ;
79+ let det = sign * ln_det. exp( ) ;
80+ assert_aclose!( det, a. eigvalsh( UPLO :: Upper ) . unwrap( ) . iter( ) . product( ) , $atol) ;
81+
6682 assert_aclose!( a. factorizeh( ) . unwrap( ) . deth( ) , det, $atol) ;
83+ {
84+ let result = a. factorizeh( ) . unwrap( ) . sln_deth( ) ;
85+ assert_aclose!( result. 0 , sign, $atol) ;
86+ assert_aclose!( result. 1 , ln_det, $atol) ;
87+ }
6788 assert_aclose!( a. factorizeh( ) . unwrap( ) . deth_into( ) , det, $atol) ;
89+ {
90+ let result = a. factorizeh( ) . unwrap( ) . sln_deth_into( ) ;
91+ assert_aclose!( result. 0 , sign, $atol) ;
92+ assert_aclose!( result. 1 , ln_det, $atol) ;
93+ }
6894 assert_aclose!( a. deth( ) . unwrap( ) , det, $atol) ;
69- assert_aclose!( a. deth_into( ) . unwrap( ) , det, $atol) ;
95+ {
96+ let result = a. sln_deth( ) . unwrap( ) ;
97+ assert_aclose!( result. 0 , sign, $atol) ;
98+ assert_aclose!( result. 1 , ln_det, $atol) ;
99+ }
100+ assert_aclose!( a. clone( ) . deth_into( ) . unwrap( ) , det, $atol) ;
101+ {
102+ let result = a. sln_deth_into( ) . unwrap( ) ;
103+ assert_aclose!( result. 0 , sign, $atol) ;
104+ assert_aclose!( result. 1 , ln_det, $atol) ;
105+ }
70106 }
71107 }
72108 for rows in 1 ..6 {
@@ -83,9 +119,10 @@ fn deth_nonsquare() {
83119 ( $elem: ty, $shape: expr) => {
84120 let a: Array2 <$elem> = Array2 :: zeros( $shape) ;
85121 assert!( a. factorizeh( ) . is_err( ) ) ;
86- assert!( a. factorizeh( ) . is_err( ) ) ;
87122 assert!( a. deth( ) . is_err( ) ) ;
88- assert!( a. deth_into( ) . is_err( ) ) ;
123+ assert!( a. sln_deth( ) . is_err( ) ) ;
124+ assert!( a. clone( ) . deth_into( ) . is_err( ) ) ;
125+ assert!( a. sln_deth_into( ) . is_err( ) ) ;
89126 }
90127 }
91128 for & dims in & [ ( 1 , 0 ) , ( 1 , 2 ) , ( 2 , 1 ) , ( 2 , 3 ) ] {
0 commit comments