Algorithme CORDIC en python

Résolu/Fermé
Longo_11 Messages postés 5 Date d'inscription samedi 11 mars 2023 Statut Membre Dernière intervention 14 mars 2023 - Modifié le 14 mars 2023 à 13:55
Longo_11 Messages postés 5 Date d'inscription samedi 11 mars 2023 Statut Membre Dernière intervention 14 mars 2023 - 14 mars 2023 à 16:51

Bonjour

Je suis tout nouveau sur le forum python. Je ne suis pas un spécialiste des langages évolués, je fais plutôt de l'assembleur. Voila pour la présentation .

Je travaille actuellement sur l'algorithme CORDIC pour le calcul sinus cosinus, et j’ai un petit problème avec le calcul suivant :

Aux = (x + ou - (Y >> k))

Je sais que sous python, les rotations droite ou gauche s'écrivent de la forme :

x >> 2

On va appliquer à x deux rotations à droite, mais dans algorithme, k vaut 0,6073. Bon même si ramène sous forme décimale, cela nous fait : y >> 6073 et c’est que je ne comprends pas.

Lien vers l'algorithme

Cordialement

5 réponses

mamiemando Messages postés 33381 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 26 novembre 2024 7 802
Modifié le 14 mars 2023 à 14:37

Bonjour,

Préliminaires

Il y a deux problèmes dans le lien que tu pointes :

  • Il y a deux variables : K (en majuscule) est effectivement un flottant, et ce qui est noté k (en minuscule) qui est en réalité i.
  • On ne peut pas appliquer >> si l'opérande de gauche est u flottant, comme c'est le cas ici. En C/C++ on joue effectivement sur les décalages de bits pour accélérer les divisions par 2, mais c'est quelque chose que je déconseille très fortement sur un type non entier (la manière dont est encodé un flottant en mémoire est très différente). L'algorithme CORDIC proposé dans wikipedia confirme bien que l'auteur a bien voulu parler de divisions par des puissances de 2. Il faut donc changer ">> i" par "/ (2 ** i)".

Code proposé : en tenant compte des remarques faites en préliminaires :

#!/usr/bin/env python3

from math import atan, radians

def cordic(theta: float) -> tuple:
    """
    Approximates (cos(theta), sin(theta)) using the CORDIC algorithm.

    Args:
        theta (float): An angle, in radians.

    Returns:
        An approximation of (cos(theta), sin(theta)).
    """
    K = 0.6072529350088814
    n = 27
    atan_tab = [atan(2 ** (-i)) for i in range(0, n + 1)]

    x = K
    y = 0
    ecart = theta
    for i in range(0, n + 1):
        s = 1 if ecart >= 0 else -1
        aux = x - (s * y / (2 ** i))
        y += (s * (x / (2 ** i)))
        x = aux
        ecart -= s * atan_tab[i]
    return (x, y)

print(cordic(radians(30)))

(Depuis je l'ai rajouté dans la page wikipedia française dédiée)

Résultat : on retrouve bien un résultat conforme à celui qu'on peut simuler sur le site que tu pointes (ici pour 30°).

(0.8660254012499423, 0.5000000043898769)

Remarque : si tu es fan des décalages de bits, tu pourrais par contre remplacer le calcul (2 ** i) par :

def two_power_of_i(i):
    return (2 << (i - 1) if i >= 1 else 1)

for i in range(10):
    print(i, two_power_of_i(i))
0 1
1 2
2 4
3 8
4 16
5 32
6 64
7 128
8 256
9 512

Même si je ne te cache pas que personne n'écrirait ça en python :p D'ailleurs la plupart des gens se contenteraient de simplement utiliser math.sin ou math.cos.

Bonne chance

1
Diablo76 Messages postés 204 Date d'inscription vendredi 25 novembre 2022 Statut Membre Dernière intervention 30 octobre 2024 44
Modifié le 14 mars 2023 à 13:52

Salut,

Pour le calcul, c'est plutôt : 

num = int(input("Entrez un nombre: "))
rot = int(input("Entrez le nombre de rotation: "))

print(num >> rot)
0
Longo_11 Messages postés 5 Date d'inscription samedi 11 mars 2023 Statut Membre Dernière intervention 14 mars 2023
Modifié le 14 mars 2023 à 13:52

Merci pour ta réponse oui sur python c’est de la forme X >> rot  avec comme rot constante ou variable.

Cordialement 

0
Longo_11 Messages postés 5 Date d'inscription samedi 11 mars 2023 Statut Membre Dernière intervention 14 mars 2023
14 mars 2023 à 16:42

Bonsoir 

Merci pour vos réponses.J’ai terminé le programme en assembleur.

IL y a 10  passes et 5 chiffres décimaux et la précision est de 0,0137 pour le Sinus de 55 degrés’. cela prend 345781 cycles machine et occupe 200 octets de mémoire . Je vais mettre le code dans la section ASM.

Je ne sais pas comment faire pour marquer cela résolu.

Encore merci pour vos réponses 

Cordialement

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Longo_11 Messages postés 5 Date d'inscription samedi 11 mars 2023 Statut Membre Dernière intervention 14 mars 2023
14 mars 2023 à 16:51

Bon je vois que c’est marqué résolu c’est super. Petit précision le micro contrôleur est un 8 bits un 18F de chez Microchip.

cordialement 

0