solvers package#
Submodules#
PyHydroGeophysX.solvers.linear_solvers module#
Linear solvers for geophysical inversion.
- class PyHydroGeophysX.solvers.linear_solvers.CGLSSolver(max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.0, verbose=False)[source]#
Bases:
LinearSolverCGLS (Conjugate Gradient Least Squares) solver.
- class PyHydroGeophysX.solvers.linear_solvers.IterativeRefinement(max_iterations=5, tolerance=1e-10, use_double_precision=True)[source]#
Bases:
objectIterative refinement to improve accuracy of a solution to a linear system.
- class PyHydroGeophysX.solvers.linear_solvers.LSQRSolver(max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.0, verbose=False)[source]#
Bases:
LinearSolverLSQR solver for least squares problems.
- class PyHydroGeophysX.solvers.linear_solvers.LinearSolver(method='cgls', max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.0, verbose=False)[source]#
Bases:
objectBase class for linear system solvers.
- class PyHydroGeophysX.solvers.linear_solvers.RRLSQRSolver(max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.1, verbose=False)[source]#
Bases:
LinearSolverRegularized LSQR solver.
- class PyHydroGeophysX.solvers.linear_solvers.RRLSSolver(max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.0, verbose=False)[source]#
Bases:
LinearSolverRange-Restricted Least Squares solver.
- class PyHydroGeophysX.solvers.linear_solvers.StackedSystem(*args: Any, **kwargs: Any)[source]#
Bases:
LinearOperatorA stacked least-squares system
[B_1; B_2; ...]held as its row blocks.An inversion’s Gauss-Newton system,
[W_d J; sqrt(lambda) W_m; ...], is a dense Jacobian over a sparse regularization. Stacked into one dense array the regularization rows cost C x n doubles - 1.5 n^2 for a pyGIMLi smoothness operator, 2.7 GB at n = 15000 - and every product with the system multiplied their zeros. Held as blocks, each block keeps the form it was built in.The least-squares solvers only multiply by the system and its transpose, which this does as a
LinearOperator.normal_matrixgives an SPD solverA^T Asummed block by block,columnskeeps a subset of the columns (cells held fixed), andtoarrayassembles the dense array for a solver that needs one, such as the GPU path.- columns(keep: Any) StackedSystem[source]#
The system restricted to the columns
keepselects.
- class PyHydroGeophysX.solvers.linear_solvers.TikhonvRegularization(regularization_matrix=None, alpha=1.0, regularization_type='identity')[source]#
Bases:
objectTikhonov regularization for ill-posed problems.
- PyHydroGeophysX.solvers.linear_solvers.block_tridiagonal_cholesky_solve(diagonal: Any, lower: Any, b: Any, *, overwrite: bool = False) Any[source]#
Solve
H x = bfor a symmetric positive definite block-tridiagonalH.diagonal[k]is the dense blockH[k, k];lower[k]is the blockH[k + 1, k]below it, either a dense matrix or a vector standing for that diagonal matrix - the form in which a temporal-difference penalty couples adjacent surveys of a time-lapse inversion.The Cholesky factor of such a matrix is block lower-bidiagonal, so this is the dense Cholesky factorization with its zero blocks left out: a Cholesky of each Schur complement, a triangular solve for the block below it and a symmetric rank update of the next diagonal block - the operations a blocked dense factorization performs on the blocks that are not zero, in O(N n^3) work and O(N n^2) memory rather than O((N n)^3) and O((N n)^2).
With
overwritethe factors are written into thediagonalblocks (float64, contiguous) and nothing of that size is allocated. A block that is not positive definite raisesLinAlgError: as forspd_choleskywithoverwrite_a=True, there is no ridge retry.>>> H = np.array([[4.0, 1.0, -0.5, 0.0], [1.0, 3.0, 0.0, -0.5], ... [-0.5, 0.0, 5.0, 2.0], [0.0, -0.5, 2.0, 6.0]]) >>> x = block_tridiagonal_cholesky_solve( ... [H[:2, :2], H[2:, 2:]], [np.array([-0.5, -0.5])], np.ones(4)) >>> bool(np.allclose(H @ x.ravel(), 1.0)) True
- PyHydroGeophysX.solvers.linear_solvers.direct_solver(A: Any, b: Any, method: Any = 'lu', **kwargs: Any) Any[source]#
Solve a linear system using direct methods.
- Parameters:
A – System matrix
b – Right-hand side vector
method – Direct solver method (‘lu’, ‘qr’, ‘svd’, ‘cholesky’)
**kwargs – Additional parameters for specific methods
- Returns:
Solution vector
- PyHydroGeophysX.solvers.linear_solvers.generalized_solver(A: Any, b: Any, method: Any = 'cgls', x: Any = None, maxiter: Any = 200, tol: Any = 1e-08, verbose: Any = False, damp: Any = 0.0, use_gpu: Any = False, parallel: Any = False, n_jobs: Any = -1, *, overwrite_a: Any = False) Any[source]#
Generalized solver for Ax = b with optional GPU acceleration and parallelism.
Parameters:#
- Aarray_like or sparse matrix
The system matrix. Two shapes of problem reach this function, and they need opposite solver families:
A stacked least-squares system,
[W_d J; sqrt(lambda) W_m; ...], with a matching stacked right-hand side. Use a least-squares method.A Gauss-Newton normal matrix,
J^T W_d^T W_d J + lambda W_m^T W_m + ..., which is square and symmetric (positive definite when the combined operators constrain every model direction), paired with a gradient right-hand side-g. Use an SPD method. A least-squares method applied to this case solvesA^T A x = A^T binstead, which squares the condition number and spends two matrix-vector products per iteration where one would do; passing one is warned about once per process.
- barray_like
Right-hand side vector.
- methodstr, optional
Solver method. Default is ‘cgls’. Iterative: ‘lsqr’, ‘rrlsqr’, ‘cgls’, ‘rrls’ SciPy: ‘scipy_lsqr’, ‘scipy_lsmr’, ‘precond_lsmr’ SPD, CPU-only, for a square symmetric positive definite
A: ‘spd_cholesky’ (direct factorization), ‘spd_cg’ (iterative, for a matrix too large to factor)- xarray_like, optional
Initial guess for the solution. If None, zeros are used.
- maxiterint, optional
Maximum number of iterations.
- tolfloat, optional
Convergence tolerance.
- verbosebool, optional
Print progress information every 10 iterations.
- dampfloat, optional
Damping factor (Tikhonov regularization).
- use_gpubool, optional
Use GPU acceleration with CuPy (if available).
- parallelbool, optional
Use parallel CPU computations.
- n_jobsint, optional
Number of parallel jobs (if parallel is True).
- overwrite_abool, optional
Keyword-only. ‘spd_cholesky’ only. Factor in the caller’s own buffer, allowing compatible input storage to be overwritten. SciPy may still copy or allocate workspace. Set it only when
Ais not needed after the call. Ignored by every other method.
Returns:#
- xarray_like
The computed solution vector.
- PyHydroGeophysX.solvers.linear_solvers.get_optimal_solver(A: Any, b: Any, estimate_condition: Any = True, time_limit: Any = None, memory_limit: Any = None) Any[source]#
Automatically select the optimal solver for a given linear system.
- Parameters:
A – System matrix
b – Right-hand side vector
estimate_condition – Whether to estimate condition number
time_limit – Maximum allowed solution time (seconds)
memory_limit – Maximum allowed memory usage (bytes)
- Returns:
Tuple of (solver_object, solver_info)
- PyHydroGeophysX.solvers.linear_solvers.spd_solve(A: Any, B: Any, what: Any = 'matrix') Any[source]#
Solve
A X = Bfor a symmetric positive definiteA.Use this wherever the code would otherwise write
inv(A) @ Borpinv(A) @ B. Three reasons it is the better default for a covariance or a Gauss-Newton normal matrix:Cholesky solves the positive-definite system without constructing an explicit SVD pseudoinverse. Runtime depends on size and BLAS backend.
pinvdiscards singular values below itsrcondwithout saying so. On a normal matrix, whose condition number is already the square of the Jacobian’s, that cut can land inside the real spectrum.Finite-precision inverse construction can introduce asymmetry or small negative eigenvalues in ill-conditioned covariance calculations.
A matrix that is genuinely not positive definite falls back to
pinvwith a warning namingwhat, so a caller learns which quantity degraded rather than silently receiving a worse answer.
- PyHydroGeophysX.solvers.linear_solvers.symmetrize(A: Any) Any[source]#
Return
(A + A.T) / 2.A covariance or resolution matrix is symmetric in exact arithmetic. Products of the form
J^T C Jaccumulate asymmetry at the rounding level, andnp.random.Generator.multivariate_normalrejects the result outright, so the halves are averaged before the matrix leaves the function that built it.
PyHydroGeophysX.solvers.solver module#
Deprecated in 0.5.0 and removed in 0.6.0: a compatibility path whose
generalized_solver warns and calls
PyHydroGeophysX.solvers.linear_solvers.generalized_solver(), documented
above.
Module contents#
Solver exports for inversion and regularized linear-system utilities.
- class PyHydroGeophysX.solvers.CGLSSolver(max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.0, verbose=False)[source]#
Bases:
LinearSolverCGLS (Conjugate Gradient Least Squares) solver.
- class PyHydroGeophysX.solvers.IterativeRefinement(max_iterations=5, tolerance=1e-10, use_double_precision=True)[source]#
Bases:
objectIterative refinement to improve accuracy of a solution to a linear system.
- class PyHydroGeophysX.solvers.LSQRSolver(max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.0, verbose=False)[source]#
Bases:
LinearSolverLSQR solver for least squares problems.
- class PyHydroGeophysX.solvers.LinearSolver(method='cgls', max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.0, verbose=False)[source]#
Bases:
objectBase class for linear system solvers.
- class PyHydroGeophysX.solvers.RRLSQRSolver(max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.1, verbose=False)[source]#
Bases:
LinearSolverRegularized LSQR solver.
- class PyHydroGeophysX.solvers.RRLSSolver(max_iterations=200, tolerance=1e-08, use_gpu=False, parallel=False, n_jobs=-1, damping=0.0, verbose=False)[source]#
Bases:
LinearSolverRange-Restricted Least Squares solver.
- class PyHydroGeophysX.solvers.TikhonvRegularization(regularization_matrix=None, alpha=1.0, regularization_type='identity')[source]#
Bases:
objectTikhonov regularization for ill-posed problems.
- PyHydroGeophysX.solvers.direct_solver(A: Any, b: Any, method: Any = 'lu', **kwargs: Any) Any[source]#
Solve a linear system using direct methods.
- Parameters:
A – System matrix
b – Right-hand side vector
method – Direct solver method (‘lu’, ‘qr’, ‘svd’, ‘cholesky’)
**kwargs – Additional parameters for specific methods
- Returns:
Solution vector
- PyHydroGeophysX.solvers.generalized_solver(A: Any, b: Any, method: Any = 'cgls', x: Any = None, maxiter: Any = 200, tol: Any = 1e-08, verbose: Any = False, damp: Any = 0.0, use_gpu: Any = False, parallel: Any = False, n_jobs: Any = -1, *, overwrite_a: Any = False) Any[source]#
Generalized solver for Ax = b with optional GPU acceleration and parallelism.
Parameters:#
- Aarray_like or sparse matrix
The system matrix. Two shapes of problem reach this function, and they need opposite solver families:
A stacked least-squares system,
[W_d J; sqrt(lambda) W_m; ...], with a matching stacked right-hand side. Use a least-squares method.A Gauss-Newton normal matrix,
J^T W_d^T W_d J + lambda W_m^T W_m + ..., which is square and symmetric (positive definite when the combined operators constrain every model direction), paired with a gradient right-hand side-g. Use an SPD method. A least-squares method applied to this case solvesA^T A x = A^T binstead, which squares the condition number and spends two matrix-vector products per iteration where one would do; passing one is warned about once per process.
- barray_like
Right-hand side vector.
- methodstr, optional
Solver method. Default is ‘cgls’. Iterative: ‘lsqr’, ‘rrlsqr’, ‘cgls’, ‘rrls’ SciPy: ‘scipy_lsqr’, ‘scipy_lsmr’, ‘precond_lsmr’ SPD, CPU-only, for a square symmetric positive definite
A: ‘spd_cholesky’ (direct factorization), ‘spd_cg’ (iterative, for a matrix too large to factor)- xarray_like, optional
Initial guess for the solution. If None, zeros are used.
- maxiterint, optional
Maximum number of iterations.
- tolfloat, optional
Convergence tolerance.
- verbosebool, optional
Print progress information every 10 iterations.
- dampfloat, optional
Damping factor (Tikhonov regularization).
- use_gpubool, optional
Use GPU acceleration with CuPy (if available).
- parallelbool, optional
Use parallel CPU computations.
- n_jobsint, optional
Number of parallel jobs (if parallel is True).
- overwrite_abool, optional
Keyword-only. ‘spd_cholesky’ only. Factor in the caller’s own buffer, allowing compatible input storage to be overwritten. SciPy may still copy or allocate workspace. Set it only when
Ais not needed after the call. Ignored by every other method.
Returns:#
- xarray_like
The computed solution vector.
- PyHydroGeophysX.solvers.get_optimal_solver(A: Any, b: Any, estimate_condition: Any = True, time_limit: Any = None, memory_limit: Any = None) Any[source]#
Automatically select the optimal solver for a given linear system.
- Parameters:
A – System matrix
b – Right-hand side vector
estimate_condition – Whether to estimate condition number
time_limit – Maximum allowed solution time (seconds)
memory_limit – Maximum allowed memory usage (bytes)
- Returns:
Tuple of (solver_object, solver_info)
- PyHydroGeophysX.solvers.spd_solve(A: Any, B: Any, what: Any = 'matrix') Any[source]#
Solve
A X = Bfor a symmetric positive definiteA.Use this wherever the code would otherwise write
inv(A) @ Borpinv(A) @ B. Three reasons it is the better default for a covariance or a Gauss-Newton normal matrix:Cholesky solves the positive-definite system without constructing an explicit SVD pseudoinverse. Runtime depends on size and BLAS backend.
pinvdiscards singular values below itsrcondwithout saying so. On a normal matrix, whose condition number is already the square of the Jacobian’s, that cut can land inside the real spectrum.Finite-precision inverse construction can introduce asymmetry or small negative eigenvalues in ill-conditioned covariance calculations.
A matrix that is genuinely not positive definite falls back to
pinvwith a warning namingwhat, so a caller learns which quantity degraded rather than silently receiving a worse answer.
- PyHydroGeophysX.solvers.symmetrize(A: Any) Any[source]#
Return
(A + A.T) / 2.A covariance or resolution matrix is symmetric in exact arithmetic. Products of the form
J^T C Jaccumulate asymmetry at the rounding level, andnp.random.Generator.multivariate_normalrejects the result outright, so the halves are averaged before the matrix leaves the function that built it.