- CORDIC
-
CORDIC (sigle de COordinate Rotation DIgital Computer : « calcul numérique par rotation de coordonnées ») est un algorithme de calcul des fonctions trigonométriques et hyperboliques, notamment utilisé dans les calculatrices. Il a été décrit pour la première fois en 1959 par Jack E. Volder. Il ressemble à des techniques qui avaient été décrites par Henry Briggs en 1624.
Il s'agit d'un algorithme de choix lorsque aucune implantation matérielle d'un multiplicateur n'est disponible (sur certains microcontrôleurs simples ou des FPGA). De plus, l'algorithme du CORDIC s'adapte bien au calcul à la chaîne. À l'origine, la programmation du CORDIC reposait sur un système binaire.
Durant les années 1970, les versions décimales du CORDIC (avec des nombres codés en BCD) commencèrent à apparaître, notamment dans les calculatrices où les critères de coût du matériel sont plus importants que la vitesse de traitement. Un autre avantage du CORDIC est sa flexibilité puisqu'il permet de calculer plusieurs fonctions avec quasiment le même code.
Sommaire
Description
CORDIC permet de déterminer le sinus ou le cosinus d'un angle donné en radians sous un format à virgule fixe. Pour trouver le sinus ou le cosinus d'un angle β, on recherche la coordonnée x ou y du point du cercle unité lui correspondant. CORDIC débute les calculs avec un vecteur v0 tel que :
Durant la première itération, le vecteur subit une rotation de 45° dans le sens anti-horaire (sens trigonométrique) afin d'obtenir un nouveau vecteur v1. Des itérations successives doivent engendrer une rotation du vecteur dans la bonne direction. À chaque itération, la rotation est faite d'un angle prédéterminé et moindre que le précédent. Ceci jusqu'à converger vers l'angle voulu.
Plus formellement, à chaque itération i, on calcule un nouveau vecteur grâce à la multiplication du vecteur vi avec la matrice de rotation Ri :
La matrice de rotation s'obtient selon la formule suivante :
En factorisant le terme on obtient :
Le facteur prend les valeurs +1 ou -1 et sert à indiquer le sens de la rotation. Si l'on restreint les choix possibles pour l'angle de manière à ce que soit égal à alors la multiplication par la tangente devient une multiplication par une puissance de 2. Une opération aisée à réaliser informatiquement puisqu'en binaire il s'agit d'un décalage de bits.
Le calcul devient :
avec
Ces coefficients Ki peuvent être ignorés pendant les itérations et factorisés en un seul coefficient multiplicatif final (dépendant de n) :
qui peut être calculé à l'avance et prémémorisé. Également, lorsque n tend vers l'infini, ce produit tend vers une constante :
- (0,60725294…)
Après suffisamment d'itérations, l'angle du vecteur sera proche de l'angle voulu.
La dernière étape consiste à déterminer à chaque itération le sens de rotation, trigonométrique ou horaire (un résultat reporté sur la valeur de ). Pour ce faire, on regarde l'angle βn + 1 actuel du vecteur que l'on soustrait à l'angle désiré. On teste si cette différence est positive (rotation dans le sens horaire) ou négative (sens trigonométrique), de façon à s'approcher de l'angle .
- ,
Les valeurs de γn sont précalculées dans une table prémémorisée de valeurs. Toutefois, pour des angles petits, on utilise l'approximation dans une représentation en virgule fixe, permettant ainsi de réduire la taille de cette table.
Comme illustré dans le schéma ci-dessus, le sinus de l'angle β est la coordonnée y du vecteur final vn, alors que la coordonnée x correspond au cosinus.
Algorithme
En 1971, John Stephen Walther de Hewlett Packard, a présenté une généralisation de l'algorithme qui fut implémentée dans la calculatrice HP-35. Cette méthode permet de calculer notamment les fonctions hyperboliques mais également d'autres fonctions comme l'exponentielle, la division ou la multiplication. La généralisation se présente comme suit[1] :
avec , εk des constantes définies à l'avance et (en fonction de la valeur de zk).
Fonctions trigonométriques
On utilise la généralisation avec les paramètres :
- (en radians)
À la fin de n itérations, on a et .
Cette méthode ne fonctionne que si :
En pratique cela ne pose pas de problème car les fonctions sinus et cosinus peuvent être extrapolées à partir des valeurs
Fonctions hyperboliques
On utilise la généralisation avec les paramètres :
- (en radians)
À la fin de n itérations, on a et , ainsi que .
Cette méthode ne fonctionne que si la valeur absolue de z est inférieure à environ 1,05. Des transformations d'expressions grâce à des identités trigonométriques permettent de contourner ces problèmes en faisant en sorte que les paramètres soient dans l'intervalle requis. La répétition de certaines itérations résout les problèmes de convergence[1].
Fonctions linéaires
CORDIC permet également de calculer la multiplication ou la division entre des nombres a et b.
Multiplication
- εk = 2 − k
- x0 = a
À la fin de n itérations, on a . En pratique, elle est peu intéressante car son domaine est restreint. Il faut impérativement que .
Division
- εk = 2 − k
À la fin de n itérations, on a . Elle a toutefois le même défaut que la multiplication puisque la condition sur b doit être remplie : .
Exemples de programmation
MATLAB
function v=cordic(beta,n) % Calcul de 'cos' et 'sin' d'un angle 'beta' (en radians) % par l'algorithme CORDIC. Résultat dans le vecteur 'v'. % 'n' est le nombre d'itérations (la précision augmente avec lui). %%Initialisation v=[1;0]; sigma=1; Kn=prod(1./sqrt(1+2.^(-2*(0:(n-1))))); %%Itérations for i=0:n-1; R=[1 -sigma*2^-i;sigma*2^-i 1]; v=R*v; beta=beta-sigma*atan(2^-i); sigma=sign(beta); end %% Calcul final v=v*Kn;
Langage C
Le code suivant utilise les flottants étendus (double). Beta est l'angle voulu en radians. On démarre par le vecteur v = (1;0), prémultiplié par K.
#include <stdio.h> #include <stdlib.h> #include <math.h> int main() { int nb_iter; // Nombre d'itérations double K = 0.6073; // Valeur de K double x = K, y = 0; // Valeur approchante de cos(beta) et sin(beta) double x_Nouveau; // Variable temporaire double beta = 0; // Angle à chercher double Pow2; // Valeur de la puissance de deux printf("Calcul par la methode CORDIC de sinus : \n\n\n Veuillez entrer beta\n"); scanf("%lf",&beta); // entrer la valeur de beta printf("Veuillez entrer le nombre d'iterations voulues\n"); scanf("%ld",&nb_iter); // Entrer le nombre d'itération int i = 0; // declaration de l'indice d'iteration for(i = 0; i < nb_iter; i++) { Pow2 = pow(2,-i); // Si beta<0 rotation dans le sens trigo if(beta < 0) { x_Nouveau = x + y*Pow2; y -= x*Pow2; beta += atan(Pow2); } // sinon dans l'autre sens else { x_Nouveau = x - y*Pow2; y += x*Pow2; beta -= atan(Pow2); } x = x_Nouveau; } printf("cos(beta) = %lf , sin(beta) = %lf \n", x,y); // Affichage du résultat return 0; }
Bibliographie
- Jack E. Volder, The CORDIC Trigonometric Computing Technique, IRE Transactions on Electronic Computers, septembre 1959
- Daggett, D. H., Decimal-Binary conversions in CORDIC, IRE Transactions on Electronic Computers, Vol. EC-8 n°5, pp335-339, IRE, septembre 1959.
- J. E. Meggitt, Pseudo Division and Pseudo Multiplication Processes, IBM Journal, avril 1962.
- Vladimir Baykov, Problems of Elementary Functions Evaluation Based on Digit by Digit (CORDIC) Technique, rapport de thèse, Université d'État de Leningrad d'ingénierie électrique, 1972
- Schmid, Hermann, Decimal computation. New York, Wiley, 1974
- V.D.Baykov,V.B.Smolov, Hardware implementation of elementary functions in computers, Université d'État de Leningrad, 1975, 96p.
- Senzig, Don, Calculator Algorithms, IEEE Compcon Reader Digest, Catalogue IEEE N° 75 CH 0920-9C, pp139-141, IEEE, 1975.
- V.D.Baykov, S.A.Seljutin, Elementary functions evaluation in microcalculators, Moscou, Radio & svjaz, 1982,64p.
- Vladimir D.Baykov, Vladimir B.Smolov, Special-purpose processors: iterative algorithms and structures, Moscou, Radio & svjaz, 1985, 288 pages
- M. E. Frerking, Digital Signal Processing in Communication Systems, 1994
- Vitit Kantabutra, On hardware for computing exponential and trigonometric functions, IEEE Trans. Computers 45 (3), 328-339 (1996).
- Andraka, Ray, A survey of CORDIC algorithms for FPGA based computers
- 'Le Secret des Algorithmes, Jacques Laporte, Paris 1981
- (en) Jean-Michel Muller, Elementary Functions – Algorithms and Implementation, 2nd Ed., Boston, Birkhäuser, 2006, 2e éd. (ISBN 978-0-8176-4372-0) (LCCN 2005048094)
- Lefèvre V., Zimmerman P., janvier 2004, Arithmétique flottante, Rapport de Recherche INRIA n°5105.
Notes
Voir aussi
Articles connexes
- Calcul numérique
- Approximation de fonction
- Variation de la Méthode de calcul du cosinus
Liens externes
- (en)Dspguru - Questions sur CORDIC
- (en)Synthèse sonore en FPGA
- (en)Vecteurs arbitraires dans CORDIC
- (en)méthode CORDIC à doubles itérations
- (en)discussions sur USENET
- (en)D'autres discussions sur USENET
- (en)Calculs de Arccos et avec CORDIC
- (en)programmation de CORDIC basée sur des tampons
- (en)http://www.math.niu.edu/~rusin/known-math/94/cordic
- (fr)Implémentation de CORDIC dans la ROM du HP-35 - Jacques Laporte (analyse pas à pas du firmware - simulateur de la ROM du calculateur avec breakpoints et trace.)
- (en)Digit by digit methods, Jacques Laporte, Paris 2006 (la filiation entre CORDIC et les anciennes méthodes notamment celle de Briggs)
Wikimedia Foundation. 2010.