@@ -5,17 +5,21 @@ extern crate num_traits;
5
5
6
6
use ndarray:: * ;
7
7
use ndarray_linalg:: * ;
8
- use num_traits:: { One , Zero } ;
8
+ use num_traits:: { Float , One , Zero } ;
9
9
10
10
#[ test]
11
11
fn deth_empty ( ) {
12
12
macro_rules! deth_empty {
13
13
( $elem: ty) => {
14
14
let a: Array2 <$elem> = Array2 :: zeros( ( 0 , 0 ) ) ;
15
15
assert_eq!( a. factorizeh( ) . unwrap( ) . deth( ) , One :: one( ) ) ;
16
+ assert_eq!( a. factorizeh( ) . unwrap( ) . sln_deth( ) , ( One :: one( ) , Zero :: zero( ) ) ) ;
16
17
assert_eq!( a. factorizeh( ) . unwrap( ) . deth_into( ) , One :: one( ) ) ;
18
+ assert_eq!( a. factorizeh( ) . unwrap( ) . sln_deth_into( ) , ( One :: one( ) , Zero :: zero( ) ) ) ;
17
19
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( ) ) ) ;
19
23
}
20
24
}
21
25
deth_empty ! ( f64 ) ;
@@ -30,7 +34,9 @@ fn deth_zero() {
30
34
( $elem: ty) => {
31
35
let a: Array2 <$elem> = Array2 :: zeros( ( 1 , 1 ) ) ;
32
36
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( ) ) ) ;
34
40
}
35
41
}
36
42
deth_zero ! ( f64 ) ;
@@ -45,7 +51,9 @@ fn deth_zero_nonsquare() {
45
51
( $elem: ty, $shape: expr) => {
46
52
let a: Array2 <$elem> = Array2 :: zeros( $shape) ;
47
53
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( ) ) ;
49
57
}
50
58
}
51
59
for & shape in & [ ( 1 , 2 ) . into_shape ( ) , ( 1 , 2 ) . f ( ) ] {
@@ -62,11 +70,39 @@ fn deth() {
62
70
( $elem: ty, $rows: expr, $atol: expr) => {
63
71
let a: Array2 <$elem> = random_hermite( $rows) ;
64
72
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
+
66
82
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
+ }
67
88
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
+ }
68
94
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
+ }
70
106
}
71
107
}
72
108
for rows in 1 ..6 {
@@ -83,9 +119,10 @@ fn deth_nonsquare() {
83
119
( $elem: ty, $shape: expr) => {
84
120
let a: Array2 <$elem> = Array2 :: zeros( $shape) ;
85
121
assert!( a. factorizeh( ) . is_err( ) ) ;
86
- assert!( a. factorizeh( ) . is_err( ) ) ;
87
122
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( ) ) ;
89
126
}
90
127
}
91
128
for & dims in & [ ( 1 , 0 ) , ( 1 , 2 ) , ( 2 , 1 ) , ( 2 , 3 ) ] {
0 commit comments