Skip to main content

rlst_suitesparse/umfpack/
mod.rs

1//! Safe UMFPACK factorization and solve support for RLST CSR matrices.
2
3use rlst::{Array, MutableRawAccessArrayImpl, RawAccessArrayImpl};
4
5mod complex;
6mod csc;
7mod error;
8mod real;
9mod sys;
10
11#[cfg(test)]
12mod tests;
13
14pub use complex::UmfpackComplexNumeric;
15pub use error::{UmfpackError, UmfpackResult};
16pub use real::UmfpackNumeric;
17
18const UMFPACK_A: i32 = 0;
19const UMFPACK_WARNING_SINGULAR_MATRIX: i32 = 1;
20
21/// Non-error status produced while constructing an UMFPACK factorization.
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum UmfpackFactorizationStatus {
24    /// UMFPACK completed factorization without warnings.
25    Success,
26    /// UMFPACK produced a factorization for a singular matrix.
27    ///
28    /// This is a warning rather than a Rust error; a subsequent solve can still
29    /// return [`UmfpackError::NativeFailure`].
30    SingularMatrix,
31    /// UMFPACK produced an implementation-defined warning status.
32    Warning(i32),
33}
34
35/// Factorize an RLST CSR matrix with UMFPACK.
36///
37/// Import this trait and call [`factorize`](UmfpackFactorize::factorize) on a
38/// [`rlst::sparse::csr_mat::CsrMatrix<f64>`] or
39/// [`rlst::sparse::csr_mat::CsrMatrix<rlst::c64>`].
40pub trait UmfpackFactorize {
41    /// Concrete numeric factorization returned for the matrix scalar type.
42    type Numeric;
43
44    /// Convert this matrix from CSR to UMFPACK's CSC representation, perform
45    /// symbolic analysis, and create a numeric factorization.
46    ///
47    /// The matrix must be nonempty and square. Dimensions and indices must fit
48    /// UMFPACK's 64-bit index type. A singular factorization is returned
49    /// successfully and reported by the numeric object's `status` method.
50    fn factorize(&self) -> UmfpackResult<Self::Numeric>;
51}
52
53fn factorization_status(status: i32) -> UmfpackFactorizationStatus {
54    match status {
55        0 => UmfpackFactorizationStatus::Success,
56        UMFPACK_WARNING_SINGULAR_MATRIX => UmfpackFactorizationStatus::SingularMatrix,
57        status => UmfpackFactorizationStatus::Warning(status),
58    }
59}
60
61fn array_data<'a, Item, ArrayImpl>(
62    array: &'a Array<ArrayImpl, 1>,
63    name: &'static str,
64) -> UmfpackResult<&'a [Item]>
65where
66    ArrayImpl: RawAccessArrayImpl<Item, 1>,
67{
68    if !array.is_contiguous() {
69        return Err(UmfpackError::NonContiguousArray(name));
70    }
71    array.data().ok_or(UmfpackError::DataUnavailable(name))
72}
73
74fn array_data_mut<'a, Item, ArrayImpl>(
75    array: &'a mut Array<ArrayImpl, 1>,
76    name: &'static str,
77) -> UmfpackResult<&'a mut [Item]>
78where
79    ArrayImpl: MutableRawAccessArrayImpl<Item, 1>,
80{
81    if !array.is_contiguous() {
82        return Err(UmfpackError::NonContiguousArray(name));
83    }
84    array.data_mut().ok_or(UmfpackError::DataUnavailable(name))
85}