Aller au contenu

« Algorithme Toom-Cook » : différence entre les versions

Un article de Wikipédia, l'encyclopédie libre.
Contenu supprimé Contenu ajouté
Fschwarzentruber (discuter | contributions)
Aucun résumé des modifications
Chouhartem (discuter | contributions)
Réécriture à partir de la version anglaise. Il reste à rajouter un exemple et les comparaisons avec les différentes version de l'algorithme pour différentes versions de k. Potentiellement lier les références aussi.
Ligne 1 : Ligne 1 :
{{Ébauche|informatique}}
{{Ébauche|informatique}}


L''''algorithme Toom-Cook''', parfois appelé '''Toom-3''', est un [[algorithme de multiplication]] dû à {{Lien|langue=en|fr=Andrei Toom}} et [[Stephen Cook]], utilisé pour multiplier deux grands nombres. Ces grands nombres sont découpés en plus petits nombres sur lesquels on effectuera les calculs. C'est un raffinement de l'[[algorithme de Karatsuba]]. L'algorithme est basé sur le paradigme [[diviser pour régner]] où on divise les écritures des nombres en k parties. Toom-3 est l'algorithme Took-Cook pour k = 3.
L''''algorithme Toom-Cook''', parfois appelé '''Toom-3''', est un [[algorithme de multiplication]] dû à {{Lien|langue=en|fr=Andrei Toom}} 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 ''Θ(n<sup>log(5)/log(3)</sup>) ≈ Θ(n<sup>1.465</sup>)''.


== Description ==
== Description ==


L'algorithme de Toom-Cook peut se décomposer en cinq phases :
Multiplier deux nombres revient à multiplier deux [[polynôme]]s

# Le découpage
# L'évaluation
# Les multiplications point par point
# L'interpolation
# La recomposition

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{{sfn|Marco Bodrato|2007}}.

=== Le découpage ===

Étant donné deux nombres ''m'' et ''n'' en base ''b'', on commence par choisir une nouvelle base ''B = b<sup>i</sup>'' de façon à ce 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 :
: <math>i=\max\left\{ \left\lfloor \frac{\lfloor \log_b m \rfloor}{k} \right\rfloor, \left\lfloor \frac{\lfloor \log_b n \rfloor}{k} \right\rfloor \right\} + 1. </math>

Ainsi on peut définir les polynômes dont ces chiffres correspondent à leurs coefficient, c'est-à-dire :
: <math>P(x) = \sum_{i=0}^{k-1} m_i x^i,</math>
: <math>Q(x) = \sum_{i=0}^{k-1} n_i x^i.</math>

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) \cdot Q(x)'' alors l’évaluation de ce produit en ''B'' coïncide avec le produit recherché: ''R(B) = m·n''.

=== Évaluation ===

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és ''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 <math>0, 1, -1, 2, \infty</math>.

Ainsi ces évaluations sur P nous donne :
: <math>P(0) = m_0,</math>
: <math>P(1) = m_2 + m_1 + m_0,</math>
: <math>P(-1) = m_2 - m_1 + m_0,</math>
: <math>P(2) = 4 \cdot m_2 + 2 \cdot m_1 + m_0,</math>
: <math>P(\infty) = m_2.</math>

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

=== Les multiplications point par point ===

Une fois qu'on a nos différentes évaluations, il est alors possible de calculer <math>R(a_i) = P(a_i) \cdot Q(a_i)</math> pour chaque point d'évaluation ''a<sub>i</sub>''. Dans le cas de Toom-3, on rappelle que ces points sont <math>(a_i)_{0 \leq i \leq 4} = (0, 1, -1, 2, \infty)</math>. Comme on multiplie deux nombres de taille ''l'', on peut réappliquer récursivement notre algorithme pour calculer ces sous-produits.

=== L'interpolation ===

Une fois qu'on a nos valeurs ''r<sub>i</sub>'' 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'':
:<math>
:<math>
A(x)
=
\begin{pmatrix}
\begin{pmatrix}
R(0)\\
x^2 & x^1 & x^0
R(1)\\
R(-1)\\
R(2)\\
R(\infty)
\end{pmatrix}
\end{pmatrix}
\begin{pmatrix}
a_2 & a_1 & a_0
\end{pmatrix}^T
</math>
et
:<math>
B(x)
=
=
\begin{pmatrix}
\begin{pmatrix}
x^2 & x^1 & x^0
1 & 0 & 0 & 0 & 0\\
1 & 1 & 1 & 1 & 1\\
1 & -1 & 1 & -1 & 1\\
1 & 2 & 4 & 8 & 16\\
0 & 0 & 0 & 0 & 1
\end{pmatrix}
\end{pmatrix}
\begin{pmatrix}
\begin{pmatrix}
r_0\\
b_2 & b_1 & b_0
r_1\\
\end{pmatrix}^T
r_2\\
r_3\\
r_4
\end{pmatrix}.
</math>
</math>

ce qui donne un troisième polynôme
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 :
:<math>
:<math>
P(x)
=
A(x)B(x)
=
\begin{pmatrix}
\begin{pmatrix}
r_0\\
x^4 & x^3 & x^2 & x^1 & x^0
r_1\\
\end{pmatrix}
r_2\\
\begin{pmatrix}
r_3\\
p_4 & p_3 & p_2 & p_1 & p_0
r_4
\end{pmatrix}^T
</math>
En évaluant <math>P</math> en cinq points distincts
:<math>
\begin{pmatrix}
P(\infty) \\
P( 2) \\
P(-1) \\
P( 1) \\
P( 0)
\end{pmatrix}
\end{pmatrix}
=
=
\begin{pmatrix}
\begin{pmatrix}
1 & 0 & 0 & 0 & 0 \\
1 & 0 & 0 & 0 & 0\\
16 & 8 & 4 & 2 & 1 \\
1 & 1 & 1 & 1 & 1\\
1 & -1 & 1 & -1 & 1 \\
1 & -1 & 1 & -1 & 1\\
1 & 1 & 1 & 1 & 1 \\
1 & 2 & 4 & 8 & 16\\
0 & 0 & 0 & 0 & 1
0 & 0 & 0 & 0 & 1
\end{pmatrix}
\end{pmatrix}^{-1}
\begin{pmatrix}
\begin{pmatrix}
p_4 \\
R(0)\\
p_3 \\
R(1)\\
p_2 \\
R(-1)\\
p_1 \\
R(2)\\
R(\infty)
p_0
\end{pmatrix}
\end{pmatrix}.
</math>
</math>

on détermine ses coefficients via une [[Interpolation polynomiale|interpolation]]
En calculant cet inverse, on obtient alors :
:<math>
:<math>
\begin{pmatrix}
\begin{pmatrix}
p_4 \\
r_0\\
p_3 \\
r_1\\
p_2 \\
r_2\\
p_1 \\
r_3\\
r_4
p_0
\end{pmatrix}
\end{pmatrix}
=
=
\begin{pmatrix}
\begin{pmatrix}
1 & 0 & 0 & 0 & 0 \\
1 & 0 & 0 & 0 & 0 \\
16 & 8 & 4 & 2 & 1 \\
-\frac{1}{2} & 1 & -\frac{1}{3} & -\frac{1}{6} & 2 \\
1 & -1 & 1 & -1 & 1 \\
-1 & \frac{1}{2} & \frac{1}{2} & 0 & -1 \\
1 & 1 & 1 & 1 & 1 \\
\frac{1}{2} & -\frac{1}{2} & -\frac{1}{6} & \frac{1}{6} & -2 \\
0 & 0 & 0 & 0 & 1
0 & 0 & 0 & 0 & 1
\end{pmatrix}^{-1}
\begin{pmatrix}
P(\infty) \\
P( 2) \\
P(-1) \\
P( 1) \\
P( 0)
\end{pmatrix}
\end{pmatrix}
</math>
Ce calcul nécessite cinq multiplications trois fois plus simples et quelques additions
:<math>\begin{align}\begin{pmatrix}
p_4 \\
p_3 \\
p_2 \\
p_1 \\
p_0
\end{pmatrix}&=\begin{pmatrix}
1 & 0 & 0 & 0 & 0 \\
16 & 8 & 4 & 2 & 1 \\
1 & -1 & 1 & -1 & 1 \\
1 & 1 & 1 & 1 & 1 \\
0 & 0 & 0 & 0 & 1
\end{pmatrix}^{-1}
\begin{pmatrix}
\begin{pmatrix}
R(0)\\
A(\infty)B(\infty) \\
R(1)\\
A( 2)B( 2) \\
A(-1)B(-1) \\
R(-1)\\
R(2)\\
A( 1)B( 1) \\
R(\infty)
A( 0)B( 0)
\end{pmatrix}\\&=\begin{pmatrix}
\end{pmatrix}.
</math>
1 & 0 & 0 & 0 & 0 \\

16 & 8 & 4 & 2 & 1 \\
=== Reconstruction ===
1 & -1 & 1 & -1 & 1 \\

1 & 1 & 1 & 1 & 1 \\
Finalement, il nous reste plus qu'à évaluer la valeur de <math>R(B) = \sum_{i=0}^{2k-2} r_i B^i</math> 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.
0 & 0 & 0 & 0 & 1

\end{pmatrix}^{-1}
== Notes et Références ==
\begin{pmatrix}
{{Traduction/Référence|en|Toom–Cook multiplication|988816153}}
a_2b_2 \\
{{Références}}
(4a_2+2a_1+a_0)(4b_2+2b_1+b_0) \\
(a_2-a_1+a_0)(b_2-b_1+b_0) \\
(a_2+a_1+a_0)(b_2+b_1+b_0) \\
a_0b_0
\end{pmatrix}~.\end{align}</math>
La [[complexité]] est donc
:<math>O(n^{\log_3 (5)}) \simeq O(n^{1{,}465})</math>.


== Références ==
== Bibliographie ==
* {{ru}} Andrei Toom, ''{{lien brisé|url=http://www.de.ufpe.br/~toom/my_articles/rusmat/MULT-R.PDF |titre=О сложности схемы из функциональных элементов, реализующей умножение целых чисел }}'', Доклады Академии Наук СССР, T. 150, {{Numéro|3}}, 1963, {{p.|496-498}}, {{en}} {{lien brisé|url=http://www.de.ufpe.br/~toom/my_articles/engmat/MULT-E.PDF |titre=The Complexity of a Scheme of Functional Elements Realizing the Multiplication of Integers }}, {{p.|714-716}}
* {{ru}} Andrei Toom, ''{{lien brisé|url=http://www.de.ufpe.br/~toom/my_articles/rusmat/MULT-R.PDF |titre=О сложности схемы из функциональных элементов, реализующей умножение целых чисел }}'', Доклады Академии Наук СССР, T. 150, {{Numéro|3}}, 1963, {{p.|496-498}}, {{en}} {{lien brisé|url=http://www.de.ufpe.br/~toom/my_articles/engmat/MULT-E.PDF |titre=The Complexity of a Scheme of Functional Elements Realizing the Multiplication of Integers }}, {{p.|714-716}}
* {{en}} [[Donald Knuth]], ''[[The Art of Computer Programming]]'', Vol. 2, {{3e}} éd. , Addison-Wesley, 1997
* {{en}} [[Donald Knuth]], ''[[The Art of Computer Programming]]'', Vol. 2, {{3e}} éd. , Addison-Wesley, 1997
* {{en}} [[Richard Crandall]], [[Carl Pomerance]], ''Prime Numbers - A Computational Perspective'', {{2e}} éd. , Springer, 2005
* {{en}} [[Richard Crandall]], [[Carl Pomerance]], ''Prime Numbers - A Computational Perspective'', {{2e}} éd. , Springer, 2005
* {{en}} [http://gmplib.org/manual/Toom-3_002dWay-Multiplication.html Toom 3-Way Multiplication], documentation de [[GNU Multiprecision Library|GMP]]
* {{en}} [http://gmplib.org/manual/Toom-3_002dWay-Multiplication.html Toom 3-Way Multiplication], documentation de [[GNU Multiprecision Library|GMP]]
* {{article|titre=Towards Optimal Toom-Cook Multiplication for Univariate and Multivariate Polynomials in Characteristic 2 and 0|auteur1=Marco Bodrato|périodique=WAIFI|année=2007|langue=en|doi=10.1007/978-3-540-73074-3_10}}


{{Palette Multiplication}}
{{Palette Multiplication}}

Version du 28 septembre 2021 à 22:42

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

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 recomposition

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

Étant donné deux nombres m et n en base b, on commence par choisir une nouvelle base B = bi de façon à ce 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) \cdot Q(x) alors l’évaluation de ce produit en B coïncide avec le produit recherché: R(B) = m·n.

Évaluation

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és 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

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

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 :

Reconstruction

Finalement, il 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.

Notes et Références

Bibliographie