Voici le principe, pour les fonctions trigonométriques. Soit à calculer et , pour un certain angle . L'idée consiste à approcher par la suite , définie par et pour tout :
La série de terme général est convergente. De plus, pour tout :
Démontrez-le, et déduisez-en que la suite converge vers , pour tout compris entre deux valeurs extrêmes :
Ce n'est pas une limitation gênante : comme vous le savez, on peut toujours se ramener à un angle compris entre 0 et , quitte à changer ensuite le signe du résultat.
n=[1:100]; sum(atan(2^(-n)))/%piLes angles sont fixes : ils peuvent être tabulés et mémorisés. Peu de valeurs sont nécessaires, car pour assez grand, est une bonne approximation de .
d=2^(-[0:10]); atan(d)-dNotons l'angle . Les valeurs approchant le cosinus et le sinus de sont , . Le vecteur de coordonnées se déduit du précédent par une rotation d'angle (d'où le nom de l'algorithme) :
Pour tout , posons
Posons , et pour tout , . Il vient :
La puissance de l'algorithme réside dans cette formule de récurrence : elle ne comporte que des additions, et des multiplications par . Or par définition de , . Multiplier par en arithmétique binaire, c'est décaler la virgule de places, et éventuellement inverser le bit de signe. Le calcul de est donc peu coûteux. Pour revenir à , il faut multiplier par : les valeurs de sont fixes et peuvent être mémorisées. Peu de valeurs sont nécessaires car le produit converge vite.
cumprod(cos(atan(2^(-[0:15]))))Voici en Scilab le calcul de et (non optimisé bien sûr).
theta=1; tn=0; v=[1;0]; V=[]; n=40; for i=0:n, s=sign(theta-tn); tn=tn+s*atan(2^(-i)); b=s*2^(-i); M=[1,-b;b,1]; v=M*v; V=[V,v]; end; K=cumprod(cos(atan(2^(-[0:n])))); sc=V.*[K;K] sc-[cos(theta);sin(theta)]*ones(1,n+1)Pour les autres fonctions usuelles, il faut définir une autre notion de «rotation», mais le principe reste le même : une récurrence linéaire peu coûteuse, éventuellement suivie d'une multiplication par des valeurs mémorisées.