Come già sottolineato da @DavidRicherby, la confusione sorge perché diverse misure di complessità si stanno confondendo. Ma lasciami elaborare un po '.
Di solito, quando si studiano algoritmi per la moltiplicazione polinomiale su anelli arbitrari, si è interessati al numero di operazioni aritmetiche nell'anello utilizzate da un algoritmo. In particolare, dati alcuni anello (commutativo, unitario) e due polinomi f , g ∈ R [ X ] di grado inferiore a n , l'algoritmo di Schönhage-Strassen necessita di moltiplicazioni O ( n log n log log n ) e aggiunte in R per calcolare f g ∈ R [ X ]Rf, g∈ R [ X]nO ( n logn loglogn )Rfg∈ R [ X]da, approssimativamente, adiacente -esimo radici primitive di unità di R per ottenere qualche grande anello D ⊃ R e quindi, mediante la trasformata di Fourier su D , calcolando il prodotto D .nRD ⊃ RDD
Se l'anello contiene un radice -esimo di unità, allora questo può essere accelerato a O ( n log n ) operazioni in R utilizzando Fast Fourier Transform direttamente sopra R . Più specificamente, su Z ⊂ C , puoi farlo usando le operazioni dell'anello O ( n log n ) (ignorando il fatto che ciò richiederebbe un'aritmetica esatta sui numeri complessi).nO ( n logn )RRZ ⊂ CO ( n logn )
L'altra misura che può essere presa in considerazione è la complessità dei bit di un'operazione. E questo è ciò che ci interessa quando si moltiplicano due numeri interi di lunghezza bit . Qui, le operazioni primitive si stanno moltiplicando e aggiungendo due cifre (con carry). Quindi, quando si moltiplicano due polinomi su Z , in realtà è necessario tenere conto del fatto che i numeri che sorgono durante il calcolo non possono essere moltiplicati utilizzando un numero costante di operazioni primitive. Questo e il fatto che Z non abbia una n -esima radice primitiva di unità per n > 2 ti impedisce di applicare O ( n log n )nZZnn > 2O ( n logn )algoritmo. Superare questo considerando con coefficienti dall'anello Z / ⟨ 2 n + 1 ⟩ , dato che i coefficienti del polinomio prodotto non supererà questo vincolato. Lì (quando n è una potenza di due), hai (la classe di congruenza di) 2 come n -esima radice di unità, e chiamando ricorsivamente l'algoritmo per le moltiplicazioni dei coefficienti, puoi ottenere un totale di O ( n log n log log n ) operazioni primitive (cioè bit). Questo quindi passa alla moltiplicazione dei numeri interi.f, gZ / ⟨ 2n+ 1 ⟩n2nO ( n logn loglogn )
Per un esempio che evidenzi bene l'importanza della differenza tra operazioni ad anello e operazioni primitive, considera due metodi per valutare i polinomi: il metodo di Horner e il metodo di Estrin. Il metodo di Horner valuta un polinomio ad alcuni x ∈ Z sfruttando l'identità
f ( x ) = ( … ( f n x + f n - 1 ) x + … + … ) +f= ∑ni = 0fioXiox ∈ Z
mentre il metodo di Estrin divide f in due parti
H = n / 2 ∑ i = 1 f n / 2 + i X i e
L = n / 2 ∑ i = 0 f i X i
cioè, H contiene i termini del grado > n / 2 e L i termini di grado ≤ n / 2 (assumere n
f( x ) = ( … ( fnx + fn - 1) x + … + … ) + f0
fH= ∑i = 1n / 2fn / 2 + iXio
L = ∑i = 0n / 2fioXio
H> n / 2L≤ n / 2n è un potere di due, per semplicità).
Quindi, possiamo calcolare usando
f ( x ) = H ( x ) x n / 2 + L ( x )
e applicando l'algoritmo in modo ricorsivo.f( x )
f( x ) = H( x ) xn / 2+ L ( x )
Il primo, usando addizioni e moltiplicazioni, si è dimostrato ottimale rispetto al numero di addizioni e moltiplicazioni (ovvero operazioni ad anello), il secondo ha bisogno di più (almeno n + log n ).nn + logn
n / 2n / 2Ω ( n2)nO ( n )O ( n logcn ) = O~( n )c > 0