Algoritmo di Strassen e ibridazione
In questa pagina 6
Il prodotto ricorsivo a blocchi (Prodotto di matrici - algoritmo iterativo e ricorsivo a blocchimodello di costo sulle matrici n x n (operazioni tra scalari, taglia n oppure N = n^2); somma in n^2 operazioni (ottima); prodotto righe per colonne iterativo con costo esatto 2n^3 - n^2; proprietà frattale del prodotto a blocchi dimostrata sugli indici; algoritmo ricorsivo RMUL con T(n) = 8T(n/2) + n^2, Theta(n^3) e soluzione esatta 2n^3 - n^2 per induzione e per srotolamento: fa le stesse operazioni dell'iterativo.Prodotto di matrici - algoritmo iterativo e ricorsivo a blocchi →) ha : la funzione di soglia è molto più grande del lavoro dei nodi interni, siamo nel caso 1 del Master Theorem - enunciato, casi e applicazioniMaster Theorem per T(n) = aT(n/b) + w(n): si confronta w(n) con la funzione soglia n^(log_b a). Caso 1 (w minore di una potenza polinomiale): Theta(n^(log_b a)); caso 2 (w della stessa taglia): Theta(n^(log_b a) log n); caso 3 (w maggiore e regolare): Theta(w(n)). Prova completa dai livelli dell'albero, versione estesa (parti intere, n0 qualsiasi), esempi, e l'uso scorretto quando nessun caso si applica (w = n log n).Master Theorem - enunciato, casi e applicazioni → e dominano le foglie. L'arietà è troppo alta. Per abbassare la complessità bisogna ridurre le chiamate ricorsive senza far crescere troppo il lavoro di divide e conquer. Strassen ha mostrato che bastano 7 chiamate su matrici , al prezzo di somme/sottrazioni di matrici .
Si assume ancora e il modello di costo del prodotto di matrici (operazioni tra scalari a costo ).
Le formule
Divide (14 fattori, somme/sottrazioni, perché sono quadranti singoli):
| 1 | ||
| 2 | ||
| 3 | ||
| 4 | ||
| 5 | ||
| 6 | ||
| 7 |
Recurse: per , con sette chiamate ricorsive.
Conquer ( somme/sottrazioni):
Non è noto come Strassen sia arrivato alle espressioni, ma per la correttezza non serve: basta verificarle sviluppando i prodotti (le matrici non commutano, quindi l'ordine dei fattori in ogni termine si mantiene).
Verifica di e :
Verifica di . Si sviluppano i quattro prodotti che compaiono:
Nella somma si cancellano a coppie: con ; con ; con ; con ; con . Restano .
Verifica di . con
Si cancellano , , , , e restano .
Esempio numerico (, i quadranti sono scalari): , .
, , , : lo stesso risultato del prodotto per definizione. Qui Strassen usa prodotti e somme/sottrazioni, in tutto operazioni, contro le dell'iterativo: sui casi piccoli non conviene.
Algoritmo SMUL
SMUL(A, B)
n <- rows(A)
if n = 1 then return [a11 * b11] { BASE }
* quadranti Aij, Bij *
{ DIVIDE: 10 somme/sottrazioni di matrici n/2 x n/2 }
A1 <- A12 - A22; B1 <- B21 + B22
A2 <- A11 + A22; B2 <- B11 + B22
A3 <- A11 - A21; B3 <- B11 + B12
A4 <- A11 + A12; B4 <- B22
A5 <- A11; B5 <- B12 - B22
A6 <- A22; B6 <- B21 - B11
A7 <- A21 + A22; B7 <- B11
{ RECURSE }
for i <- 1 to 7 do Pi <- SMUL(Ai, Bi)
{ CONQUER: 8 somme/sottrazioni }
C11 <- P1 + P2 - P4 + P6; C12 <- P4 + P5
C21 <- P6 + P7; C22 <- P2 - P3 + P5 - P7
return CLa correttezza segue dalle quattro identità verificate sopra, per induzione sulla taglia (la stessa struttura del prodotto ricorsivo; vedi Dimostrazioni, induzione e invariantiTecniche di dimostrazione (esempio, controesempio, assurdo), induzione con casi base multipli, invarianti di ciclo (inizializzazione, conservazione, uso alla fine), schema generale per provare la correttezza; esempi svolti su arrayMax, sequenza di bit e numeri di Fibonacci.Dimostrazioni, induzione e invarianti →).
Analisi
Costi per : il divide fa operazioni su matrici di , cioè ; il conquer ne fa , cioè ; la ricorsione costa . Il lavoro dei nodi interni è :
Ordine di grandezza. La soglia è , sopra : siamo ancora nel caso 1 e , contro il dell'iterativo.
Soluzione esatta con la formula generale (Albero della ricorrenza e formula generale per le ricorrenzeL'albero della ricorrenza ha la forma dell'albero delle chiamate dell'istanza peggiore e T(n) è la somma dei lavori dei nodi. Per la famiglia T(n) = s(n)T(f(n)) + w(n) con base T0 per n <= n0, contando i nodi per livello con le iterate di f e il livello f*(n,n0) si ottiene la formula chiusa T(n) = somma_l [prodotto_j s(f^(j)(n))] w(f^(l)(n)) + [prodotto s] T0, verificata per induzione e applicata a esempi (merge sort, Hanoi, ricorrenze con radice).Albero della ricorrenza e formula generale per le ricorrenze →): , , , , , profondità . Il livello ha nodi di taglia ; le foglie sono (perché ):
La somma geometrica vale , e . Quindi
Controllo: dà ; dà , il numero di operazioni dell'esempio numerico; dà .
Costanti a confronto. Il termine dominante di Strassen ha costante , quello dell'iterativo costante : più che tripla. Per quale Strassen conviene? Si cerca il primo con
Numericamente il passaggio avviene a . Per le sole potenze di (le taglie ammesse) la prima è : matrici con più di un milione di elementi.
| Strassen | iterativo | |
|---|---|---|
| 8 | 2017 | 960 |
| 64 | 798967 | 520192 |
| 512 | 280902385 | 268173312 |
| 1024 | 1971035287 | 2146435072 |
| 2048 | 13816121377 | 17175674880 |
Grafico interattivo: Rapporto tra le operazioni di Strassen puro e quelle dell'iterativo: sopra 1 Strassen perde, il rapporto scende sotto 1 solo da n = 655 (a n = 1024 vale 0.918)
E il modello di costo ignora la ricorsione, i pattern di accesso alla memoria (meno regolari, quindi peggiori per la cache) e le matrici temporanee per i fattori e i prodotti , che l'iterativo non richiede. In pratica il punto di incrocio è molto più alto di quello teorico.
Evoluzioni. Strassen non è più l'algoritmo asintoticamente migliore: esponenti via via più piccoli (le dispense riportano , Le Gall 2014) sono stati ottenuti con tecniche molto più complesse, con costanti enormi e senza implementazioni usabili. Strassen, pur con costanti più alte dell'iterativo, è invece usato nella pratica per matrici di grande taglia, tipicamente in forma ibrida.
Ibridazione
Definizione (ibridazione). Dati due algoritmi e per lo stesso problema, con ma con costanti moltiplicative più alte per nell'espressione esatta, l'ibridazione li combina in un algoritmo che ha lo stesso andamento asintotico del migliore ma, se possibile, costanti più basse.
Ibrido ingenuo (STUPID_HYBRID): se è sotto una soglia (per esempio ) si esegue MUL, altrimenti SMUL. Il costo è il minimo delle due funzioni, ma per l'algoritmo coincide con SMUL, quindi la costante di resta : nessun miglioramento asintotico, e l'iterativo viene eseguito al più una volta.
Cambiare il caso base. Si fissa una soglia (potenza di ) e si usa l'iterativo a ogni foglia dell'albero di Strassen, che viene interrotto alla taglia :
H_MUL(A, B)
n <- rows(A)
if n <= n0 then return MUL(A, B)
{ DIVIDE, RECURSE, CONQUER come in SMUL, con chiamate ricorsive a H_MUL }(Le dispense scrivono n < n0 nel codice e n <= n0 nella ricorrenza: qui si usa n <= n0, coerente con la ricorrenza.) La correttezza è la composizione di due algoritmi corretti: l'impianto è quello ricorsivo, e il caso base è risolto da un algoritmo corretto. La ricorrenza diventa
Analisi parametrica
Si pone , e livelli interni: ultimo livello interno, e foglie, ciascuna con costo :
Ora , perché . Sostituendo:
Infine , da cui
Controllo: per si ottiene (Strassen puro); per si ottiene (iterativo).
Per , : , contro dell'iterativo e di Strassen puro.
Scelta di
La costante del termine dominante è , da minimizzare sulle potenze di . Posto , ha derivata
positiva se e solo se , cioè
Quindi scende fino a circa e poi cresce: tra le potenze di il minimo è in o .
| 1 | 2 | 4 | 8 | 16 | 32 | 64 | |
|---|---|---|---|---|---|---|---|
| 7.000 | 5.143 | 4.245 | 3.918 | 3.945 | 4.204 | 4.631 |
Grafico interattivo: Costante g(n0) del termine dominante dell'ibrido: dal 7 di Strassen puro (n0 = 1) scende fino a 3.918 con n0 = 8 e poi risale
Si sceglie : la costante passa da a , quasi dimezzata. Con l'ibrido supera l'iterativo già da (non da come Strassen puro). Per i costi relativi all'iterativo sono: , ; , ; , ; , ; , ; , . Come sempre, l'analisi teorica non conta ricorsione, accessi alla memoria e matrici temporanee: nelle implementazioni la soglia ottimale è più alta e si trova per via sperimentale.
Verifica con un programma
Un'implementazione di iterativo, ricorsivo, SMUL e H_MUL che conta le operazioni (somme/sottrazioni di matrici a , prodotti iterativi a ) per e ogni dà gli stessi risultati del prodotto di numpy, e conteggi uguali a , a e alla formula parametrica, per tutti i valori provati.
Esercizi collegati
- Esercizio - matrici ARB, prodotto con tre chiamate ricorsive (compito del 19 giugno 2024, es. 1): stessa idea (meno chiamate, più somme) su una famiglia di matrici strutturate, con prodotti invece di .
- Esercizio - algoritmo di Strassen sulle matrici supercircolanti (esercizi su supercircolanti e circolanti, es. SC 6): come si semplifica Strassen sulle supercircolanti e perché non basta.
- Esercizio - domande di prima parte su moltiplicazione di matrici (simulazioni d'esame): conteggi con Strassen e con l'ibrido.
Domande d'esame
- Quante chiamate ricorsive fa l'algoritmo di Strassen e di quante somme/sottrazioni di matrici ha bisogno? Risposta: chiamate, somme/sottrazioni nel divide e nel conquer, in tutto ; , .
- Strassen puro batte l'algoritmo iterativo? Da quale taglia? Traccia: asintoticamente sì ( contro ), ma solo da , quindi per le potenze di da .
- Perché
STUPID_HYBRIDnon migliora la costante eH_MULsì? Traccia: il primo sceglie solo in base alla taglia di partenza, per grande coincide conSMUL, costante ; il secondo usa l'iterativo alle foglie di tutto l'albero, costante , minima () con .
Versione ripasso
- Idea: l'arietà di Prodotto di matrici - algoritmo iterativo e ricorsivo a blocchimodello di costo sulle matrici n x n (operazioni tra scalari, taglia n oppure N = n^2); somma in n^2 operazioni (ottima); prodotto righe per colonne iterativo con costo esatto 2n^3 - n^2; proprietà frattale del prodotto a blocchi dimostrata sugli indici; algoritmo ricorsivo RMUL con T(n) = 8T(n/2) + n^2, Theta(n^3) e soluzione esatta 2n^3 - n^2 per induzione e per srotolamento: fa le stesse operazioni dell'iterativo.Prodotto di matrici - algoritmo iterativo e ricorsivo a blocchi → è troppo alta (domina il lavoro alle foglie). Strassen usa 7 chiamate e somme/sottrazioni di matrici ().
- Divide ( operazioni, sono quadranti singoli):
- , ;
- , ;
- , ;
- , ;
- , ;
- , ;
- , .
- Recurse: (sette chiamate ricorsive).
- Conquer ( operazioni): , , , .
- Verifica: si sviluppano i prodotti rispettando l'ordine dei fattori (le matrici non commutano) e si cancellano i termini a coppie. Per esempio . Esempio con , : e , con operazioni (l'iterativo ne fa ).
- Ricorrenza: divide , conquer : Soglia , caso 1: (Master Theorem - enunciato, casi e applicazioniMaster Theorem per T(n) = aT(n/b) + w(n): si confronta w(n) con la funzione soglia n^(log_b a). Caso 1 (w minore di una potenza polinomiale): Theta(n^(log_b a)); caso 2 (w della stessa taglia): Theta(n^(log_b a) log n); caso 3 (w maggiore e regolare): Theta(w(n)). Prova completa dai livelli dell'albero, versione estesa (parti intere, n0 qualsiasi), esempi, e l'uso scorretto quando nessun caso si applica (w = n log n).Master Theorem - enunciato, casi e applicazioni →).
- Esatto (formula generale, , , foglie ): . Controlli: dà , dà .
- Costante contro dell'iterativo: solo da , per le potenze di da (; a perde). Il modello ignora ricorsione, cache e matrici temporanee: nella pratica la soglia è più alta. Gli algoritmi asintoticamente migliori (esponente ) non sono implementabili.
- Ibridazione:
STUPID_HYBRIDsceglie in base alla taglia di partenza, per grande coincide conSMUL, quindi la costante non cambia.H_MULusaMULper a ogni foglia: La correttezza è la composizione di due algoritmi corretti. - Formula parametrica: con livelli, e : Controlli: Strassen puro, iterativo. Esempio , : .
- Scelta di : ; sse . Potenze di : , quindi (costante da a ; per costo volte l'iterativo).
- Errori tipici: dire operazioni nel divide ( divide, conquer); scambiare l'ordine dei fattori nelle verifiche; confondere la soglia reale con quella per le potenze di (); dimenticare che va scelto tra le potenze di ( o , non ).
Esercizi su questo argomento
- Esercizio - algoritmo di Strassen sulle matrici supercircolanti (esercizi su supercircolanti e circolanti, es. SC 6)
- Esercizio - domande di prima parte su moltiplicazione di matrici (simulazioni d'esame)
- Esercizio - matrice di Fourier per una matrice generica a sinistra e a destra e per aI + bU (compito del 27 gennaio 2025, es. 2)
- Esercizio - matrici ARB, prodotto con tre chiamate ricorsive (compito del 19 giugno 2024, es. 1)