CORDIC - Définition

Source: Wikipédia sous licence CC-BY-SA 3.0.
La liste des auteurs de cet article est disponible ici.

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       #include       #include              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                 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                 for(int 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;      }      

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 :

\left\{\begin{matrix} x_{k+1} = x_k - m\sigma_k y_k 2^{-k} \\ y_{k+1} = y_k + \sigma_k x_k 2^{-k} \\ z_{k+1} = z_k - \sigma_k \varepsilon_k \end{matrix}\right.

avec m \in \{-1; 0; 1\} , \varepsilon_k des constantes définies à l'avance et \sigma_k \in \{-1; 1\} (en fonction de la valeur de zk).

Fonctions trigonométriques

On utilise la généralisation avec les paramètres :

m = 1~
\varepsilon_k = \operatorname{atan}(2^{-k})
\sigma_k = \operatorname{sgn}(z_k)
x_0 =\prod_{i=0}^{\infty} \cos(\operatorname{atan}(2^{-i})) \approx 0,60725
y_0 = 0~
z_0 = \theta~ (en radians)

À la fin de n itérations, on a x_n \approx \cos(\theta) et y_n \approx \sin(\theta) .

Cette méthode ne fonctionne que si :

| \theta | < \sum_{i=0}^{\infty} \operatorname{atan}(2^{-i}) \approx 1,7

En pratique cela ne pose pas de problème car les fonctions sinus et cosinus peuvent être extrapolées à partir des valeurs | \theta | < \frac{\pi}{2}

Fonctions hyperboliques

On utilise la généralisation avec les paramètres :

m = -1~
\varepsilon_k = \operatorname{atanh}(2^{-k})
\sigma_k = \operatorname{sgn}(z_k)
x_0 =\prod_{i=0}^{\infty} \cosh(\operatorname{atanh}(2^{-i})) \approx 1,20513
y_0 = 0~
z_0 = \theta~ (en radians)

À la fin de n itérations, on a x_n \approx \cosh(\theta) et y_n \approx \sinh(\theta) , ainsi que x_n + y_n \approx e^\theta .

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.

Fonctions linéaires

CORDIC permet également de calculer la multiplication ou la division entre des nombres a et b.

Multiplication

m = 0~
\varepsilon_k = 2^{-k}
\sigma_k = \operatorname{sgn}(z_k)
x0 = a
y_0 = 0~
z_0 = b~

À la fin de n itérations, on a y_n \approx a \cdot b . En pratique, elle est peu intéressante car son domaine est restreint. Il faut impérativement que b \in [-2;2] .

Division

m = 0~
\varepsilon_k = 2^{-k}
\sigma_k = -\operatorname{sgn}(y_k)
x_0 = b~
y_0 = a~
z_0 = 0~

À la fin de n itérations, on a z_n \approx a / b . Elle a toutefois le même défaut que la multiplication puisque la condition sur b doit être remplie : b \in [-2;2] .

Page générée en 0.124 seconde(s) - site hébergé chez Contabo
Ce site fait l'objet d'une déclaration à la CNIL sous le numéro de dossier 1037632
A propos - Informations légales
Version anglaise | Version allemande | Version espagnole | Version portugaise