In maniera molto simile a quanto è stato fatto per creare una funzione per eseguire velocemente moltiplicazioni tra grandi matrici con l'algoritmo di Strassen (vedi post precedente), scriviamo adesso funzioni per calcolare velocemente l'inversa di una matrice.
Per evitare di scrivere pagine e pagine di commenti e formule, come ho fatto per la moltiplicazione tra matrici, questa volta posto direttamente il codice delle funzioni create (il ragionamento che sta alla base è del tutto analogo). Copiate e incollate tutto il codice per poterlo visualizzare correttamente.
Proviamo a fare qualche prova. Innanzitutto controlliamo che la funzione esegua correttamente i calcoli, confrontandoli con il risultato della funzione standard di R (solve):
La funzione esegue correttamente i calcoli. Esiste però un problema di approssimazione, per cui le prime due funzioni riportano il risultato identico fino alla ottava cifra decimale, mentre il secondo fino alla sesta. Più che un problema di calcoli, è un problema di espressione dei numeri in formato binario e 32 bit, che determina questi errori.
Ora analizziamo i tempi di esecuzione. Riporto in tabella il risultato ottenuto eseguendo il seguente codice:
Time computation
A <- matrix(trunc(rnorm(512*512)*100), 512,512) system.time(solve(A)) system.time(strassenInv(A)) system.time(strassenInv2(A)) system.time(strassenInv3(A))
A <- matrix(trunc(rnorm(1024*1024)*100), 1024,1024) system.time(solve(A)) system.time(strassenInv(A)) system.time(strassenInv2(A)) system.time(strassenInv3(A))
A <- matrix(trunc(rnorm(2048*2048)*100), 2048,2048) system.time(solve(A)) system.time(strassenInv(A)) system.time(strassenInv2(A)) system.time(strassenInv3(A))
A <- matrix(trunc(rnorm(4096*4096)*100), 4096,4096) system.time(solve(A)) system.time(strassenInv(A)) system.time(strassenInv2(A)) system.time(strassenInv3(A))
I risultati sono abbastanza evidenti, e utilizzando una modificazione dell'algoritmo di Strassen per l'inversione di matrici, esiste un effettivo risparmio di tempo.
Nuovamente valgono le due raccomandazioni già fatte: - il codice è da migliorare; se qualcuno vuole aiutarmi, sarò lieto di aggiornare il mio codice - se ritenete utili queste funzioni e le usate per qualche lavoro, una citazione è sempre gradita
Nel pdf qui sotto ho implementato una prima versione dell'algoritmo di Strassen in R, utile per svolgere rapidamente moltiplicazioni tra matrici.
Il codice è sicuramente da rivedere, e perfezionare, però può essere un utile inizio per una implementazione migliore. Vorrei ringraziare l'utente G. Grothendieck per avermi suggerito un modo per creare matrici quadrate più grandi partendo da matrici più piccole (capirete leggendo il pdf), su StackOverFlow.
Se utilizzate il mio codice, è sempre cortese specificare la fonte. Inoltre se qualcuno vuole collaborare, perfezionando il codice, è assolutamente ben accetto!
La prima funzione permette di convertire numeri interi (o prima della virgola) in codice binario, mentre la seconda permette di eseguire la conversione dei numeri decimali (dopo la virgola). Il parametro precs indica il numero di bit da utilizzare.
Ad esempio:
decInt_to_8bit(11, 8) [1] 0 0 0 0 1 0 1 1
Il numero 11, in codice binario a 8 bit è: 00001011.
devDec_to_8bit(0.625, 8) [1] 1 0 1 0 0 0 0 0
Il numero 0.625 in codice binario a 8 bit è 10100000. Aumentando la precisione, nel primo caso permettiamo il calcolo di numeri superiori a 256 (limite massimo per gli 8-bit), mentre nel secondo caso permette di aumentare la precisione dopo la virgola:
Imparato quindi a convertire i numeri decimali in numeri binari, possiamo passare alla conversione in IEEE-754 single precision (ossia 32bit), utilizzando la seguente funzione:
Ho già parlato della regressione polinomiale in un mio post precedente, dove ho focalizzato l'attenzione essenzialmente sui comandi da dare ad R, e sulla rappresentazione grafica dei modelli. Ho deciso di scrivere un secondo post sullo stesso argomento per spiegare il procedimento formale per ottenere il modello, dando un forte rilievo ai calcoli manuali (più volte nel mio blog ho dato questa impostazione, per non ridurre la pratica statistica a semplici comandi testuali con R).
Nel pdf che ho scritto, vedremo quindi come calcolare formalmente i coefficienti beta del modello di regressione polinomiale. Per altro questa è una delle possibili applicazioni della decomposizione-LU di cui ho parlato nel mio ultimo post.
Il pane quotidiano della statistica è l'algebra lineare, e in particolare l'algebra delle matrici. Risulta pertanto fondamentale avere delle basi dei metodi utilizzati per poter apprendere a pieno i procedimenti. In questo post voglio condividere un file pdf che ho scritto, per la soluzione di sistemi di equazioni con il metodo della decomposizione LU (o di Doolittle). Ho cercato di descrivere tutti i passaggi nella maniera più chiara possibile, ma sicuramente una spiegazione "in diretta" risulta più utile. Pertanto ho selezionato i seguenti due video, disponibili su YouTube, che spiegano lo stesso procedimento che ho cercato di descrivere nel pdf. Ho avuto la necessità di scrivere il pdf, in quanto nel video non viene spiegata come effettuare le permutazioni delle righe; procedimento che invece ho cercato di spiegare nel documento, in quanto R utilizza la decomposizione PLU (e non la decomposizione LU).
Consiglio infine la lettura di questa pagina sullo stesso argomento.
NOTA: nel documento sarà presente qualche errore di sillabazione... la ragione è che non sono ancora riuscito a imparare come far sillabare correttamente le parole a latex!