2011-10-09 11 views
5

Mi è stata data una matrice molto grande (non posso modificare i valori della matrice) e ho bisogno di calcolare l'inverso di una matrice (covarianza).det di una matrice restituisce 0 in matlab

A volte ho l'errore che dice

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

In queste situazioni vedo che il valore del det restituisce 0.

Prima di calcolare inversa (di una matrice di covarianza) Voglio controllare il valore del det ed eseguire qualcosa di simile

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

c'è un modo per utilizzare il nuovo det e quindi utilizzare questo per calcolare l'inverso della matrice di covarianza?

risposta

1

In tale scenario, il calcolo di un inverso non è una buona idea. Se si dispone solo di farlo, vorrei suggerire di utilizzare questo per aumentare la visualizzazione di precisione:

format long; 

altro suggerimento potrebbe essere quello di provare a utilizzare uno SVD della matrice e armeggiare intorno con valori singolari là.

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

Σ è una matrice diagonale dove si trova uno degli elementi diagonali vicino a 0. Provare a giocare in giro con questo numero se si desidera una sorta di un'approssimazione.

+0

c'è la funzione PINV per pseudoinversa – Amro

16

Sigh. Il calcolo del determinante per determinare la singolarità è una cosa ridicola da fare, assolutamente così. Soprattutto per una grande matrice. Ci dispiace, ma lo è. Perché? Sì, alcuni libri ti dicono di farlo. Forse anche il tuo istruttore.

La singolarità analitica è una cosa. Ma che ne è della determinazione numerica della singolarità? A meno che non si stia utilizzando uno strumento simbolico, MATLAB utilizza l'aritmetica in virgola mobile. Ciò significa che memorizza i numeri come virgola mobile, valori a doppia precisione. Questi numeri non possono essere più piccoli in grandezza rispetto

>> realmin 
ans = 
    2.2251e-308 

(In realtà, MATLAB va un po 'inferiore a quello, in termini di numeri denormalizzati, che possono andare fino a circa 1e-323). Vedere che quando provo a memorizzare un numero più piccolo di quello, MATLAB pensa che sia zero.

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

>> A = 1e-324 
A = 
    0 

Cosa succede con una matrice di grandi dimensioni? Ad esempio, è questo singolare matrice:

M = eye(1000); 

Poiché M è una matrice di identità, è abbastanza chiaramente non singolare. In effetti, det suggerisce che non è singolare.

>> det(M) 
ans = 
    1 

Ma, moltiplica per qualche costante. Questo lo rende non singolare? NO!!!!!!!!!!!!!!!!!!!!!!!! Ovviamente no. Ma provalo lo stesso.

>>  det(M*0.1) 
ans = 
    0 

Hmm. Questo è strano. MATLAB mi dice che il determinante è zero. Ma sappiamo che il determinante è 1e-1000. Oh si. Accidenti, 1e-1000 è più piccolo, di una quantità considerevole rispetto al numero più piccolo che ti ho appena mostrato che MATLAB può memorizzare come doppio. Quindi il determinante subisce un underflow, anche se ovviamente è diverso da zero. La matrice è singolare? Ovviamente no. Ma l'uso di det fallisce qui?Certo che lo farà, e questo è completamente previsto.

Utilizzare invece un buon strumento per la determinazione della singolarità. Usa uno strumento come cond, o rank. Ad esempio, possiamo ingannare il rango?

>> rank(M) 
ans = 
     1000 

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

Vedi che il rango sa che questo è una matrice di rango pieno, indipendentemente dal fatto che scalare o no. Lo stesso vale per cond, calcolando il numero di condizione di M.

>> cond(M) 
ans = 
    1 

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

Benvenuti nel mondo dell'aritmetica in virgola mobile. E, a proposito, dimentica det come strumento per quasi tutti i calcoli usando l'aritmetica in virgola mobile. È una scelta scadente quasi sempre.

5

I trucioli di legno ti hanno fornito un'ottima spiegazione del motivo per cui non dovresti utilizzare il determinante. Questo sembra essere un malinteso comune e la tua domanda è molto correlata a un'altra domanda sull'inversione delle matrici: Is there a fast way to invert a matrix in Matlab?, in cui l'OP ha deciso che poiché il determinante della sua matrice era 1, era decisamente invertibile! Ecco un frammento dalla mia risposta

Piuttosto che det(A)=1, è il condition number of your matrix che detta come precisa o stabile l'inverso sarà. Si noti che det(A)=∏i=1:n λi. Quindi, basta impostare λ1=M, λn=1/M e λi≠1,n=1 per ottenere det(A)=1. Tuttavia, come M → ∞, cond(A) = M2 → ∞ e λn → 0, significa che la tua matrice si sta avvicinando alla singolarità e ci saranno grossi errori numerici nel calcolare l'inverso.

È possibile verificare questo in MATLAB con il seguente semplice esempio:

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

%# calculate determinant 
det(A) 
ans = 

    1 

%# calculate condition number 
cond(A) 
ans = 

    1.0000e+30 
Problemi correlati