Löse

12

Ich portiere einen vorhandenen Code von MATLAB nach C ++ und habe ein lineares System zum Lösen von (anstelle der typischeren Form A x = b )xA=bAx=b

Die Matrix ist dicht und von allgemeiner Form, aber nicht größer als 1000 × 1000. In MATLAB wird die Lösung also durch die Funktion oder die Schrägstrichnotation gefundenAmrdivide(b,A)x = b/A;

Wie soll ich das in meinem C ++ - Code mit BLAS- und LAPACK-Routinen lösen?

Ich kenne die LAPACK-Routine, DGESVdie für x auflöst .Ax=bx

Ein Gedanke, den ich hatte, ist, einige Manipulationen mit Matrix-Transponierten-Identitäten durchzuführen:

(xEIN)T=bT

EINTxT=bT

xT=(EINT)-1bT

Lösen Sie dann das endgültige Formular, indem Sie DGESVdas transponierte . (also kosten um A zu transponieren und kosten um System zu lösen)EINTEIN

Gibt es einen effizienteren oder auf andere Weise besseren Ansatz ?

Ich arbeite mit Matrix- und Vektorklassen sowie der BLAS-Implementierung aus der BOOST-uBLAS-Bibliothek sowie Bindungen an die LAPACK-Bibliotheksroutinen. Ich habe dieses Setup erfolgreich für andere Vorgänge verwendet und hoffe, eine Lösung zu finden, die auf diese Bibliotheken beschränkt ist.

Außerdem sollte ich beachten, dass ich diese Art von Operation nur einige Male während der Code-Einrichtung durchführe, sodass die Leistung kein kritisches Problem darstellt.

Vielleicht MATLAB Dokumentation auf mrdividefür andere hilfreich.

NoahR
quelle

Antworten:

10

Triviale Antwort für Quadrat : Benutze, was auch für A T x = b gilt, wenn .EINdgesvxEINTx=bTRANS = 'T'

Bitte beachten Sie, dass Sie mit BLAS oder LAPACK eine Matrix kaum transponieren (Elemente im Speicher vertauschen) müssen: Die meisten Unterprogramme haben ein TRANSArgument, das für den Betrieb mit der transponierten Matrix oder einer Matrix mit einem anderen Speicherlayout geeignet ist. (Die Transposition entspricht der Änderung des Fortran-zusammenhängenden Speicherlayouts in einen C-zusammenhängenden Speicher und umgekehrt.)

Stefano M
quelle
Danke für die Antwort und Erklärung! Ich habe sehr wenig mit LAPACK gearbeitet und jetzt weiß ich, wie ich nach der Option TRANS Ausschau halte. Ich habe Probleme, das TRANS-Argument durchzuarbeiten boost::numeric::bindings::lapack::gesvx(), aber dies ist nicht Teil meiner Frage hier. Wenn ich Erfolg habe, werde ich mit einem Hinweis darauf zurückkommen, wie es geht.
NoahR
gesvx()gesvxEINTX=BEINTXT=BTXBEINXBsind nicht. Großartig, das ist bequemer. Wenn jemand anderes auf dieses Problem stößt und versucht, numerische Boost-Bindungen zu verwenden, kann ich sagen, dass ich die in dieser Lösung verwendete Transponierungsschnittstelle nicht bekommen habe. die Bindungen durcharbeiten.
NoahR
gesvxboost::numeric::bindingsEINTtrans()boost::numeric::bindings::lapack::gesvx( FACT, boost::numeric::bindings::trans(Atransposed), af, ipiv, equed, r, c, b, x, rcond, ferr, berr );
0

EIN

xEIN=bxQ.R=bx=bR-1Q.T

EIN

Gil
quelle
3
EINRR-1