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)