Boost-Bibliothek, wie Determinante von lu_factorize zu bekommen ()?
-
07-07-2019 - |
Frage
Ich versuche, eine Determinante mit Hilfe der Boost C ++ Bibliotheken zu berechnen. Ich fand den Code für die Funktion InvertMatrix (), die ich weiter unten kopiert haben. Jedes Mal, wenn ich diese inverse berechnen, möchte ich auch die Determinante. Ich habe eine gute Idee, wie zu berechnen, indem die Diagonale der Matrix U aus der LU-Zerlegung Multiplizieren unten. Es gibt ein Problem, ich bin in der Lage, die Determinante richtig zu berechnen, mit Ausnahme der Zeichen. Je nach Schwenk erhalte ich die Zeichen falsch die Hälfte der Zeit. Hat jemand einen Vorschlag, wie das Zeichen richtig zu machen, jedes Mal? Vielen Dank im Voraus.
template<class T>
bool InvertMatrix(const ublas::matrix<T>& input, ublas::matrix<T>& inverse)
{
using namespace boost::numeric::ublas;
typedef permutation_matrix<std::size_t> pmatrix;
// create a working copy of the input
matrix<T> A(input);
// create a permutation matrix for the LU-factorization
pmatrix pm(A.size1());
// perform LU-factorization
int res = lu_factorize(A,pm);
if( res != 0 ) return false;
Hier ist, wo ich bei der Berechnung der Determinante mein Bestes eingefügt.
T determinant = 1;
for(int i = 0; i < A.size1(); i++)
{
determinant *= A(i,i);
}
Ende meines Teil des Codes.
// create identity matrix of "inverse"
inverse.assign(ublas::identity_matrix<T>(A.size1()));
// backsubstitute to get the inverse
lu_substitute(A, pm, inverse);
return true;
}
Lösung
Die Permutationsmatrix pm
enthält die Informationen, die Sie den Vorzeichenwechsel bestimmen müssen: Sie werden Ihre Determinante durch die Determinante der Permutationsmatrix multiplizieren möchten
Durchlesen der Quelldatei lu.hpp
wir eine Funktion namens swap_rows
finden, die erzählt, wie eine Permutationsmatrix auf eine Matrix anzuwenden. Es ist leicht die Determinante der Permutationsmatrix (das Vorzeichen der Permutation), gegeben zu ergeben modifiziert, dass jeder tatsächliche Swap einen Faktor von -1 trägt:
template <typename size_type, typename A>
int determinant(const permutation_matrix<size_type,A>& pm)
{
int pm_sign=1;
size_type size=pm.size();
for (size_type i = 0; i < size; ++i)
if (i != pm(i))
pm_sign* = -1; // swap_rows would swap a pair of rows here, so we change sign
return pm_sign;
}
Eine andere Alternative wäre, die lu_factorize
und lu_substitute
Methoden zu verwenden, die jede Verschwenkung nicht tun (konsultieren Sie die Quelle, aber im Grunde die pm
in den Drop-Anrufen lu_factorize
und lu_substitute
). Diese Änderung würde Ihre Determinante Berechnung Arbeit machen, wie sie ist. Seien Sie vorsichtig, aber:. Verschwenkung Entfernen des Algorithmus weniger numerisch stabil machen
Andere Tipps
Nach http://qiangsong.wordpress.com / 2011/07/16 / lu-Faktorisierung-in-ublas / :
Just determinant *= A(i,i)
ändern determinant *= (pm(i) == i ? 1 : -1) * A(i,i)
.
Ich habe versucht, auf diese Weise und es funktioniert.
Ich weiß, dass es zu Managu Antwort tatsächlich sehr ähnlich ist und die Idee ist die gleiche, aber ich glaube, dass es einfacher ist (und „2 in 1“, wenn in InvertMatrix Funktion verwendet wird).