IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Calcul sur une valeur de sinus approximative [Python 3.X]


Sujet :

Python

  1. #1
    Membre averti Avatar de speedy_souris
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 47
    Par défaut Calcul sur une valeur de sinus approximative
    Bonjour,

    Mon objectif calculer la valeur approximative de sinus d'un angle qui aurait une valeur <~10-6
    en utilisant la serie de TAYLOR
    je voudrais comprendre pourquoi je n'ai pas le résultat attendu dans mon script
    merci de m'aiguiller
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    from math import factorial
    """Script pour le calcul d'une valeur approximative du sinus d'un angle
        donné par l'utilisateur en utilisant la serie de TAYLOR
        avec une valeur d'affichage du sinus < ~ 10-6
     """
     
    x = float(input())
    n = 0
    expo, fact = 0, 0
    expo2, fact2 = 0, 0
    sinX = 0
     
    while not (sinX < sinX * 10 ** -6):
        expo = 2 * n + 1
        fact = factorial(expo)
        n += 1
        expo2 = 2 * n + 1
        fact2 = factorial(expo2)
        n += 1
        sinX = -1 ** n * ((((x ** expo) * fact2) + ((x ** expo2) * fact)) / (fact * fact2))
     
    print(sinX)

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Je ne reconnais pas du tout la série de Taylor dans votre code ....

    Une série de Taylor c'est une somme. Donc je devrais voir :
    1) une somme qui se cumule au fil des boucles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ma_somme = 0
    while ...
         ma_somme += qqch
    2) le terme général de la somme dans la boucle

    Ensuite votre critère d'arrêt... Vous êtes sûr que ca va s'arrêter ? Si SinX est strictement positif, alors 0.00001 * SinX est nécéssairement plus petit et on ne sort jamais de votre while .... Vous avez une certain valeur du sinus. A l'itération suivante vous en avez une autre. La précision c'est la différence entre ces 2 valeurs calculée à une itération d'écart.

  3. #3
    Membre averti Avatar de speedy_souris
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 47
    Par défaut
    bonjour lg_53,
    merci pour la réponse,
    voila l'énoncé que je dois résoudre,
    Nom : Capture du 2019-02-27 17-29-42.png
Affichages : 7395
Taille : 69,0 Ko
    formule sur laquelle je mesuis référencé:
    Nom : Capture du 2019-02-27 17-33-55.png
Affichages : 5681
Taille : 62,6 Ko
    débutant en programmation python et de ce que je me rappelle de l'école (trés lointain souvenir...)
    pour additionner une fraction il faut les mettrent au même dénominateur non ?

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Non, python sait additionner 1/2 et 1/3 puisqu'il représente tous cela en nombre réels ! Ne cherchez pas midi à 14h, entrez la formule telle quelle, python saura se débrouiller.

    Effectivement basé vous sur la formule wikipédia, le symbole somme infinie c'est votre boucle, et ce qu'il y a dedans c'est le terme général de votre somme, c'est à dire ce que vous allez ajouter à votre approximation à chaque tour de boucle.

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Ce genre de calcul est facile à faire une fois qu'on en a compris la méthode.

    On fait une boucle while, et on a 3 variables à suivre:
    - n=le numéro du terne qu'on est en train de calculer: on commence à n=0 et on ajoute 1 à chaque tour de boucle.
    - t=le terme qu'il faut calculer à partir du terme précédent (ce qui évitera de calculer la factorielle). Le 1er terme pour n=0, c'est t=x
    - s= la somme des termes qu'on a déjà calculée. Pour n=0, c'est s=t. Après, ce sera s=s+t

    Le point délicat, c'est comment passe-t-on du terme précédent n-1 au terme suivant n?
    Exemples:
    - comment passer de +x pour n=0, à -x**3/3! pour n=1 ?
    - comment passer de -x**3/3! pour n=1, à +x**5/5! pour n=2 ?
    - etc...
    On voit bien qu'en utilisant la valeur de x et de n, on peut trouver une formule simple pour faire ça!. On va créer de ce fait une "formule de récurrence".

    Et on arrête la boucle quand le terme qu'on vient de calculer devient inférieur à la valeur qu'on a prise comme précision (e=1.0e-6).

    A noter qu'au lieu de s'arrêter plus tôt, on peut aller "au bout", c'est à dire arrêter la boucle quand la somme ne varie plus, et qu'on trouve alors la même valeur de sinus que celle du module "math". Mieux encore, en faisant le calcul avec le module "decimal", on peut calculer ce même sinus avec 50 ou 100 décimales, ce qui n'a, bien sûr, aucun intérêt pratique...

  6. #6
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    t=le terme qu'il faut calculer à partir du terme précédent (ce qui évitera de calculer la factorielle). Le 1er terme pour n=0, c'est t=x
    Certes on peut ne pas recalculer la factorielle, mais déjà s'il comprend comment fait-on en rentrant la formule brute, qui recalcule toute la factorielle à chaque fois ce sera déjà pas mal je pense...

  7. #7
    Membre averti Avatar de speedy_souris
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 47
    Par défaut
    merci à vous pour vos remarques,
    je viens d'installer l'IDE Thonny qui va je pense beaucoup m'aidé au niveau du debugage du code

  8. #8
    Membre averti Avatar de speedy_souris
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 47
    Par défaut
    je reviens vers vous avec un nouveau code nouveau soucis
    mon code en pas a pas (mode debug) donne deux valeurs une positive l'autre négative
    comment on peut s'en douter les valeurs sont fausses
    mais le plus curieux c'est qu'il se limite a 2 tours de boucles meme avec une condition toujours vrai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    from math import factorial
     
    x = float(input())
    n, s, t = 0, 0, 0
     
    expo, fact = 0, 0
     
    while s+1 > 0.000001:
        t = (-1)**n*x
        s = t
        n += 1
        t = (-1)**n*x
        expo = 2 * n + 1
        fact = factorial(expo)
        s += t * expo / fact
     
    print(s)

  9. #9
    Membre averti Avatar de speedy_souris
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 47
    Par défaut
    en fin de compte la solution était plus simple que mon code de départ,
    encore merci pour conseils qui m'ont beaucoup aider
    voici mon code final
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from math import factorial
     
    x = float(input())
    t, n, s = 1, 0, 0
     
    while abs(t) > 1e-6:
        t = (-1)**n * x**(2*n+1) / factorial(2*n+1)
        s += t
        n += 1
     
    print(s)

  10. #10
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Voilà !

    On voit bien une somme s, qui s'incrémente au fil de tes boucles. On voit aussi bien le terme général de la somme, t, qui est exactement la formule wikipédia (texto).

    Maintenant ce code est fonctionnel mais tu va vite avoir des calculs lent si tu demandes une précision très petite. A voir si tu en as besoin ou pas, mais sinon, il faudra s'orienter vers l'optimisation proposée par tyrtamos pour ne pas recalculer des choses déjà précédemment calculé, ce qui accélèrera l'éxécution du code.

  11. #11
    Futur Membre du Club Avatar de le237sims
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Par défaut une solution sans math
    Citation Envoyé par speedy_souris Voir le message
    en fin de compte la solution était plus simple que mon code de départ,
    encore merci pour conseils qui m'ont beaucoup aider
    voici mon code final
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from math import factorial
     
    x = float(input())
    t, n, s = 1, 0, 0
     
    while abs(t) > 1e-6:
        t = (-1)**n * x**(2*n+1) / factorial(2*n+1)
        s += t
        n += 1
     
    print(s)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
     
    facto=float(1)
    x=float(input())
    sin=float(0)
    n=float()
    terme=float(0)
    k=0
    sauv_n=float(0)
    while  sin  < 10e-6 or sin==0:
        for n in range (1, 7, 2):
            sauv_n=n
            #Factoriel
            facto =1
            for ii in range(2,n+1):
                facto =facto*ii
            #Calcule d'un terme de l'équation
     
     
            terme = (x**sauv_n)/facto
     
            #Operation
            i=k%2
            if i == 0:
     
                sin=sin+terme
     
            elif i!=0:
     
                sin = sin-terme
     
            k+=1
     
    print(sin)

  12. #12
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par le237sims Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
     
    facto=float(1)
    x=float(input())
    sin=float(0)
    n=float()
    terme=float(0)
    k=0
    sauv_n=float(0)
    while  sin  < 10e-6 or sin==0:
        for n in range (1, 7, 2):
            sauv_n=n
            #Factoriel
            facto =1
            for ii in range(2,n+1):
                facto =facto*ii
            #Calcule d'un terme de l'équation
     
     
            terme = (x**sauv_n)/facto
     
            #Operation
            i=k%2
            if i == 0:
     
                sin=sin+terme
     
            elif i!=0:
     
                sin = sin-terme
     
            k+=1
     
    print(sin)
    Mouais. Déterrer un topic vieux de 3 ans, dans lequel une élégante solution de 11 lignes a été proposée, pour nous montrer ton "truc" de 34 lignes (limité en plus aux 3 premiers termes de la suite) ça reste très moyen

    Déjà la variable "sauv_n" sert à que dalle. Et ce elif i!=0 sans déconner (si égal 0 je fais un truc et sinon ben je vais quand-même tester s'il est différent de 0 au cas où il y aurait une 3° possibilité)... tiens rien que pour lui
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  13. #13
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Pour le fun, et comme je continue à détester les solutions qui calculent les factorielles, voilà une solution sans:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    def sin2(x):
        """ Calcul du sinus de x par série """
        xc = x*x # pour gagner du temps
        n, t = 0, x
        s1 = t
        while True:
            n += 1
            t *= -xc/(2*n*(2*n+1))
            s2 = s1 + t
            if s2==s1:
                break
            s1 = s2
        return s2
     
    print(sin2(0.5))
    Ce qui affiche:

    qui coïncide avec la valeur du sin(0.5) du module math (0.479425538604203)

    En ce qui concerne le choix de la condition d'arrêt, il faudrait tout de même vérifier qu'elle convient à toute la plage des valeurs de x, et si non, la remplacer par une autre condition du genre t<1e-16.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 23/12/2011, 08h40
  2. [2000] Comment calculer une valeur dans SSRS ?
    Par djimmy17 dans le forum SSRS
    Réponses: 1
    Dernier message: 14/07/2011, 08h52
  3. calculer une valeur dans un textbox au moment de la saisie
    Par Msysteme dans le forum Windows Forms
    Réponses: 9
    Dernier message: 16/04/2009, 18h15
  4. Decode avec des dates pour calculer une valeur
    Par decisio dans le forum Langage SQL
    Réponses: 1
    Dernier message: 19/01/2009, 12h50
  5. Réponses: 2
    Dernier message: 12/02/2008, 14h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo