1
- //! Solve linear problems
1
+ //! Solve systems of linear equations and invert matrices
2
+ //!
3
+ //! # Examples
4
+ //!
5
+ //! Solve `A * x = b`:
6
+ //!
7
+ //! ```
8
+ //! #[macro_use]
9
+ //! extern crate ndarray;
10
+ //! extern crate ndarray_linalg;
11
+ //!
12
+ //! use ndarray::prelude::*;
13
+ //! use ndarray_linalg::Solve;
14
+ //! # fn main() {
15
+ //!
16
+ //! let a: Array2<f64> = array![[3., 2., -1.], [2., -2., 4.], [-2., 1., -2.]];
17
+ //! let b: Array1<f64> = array![1., -2., 0.];
18
+ //! let x = a.solve_into(b).unwrap();
19
+ //! assert!(x.all_close(&array![1., -2., -2.], 1e-9));
20
+ //!
21
+ //! # }
22
+ //! ```
23
+ //!
24
+ //! There are also special functions for solving `A^T * x = b` and
25
+ //! `A^H * x = b`.
26
+ //!
27
+ //! If you are solving multiple systems of linear equations with the same
28
+ //! coefficient matrix `A`, it's faster to compute the LU factorization once at
29
+ //! the beginning than solving directly using `A`:
30
+ //!
31
+ //! ```
32
+ //! # extern crate ndarray;
33
+ //! # extern crate ndarray_linalg;
34
+ //! use ndarray::prelude::*;
35
+ //! use ndarray_linalg::*;
36
+ //! # fn main() {
37
+ //!
38
+ //! let a: Array2<f64> = random((3, 3));
39
+ //! let f = a.factorize_into().unwrap(); // LU factorize A (A is consumed)
40
+ //! for _ in 0..10 {
41
+ //! let b: Array1<f64> = random(3);
42
+ //! let x = f.solve_into(b).unwrap(); // Solve A * x = b using factorized L, U
43
+ //! }
44
+ //!
45
+ //! # }
46
+ //! ```
2
47
3
48
use ndarray:: * ;
4
49
@@ -9,43 +54,82 @@ use super::types::*;
9
54
10
55
pub use lapack_traits:: { Pivot , Transpose } ;
11
56
57
+ /// An interface for solving systems of linear equations.
58
+ ///
59
+ /// There are three groups of methods:
60
+ ///
61
+ /// * `solve*` (normal) methods solve `A * x = b` for `x`.
62
+ /// * `solve_t*` (transpose) methods solve `A^T * x = b` for `x`.
63
+ /// * `solve_h*` (Hermitian conjugate) methods solve `A^H * x = b` for `x`.
64
+ ///
65
+ /// Within each group, there are three methods that handle ownership differently:
66
+ ///
67
+ /// * `*` methods take a reference to `b` and return `x` as a new array.
68
+ /// * `*_into` methods take ownership of `b`, store the result in it, and return it.
69
+ /// * `*_mut` methods take a mutable reference to `b` and store the result in that array.
70
+ ///
71
+ /// If you plan to solve many equations with the same `A` matrix but different
72
+ /// `b` vectors, it's faster to factor the `A` matrix once using the
73
+ /// `Factorize` trait, and then solve using the `Factorized` struct.
12
74
pub trait Solve < A : Scalar > {
13
- fn solve < S : Data < Elem = A > > ( & self , a : & ArrayBase < S , Ix1 > ) -> Result < Array1 < A > > {
14
- let mut a = replicate ( a) ;
15
- self . solve_mut ( & mut a) ?;
16
- Ok ( a)
75
+ /// Solves a system of linear equations `A * x = b` where `A` is `self`, `b`
76
+ /// is the argument, and `x` is the successful result.
77
+ fn solve < S : Data < Elem = A > > ( & self , b : & ArrayBase < S , Ix1 > ) -> Result < Array1 < A > > {
78
+ let mut b = replicate ( b) ;
79
+ self . solve_mut ( & mut b) ?;
80
+ Ok ( b)
17
81
}
18
- fn solve_into < S : DataMut < Elem = A > > ( & self , mut a : ArrayBase < S , Ix1 > ) -> Result < ArrayBase < S , Ix1 > > {
19
- self . solve_mut ( & mut a) ?;
20
- Ok ( a)
82
+ /// Solves a system of linear equations `A * x = b` where `A` is `self`, `b`
83
+ /// is the argument, and `x` is the successful result.
84
+ fn solve_into < S : DataMut < Elem = A > > ( & self , mut b : ArrayBase < S , Ix1 > ) -> Result < ArrayBase < S , Ix1 > > {
85
+ self . solve_mut ( & mut b) ?;
86
+ Ok ( b)
21
87
}
88
+ /// Solves a system of linear equations `A * x = b` where `A` is `self`, `b`
89
+ /// is the argument, and `x` is the successful result.
22
90
fn solve_mut < ' a , S : DataMut < Elem = A > > ( & self , & ' a mut ArrayBase < S , Ix1 > ) -> Result < & ' a mut ArrayBase < S , Ix1 > > ;
23
91
24
- fn solve_t < S : Data < Elem = A > > ( & self , a : & ArrayBase < S , Ix1 > ) -> Result < Array1 < A > > {
25
- let mut a = replicate ( a) ;
26
- self . solve_t_mut ( & mut a) ?;
27
- Ok ( a)
92
+ /// Solves a system of linear equations `A^T * x = b` where `A` is `self`, `b`
93
+ /// is the argument, and `x` is the successful result.
94
+ fn solve_t < S : Data < Elem = A > > ( & self , b : & ArrayBase < S , Ix1 > ) -> Result < Array1 < A > > {
95
+ let mut b = replicate ( b) ;
96
+ self . solve_t_mut ( & mut b) ?;
97
+ Ok ( b)
28
98
}
29
- fn solve_t_into < S : DataMut < Elem = A > > ( & self , mut a : ArrayBase < S , Ix1 > ) -> Result < ArrayBase < S , Ix1 > > {
30
- self . solve_t_mut ( & mut a) ?;
31
- Ok ( a)
99
+ /// Solves a system of linear equations `A^T * x = b` where `A` is `self`, `b`
100
+ /// is the argument, and `x` is the successful result.
101
+ fn solve_t_into < S : DataMut < Elem = A > > ( & self , mut b : ArrayBase < S , Ix1 > ) -> Result < ArrayBase < S , Ix1 > > {
102
+ self . solve_t_mut ( & mut b) ?;
103
+ Ok ( b)
32
104
}
105
+ /// Solves a system of linear equations `A^T * x = b` where `A` is `self`, `b`
106
+ /// is the argument, and `x` is the successful result.
33
107
fn solve_t_mut < ' a , S : DataMut < Elem = A > > ( & self , & ' a mut ArrayBase < S , Ix1 > ) -> Result < & ' a mut ArrayBase < S , Ix1 > > ;
34
108
35
- fn solve_h < S : Data < Elem = A > > ( & self , a : & ArrayBase < S , Ix1 > ) -> Result < Array1 < A > > {
36
- let mut a = replicate ( a) ;
37
- self . solve_h_mut ( & mut a) ?;
38
- Ok ( a)
109
+ /// Solves a system of linear equations `A^H * x = b` where `A` is `self`, `b`
110
+ /// is the argument, and `x` is the successful result.
111
+ fn solve_h < S : Data < Elem = A > > ( & self , b : & ArrayBase < S , Ix1 > ) -> Result < Array1 < A > > {
112
+ let mut b = replicate ( b) ;
113
+ self . solve_h_mut ( & mut b) ?;
114
+ Ok ( b)
39
115
}
40
- fn solve_h_into < S : DataMut < Elem = A > > ( & self , mut a : ArrayBase < S , Ix1 > ) -> Result < ArrayBase < S , Ix1 > > {
41
- self . solve_h_mut ( & mut a) ?;
42
- Ok ( a)
116
+ /// Solves a system of linear equations `A^H * x = b` where `A` is `self`, `b`
117
+ /// is the argument, and `x` is the successful result.
118
+ fn solve_h_into < S : DataMut < Elem = A > > ( & self , mut b : ArrayBase < S , Ix1 > ) -> Result < ArrayBase < S , Ix1 > > {
119
+ self . solve_h_mut ( & mut b) ?;
120
+ Ok ( b)
43
121
}
122
+ /// Solves a system of linear equations `A^H * x = b` where `A` is `self`, `b`
123
+ /// is the argument, and `x` is the successful result.
44
124
fn solve_h_mut < ' a , S : DataMut < Elem = A > > ( & self , & ' a mut ArrayBase < S , Ix1 > ) -> Result < & ' a mut ArrayBase < S , Ix1 > > ;
45
125
}
46
126
127
+ /// Represents the LU factorization of a matrix `A` as `A = P*L*U`.
47
128
pub struct Factorized < S : Data > {
129
+ /// The factors `L` and `U`; the unit diagonal elements of `L` are not
130
+ /// stored.
48
131
pub a : ArrayBase < S , Ix2 > ,
132
+ /// The pivot indices that define the permutation matrix `P`.
49
133
pub ipiv : Pivot ,
50
134
}
51
135
@@ -134,6 +218,7 @@ where
134
218
A : Scalar ,
135
219
S : DataMut < Elem = A > ,
136
220
{
221
+ /// Computes the inverse of the factorized matrix.
137
222
pub fn into_inverse ( mut self ) -> Result < ArrayBase < S , Ix2 > > {
138
223
unsafe {
139
224
A :: inv (
@@ -146,11 +231,17 @@ where
146
231
}
147
232
}
148
233
234
+ /// An interface for computing LU factorizations of matrix refs.
149
235
pub trait Factorize < S : Data > {
236
+ /// Computes the LU factorization `A = P*L*U`, where `P` is a permutation
237
+ /// matrix.
150
238
fn factorize ( & self ) -> Result < Factorized < S > > ;
151
239
}
152
240
241
+ /// An interface for computing LU factorizations of matrices.
153
242
pub trait FactorizeInto < S : Data > {
243
+ /// Computes the LU factorization `A = P*L*U`, where `P` is a permutation
244
+ /// matrix.
154
245
fn factorize_into ( self ) -> Result < Factorized < S > > ;
155
246
}
156
247
@@ -180,13 +271,17 @@ where
180
271
}
181
272
}
182
273
274
+ /// An interface for inverting matrix refs.
183
275
pub trait Inverse {
184
276
type Output ;
277
+ /// Computes the inverse of the matrix.
185
278
fn inv ( & self ) -> Result < Self :: Output > ;
186
279
}
187
280
281
+ /// An interface for inverting matrices.
188
282
pub trait InverseInto {
189
283
type Output ;
284
+ /// Computes the inverse of the matrix.
190
285
fn inv_into ( self ) -> Result < Self :: Output > ;
191
286
}
192
287
0 commit comments