lsqr#
- scipy.sparse.linalg.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)[Quelle]#
Findet die kleinsten Quadrate Lösung eines großen, dünnbesetzten linearen Gleichungssystems.
Die Funktion löst
Ax = bodermin ||Ax - b||^2odermin ||Ax - b||^2 + d^2 ||x - x0||^2.Die Matrix A kann quadratisch oder rechteckig sein (überbestimmt oder unterbestimmt) und kann beliebigen Rang haben.
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
- Parameter:
- A{sparse array, ndarray, LinearOperator}
Repräsentation einer m-mal-n-Matrix. Alternativ kann
Aein linearer Operator sein, derAxundA^T xerzeugen kann, z. B. überscipy.sparse.linalg.LinearOperator.- barray_like, shape (m,)
Vektor der rechten Seite
b.- dampfloat
Dämpfungskoeffizient. Standard ist 0.
- atol, btolfloat, optional
Abbruch-Toleranzen.
lsqrsetzt die Iterationen fort, bis ein bestimmter Fehler in Rückwärtsrichtung kleiner als eine Größe ist, die von atol und btol abhängt. Seir = b - Axder Residuenvektor für die aktuelle ungefähre Lösungx. WennAx = bkonsistent zu sein scheint, terminiertlsqr, wennnorm(r) <= atol * norm(A) * norm(x) + btol * norm(b). Andernfalls terminiertlsqr, wennnorm(A^H r) <= atol * norm(A) * norm(r). Wenn beide Toleranzen 1,0e-6 (Standard) betragen, sollte die finalenorm(r)auf etwa 6 Stellen genau sein. (Die finalexwird normalerweise weniger korrekte Stellen haben, abhängig voncond(A)und der Größe von LAMBDA.) Wenn atol oder btol None ist, wird ein Standardwert von 1,0e-6 verwendet. Idealerweise sollten sie Schätzungen des relativen Fehlers in den Einträgen vonAbzw.bsein. Wenn beispielsweise die Einträge vonA7 korrekte Ziffern haben, setzen Sieatol = 1e-7. Dies verhindert, dass der Algorithmus unnötige Arbeit über die Unsicherheit der Eingabedaten hinaus leistet.- conlimfloat, optional
Eine weitere Abbruch-Toleranz. lsqr bricht ab, wenn eine Schätzung von
cond(A)conlim überschreitet. Für konsistente SystemeAx = bkönnte conlim bis zu 1,0e+12 (z. B.) betragen. Für Probleme mit kleinsten Quadraten sollte conlim kleiner als 1,0e+8 sein. Maximale Präzision kann durch Setzen vonatol = btol = conlim = nullerreicht werden, aber die Anzahl der Iterationen kann dann exzessiv sein. Standard ist 1e8.- iter_limint, optional
Explizite Begrenzung der Anzahl der Iterationen (zur Sicherheit).
- showbool, optional
Anzeige eines Iterationsprotokolls. Standard ist False.
- calc_varbool, optional
Ob die Diagonalen von
(A'A + damp^2*I)^{-1}geschätzt werden sollen.- x0array_like, shape (n,), optional
Anfangsschätzung von x, bei None werden Nullen verwendet. Standard ist None.
Hinzugefügt in Version 1.0.0.
- Rückgabe:
- xndarray von float
Die finale Lösung.
- istopint
Gibt den Grund für die Beendigung an. 1 bedeutet, dass x eine ungefähre Lösung von Ax = b ist. 2 bedeutet, dass x das Problem der kleinsten Quadrate ungefähr löst.
- itnint
Iteraionsnummer bei Beendigung.
- r1normfloat
norm(r), wobeir = b - Ax.- r2normfloat
sqrt( norm(r)^2 + damp^2 * norm(x - x0)^2 ). Gleich r1norm, wenndamp == 0.- anormfloat
Schätzung der Frobenius-Norm von
Abar = [[A]; [damp*I]].- acondfloat
Schätzung von
cond(Abar).- arnormfloat
Schätzung von
norm(A'@r - damp^2*(x - x0)).- xnormfloat
norm(x)- varndarray von float
Wenn
calc_varTrue ist, werden alle Diagonalen von(A'A)^{-1}(wenndamp == 0) oder allgemeiner von(A'A + damp^2*I)^{-1}geschätzt. Dies ist gut definiert, wenn A vollen Spaltenrang hat oderdamp > 0. (Nicht sicher, was var bedeutet, wennrank(A) < nunddamp = 0.)
Hinweise
LSQR verwendet eine iterative Methode, um die Lösung zu approximieren. Die Anzahl der Iterationen, die zur Erreichung einer bestimmten Genauigkeit erforderlich sind, hängt stark von der Skalierung des Problems ab. Eine schlechte Skalierung der Zeilen oder Spalten von A sollte daher, wo immer möglich, vermieden werden.
Beispielsweise bleibt die Lösung im ersten Beispiel von der Zeilenskalierung unverändert. Wenn eine Zeile von A sehr klein oder groß im Vergleich zu den anderen Zeilen von A ist, sollte die entsprechende Zeile von ( A b ) hoch- oder runterskaliert werden.
In den Problemen 1 und 2 lässt sich die Lösung x nach der Spaltenskalierung leicht wiederherstellen. Sofern keine besseren Informationen vorliegen, sollten die von Null verschiedenen Spalten von A so skaliert werden, dass sie alle die gleiche euklidische Norm haben (z. B. 1,0).
In Problem 3 gibt es keine Freiheit zur Neuskalierung, wenn damp ungleich Null ist. Der Wert von damp sollte jedoch erst zugewiesen werden, nachdem die Skalierung von A berücksichtigt wurde.
Der Parameter damp soll zur Regularisierung schlecht konditionierter Systeme beitragen, indem er verhindert, dass die wahre Lösung sehr groß wird. Eine weitere Hilfe zur Regularisierung bietet der Parameter acond, der verwendet werden kann, um Iterationen zu beenden, bevor die berechnete Lösung sehr groß wird.
Wenn eine anfängliche Schätzung
x0bekannt ist unddamp == 0ist, könnte man wie folgt vorgehen:Berechnen Sie einen Residuenvektor
r0 = b - A@x0.Verwenden Sie LSQR, um das System
A@dx = r0zu lösen.Addieren Sie die Korrektur dx, um eine endgültige Lösung
x = x0 + dxzu erhalten.
Dies erfordert, dass
x0vor und nach dem Aufruf von LSQR verfügbar ist. Um die Vorteile zu beurteilen, nehmen wir an, LSQR benötigt k1 Iterationen, um A@x = b zu lösen, und k2 Iterationen, um A@dx = r0 zu lösen. Wenn x0 "gut" ist, wird norm(r0) kleiner als norm(b) sein. Wenn die gleichen Abbruch-Toleranzen atol und btol für jedes System verwendet werden, werden k1 und k2 ähnlich sein, aber die endgültige Lösung x0 + dx sollte genauer sein. Der einzige Weg, die Gesamtarbeit zu reduzieren, ist die Verwendung einer größeren Abbruch-Toleranz für das zweite System. Wenn ein Wert btol für A@x = b geeignet ist, sollte der größere Wert btol*norm(b)/norm(r0) für A@dx = r0 geeignet sein.Vorkonditionierung ist eine weitere Möglichkeit, die Anzahl der Iterationen zu reduzieren. Wenn es möglich ist, ein verwandtes System
M@x = beffizient zu lösen, wobei M A auf hilfreiche Weise approximiert (z. B. M - A hat niedrigen Rang oder seine Elemente sind klein im Verhältnis zu denen von A), kann LSQR auf dem SystemA@M(inverse)@z = bschneller konvergieren, wonach x durch Lösen von M@x = z wiederhergestellt werden kann.Wenn A symmetrisch ist, sollte LSQR nicht verwendet werden!
Alternativen sind die symmetrische Konjugierten-Gradienten-Methode (cg) und/oder SYMMLQ. SYMMLQ ist eine Implementierung von symmetrischem cg, die für jedes symmetrische A gilt und schneller konvergiert als LSQR. Wenn A positiv definit ist, gibt es andere Implementierungen von symmetrischem cg, die pro Iteration etwas weniger Arbeit erfordern als SYMMLQ (aber die gleiche Anzahl von Iterationen benötigen).
Referenzen
[1]C. C. Paige und M. A. Saunders (1982a). „LSQR: An algorithm for sparse linear equations and sparse least squares“, ACM TOMS 8(1), 43-71.
[2]C. C. Paige und M. A. Saunders (1982b). „Algorithm 583. LSQR: Sparse linear equations and least squares problems“, ACM TOMS 8(2), 195-209.
[3]M. A. Saunders (1995). „Solution of sparse rectangular systems using LSQR and CRAIG“, BIT 35, 588-604.
Beispiele
>>> 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)
Das erste Beispiel hat die triviale Lösung
[0, 0].>>> b = np.array([0., 0., 0.], dtype=float) >>> x, istop, itn, normr = lsqr(A, b)[:4] >>> istop 0 >>> x array([ 0., 0.])
Der Abbruchcode
istop=0zeigt an, dass ein Nullvektor als Lösung gefunden wurde. Die zurückgegebene Lösung x enthält tatsächlich[0., 0.]. Das nächste Beispiel hat eine nicht-triviale Lösung.>>> b = np.array([1., 0., -1.], dtype=float) >>> x, istop, itn, r1norm = lsqr(A, b)[:4] >>> istop 1 >>> x array([ 1., -1.]) >>> itn 1 >>> r1norm 4.440892098500627e-16
Wie durch
istop=1angezeigt, hatlsqreine Lösung gefunden, die den Toleranzgrenzen entspricht. Die gegebene Lösung[1., -1.]löst offensichtlich die Gleichung. Die restlichen Rückgabewerte enthalten Informationen über die Anzahl der Iterationen (itn=1) und die verbleibende Differenz zwischen linker und rechter Seite der gelösten Gleichung. Das letzte Beispiel demonstriert das Verhalten für den Fall, dass keine Lösung für die Gleichung existiert.>>> b = np.array([1., 0.01, -1.], dtype=float) >>> x, istop, itn, r1norm = lsqr(A, b)[:4] >>> istop 2 >>> x array([ 1.00333333, -0.99666667]) >>> A.dot(x)-b array([ 0.00333333, -0.00333333, 0.00333333]) >>> r1norm 0.005773502691896255
istop zeigt an, dass das System inkonsistent ist und somit x eher eine ungefähre Lösung des entsprechenden Problems der kleinsten Quadrate ist. r1norm enthält die Norm des minimalen gefundenen Residuums.