bundles / scipy 1.17.1 / scipy / sparse / linalg / _isolve / lsqr / lsqr
function
scipy.sparse.linalg._isolve.lsqr:lsqr
Signature
def lsqr ( A , b , damp = 0.0 , atol = 1e-06 , btol = 1e-06 , conlim = 100000000.0 , iter_lim = None , show = False , calc_var = False , x0 = None ) Summary
Find the least-squares solution to a large, sparse, linear system of equations.
Extended Summary
The function solves Ax = b or min ||Ax - b||^2 or min ||Ax - b||^2 + d^2 ||x - x0||^2.
The matrix A may be square or rectangular (over-determined or under-determined), and may have any rank.
1. Unsymmetric equations -- solve Ax = b 2. Linear least squares -- solve Ax = b in the least-squares sense 3. Damped least squares -- solve ( A )*x = ( b ) ( damp*I ) ( damp*x0 ) in the least-squares sense
Parameters
A: {sparse array, ndarray, LinearOperator}Representation of an m-by-n matrix. Alternatively,
Acan be a linear operator which can produceAxandA^T xusing, e.g.,scipy.sparse.linalg.LinearOperator.b: array_like, shape (m,)Right-hand side vector
b.damp: floatDamping coefficient. Default is 0.
atol, btol: float, optionalStopping tolerances. lsqr continues iterations until a certain backward error estimate is smaller than some quantity depending on atol and btol. Let
r = b - Axbe the residual vector for the current approximate solutionx. IfAx = bseems to be consistent, lsqr terminates whennorm(r) <= atol * norm(A) * norm(x) + btol * norm(b). Otherwise, lsqr terminates whennorm(A^H r) <= atol * norm(A) * norm(r). If both tolerances are 1.0e-6 (default), the finalnorm(r)should be accurate to about 6 digits. (The finalxwill usually have fewer correct digits, depending oncond(A)and the size of LAMBDA.) Ifatolorbtolis None, a default value of 1.0e-6 will be used. Ideally, they should be estimates of the relative error in the entries ofAandbrespectively. For example, if the entries ofAhave 7 correct digits, setatol = 1e-7. This prevents the algorithm from doing unnecessary work beyond the uncertainty of the input data.conlim: float, optionalAnother stopping tolerance. lsqr terminates if an estimate of
cond(A)exceedsconlim. For compatible systemsAx = b,conlimcould be as large as 1.0e+12 (say). For least-squares problems, conlim should be less than 1.0e+8. Maximum precision can be obtained by settingatol = btol = conlim = zero, but the number of iterations may then be excessive. Default is 1e8.iter_lim: int, optionalExplicit limitation on number of iterations (for safety).
show: bool, optionalDisplay an iteration log. Default is False.
calc_var: bool, optionalWhether to estimate diagonals of
(A'A + damp^2*I)^{-1}.x0: array_like, shape (n,), optionalInitial guess of x, if None zeros are used. Default is None.
Returns
x: ndarray of floatThe final solution.
istop: intGives the reason for termination. 1 means x is an approximate solution to Ax = b. 2 means x approximately solves the least-squares problem.
itn: intIteration number upon termination.
r1norm: floatnorm(r), wherer = b - Ax.r2norm: floatsqrt( norm(r)^2 + damp^2 * norm(x - x0)^2 ). Equal to r1norm ifdamp == 0.anorm: floatEstimate of Frobenius norm of
Abar = [[A]; [damp*I]].acond: floatEstimate of
cond(Abar).arnorm: floatEstimate of
norm(A'@r - damp^2*(x - x0)).xnorm: floatnorm(x)var: ndarray of floatIf
calc_varis True, estimates all diagonals of(A'A)^{-1}(ifdamp == 0) or more generally(A'A + damp^2*I)^{-1}. This is well defined if A has full column rank ordamp > 0. (Not sure what var means ifrank(A) < nanddamp = 0.)
Notes
LSQR uses an iterative method to approximate the solution. The number of iterations required to reach a certain accuracy depends strongly on the scaling of the problem. Poor scaling of the rows or columns of A should therefore be avoided where possible.
For example, in problem 1 the solution is unaltered by row-scaling. If a row of A is very small or large compared to the other rows of A, the corresponding row of ( A b ) should be scaled up or down.
In problems 1 and 2, the solution x is easily recovered following column-scaling. Unless better information is known, the nonzero columns of A should be scaled so that they all have the same Euclidean norm (e.g., 1.0).
In problem 3, there is no freedom to re-scale if damp is nonzero. However, the value of damp should be assigned only after attention has been paid to the scaling of A.
The parameter damp is intended to help regularize ill-conditioned systems, by preventing the true solution from being very large. Another aid to regularization is provided by the parameter acond, which may be used to terminate iterations before the computed solution becomes very large.
If some initial estimate x0 is known and if damp == 0, one could proceed as follows:
Compute a residual vector
r0 = b - A@x0.Use LSQR to solve the system
A@dx = r0.Add the correction dx to obtain a final solution
x = x0 + dx.
This requires that x0 be available before and after the call to LSQR. To judge the benefits, suppose LSQR takes k1 iterations to solve A@x = b and k2 iterations to solve A@dx = r0. If x0 is "good", norm(r0) will be smaller than norm(b). If the same stopping tolerances atol and btol are used for each system, k1 and k2 will be similar, but the final solution x0 + dx should be more accurate. The only way to reduce the total work is to use a larger stopping tolerance for the second system. If some value btol is suitable for A@x = b, the larger value btol*norm(b)/norm(r0) should be suitable for A@dx = r0.
Preconditioning is another way to reduce the number of iterations. If it is possible to solve a related system M@x = b efficiently, where M approximates A in some helpful way (e.g. M - A has low rank or its elements are small relative to those of A), LSQR may converge more rapidly on the system A@M(inverse)@z = b, after which x can be recovered by solving M@x = z.
If A is symmetric, LSQR should not be used!
Alternatives are the symmetric conjugate-gradient method (cg) and/or SYMMLQ. SYMMLQ is an implementation of symmetric cg that applies to any symmetric A and will converge more rapidly than LSQR. If A is positive definite, there are other implementations of symmetric cg that require slightly less work per iteration than SYMMLQ (but will take the same number of iterations).
Examples
import numpy as np from scipy.sparse import csc_array from scipy.sparse.linalg import lsqr A = csc_array([[1., 0.], [1., 1.], [0., 1.]], dtype=float)✓
b = np.array([0., 0., 0.], dtype=float) x, istop, itn, normr = lsqr(A, b)[:4] istop✓
x
✗b = np.array([1., 0., -1.], dtype=float) x, istop, itn, r1norm = lsqr(A, b)[:4] istop x itn r1norm✓
b = np.array([1., 0.01, -1.], dtype=float) x, istop, itn, r1norm = lsqr(A, b)[:4] istop✓
x A.dot(x)-b✗
r1norm
✓Aliases
-
scipy.sparse.linalg.lsqr