visualdynamics.core.sparse_solve¶
sparse_solve
¶
A sparse symmetric matrix factored once and solved many times, by the fastest solver the machine has.
The modal solve of a large model factors (K - sigma M) once and solves with it a few hundred times: every Lanczos step and every polish step is a solve. On macOS the factorization is Apple's, in the Accelerate framework every Mac carries (Sparse Solvers: a supernodal Cholesky, or LDLT when the matrix is not positive definite), reached through ctypes from the layouts in its public header. On Windows and Linux on Intel and AMD processors it is PARDISO, the multithreaded supernodal solver in Intel's oneMKL, through pypardiso (Cholesky, or LDLT with Bunch-Kaufman pivoting). Everywhere else, and wherever those refuse a matrix, it is SuperLU's LU through scipy, told the matrix is symmetric so it orders and pivots for that.
Classes:
| Name | Description |
|---|---|
SuperLUFactor |
SuperLU's factorization of a symmetric matrix, through scipy. |
AccelerateFactor |
Apple's supernodal factorization of a symmetric matrix: Cholesky, |
PardisoFactor |
PARDISO's supernodal factorization of a symmetric matrix: |
Functions:
| Name | Description |
|---|---|
probe_backward_error |
|A x - b| / |b| for one solve with a fixed right-hand side, the |
count_below |
How many eigenvalues of K phi = lambda M phi lie below |
expected_backend |
The backend this machine should factor with: 'accelerate' on a |
check |
Check that this installation factors with the solver it should. |
factor_symmetric |
The matrix factored by the fastest solver here that takes it: |
Classes¶
SuperLUFactor
¶
SuperLU's factorization of a symmetric matrix, through scipy.
Methods:
| Name | Description |
|---|---|
solve |
X with A X = |
Source code in src/visualdynamics/core/sparse_solve.py
AccelerateFactor
¶
Apple's supernodal factorization of a symmetric matrix: Cholesky, or LDLT when the matrix is not positive definite.
Raises ValueError when Accelerate refuses the matrix, naming its
status, so the caller can fall back.
Methods:
| Name | Description |
|---|---|
solve |
X with A X = |
Source code in src/visualdynamics/core/sparse_solve.py
Methods:¶
solve
¶
X with A X = rhs, for one right-hand side or a block of
them, in the shape rhs came in.
Source code in src/visualdynamics/core/sparse_solve.py
PardisoFactor
¶
PARDISO's supernodal factorization of a symmetric matrix: Cholesky, or LDLT when the matrix is not positive definite.
Raises ValueError when PARDISO is not available or refuses the
matrix, so the caller can fall back.
Methods:
| Name | Description |
|---|---|
solve |
X with A X = |
Source code in src/visualdynamics/core/sparse_solve.py
Functions:¶
probe_backward_error
¶
|A x - b| / |b| for one solve with a fixed right-hand side, the cosines of the row numbers; infinite when the answer is not.
Source code in src/visualdynamics/core/sparse_solve.py
count_below
¶
How many eigenvalues of K phi = lambda M phi lie below shift,
read off the signs of one factorization of K - shift M.
By Sylvester's law of inertia, a symmetric matrix factored as L D Lᵀ has as many negative entries in D as it has negative eigenvalues, and the negative eigenvalues of K - shift M are the modes below the shift (M positive definite). Where PARDISO is available its LDLT reports the count itself; Bunch-Kaufman's 2 x 2 pivots keep the count. Elsewhere SuperLU in symmetric mode with no pivoting off the diagonal is that factorization, its U's diagonal being D, which is why the threshold is zero here and not the factor the solves use. A pivot within round-off of zero, from a shift on top of an eigenvalue, has a sign that is round-off, so a caller allows the count one either way.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stiffness
|
scipy.sparse matrix
|
K and M, symmetric, M positive definite. |
required |
mass
|
scipy.sparse matrix
|
K and M, symmetric, M positive definite. |
required |
shift
|
float
|
The eigenvalue to count below, (rad/s)². |
required |
Returns:
| Type | Description |
|---|---|
int
|
The count, rigid-body modes included when the shift is above zero. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the factorization fails, had to pivot off the diagonal or perturbed a pivot, so its signs are not the inertia. |
References
A standard method, used here to size the search up to a frequency:
- J. J. Sylvester, A demonstration of the theorem that every homogeneous quadratic polynomial is reducible by real orthogonal substitutions to the form of a sum of positive and negative squares, Philosophical Magazine, 1852.
Source code in src/visualdynamics/core/sparse_solve.py
expected_backend
¶
The backend this machine should factor with: 'accelerate' on a
Mac, 'pardiso' on x86-64 Windows and Linux (where pypardiso is a
dependency), 'superlu' anywhere else.
Source code in src/visualdynamics/core/sparse_solve.py
check
¶
Check that this installation factors with the solver it should.
visualdynamics --check-solver runs this and exits with the
returned code. The packaged builds are tested with it, because a
bundle that leaves oneMKL out still solves, through SuperLU, many
times slower on a large model.
Returns:
| Type | Description |
|---|---|
tuple of (int, str)
|
0 and the backend, with the library it loaded, when a small
model's factorization took |
Source code in src/visualdynamics/core/sparse_solve.py
factor_symmetric
¶
factor_symmetric(matrix: Any) -> AccelerateFactor | PardisoFactor | SuperLUFactor
The matrix factored by the fastest solver here that takes it:
Accelerate on a Mac, PARDISO on x86-64 Windows and Linux, else
SuperLU. Each answers solve(rhs) and shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
matrix
|
sparse matrix
|
Square and symmetric. |
required |
Returns:
| Type | Description |
|---|---|
(AccelerateFactor, PardisoFactor or SuperLUFactor)
|
|