2017-06-13 4 views
0

J'utilise Armadillo & C++ et j'essaie de trouver l'inverse d'une matrice, cependant, l'inverse renvoie juste la matrice elle-même.Armadillo C++ ne trouve pas matrice inverse

Il me semble qu'il n'y a pas de calcul. En outre, il n'y a pas d'erreurs lancées.

J'utilise l'en-tête suivant:

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

et je l'ai utilisé Armadillo pendant deux jours et a couru à travers plusieurs manipulations de la matrice qui fonctionnent correctement.

Entrée:

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

Sortie:

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 

Question:

Pourquoi ne pas INV (ofAMatrix) de travail, des conseils ou des idées? Merci!

Répondre

1

Cela fonctionne très bien avec Armadillo 7.900.1 avec backend de Intel (R) MKL et Clang 5.0.

Vous ne devez jamais prendre l'inverse d'une matrice à moins que ce ne soit absolument nécessaire. Aussi, vous devez vous assurer que l'inverse existe réellement, sinon l'algorithme va heureusement sortir des ordures. Si vous voulez calculer l'inverse de A pour trouver x comme dans

x =A-1b

il est préférable de résoudre le système linéaire

Ax = b

place. Ces solveurs sont beaucoup plus rapides et ont une meilleure convergence.

#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: "); 
} 

Sortie:

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

Merci de répondre si rapidement! 1. Je ne sais pas ce que MKL est. 2. N'est-il pas étrange que je ne reçois même pas d'erreurs? Pourrait-il être un problème d'éditeur de liens/compilateur? Ou peut-être que je manque une bibliothèque? 3. Malheureusement, j'ai besoin d'inverse, et je suis conscient que l'inverse est généralement un goulot d'étranglement, merci! –

+1

Veuillez utiliser le [système de vote] (https://stackoverflow.com/help/why-vote) au lieu de poster "merci". Mais de toute façon, vous êtes les bienvenus :) –

+0

MKL est l'implémentation d'Intel de la bibliothèque LAPACK avec des optimisations spéciales pour leurs processeurs. Cela peut vous donner un peu d'accélération. De plus, beaucoup d'algorithmes sont implémentés en parallèle en utilisant OpenMP, ce qui vous donne une vitesse supplémentaire. –

0

"fonctionne pour moi", comme ils. Conduire ce de R et RcppArmadillo:

D'abord, on lit la matrice et utiliser l'inverse généralisée de l'emballage MASS:

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> 

L'on utilise 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> 

Même réponse dans les deux sens .

+0

Merci pour la réponse rapide, mais je n'utilise pas R. –

+1

Cela n'a pas d'importance. Le code Armadillo est du code Armadillo, je viens de l'appeler R, et ils utilisent tous deux le même backend LAPACK. Donc, je vous ai donné une preuve de l'existence: aucun problème avec Armadillo, problème local probable à votre fin, vous devez résoudre. –

+0

Merci, je suis conscient que c'est un problème local, je suis sûr que ce n'est pas un problème Armadillo, mais j'apprécierais tout aperçu de ce que le problème pourrait être, merci! –