Algorithme Toom-Cook — Wikipédia

L'algorithme Toom-Cook, parfois appelé Toom-3, est un algorithme de multiplication dû à Andrei Toom (en) et Stephen Cook, utilisé pour multiplier deux grands nombres.

Ces grands nombres sont découpés en k morceaux de longueur l sur lesquels les multiplications sont faites récursivement à la manière d’un diviser pour régner. C’est une généralisation de l’algorithme de Karatsuba qui coïncide au cas où k = 2.

Par abus de langage, Toom-3 et Toom-Cook sont souvent utilisés de manière interchangeable. Or, Toom-3 est le cas où k = 3, où il y est fait 5 multiplications, ce qui, par application du master theorem donne une complexité en Θ(nlog(5)/log(3)) ≈ Θ(n1.465).

Description[modifier | modifier le code]

L'algorithme de Toom-Cook peut se décomposer en cinq phases :

  1. Le découpage
  2. L'évaluation
  3. Les multiplications point par point
  4. L’interpolation
  5. La reconstruction

Dans la suite, nous expliquerons le déroulement de l'algorithme de Toom-k pour n’importe quelle valeur de k. C'est une simplification de la description de l'algorithme donnée par Marco Bodrato[1].

Le découpage[modifier | modifier le code]

Étant donné deux nombres m et n en base b, on commence par choisir une nouvelle base B = bi afin que le nombre de chiffres en base B de m et n soit au plus k (par exemple 3 pour Toom-3). Un choix usuel est :

Ainsi on peut définir les polynômes dont ces chiffres correspondent à leurs coefficient, c'est-à-dire :

On remarque que P(B) = m et Q(B) = n, ainsi si on effectue le produit des polynômes pour avoir R(x) = P(x) · Q(x) alors l’évaluation de ce produit en B coïncide avec le produit recherché: R(B) = m·n.

L’évaluation[modifier | modifier le code]

Maintenant que nous avons défini les polynômes P et Q, calculer leur produit se fait par la méthode d’évaluation-interpolation. Pour cela on va évaluer le résultat du polynôme produit R en plusieurs points que l'on utilisera ensuite afin de l'interpoler et donc d'en trouver les coefficients.

Comme P et Q sont de degrés (k − 1), alors leur produit est de degré (2 · k − 2). Par exemple dans le cas de Toom-3, le produit de P et Q est de degré 4, il nous faut donc 5 points pour en calculer l’interpolation. Le choix des points importe peu, il suffit de garantir que l'interpolation est possible (ce qui sera rappelé dans la section Interpolation). Par exemple pour Toom-3, les points traditionnellement choisis sont .

Ainsi ces évaluations sur P nous donne :

On procède de manière similaire pour Q.

Les multiplications point par point[modifier | modifier le code]

Une fois qu'on a nos différentes évaluations, il est alors possible de calculer pour chaque point d'évaluation ai. Dans le cas de Toom-3, on rappelle que ces points sont . Comme on multiplie deux nombres de taille l, on peut réappliquer récursivement notre algorithme pour calculer ces sous-produits.

L’interpolation[modifier | modifier le code]

Une fois qu'on a nos valeurs ri pour i compris entre 0 et 2k - 2, on peut alors réécrire les relations entre P, Q et R de manière matricielle. Pour plus de clarté on explicitera le cas k = 3:

Cette matrice de passage correspondant à une matrice de Vandermonde, il suffisait alors de prendre des points deux à deux distincts pour qu'elle soit inversible. Ce qui se traduit alors par :

En calculant cet inverse, on obtient alors :

La reconstruction[modifier | modifier le code]

Finalement, il ne nous reste plus qu'à évaluer la valeur de afin d'obtenir le résultat du produit. Comme B est une puissance de notre base de travail b, cela se fait simplement à l'aide d'additions avec retenue.

Exemple[modifier | modifier le code]

Pour illustrer l’algorithme, on observera le déroulé de Toom-3 sur le produit de deux nombres à 60 décimales :

m = 834544525917432883830350648457459637471433260128185184920699

et

n = 198998441043619592623230746397999173308818723846794281749622

Le découpage : on commence par les découper en trois morceaux de 20 chiffres (c'est-à-dire qu'en base 10, on a pris i = 20) :

m2 = 83454452591743288383
m1 = 03506484574596374714
m0 = 33260128185184920699

et

n2 = 19899844104361959262
n1 = 32307463979991733088
n0 = 18723846794281749622.

L’évaluation : on utilise ensuite ces coefficients pour calculer les valeurs de et .

P(0) = 33260128185184920699
P(1) = 83454452591743288383 + 03506484574596374714 + 33260128185184920699
= 120221065351524583796
P(-1) = 83454452591743288383 - 03506484574596374714 + 33260128185184920699
= 113208096202331834368
P(2) = 4 × 83454452591743288383 + 2 × 03506484574596374714 + 33260128185184920699
= 374090907701350823659
P(∞) = 83454452591743288383
Q(0) = 18723846794281749622
Q(1) = 19899844104361959262 + 32307463979991733088 + 18723846794281749622
= 70931154878635441972
Q(-1) = 19899844104361959262 - 32307463979991733088 + 18723846794281749622
= 6316226918651975796
Q(2) = 4 × 19899844104361959262 + 2 × 32307463979991733088 + 18723846794281749622
= 162938151171713052846
Q(∞) = 19899844104361959262.

Remarque : À cette étape, il peut arriver que certaines évaluations (comme celle de P(-1)) soient négatives. Cela est normal et n'impacte en rien la correction ni le déroulement de l'algorithme.

Les multiplications point à point : une fois ces valeurs calculées, il suffit de les multiplier entre elles pour avoir les valeurs de et  :

R(0) = 33260128185184920699 × 18723846794281749622 = 622757544497574744270962786413043225778
R(1) = 120221065351524583796 × 70931154878635441972 = 8527419006123543277501478811621809485712
R(-1) = 113208096202331834368 × 6316226918651975796 = 715048024642510845238638992592216956928
R(2) = 374090907701350823659 × 162938151171713052846 = 60953680871006055212654676877543494083514
R(∞) = 83454452591743288383 × 19899844104361959262 = 1660730596390557308480735631788563853346.

L'interpolation : en utilisant la matrice d'interpolation de l'équation (1) on retrouve les coefficients de r :

La reconstruction : afin de retrouver le résultat final, il ne nous reste plus qu'à calculer la somme .

r = 1660730596390557308480735631788563853346 × 1080 + 2765980217466491844325943704643702017772 × 1060 + 2337745374494895008618360483905406142196 × 1040 + 1140205273274024371805476204871094246620 × 1020 + 622757544497574744270962786413043225778.

Ce qui donne bien :

r = 166073059639055730850839543396322877178949321158388650967858297625366381463859141170378031606999406270962786413043225778,

qui est le résultat du produit de m par n.

Notes et références[modifier | modifier le code]

Bibliographie[modifier | modifier le code]