@@ -6,7 +6,7 @@ use ndarray::prelude::*;
6
6
use ndarray:: LinalgScalar ;
7
7
use lapack:: c:: Layout ;
8
8
9
- use error:: LapackError ;
9
+ use error:: { LinalgError , StrideError } ;
10
10
use qr:: ImplQR ;
11
11
use svd:: ImplSVD ;
12
12
use norm:: ImplNorm ;
@@ -20,19 +20,19 @@ pub trait Matrix: Sized {
20
20
/// number of (rows, columns)
21
21
fn size ( & self ) -> ( usize , usize ) ;
22
22
/// Layout (C/Fortran) of matrix
23
- fn layout ( & self ) -> Layout ;
23
+ fn layout ( & self ) -> Result < Layout , StrideError > ;
24
24
/// Operator norm for L-1 norm
25
25
fn norm_1 ( & self ) -> Self :: Scalar ;
26
26
/// Operator norm for L-inf norm
27
27
fn norm_i ( & self ) -> Self :: Scalar ;
28
28
/// Frobenius norm
29
29
fn norm_f ( & self ) -> Self :: Scalar ;
30
30
/// singular-value decomposition (SVD)
31
- fn svd ( self ) -> Result < ( Self , Self :: Vector , Self ) , LapackError > ;
31
+ fn svd ( self ) -> Result < ( Self , Self :: Vector , Self ) , LinalgError > ;
32
32
/// QR decomposition
33
- fn qr ( self ) -> Result < ( Self , Self ) , LapackError > ;
33
+ fn qr ( self ) -> Result < ( Self , Self ) , LinalgError > ;
34
34
/// LU decomposition
35
- fn lu ( self ) -> Result < ( Self :: Permutator , Self , Self ) , LapackError > ;
35
+ fn lu ( self ) -> Result < ( Self :: Permutator , Self , Self ) , LinalgError > ;
36
36
/// permutate matrix (inplace)
37
37
fn permutate ( & mut self , p : & Self :: Permutator ) ;
38
38
/// permutate matrix (outplace)
@@ -52,12 +52,18 @@ impl<A> Matrix for Array<A, Ix2>
52
52
fn size ( & self ) -> ( usize , usize ) {
53
53
( self . rows ( ) , self . cols ( ) )
54
54
}
55
- fn layout ( & self ) -> Layout {
55
+ fn layout ( & self ) -> Result < Layout , StrideError > {
56
56
let strides = self . strides ( ) ;
57
+ if min ( strides[ 0 ] , strides[ 1 ] ) != 1 {
58
+ return Err ( StrideError {
59
+ s0 : strides[ 0 ] ,
60
+ s1 : strides[ 1 ] ,
61
+ } ) ; ;
62
+ }
57
63
if strides[ 0 ] < strides[ 1 ] {
58
- Layout :: ColumnMajor
64
+ Ok ( Layout :: ColumnMajor )
59
65
} else {
60
- Layout :: RowMajor
66
+ Ok ( Layout :: RowMajor )
61
67
}
62
68
}
63
69
fn norm_1 ( & self ) -> Self :: Scalar {
@@ -82,35 +88,24 @@ impl<A> Matrix for Array<A, Ix2>
82
88
let ( m, n) = self . size ( ) ;
83
89
ImplNorm :: norm_f ( m, n, self . clone ( ) . into_raw_vec ( ) )
84
90
}
85
- fn svd ( self ) -> Result < ( Self , Self :: Vector , Self ) , LapackError > {
86
- let strides = self . strides ( ) ;
87
- let ( m, n) = if strides[ 0 ] > strides[ 1 ] {
88
- self . size ( )
89
- } else {
90
- let ( n, m) = self . size ( ) ;
91
- ( m, n)
92
- } ;
93
- let ( u, s, vt) = try!( ImplSVD :: svd ( m, n, self . clone ( ) . into_raw_vec ( ) ) ) ;
91
+ fn svd ( self ) -> Result < ( Self , Self :: Vector , Self ) , LinalgError > {
92
+ let ( n, m) = self . size ( ) ;
93
+ let layout = self . layout ( ) ?;
94
+ let ( u, s, vt) = ImplSVD :: svd ( layout, m, n, self . clone ( ) . into_raw_vec ( ) ) ?;
94
95
let sv = Array :: from_vec ( s) ;
95
- if strides[ 0 ] > strides[ 1 ] {
96
- let ua = Array :: from_vec ( u) . into_shape ( ( n, n) ) . unwrap ( ) ;
97
- let va = Array :: from_vec ( vt) . into_shape ( ( m, m) ) . unwrap ( ) ;
98
- Ok ( ( va, sv, ua) )
99
- } else {
100
- let ua = Array :: from_vec ( u) . into_shape ( ( n, n) ) . unwrap ( ) . reversed_axes ( ) ;
101
- let va = Array :: from_vec ( vt) . into_shape ( ( m, m) ) . unwrap ( ) . reversed_axes ( ) ;
102
- Ok ( ( ua, sv, va) )
96
+ let ua = Array :: from_vec ( u) . into_shape ( ( n, n) ) . unwrap ( ) ;
97
+ let va = Array :: from_vec ( vt) . into_shape ( ( m, m) ) . unwrap ( ) ;
98
+ match layout {
99
+ Layout :: RowMajor => Ok ( ( ua, sv, va) ) ,
100
+ Layout :: ColumnMajor => Ok ( ( ua. reversed_axes ( ) , sv, va. reversed_axes ( ) ) ) ,
103
101
}
104
102
}
105
- fn qr ( self ) -> Result < ( Self , Self ) , LapackError > {
103
+ fn qr ( self ) -> Result < ( Self , Self ) , LinalgError > {
106
104
let ( n, m) = self . size ( ) ;
107
105
let strides = self . strides ( ) ;
108
106
let k = min ( n, m) ;
109
- let ( q, r) = if strides[ 0 ] < strides[ 1 ] {
110
- try!( ImplQR :: qr ( m, n, self . clone ( ) . into_raw_vec ( ) ) )
111
- } else {
112
- try!( ImplQR :: lq ( n, m, self . clone ( ) . into_raw_vec ( ) ) )
113
- } ;
107
+ let layout = self . layout ( ) ?;
108
+ let ( q, r) = ImplQR :: qr ( layout, m, n, self . clone ( ) . into_raw_vec ( ) ) ?;
114
109
let ( qa, ra) = if strides[ 0 ] < strides[ 1 ] {
115
110
( Array :: from_vec ( q) . into_shape ( ( m, n) ) . unwrap ( ) . reversed_axes ( ) ,
116
111
Array :: from_vec ( r) . into_shape ( ( m, n) ) . unwrap ( ) . reversed_axes ( ) )
@@ -136,23 +131,14 @@ impl<A> Matrix for Array<A, Ix2>
136
131
}
137
132
Ok ( ( qm, rm) )
138
133
}
139
- fn lu ( self ) -> Result < ( Self :: Permutator , Self , Self ) , LapackError > {
134
+ fn lu ( self ) -> Result < ( Self :: Permutator , Self , Self ) , LinalgError > {
140
135
let ( n, m) = self . size ( ) ;
141
- println ! ( "n={}, m={}" , n, m) ;
142
136
let k = min ( n, m) ;
143
- let ( p, mut a) = match self . layout ( ) {
144
- Layout :: ColumnMajor => {
145
- println ! ( "ColumnMajor" ) ;
146
- let ( p, l) = ImplSolve :: lu ( self . layout ( ) , n, m, self . clone ( ) . into_raw_vec ( ) ) ?;
147
- ( p, Array :: from_vec ( l) . into_shape ( ( m, n) ) . unwrap ( ) . reversed_axes ( ) )
148
- }
149
- Layout :: RowMajor => {
150
- println ! ( "RowMajor" ) ;
151
- let ( p, l) = ImplSolve :: lu ( self . layout ( ) , n, m, self . clone ( ) . into_raw_vec ( ) ) ?;
152
- ( p, Array :: from_vec ( l) . into_shape ( ( n, m) ) . unwrap ( ) )
153
- }
137
+ let ( p, l) = ImplSolve :: lu ( self . layout ( ) ?, n, m, self . clone ( ) . into_raw_vec ( ) ) ?;
138
+ let mut a = match self . layout ( ) ? {
139
+ Layout :: ColumnMajor => Array :: from_vec ( l) . into_shape ( ( m, n) ) . unwrap ( ) . reversed_axes ( ) ,
140
+ Layout :: RowMajor => Array :: from_vec ( l) . into_shape ( ( n, m) ) . unwrap ( ) ,
154
141
} ;
155
- println ! ( "a (after LU) = \n {:?}" , & a) ;
156
142
let mut lm = Array :: zeros ( ( n, k) ) ;
157
143
for ( ( i, j) , val) in lm. indexed_iter_mut ( ) {
158
144
if i > j {
@@ -171,7 +157,6 @@ impl<A> Matrix for Array<A, Ix2>
171
157
} else {
172
158
a
173
159
} ;
174
- println ! ( "am = \n {:?}" , am) ;
175
160
Ok ( ( p, lm, am) )
176
161
}
177
162
fn permutate ( & mut self , ipiv : & Self :: Permutator ) {
0 commit comments