Comme le souligne déjà @DavidRicherby, la confusion vient du fait que différentes mesures de complexité se mélangent. Mais laissez-moi développer un peu.
Habituellement, lorsque l'on étudie les algorithmes de multiplication polynomiale sur des anneaux arbitraires, on s'intéresse au nombre d'opérations arithmétiques dans l'anneau qu'un algorithme utilise. En particulier, étant donné un anneau (commutatif, unitaire) et deux polynômes de degré inférieur à , l'algorithme de Schönhage-Strassen a besoin de multiplications et additions dans afin de calculer en, grosso modo, en attachant -èmes racines primitives d'unité à pour obtenir un anneau plus grand et ensuite, en utilisant le Fast Transformation de Fourier surf , g ∈ R [ X ] n O ( n log n log log n ) R f g ∈ R [ X ] n R D ⊃ R D DRf,g∈R[X]nO(nlognloglogn)Rfg∈R[X]nRD⊃RD, Le calcul du produit .D
Si votre bague contient une racine -ième de l' unité, cela peut être accéléré jusqu'à opérations dans en utilisant la transformée de Fourier rapide directement sur . Plus spécifiquement, sur , vous pouvez le faire en utilisant les opérations d'anneau (en ignorant le fait que cela nécessiterait une arithmétique exacte sur les nombres complexes).O ( n log n ) R R Z ⊂ C O ( n log n )nO(nlogn)RRZ⊂CO(nlogn)
L'autre mesure qui peut être prise en compte est la complexité en bits d'une opération. Et c'est ce qui nous intéresse en multipliant deux entiers de longueur de bit . Ici, les opérations primitives se multiplient et ajoutent deux chiffres (avec report). Ainsi, lorsque vous multipliez deux polynômes sur , vous devez réellement prendre en compte le fait que les nombres qui surviennent pendant le calcul ne peuvent pas être multipliés à l'aide d'un nombre constant d'opérations primitives. Ceci et le fait que ne possède pas de -ième racine primitive d'unité pour vous empêche d'appliquer l'algorithme . Vous surmontez cela en considérantZ Z n n > 2 O ( n log n ) f , g Z / ⟨ 2 n + 1 ⟩ n 2 n O ( n log n log log n )nZZnn>2O(nlogn)f,gavec des coefficients de l'anneau , car les coefficients du polynôme produit ne dépasseront pas cette limite. Là (quand est une puissance de deux), vous avez (la classe de congruence de) comme -ième racine d'unité, et en appelant récursivement l'algorithme pour les multiplications de coefficient, vous pouvez obtenir un total de primitives (c'est-à-dire bit). Cela se transforme ensuite en multiplication entière.Z/⟨2n+1⟩n2nO(nlognloglogn)
Pour un exemple qui met bien en évidence l'importance de la différence entre les opérations en anneau et les opérations primitives, considérons deux méthodes pour évaluer les polynômes: la méthode de Horner et la méthode d'Estrin. La méthode de Horner évalue un polynôme à un certain en exploitant l'identité
tandis que la méthode d'Estrin divise en deux parties
et
c'est-à-dire que contient les termes de degré et les termes de degréf=∑ni=0fiXix∈Z
f(x)=(…(fnx+fn−1)x+…+…)+f0
fH=∑i=1n/2fn/2+iXi
L=∑i=0n/2fiXi
H>n/2L≤n/2(supposons que est une puissance de deux, pour plus de simplicité).
n
Ensuite, nous pouvons calculer utilisant
et en appliquant l'algorithme de manière récursive.f(x)
f(x)=H(x)xn/2+L(x)
Le premier, utilisant additions et multiplications, s'est avéré être optimal par rapport au nombre d'additions et de multiplications (c'est-à-dire les opérations en anneau), le second a besoin de plus (au moins ).nn+logn
Mais, au niveau des opérations sur les bits, on peut (assez facilement) montrer que dans le pire des cas, la méthode de Horner effectue multiplications de nombres de taille au moins , conduisant à plusieurs bits opérations (cela vaut même si nous supposons que deux nombres à bits peuvent être multipliés dans le temps ), alors que le schéma d'Estrin utilise pour certains , ce qui est de loin asymptotiquement plus rapide.n / 2 Ω ( n 2 ) n O ( n ) O ( n log c n ) = ˜ O ( n ) c > 0n/2n/2Ω(n2)nO(n)O(nlogcn)=O~(n)c>0