1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! Implementation of ?getrf - LU factorization with partial pivoting
use lapack::{cgetrf, dgetrf, sgetrf, zgetrf};
use crate::base_types::LapackResult;
use crate::base_types::{LapackError, c32, c64};
/// ?getrf - LU factorization with partial pivoting.
///
/// **Arguments:**
///
/// - `m`: Number of rows in the matrix `a`.
/// - `n`: Number of columns in the matrix `a`.
/// - `a`: The matrix to be factored, stored in column-major order.
/// - `ipiv`: Output vector of pivot indices, which indicates the row swaps performed during.
/// `ipiv` must have length `min(m, n)`.
/// - `lda`: Leading dimension of the matrix `a`.
///
pub trait Getrf: Sized {
/// Perform LU factorization of a matrix `a` with dimensions `m` x `n`.
fn getrf(m: usize, n: usize, a: &mut [Self], lda: usize, ipiv: &mut [i32]) -> LapackResult<()>;
}
macro_rules! impl_getrf {
($scalar:ty, $getrf:expr) => {
impl Getrf for $scalar {
fn getrf(
m: usize,
n: usize,
a: &mut [$scalar],
lda: usize,
ipiv: &mut [i32],
) -> LapackResult<()> {
let k = std::cmp::min(m, n);
let mut info = 0;
assert!(
lda >= std::cmp::max(1, m),
"Require `lda` {} >= `max(1, M)` {} .",
lda,
std::cmp::max(1, m)
);
assert_eq!(
a.len(),
lda * n,
"Require `a.len()` {} == `lda * n` {}.",
a.len(),
lda * n,
);
assert_eq!(
ipiv.len(),
k,
"Require `ipiv.len()` {} == `min(m, n)` {}.",
ipiv.len(),
k,
);
unsafe {
$getrf(m as i32, n as i32, a, lda as i32, ipiv, &mut info);
}
if info != 0 {
Err(LapackError::LapackInfoCode(info))
} else {
Ok(())
}
}
}
};
}
impl_getrf!(f32, sgetrf);
impl_getrf!(f64, dgetrf);
impl_getrf!(c32, cgetrf);
impl_getrf!(c64, zgetrf);