1
+ //! Solve linear equations using LU-decomposition
2
+
1
3
use crate :: { error:: * , layout:: MatrixLayout , * } ;
2
4
use cauchy:: * ;
3
5
use num_traits:: { ToPrimitive , Zero } ;
4
6
5
- #[ cfg_attr( doc, katexit:: katexit) ]
6
- /// Solve linear equations using LU-decomposition
7
- ///
8
- /// For a given matrix $A$, LU decomposition is described as $A = PLU$ where:
9
- ///
10
- /// - $L$ is lower matrix
11
- /// - $U$ is upper matrix
12
- /// - $P$ is permutation matrix represented by [Pivot]
7
+ /// Helper trait to abstract `*getrf` LAPACK routines for implementing [Lapack::lu]
13
8
///
14
- /// This is designed as two step computation according to LAPACK API:
9
+ /// LAPACK correspondance
10
+ /// ----------------------
15
11
///
16
- /// 1. Factorize input matrix $A$ into $L$, $U$, and $P$.
17
- /// 2. Solve linear equation $Ax = b$ or compute inverse matrix $A^{-1}$
18
- /// using the output of LU decomposition.
12
+ /// | f32 | f64 | c32 | c64 |
13
+ /// |:-------|:-------|:-------|:-------|
14
+ /// | sgetrf | dgetrf | cgetrf | zgetrf |
19
15
///
20
16
pub trait LuImpl : Scalar {
21
17
fn lu ( l : MatrixLayout , a : & mut [ Self ] ) -> Result < Pivot > ;
@@ -57,6 +53,36 @@ impl_lu!(c32, lapack_sys::cgetrf_);
57
53
impl_lu ! ( f64 , lapack_sys:: dgetrf_) ;
58
54
impl_lu ! ( f32 , lapack_sys:: sgetrf_) ;
59
55
56
+ /// Helper trait to abstract `*getrs` LAPACK routines for implementing [Lapack::solve]
57
+ ///
58
+ /// If the array has C layout, then it needs to be handled
59
+ /// specially, since LAPACK expects a Fortran-layout array.
60
+ /// Reinterpreting a C layout array as Fortran layout is
61
+ /// equivalent to transposing it. So, we can handle the "no
62
+ /// transpose" and "transpose" cases by swapping to "transpose"
63
+ /// or "no transpose", respectively. For the "Hermite" case, we
64
+ /// can take advantage of the following:
65
+ ///
66
+ /// ```text
67
+ /// A^H x = b
68
+ /// ⟺ conj(A^T) x = b
69
+ /// ⟺ conj(conj(A^T) x) = conj(b)
70
+ /// ⟺ conj(conj(A^T)) conj(x) = conj(b)
71
+ /// ⟺ A^T conj(x) = conj(b)
72
+ /// ```
73
+ ///
74
+ /// So, we can handle this case by switching to "no transpose"
75
+ /// (which is equivalent to transposing the array since it will
76
+ /// be reinterpreted as Fortran layout) and applying the
77
+ /// elementwise conjugate to `x` and `b`.
78
+ ///
79
+ /// LAPACK correspondance
80
+ /// ----------------------
81
+ ///
82
+ /// | f32 | f64 | c32 | c64 |
83
+ /// |:-------|:-------|:-------|:-------|
84
+ /// | sgetrs | dgetrs | cgetrs | zgetrs |
85
+ ///
60
86
pub trait SolveImpl : Scalar {
61
87
fn solve ( l : MatrixLayout , t : Transpose , a : & [ Self ] , p : & Pivot , b : & mut [ Self ] ) -> Result < ( ) > ;
62
88
}
@@ -71,26 +97,6 @@ macro_rules! impl_solve {
71
97
ipiv: & Pivot ,
72
98
b: & mut [ Self ] ,
73
99
) -> Result <( ) > {
74
- // If the array has C layout, then it needs to be handled
75
- // specially, since LAPACK expects a Fortran-layout array.
76
- // Reinterpreting a C layout array as Fortran layout is
77
- // equivalent to transposing it. So, we can handle the "no
78
- // transpose" and "transpose" cases by swapping to "transpose"
79
- // or "no transpose", respectively. For the "Hermite" case, we
80
- // can take advantage of the following:
81
- //
82
- // ```text
83
- // A^H x = b
84
- // ⟺ conj(A^T) x = b
85
- // ⟺ conj(conj(A^T) x) = conj(b)
86
- // ⟺ conj(conj(A^T)) conj(x) = conj(b)
87
- // ⟺ A^T conj(x) = conj(b)
88
- // ```
89
- //
90
- // So, we can handle this case by switching to "no transpose"
91
- // (which is equivalent to transposing the array since it will
92
- // be reinterpreted as Fortran layout) and applying the
93
- // elementwise conjugate to `x` and `b`.
94
100
let ( t, conj) = match l {
95
101
MatrixLayout :: C { .. } => match t {
96
102
Transpose :: No => ( Transpose :: Transpose , false ) ,
@@ -138,11 +144,21 @@ impl_solve!(f32, lapack_sys::sgetrs_);
138
144
impl_solve ! ( c64, lapack_sys:: zgetrs_) ;
139
145
impl_solve ! ( c32, lapack_sys:: cgetrs_) ;
140
146
147
+ /// Working memory for computing inverse matrix
141
148
pub struct InvWork < T : Scalar > {
142
149
pub layout : MatrixLayout ,
143
150
pub work : Vec < MaybeUninit < T > > ,
144
151
}
145
152
153
+ /// Helper trait to abstract `*getri` LAPACK rotuines for implementing [Lapack::inv]
154
+ ///
155
+ /// LAPACK correspondance
156
+ /// ----------------------
157
+ ///
158
+ /// | f32 | f64 | c32 | c64 |
159
+ /// |:-------|:-------|:-------|:-------|
160
+ /// | sgetri | dgetri | cgetri | zgetri |
161
+ ///
146
162
pub trait InvWorkImpl : Sized {
147
163
type Elem : Scalar ;
148
164
fn new ( layout : MatrixLayout ) -> Result < Self > ;
0 commit comments