2011-10-09 5 views
5

J'ai été donné une très grande matrice (je ne peux pas changer les valeurs de la matrice) et j'ai besoin de calculer l'inverse d'une matrice (covariance).det d'une matrice retourne 0 dans matlab

Parfois, je reçois l'erreur en disant

Matrix is close to singular or badly scaled. 
    Results may be inaccurate 

Dans ces situations, je vois que la valeur de la det retourne 0.

Avant de calculer inverse (d'une matrice de covariance) Je veux vérifier la valeur du det et exécuter quelque chose comme ça

covarianceFea=cov(fea_class); 
covdet=det(covarianceFea); 
if(covdet ==0) 
    covdet=covdet+.00001; 
    %calculate the covariance using this new det 
end 

Est-il possible d'utiliser la nouvelle det puis l'utiliser pour calculer l'inverse de la matrice de covariance?

Répondre

1

Dans un tel scénario, calculer un inverse n'est pas une très bonne idée. Si vous avez juste à le faire, je suggère d'utiliser cette fonction pour augmenter la précision d'affichage:

format long; 

Autre suggestion pourrait être d'essayer d'utiliser un SVD de la matrice et bricoler avec des valeurs singulières là.

A = U∑V' 
inv(A) = V*inv(∑)*U' 

Σ est une matrice diagonale où vous verrez une des entrées en diagonale proche de 0. Essayez de jouer avec ce numéro si vous voulez une sorte d'une approximation.

+0

il y a la fonction PINV pour pseudoinverse – Amro

16

Soupir. Calcul du déterminant pour déterminer la singularité est une chose ridicule à faire, tout à fait ainsi. Surtout pour une grande matrice. Désolé, mais c'est le cas. Pourquoi? Oui, certains livres vous disent de le faire. Peut-être même votre instructeur.

La singularité analytique est une chose. Mais qu'en est-il de la détermination numérique de la singularité? À moins que vous n'utilisiez un outil symbolique, MATLAB utilise l'arithmétique à virgule flottante. Cela signifie qu'il stocke des nombres en tant que valeurs à virgule flottante et à double précision. Ces chiffres ne peuvent pas être plus petite amplitude que

>> realmin 
ans = 
    2.2251e-308 

(En fait, Matlab va un peu inférieur à celui, en termes de nombre dénormalisées, qui peuvent aller jusqu'à environ 1E-323.) Voir que lorsque je tente de stocker un nombre plus petit que cela, MATLAB pense que c'est zéro. Que se passe-t-il avec une grande matrice?

>> A = 1e-323 
A = 
    9.8813e-324 

>> A = 1e-324 
A = 
    0 

Par exemple, cette matrice est-elle singulière:

M = eye(1000); 

Puisque M est une matrice d'identité, elle est assez clairement non singulière. En fait, det suggère qu'il est non-singulier.

>> det(M) 
ans = 
    1 

Mais, multipliez-le par une constante. Est-ce que cela le rend non-singulier? NON!!!!!!!!!!!!!!!!!!!!!!!! Bien sûr que non. Mais essayez quand même.

>>  det(M*0.1) 
ans = 
    0 

Hmm. C'est étrange. MATLAB me dit que le déterminant est zéro. Mais nous savons que le déterminant est 1e-1000. Oh oui. Gosh, 1e-1000 est plus petit, d'une quantité considérable que le plus petit nombre que je viens de vous montrer que MATLAB peut stocker comme un double. Donc le déterminant déborde, même s'il est évidemment non nul. La matrice est-elle singulière? Bien sûr que non. Mais l'utilisation de det échoue-t-elle ici?Bien sûr que ce sera le cas, et c'est complètement prévu.

Utilisez plutôt un bon outil pour la détermination de la singularité. Utilisez un outil comme cond, ou rank. Par exemple, pouvons-nous tromper le rang?

>> rank(M) 
ans = 
     1000 

>> rank(M*.1) 
ans = 
     1000 

Voir ce rang sait qu'il s'agit d'une matrice de rang complet, que nous l'ayons mise à l'échelle ou non. La même chose est vraie de cond, en calculant le numéro de condition de M.

>> cond(M) 
ans = 
    1 

>> cond(M*.1) 
ans = 
    1 

Bienvenue dans le monde de l'arithmétique à virgule flottante. Et oh, au fait, oubliez det comme un outil pour presque n'importe quel calcul en utilisant l'arithmétique en virgule flottante. C'est un mauvais choix presque toujours.

5

Les copeaux de bois vous ont donné une très bonne explication des raisons pour lesquelles vous ne devriez pas utiliser le déterminant. Cela semble être une idée fausse commune et votre question est très liée à une autre question sur l'inversion des matrices: Is there a fast way to invert a matrix in Matlab?, où l'OP a décidé que parce que le déterminant de sa matrice était 1, il était définitivement inversible! Voici un extrait de ma réponse

Plutôt que det(A)=1, il est le condition number of your matrix qui dicte comment l'inverse précise ou sera stable. Notez que det(A)=∏i=1:n λi. Donc, simplement définir λ1=M, λn=1/M et λi≠1,n=1 vous donnera det(A)=1. Cependant, comme M → ∞, cond(A) = M2 → ∞ et λn → 0, ce qui signifie que votre matrice approche de la singularité et il y aura de grandes erreurs numériques dans le calcul de l'inverse.

Vous pouvez le tester en Matlab avec l'exemple simple suivant:

A = eye(10); 
A([1 2]) = [1e15 1e-15]; 

%# calculate determinant 
det(A) 
ans = 

    1 

%# calculate condition number 
cond(A) 
ans = 

    1.0000e+30