Trasformate notevoli ed esponenziazione di polinomi con la FFT
In questa pagina 4
Due esercitazioni sulla FFT. Nella prima si sfrutta la struttura del vettore per calcolare la DFT con meno operazioni della FFT generale (Fast Fourier Transform - algoritmo ricorsivo e trasformata inversala FFT calcola DFT_n (n potenza di due) con divide et impera: si separano i coefficienti di indice pari e dispari, p(x) = p0(x^2) + x p1(x^2), e per il lemma di dimezzamento bastano due DFT di ordine n/2; y_i = y0_i + w^i y1_i e y_{i+n/2} = y0_i - w^i y1_i. La ricorrenza T(n) = 2T(n/2) + 2n con T(1) = 0 ha soluzione esatta 2 n log2 n. L'inversa ha matrice F^{-1}_{ij} = w^{-ij}/n: si ottiene con la FFT sulle potenze negative (poi si divide per n fuori dalla ricorsione) oppure con DFT_n(y) rovesciato. LIN_CONV moltiplica due polinomi con n coefficienti in 12 n log2(2n) + 4n operazioni.Fast Fourier Transform - algoritmo ricorsivo e trasformata inversa →); nella seconda si usa la rappresentazione per valori per calcolare i coefficienti della potenza di un polinomio. Il metodo è lo stesso del capitolo: si modifica la proprietà di sottostruttura della FFT con le informazioni aggiuntive sull'istanza, e si ricava la nuova ricorrenza. Una situazione analoga (struttura che abbassa il costo) è nelle matrici circolanti (Matrici circolanti e supercircolanti - algoritmi divide and conquerle matrici supercircolanti (quadranti alternati ricorsivi) hanno solo n valori distinti: somma in n operazioni, prodotto in 4n log2 n + n con il trucco (A1+A2)(B1+B2) e (A1-A2)(B1-B2) invece delle 4 chiamate (Theta(n^2)); gli autovalori sono la trasformata di Hadamard della prima riga (FHT, n log2 n) e il prodotto passa dalla base diagonalizzante; le matrici circolanti sono polinomi nella matrice di rotazione R, il loro prodotto è la convoluzione ciclica delle prime righe e si diagonalizzano con la matrice di Fourier: prodotto in O(n log n) con la FFT.Matrici circolanti e supercircolanti - algoritmi divide and conquer →).
Trasformate note a priori
La componente di è il prodotto scalare della riga di con . La prima riga di è fatta di soli .
Vettore costante. Se allora .
Dimostrazione. . Per , per il lemma di somma, perché non è un multiplo di .
Vettore con la sola prima componente. Se allora .
Dimostrazione. , con la prima colonna di , e è la prima colonna di , tutta di . In termini di polinomio: vale in ogni punto.
Più in generale la DFT di è la colonna di , cioè .
Esempio (). e (controllati con numpy).
Vettori -sparsi
Definizione. Siano e potenze di due, . Un vettore è -sparso se per ogni indice con .
Le componenti possono essere diverse da zero solo agli indici multipli di (sono , separate da zeri; non si esclude che anche quelle siano nulle). Esempio: un vettore -sparso ha la forma . Casi estremi: ogni vettore è -sparso; un vettore -sparso ha al più la sola componente (la sua DFT è nota).
Obiettivo. Un algoritmo D&C che calcoli per -sparso con operazioni: per si ritrova , per nessuna operazione.
Sottostruttura rinforzata. Siano e i vettori degli indici pari e dispari di , come nella FFT. Se (cioè pari):
- è -sparso: è nullo se , cioè se ;
- è il vettore nullo: ha indice dispari, che non può essere un multiplo della potenza di due .
Quindi e le formule di ricombinazione della FFT diventano e : la DFT è la concatenazione di con se stessa, senza nessuna operazione.
SPARSE_FFT(x, k)
n <- x.len
if k = 1 then return FFT(x)
if k = n then return (x[0], x[0], ..., x[0]) { n copie }
x0 <- (x[0], x[2], ..., x[n-2])
y0 <- SPARSE_FFT(x0, k/2)
for i <- 0 to n/2 - 1
y[i] <- y0[i]; y[i + n/2] <- y0[i]
return yCorrettezza. Segue dalla correttezza della FFT e dalla sottostruttura rinforzata, per induzione su .
Costo. Nel conquer ci sono solo assegnamenti, che non si contano come operazioni aritmetiche. La ricorrenza a due parametri è Srotolando (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 →) per : . L'ordine di grandezza vale anche per e per (). Se si contasse un'unità per ogni assegnamento, il lavoro sarebbe lineare e si otterrebbe . Il conteggio è stato verificato con un'implementazione per tutte le coppie , .
Conseguenza. La DFT di un vettore -sparso è formata da copie della del vettore che contiene le sue componenti non banali. Lo si vede anche direttamente: (cancellazione), che è periodica in con periodo .
Esempio (, ). . Le componenti non nulle hanno , ripetuta volte: .
Esempio d'esame. , . Per linearità ( è lineare) si scompone . Il primo addendo è costante, con DFT ; il secondo è -sparso con DFT . Somma: (verificato con la DFT calcolata dalla definizione).
La strategia, ripetibile in esercizi simili, è: guardare la struttura del vettore, scomporlo (anche con la linearità) in pezzi con trasformata nota, oppure riscrivere la sottostruttura della FFT usando la struttura, e studiare la ricorrenza.
Esponenziazione di polinomi
Dato e un intero , si vogliono i coefficienti di , cioè ( volte). Il limite di grado di è .
Primo approccio: quadrature successive con la convoluzione
La convoluzione è associativa, quindi si applica lo schema di Esponenziazione veloce per quadrature successivepotenza x^n con un operatore associativo con elemento neutro, costo = numero di applicazioni dell'operatore; STUPID_POWER costa n-1, la sottostruttura x^n = (x^floor(n/2))^2 (per n dispari per x) dà POWER con T(n) = floor(log2 n) + (numero di bit a 1 di n) - 1, Theta(log n) (caso peggiore 2 floor(log2 n), n = 2^t - 1); versioni iterative POWER2 e POWER3 dalla rappresentazione binaria di n; esempio con la matrice di Fibonacci; il modello a costo unitario vale solo se l'operatore non fa crescere gli operandi.Esponenziazione veloce per quadrature successive → con al posto del prodotto. Siano e le cifre binarie di , . Allora .
EXPONENTIATE(a, k)
d <- floor(log2 k) + 1
h <- k { h = (k_{d-1} ... k_0) in base 2 }
y <- a { all'iterazione i: y = a^(2^i) }
z <- (1) { elemento neutro della convoluzione; accumula il prodotto }
for i <- 0 to d - 1
if h è dispari then z <- LIN_CONV(z, y) { cifra k_i = 1 }
y <- LIN_CONV(y, y) { y = a^(2^(i+1)) }
h <- floor(h / 2)
return zLIN_CONV va nella versione per vettori di lunghezza qualsiasi (padding alla potenza di due). Analisi. All'inizio dell'iterazione , y ha lunghezza al più (la lunghezza di è ) e z ha lunghezza minore di (è la convoluzione di fattori di lunghezze , , e ). Quindi l'iterazione costa , e poiché :
Secondo approccio: potenza dei valori
Se si ha una rappresentazione per valori di su una base estesa con punti, i valori di sono le potenze dei valori di : , cioè . Basta quindi valutare, elevare e interpolare.
EXPONENTIATE2(a, k)
n <- a.len
h <- 2^ceil(log2((n-1)*k + 1)) { prima potenza di due >= (n-1)k+1 }
yp <- FFT((a | 0_{h-n}))
for i <- 0 to h - 1
yq[i] <- POWER3(yp[i], k) { potenza scalare per quadrature, O(log k) }
return INV_FFT(yq)La correttezza segue dalle considerazioni sopra: ha limite di grado , quindi lo determina e INV_FFT restituisce i suoi coefficienti (seguiti da zeri di padding). Costo: FFT e INV_FFT su vettori di taglia , quindi ; più potenze scalari ciascuna di prodotti, in tutto . Il totale è . Stesso ordine del primo approccio, ma l'algoritmo è più semplice e con costanti migliori: una trasformata diretta, una inversa e potenze, invece di convoluzioni di vettori sempre più lunghi.
Esempio (, ). , il limite di grado di è , quindi . e . Le potenze quarte:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
|---|---|---|---|---|---|---|---|---|
(per esempio e quindi .) L'antitrasformata di questo vettore è , cioè , con i tre zeri finali di padding. Verificato con numpy insieme a casi casuali per ciascun approccio.
Domande d'esame
- Calcolare senza eseguire la FFT. Traccia: , DFT .
- Quante operazioni esegue
SPARSE_FFTsu un vettore -sparso con e perché? Traccia: nessuna nel conquer, , quindi . - Per elevare alla sesta potenza un polinomio con 5 coefficienti usando la FFT, su quanti punti si valuta? Traccia: , .
Esercizi svolti: Esercizio - polinomio con tutte le radici dell'unità tranne 1 e -1, valutazione e DFT dei coefficienti (compito del 26 giugno 2025, es. 1); Esercizio - domande di prima parte su polinomi, DFT e FFT (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).
Versione ripasso
- Notevoli (DFT, matrice di Fourier e radici n-esime dell'unitàla DFT di ordine n valuta un polinomio di grado limitato da n sulle n radici n-esime dell'unità, y_i = p(ω^i) con ω = e^{2πi/n}; è il prodotto per la matrice di Fourier F_n, una Vandermonde invertibile. Le radici formano un gruppo moltiplicativo e valgono tre lemmi: cancellazione (ω_{dn}^{dk} = ω_n^k, ω_n^{n/2} = -1), dimezzamento (i quadrati delle n radici sono le n/2 radici n/2-esime, ciascuna due volte) e somma (la somma delle potenze di ω^k vale n se k è multiplo di n, 0 altrimenti). Teorema di convoluzione lineare: (c|0) = DFT^{-1}{2n}(DFT{2n}(a|0) ⊙ DFT_{2n}(b|0)).DFT, matrice di Fourier e radici n-esime dell'unità →): (riga di fatta di ; righe con il lemma di somma); (prima colonna di ). Esempio : , .
- -sparso: se ( potenze di due). Per : è -sparso (da ) e (indici dispari), quindi senza operazioni. La DFT è copie della ; direttamente: per cancellazione, periodica di periodo .
- SPARSE_FFT: : FFT; : copie di ; altrimenti ricorre su e duplica. Costo (gli assegnamenti non contano): (Fast Fourier Transform - algoritmo ricorsivo e trasformata inversala FFT calcola DFT_n (n potenza di due) con divide et impera: si separano i coefficienti di indice pari e dispari, p(x) = p0(x^2) + x p1(x^2), e per il lemma di dimezzamento bastano due DFT di ordine n/2; y_i = y0_i + w^i y1_i e y_{i+n/2} = y0_i - w^i y1_i. La ricorrenza T(n) = 2T(n/2) + 2n con T(1) = 0 ha soluzione esatta 2 n log2 n. L'inversa ha matrice F^{-1}_{ij} = w^{-ij}/n: si ottiene con la FFT sulle potenze negative (poi si divide per n fuori dalla ricorsione) oppure con DFT_n(y) rovesciato. LIN_CONV moltiplica due polinomi con n coefficienti in 12 n log2(2n) + 4n operazioni.Fast Fourier Transform - algoritmo ricorsivo e trasformata inversa →); se si contassero gli assegnamenti .
- Esempio: : ripetuta volte. Esame: , per linearità .
- Strategia: guardare la struttura dell'istanza, scomporre per linearità o riscrivere la sottostruttura della FFT, studiare la ricorrenza a due parametri.
- Esponenziazione, approccio 1: delle con (schema Esponenziazione veloce per quadrature successivepotenza x^n con un operatore associativo con elemento neutro, costo = numero di applicazioni dell'operatore; STUPID_POWER costa n-1, la sottostruttura x^n = (x^floor(n/2))^2 (per n dispari per x) dà POWER con T(n) = floor(log2 n) + (numero di bit a 1 di n) - 1, Theta(log n) (caso peggiore 2 floor(log2 n), n = 2^t - 1); versioni iterative POWER2 e POWER3 dalla rappresentazione binaria di n; esempio con la matrice di Fibonacci; il modello a costo unitario vale solo se l'operatore non fa crescere gli operandi.Esponenziazione veloce per quadrature successive → con LIN_CONV). All'iterazione i vettori hanno lunghezza e costo ; con il totale è .
- Approccio 2 (EXPONENTIATE2): limite di grado di è ; ; , ogni valore alla con POWER3 (), poi
INV_FFT. Costo , più semplice del primo. Esempio : , , antitrasformata . - Pseudocodice:
EXPONENTIATE(a,k):y <- a; z <- (1); h <- k; per : se è dispariz <- LIN_CONV(z,y);y <- LIN_CONV(y,y);h <- floor(h/2); restituiscez.EXPONENTIATE2(a,k):h <- 2^ceil(log2((n-1)k+1));yp <- FFT((a|0));yq[i] <- POWER3(yp[i],k); restituisceINV_FFT(yq). - Domande tipo: quante operazioni fa
SPARSE_FFTcon (nessuna nel conquer, in tutto); su quanti punti si valuta un polinomio con coefficienti elevato alla sesta: , . - Esercizi svolti: Esercizio - polinomio con tutte le radici dell'unità tranne 1 e -1, valutazione e DFT dei coefficienti (compito del 26 giugno 2025, es. 1); Esercizio - domande di prima parte su polinomi, DFT e FFT (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).
- Errori tipici: usare o invece di una potenza di due ; contare gli assegnamenti come operazioni; scambiare le due famiglie e ; dimenticare che la sparsità richiede potenza di due.
Esercizi su questo argomento
- Esercizio - domande di prima parte su polinomi, DFT e FFT (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 - polinomio con tutte le radici dell'unità tranne 1 e -1, valutazione e DFT dei coefficienti (compito del 26 giugno 2025, es. 1)