1+ //! Solve linear equations using LU-decomposition
2+
13use crate :: { error:: * , layout:: MatrixLayout , * } ;
24use cauchy:: * ;
35use num_traits:: { ToPrimitive , Zero } ;
46
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]
138///
14- /// This is designed as two step computation according to LAPACK API:
9+ /// LAPACK correspondance
10+ /// ----------------------
1511///
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 |
1915///
2016pub trait LuImpl : Scalar {
2117 fn lu ( l : MatrixLayout , a : & mut [ Self ] ) -> Result < Pivot > ;
@@ -57,6 +53,36 @@ impl_lu!(c32, lapack_sys::cgetrf_);
5753impl_lu ! ( f64 , lapack_sys:: dgetrf_) ;
5854impl_lu ! ( f32 , lapack_sys:: sgetrf_) ;
5955
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+ ///
6086pub trait SolveImpl : Scalar {
6187 fn solve ( l : MatrixLayout , t : Transpose , a : & [ Self ] , p : & Pivot , b : & mut [ Self ] ) -> Result < ( ) > ;
6288}
@@ -71,26 +97,6 @@ macro_rules! impl_solve {
7197 ipiv: & Pivot ,
7298 b: & mut [ Self ] ,
7399 ) -> 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`.
94100 let ( t, conj) = match l {
95101 MatrixLayout :: C { .. } => match t {
96102 Transpose :: No => ( Transpose :: Transpose , false ) ,
@@ -138,11 +144,21 @@ impl_solve!(f32, lapack_sys::sgetrs_);
138144impl_solve ! ( c64, lapack_sys:: zgetrs_) ;
139145impl_solve ! ( c32, lapack_sys:: cgetrs_) ;
140146
147+ /// Working memory for computing inverse matrix
141148pub struct InvWork < T : Scalar > {
142149 pub layout : MatrixLayout ,
143150 pub work : Vec < MaybeUninit < T > > ,
144151}
145152
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+ ///
146162pub trait InvWorkImpl : Sized {
147163 type Elem : Scalar ;
148164 fn new ( layout : MatrixLayout ) -> Result < Self > ;
0 commit comments