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.
c'è la funzione PINV per pseudoinversa – Amro