low_rank_toolbox.krylov.solvers
Matrix Equation Solvers.
This submodule provides iterative solvers for large-scale matrix equations using Krylov subspace methods. These solvers are efficient for large sparse matrices where direct methods would be computationally prohibitive.
Functions
solve_sylvester : Solve the Sylvester equation AX + XB = C solve_lyapunov : Solve the Lyapunov equation AX + XA^T = C
Author: Benjamin Carrel, University of Geneva
- low_rank_toolbox.krylov.solvers.solve_lyapunov(A, C, tol=1e-12, max_iter=None, is_symmetric=None, krylov_kwargs=None)[source]
Efficient low-rank compatible solver for the Lyapunov equation.
Find X such that AX + XA^H = C.
This function is a wrapper that selects the appropriate solver based on the types of A and C.
For lower computational cost, if A and C are symmetric, set is_symmetric=True. This enables the use of the Lanczos algorithm (3-term recurrence) instead of Arnoldi (full orthogonalization), approximately halving the computational cost and memory usage per iteration.
- Parameters:
A (ndarray | spmatrix) – The matrix A of shape (n, n)
C (ndarray | LowRankMatrix) – The matrix C of shape (n, n)
tol (float, optional) – Convergence tolerance for Krylov solver, by default 1e-12
max_iter (int, optional) – Maximum iterations for Krylov solver, by default None
is_symmetric (bool, optional) – If True, use symmetric solver (only for sparse A and low-rank C). Exploits symmetry using Lanczos algorithm for ~2x speedup. If None, symmetry is auto-detected (with efficiency warning).
krylov_kwargs (dict, optional) – Krylov space configuration (see solve_sparse_low_rank_symmetric_lyapunov or solve_sparse_low_rank_non_symmetric_lyapunov for details)
- Returns:
The solution X, either dense or low-rank and symmetric if and only if C is symmetric.
- Return type:
ndarray | LowRankMatrix
Examples
>>> import numpy as np >>> from scipy.sparse import csr_matrix >>> from low_rank_toolbox import LowRankMatrix >>> from low_rank_toolbox.krylov import solve_lyapunov >>> # Small dense case >>> A_small = np.array([[4, 1], [1, 3]]) >>> C_small = np.array([[1, 0], [0, 1]]) >>> X_small = solve_lyapunov(A_small, C_small) >>> # Verify: AX + XA = C >>> np.allclose(A_small @ X_small + X_small @ A_small, C_small) True >>> # Large sparse case with low-rank RHS >>> from scipy.sparse import diags >>> n = 100 >>> A = diags([1, 4, 1], [-1, 0, 1], shape=(n, n), format='csr') >>> U = np.zeros((n, 1)) >>> U[0, 0] = 1.0 >>> C = LowRankMatrix(U, U.T) >>> X = solve_lyapunov(A, C, is_symmetric=True, tol=1e-10) >>> # Solution is low-rank and symmetric >>> type(X).__name__ 'SVD' >>> X.rank <= n # Much lower rank than n True
- low_rank_toolbox.krylov.solvers.solve_sylvester(A, B, C, tol=1e-12, max_iter=None, krylov_kwargs=None, is_A_symmetric=None, is_B_symmetric=None)[source]
Efficient low-rank compatible solver for the Sylvester equation.
Find X such that AX + XB = C.
This function is a wrapper that selects the appropriate solver based on the types of A, B, and C.
- Parameters:
A (ndarray | spmatrix) – Matrix of shape (m, m)
B (ndarray | spmatrix) – Matrix of shape (n, n)
C (ndarray | LowRankMatrix) – Right-hand side of shape (m, n)
tol (float, optional) – Convergence tolerance for Krylov solver, by default 1e-12
max_iter (int, optional) – Maximum iterations for Krylov solver, by default None
krylov_kwargs (dict, optional) – Krylov space configuration for sparse low-rank solver
is_A_symmetric (bool, optional) – If True, A is symmetric. Auto-detected if None.
is_B_symmetric (bool, optional) – If True, B is symmetric. Auto-detected if None.
- Returns:
Solution X of shape (m, n), either dense or low-rank depending on inputs
- Return type:
ndarray | LowRankMatrix
Examples
>>> import numpy as np >>> from scipy.sparse import csr_matrix >>> from low_rank_toolbox import LowRankMatrix >>> from low_rank_toolbox.krylov import solve_sylvester >>> # Small dense case >>> A_small = np.array([[4, 1], [1, 3]]) >>> B_small = np.array([[2, 1], [1, 1]]) >>> C_small = np.array([[1, 0], [0, 1]]) >>> X_small = solve_sylvester(A_small, B_small, C_small) >>> # Verify: AX + XB = C >>> np.allclose(A_small @ X_small + X_small @ B_small, C_small) True >>> # Large sparse case with low-rank RHS >>> from scipy.sparse import diags >>> n, m = 100, 80 >>> A = diags([1, 4, 1], [-1, 0, 1], shape=(n, n), format='csr') >>> B = diags([1, 2, 1], [-1, 0, 1], shape=(m, m), format='csr') >>> U = np.zeros((n, 1)) >>> U[0, 0] = 1.0 >>> V = np.zeros((m, 1)) >>> V[0, 0] = 1.0 >>> C = LowRankMatrix(U, V.T) >>> X = solve_sylvester(A, B, C, tol=1e-10) >>> # Solution is low-rank >>> type(X).__name__ 'SVD' >>> X.rank <= 50 True
Modules
Krylov-based solvers for the Lyapunov equation. |
|
Krylov-based solvers for the Sylvester equation. |