Source code for femorph_solver.solvers.linear._umfpack

"""UMFPACK sparse LU via ``scikit-umfpack``.

UMFPACK tends to be faster than SuperLU on unsymmetric
sparse problems with moderate fill-in.  Ships as a separate pip package
because it links against the SuiteSparse system library.

References
----------
- Davis, T. A.  "Algorithm 832: UMFPACK V4.3 — An Unsymmetric-Pattern
  Multifrontal Method."  ACM Trans. Math. Softw. 30 (2), 196-199
  (2004).  [the shipped multifrontal algorithm]
- Davis, T. A. & Duff, I. S.  "An Unsymmetric-Pattern Multifrontal
  Method for Sparse LU Factorization."  SIAM J. Matrix Anal. Appl.
  18 (1), 140-158 (1997).  [foundational method paper]
"""

from __future__ import annotations

from typing import ClassVar

import numpy as np

from ._base import LinearSolverBase

try:
    from scikits.umfpack import UMFPACK_A, UmfpackContext

    _HAVE = True
except ImportError:
    _HAVE = False
    UMFPACK_A = 0  # never used, but keeps the symbol defined when unavailable


[docs] class UMFPACKSolver(LinearSolverBase): """UMFPACK LU factorization via scikit-umfpack.""" name: ClassVar[str] = "umfpack" kind: ClassVar[str] = "direct" spd_only: ClassVar[bool] = False install_hint: ClassVar[str] = ( "install SuiteSparse system library + `pip install scikit-umfpack`" )
[docs] @staticmethod def available() -> bool: return _HAVE
def _factor(self, A): A = A.tocsc().astype(np.float64) self._A = A self._ctx = UmfpackContext() self._ctx.numeric(A)
[docs] def solve(self, b: np.ndarray) -> np.ndarray: return self._ctx.solve(UMFPACK_A, self._A, b, autoTranspose=True)