2017-06-13 3 views
0

Ich benutze Armadillo & C++ und ich versuche, die Umkehrung einer Matrix zu finden, aber die Umkehrung gibt nur die Matrix selbst zurück.Armadillo C++ findet keine Matrix invers

Es scheint mir, dass es keine Berechnung gibt. Außerdem werden keine Fehler ausgegeben.

Ich bin mit dem folgenden Header:

#include <armadillo> 
using namespace std; 
using namespace arma; 

und ich habe für ein paar Tage Armadillo wurde mit und lief durch mehr Matrix Manipulationen, die richtig funktionieren.

Eingang:

mat A = randu<mat>(5,5); 
A.print("A: "); 
mat B = inv(A); 
B.print("inv(A): "); 

Ausgang:

A: 
    0.0013 0.1741 0.9885 0.1662 0.8760 
    0.1933 0.7105 0.1191 0.4508 0.9559 
    0.5850 0.3040 0.0089 0.0571 0.5393 
    0.3503 0.0914 0.5317 0.7833 0.4621 
    0.8228 0.1473 0.6018 0.5199 0.8622 
inv(A): 
    0.0013 0.1741 0.9885 0.1662 0.8760 
    0.1933 0.7105 0.1191 0.4508 0.9559 
    0.5850 0.3040 0.0089 0.0571 0.5393 
    0.3503 0.0914 0.5317 0.7833 0.4621 
    0.8228 0.1473 0.6018 0.5199 0.8622 
Process finished with exit code 0 

Frage:

Warum INV nicht (ofAMatrix) arbeiten, irgendwelche Hinweise oder Anregungen? Danke!

Antwort

1

Dies funktioniert gut mit Armadillo 7.900.1 mit Intel (R) MKL Backend und Clang 5.0.

Sie sollten niemals die Inverse einer Matrix nehmen, es sei denn, es ist absolut notwendig. Außerdem müssen Sie sicherstellen, dass die Umkehrung tatsächlich existiert, andernfalls wird der Algorithmus gerne Müll ausgeben. Wenn Sie die Inverse von A berechnen zu finden x wie in

x = A-1b

es besser ist, die zu lösen lineares System

Ax =b

statt. Diese Löser sind viel schneller und haben eine viel bessere Konvergenz.

#include <armadillo> 

int main() 
{ 
    arma::mat A = { { 0.0013 , 0.1741 , 0.9885 , 0.1662 , 0.8760 } , 
        { 0.1933 , 0.7105 , 0.1191 , 0.4508 , 0.9559 } , 
        { 0.5850 , 0.3040 , 0.0089 , 0.0571 , 0.5393 } , 
        { 0.3503 , 0.0914 , 0.5317 , 0.7833 , 0.4621 } , 
        { 0.8228 , 0.1473 , 0.6018 , 0.5199 , 0.8622 } }; 
    A.print("A: "); 
    arma::mat B = arma::inv(A); 
    B.print("inv(A): "); 
    arma::mat I = A*B; 
    I.print("I: "); 
} 

Ausgang:

A: 
    0.0013 0.1741 0.9885 0.1662 0.8760 
    0.1933 0.7105 0.1191 0.4508 0.9559 
    0.5850 0.3040 0.0089 0.0571 0.5393 
    0.3503 0.0914 0.5317 0.7833 0.4621 
    0.8228 0.1473 0.6018 0.5199 0.8622 
inv(A): 
    0.4736 -1.7906 4.4377 2.2515 -2.4784 
    2.9108 -3.1697 12.1159 7.7356 -11.1675 
    2.5212 -2.8557 6.8074 4.7142 -6.1801 
    -1.0317 0.9400 -2.3230 0.2413 1.3297 
    -2.0869 3.6766 -9.6555 -6.9062 8.9447 
I: 
    1.0000e+00 1.1340e-16 -1.8134e-15 -6.4918e-16 -4.8899e-17 
    7.6334e-17 1.0000e+00 -9.1810e-16 -9.4668e-16 8.7907e-16 
    2.5424e-16 -4.3981e-16 1.0000e+00 9.2981e-16 -2.0864e-15 
    9.3036e-17 -2.6745e-17 7.5137e-16 1.0000e+00 -8.1372e-16 
    4.3422e-16 -4.2293e-16 1.1321e-15 1.0687e-15 1.0000e+00 
+0

Danke für die Antwort so schnell! 1. Ich weiß nicht, was MKL ist. 2. Ist es nicht seltsam, dass ich nicht einmal Fehler bekomme? Könnte es ein Linker/Compiler-Problem sein? Oder vielleicht fehlt mir eine Bibliothek? 3. Leider brauche ich inverse, und mir ist bewusst, dass inverse in der Regel ein Engpass ist, danke! –

+1

Bitte verwenden Sie das [Abstimmungssystem] (https://Stackoverflow.com/help/why-vote) anstatt "Danke" zu posten. Aber wie auch immer, Sie sind willkommen :) –

+0

MKL ist Intels Implementierung der LAPACK-Bibliothek mit speziellen Optimierungen für ihre Prozessoren. Dies kann Ihnen eine gewisse Beschleunigung bringen. Außerdem werden viele Algorithmen parallel mit OpenMP implementiert, was Ihnen zusätzliche Geschwindigkeit bringt. –

0

"Werke für mich", wie sie. Fahren diese von R und RcppArmadillo:

Zuerst lesen wir die Matrix und verwenden Sie die verallgemeinerte Inverse von der MASS-Paket:

R> M <- as.matrix(read.table(text="0.0013 0.1741 0.9885 0.1662 0.8760 
    0.1933 0.7105 0.1191 0.4508 0.9559 
    0.5850 0.3040 0.0089 0.0571 0.5393 
    0.3503 0.0914 0.5317 0.7833 0.4621 
    0.8228 0.1473 0.6018 0.5199 0.8622")) 
M <- as.matrix(read.table(text="0.0013 0.1741 0.9885 0.1662 0.8760 
+ 0.1933 0.7105 0.1191 0.4508 0.9559 
+ 0.5850 0.3040 0.0089 0.0571 0.5393 
+ 0.3503 0.0914 0.5317 0.7833 0.4621 
+ 0.8228 0.1473 0.6018 0.5199 0.8622")) 
R> M 
     V1  V2  V3  V4  V5 
[1,] 0.0013 0.1741 0.9885 0.1662 0.8760 
[2,] 0.1933 0.7105 0.1191 0.4508 0.9559 
[3,] 0.5850 0.3040 0.0089 0.0571 0.5393 
[4,] 0.3503 0.0914 0.5317 0.7833 0.4621 
[5,] 0.8228 0.1473 0.6018 0.5199 0.8622 
R> MASS::ginv(M) 
      [,1]  [,2]  [,3]  [,4]  [,5] 
[1,] 0.473579 -1.790599 4.43767 2.251542 -2.47842 
[2,] 2.910752 -3.169657 12.11587 7.735612 -11.16755 
[3,] 2.521167 -2.855651 6.80743 4.714239 -6.18015 
[4,] -1.031667 0.940028 -2.32302 0.241345 1.32967 
[5,] -2.086858 3.676647 -9.65548 -6.906203 8.94472 
R> 

Die verwenden wir RcppArmadillo:

R> Rcpp::cppFunction("arma::mat armaInv(arma::mat x) { return arma::inv(x); }", depends="RcppArmadillo") 
R> armaInv(M) 
      [,1]  [,2]  [,3]  [,4]  [,5] 
[1,] 0.473579 -1.790599 4.43767 2.251542 -2.47842 
[2,] 2.910752 -3.169657 12.11587 7.735612 -11.16755 
[3,] 2.521167 -2.855651 6.80743 4.714239 -6.18015 
[4,] -1.031667 0.940028 -2.32302 0.241345 1.32967 
[5,] -2.086858 3.676647 -9.65548 -6.906203 8.94472 
R> 

gleiche Antwort in beide Richtungen .

+0

Danke für die schnelle Antwort, aber ich benutze nicht R. –

+1

Das ist egal. Armadillo-Code ist Armadillo-Code, ich habe ihn gerade von R aufgerufen, und beide verwenden das gleiche LAPACK-Backend. Also habe ich dir einen Beweis gegeben: kein Problem mit Armadillo, wahrscheinlich ein lokales Problem an deinem Ende, das du lösen musst. –

+0

Danke, ich bin mir bewusst, dass es sich um ein lokales Problem handelt, ich bin mir sicher, dass es kein Armadillo-Problem ist, aber ich würde mich über jede Einsicht freuen, was das Problem sein könnte, danke! –

Verwandte Themen