[Python] Approximations de Pi... (Page 1) / Programmation / Forum de mathématiques - Bibm@th.net

Forum de mathématiques - Bibm@th.net

Bienvenue dans les forums du site BibM@th, des forums où on dit Bonjour (Bonsoir), Merci, S'il vous plaît...

Vous n'êtes pas identifié(e).

#1 21-05-2010 15:34:27

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 11 078

[Python] Approximations de Pi...

Bonjour,


Approximations via le calcul de la valeur approchée de \(\displaystyle \int_0^1 \frac{4}{1+x^2}\,dx\)
Justification :
          \(\displaystyle \int_0^1 \frac{4}{1+x^2}\,dx=4\big[arctan(x)\big]_0^1=4\left(\frac{\pi}{4}-0\right)=\pi\)
4 méthodes au choix :
méthode des rectangles, des trapèzes, des tangentes et formule de Simpson composée.
Seul le pas vous sera demandé, exclusivement 0.1, 0.01, 0.001, 0.0001... etc.

: Python

  1. # -*- coding: cp1252 -*-
  2.  
  3. from __future__ import division
  4. from decimal import Decimal
  5. import decimal as d
  6.  
  7. def titre():
  8.     print
  9.     print
  10.     print
  11.     print "                  *******************************************"
  12.     print "                  *      +- APPROXIMATIONS de Pi -+         *"
  13.     print "                  *******************************************"
  14.     print
  15.     print
  16.     print
  17.     print "Calcul de la valeur approchée de l'intégrale de 0 à 1 de f(x)=4/(1+x^2)"
  18.     print "                         par :"
  19.    
  20. def sortie():
  21.     print
  22.     print
  23.     print "   Au revoir !"
  24.  
  25. def incorrect():
  26.     print "           ...Désolé, valeur incorrecte. Veuillez recommencer ..."
  27.  
  28. def pas_nb():
  29.     print "             ... Ce n'est pas un nombre. Veuillez recommencer..."    
  30.  
  31. def message(cx):
  32.     ch={0:'       ... Pour retourner au menu,',
  33.         1:'... Pour la suite,',2:'... '}
  34.     print
  35.     print "       ",ch[cx],"Presser ENTREE ..."
  36.     raw_input("")
  37.  
  38. def pas():
  39.     ok=0
  40.     print "\n\n"
  41.     while not ok:
  42.         chp=raw_input("Choisissez un pas (0.1, 0.01, 0.001...) : ")
  43.         l=len(chp)
  44.         try:
  45.             p=float(chp)
  46.             if p>0 and p<1:
  47.                 if chp=="0."+(l-3)*"0"+"1" :
  48.                     ok=1
  49.                 else:
  50.                     incorrect()
  51.                     message(2)
  52.             else:
  53.                 incorrect()
  54.                 message(2)          
  55.         except ValueError:
  56.             pas_nb()
  57.             message(1)
  58.     return p
  59.  
  60. def affiche_resultat(p,s):
  61.     print "\n\n"
  62.     print "-------------------------------------------------------"
  63.     print
  64.     print "            *****************************"
  65.     print "   **********    Résultat du calcul      ***********"
  66.     print "            *****************************"
  67.     print
  68.     print "Valeur calculée de Pi :",s, "avec un pas de",p
  69.     print "Valeur  connue  de Pi : 3.14159265358979323846..."
  70.     print
  71.     print "-------------------------------------------------------\n\n"
  72.          
  73. def rectangles():
  74.     # Somme des aires des rectangles de largeur x-p/2 ; x+p/2
  75.     p=0
  76.     p=pas()
  77.     nt,x,s=int(1/p),p/2,0
  78.     for k in xrange(nt):
  79.         s+=4/(1+(x+k*p)**2)*p
  80.     affiche_resultat(p,s)
  81.  
  82. def trapezes():
  83.     s=0
  84.     p=pas()
  85.     nt,x,s=int(1/p),p/2,0
  86.     for k in xrange(nt):
  87.         s+=(4/(1+(k*p)**2)+4/(1+((k+1)*p)**2))/2
  88.     s=s*p
  89.     affiche_resultat(p,s)
  90.  
  91. def tangentes():
  92.     s=0
  93.     p=pas()
  94.     nt,x=int(1/p),p/2
  95.     for k in xrange(nt):
  96.         s+=4/(1+(x+k*p)**2)
  97.     s=s*p
  98.     affiche_resultat(p,s)
  99.  
  100. def simpson():
  101.     d.getcontext().prec = 21
  102.     s=0
  103.     p=pas()
  104.     a,b,nt=0,1,int(1/p)
  105.     for k in xrange(1,nt):
  106.         s+=Decimal((1+k%2))*(Decimal(4)/Decimal(str((1+(a+k*p)**2))))
  107.     s=Decimal(str(p))/Decimal(3)*(Decimal(4)/Decimal(1+a**2)+Decimal(4)/Decimal(1+b**2)+Decimal(2*s))
  108.     affiche_resultat(p,s)
  109.    
  110. fin=5
  111. while fin>0:
  112.     titre()
  113.     print "      1.la méthode des rectangles"
  114.     print "      2.la méthode des trapèzes"
  115.     print "      3.la méthode des tangentes"
  116.     print "      4.la formule de Simpson composée"  
  117.     print
  118.     print " 0. Sortie du programme\n"
  119.     chx_menu='5'
  120.     while chx_menu=='5':
  121.         chx_menu=raw_input(" Votre choix : ")
  122.         try:
  123.             fin = int(chx_menu)
  124.             choix2 = {'1': rectangles,
  125.                       '2': trapezes,
  126.                       '3': tangentes,
  127.                       '4': simpson,
  128.                       '0': sortie}
  129.             if not fin in [0,1,2,3,4]:
  130.                 chx_menu='5'
  131.                 incorrect()
  132.         except ValueError:
  133.             pas_nb()
  134.             chx_menu='5'
  135.     choix2[chx_menu]()

Un exemple de sortie avec la formule de Simpson :

---------------------------------------------------------------

                   *****************************
   **********          Résultat du calcul             ***********
                   *****************************

Valeur calculée de Pi : 3.14159265358979323840 avec un pas de 0.001
Valeur connue de Pi : 3.1415926535897932384626..."...

La troncature à \(\displaystyle 10^{-19}\) de la valeur calculée est juste !

Le module "decimal" de Python permet, à partir de la version 2.4, d'augmenter la précision d'un calcul en virgule flottante.
A noter aussi que le même calcul en C est précis, avec une déclaration "double s" également jusqu'à \(\displaystyle 10^{-17}\) pour p=0.001

Commentaires, réactions ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#2 21-05-2010 16:49:23

thadrien
Membre
Lieu : Grenoble
Inscription : 18-06-2009
Messages : 526
Site Web

Re : [Python] Approximations de Pi...

Salut,

Juste pour le fun, ajoute aussi une intégration par une méthode type monté-carlo.

Hors ligne

#3 21-05-2010 17:21:42

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 11 078

Re : [Python] Approximations de Pi...

Re,

Je vais chercher ça, connais pas !

Merci.

@+

[EDIT]
J'ai vu...
Je comprends le "pour le fun" de thadrien, et aussi le pourquoi de "Monte Carlo" !
Nan, je vais plutôt chercher une autre méthode -sérieuse- d'approximation d'une intégrale...

Le Bac devient intéressant, Valentin n'aurait pas intérêt à le repasser.
Epreuve au Bac :
http://lyc-eparny.ac-reunion.fr/IMG/pdf/Sujet071.pdf

Dernière modification par yoshi (21-05-2010 18:08:50)


Arx Tarpeia Capitoli proxima...

Hors ligne

#4 24-05-2010 16:57:39

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 11 078

Re : [Python] Approximations de Pi...

Re,

Petite explication sur "ma" formule de Simpson :
La formule officielle est (avec m=nb/2, nb étant le nombre total d'intervalles, obligatoirement pair) :
\(\displaystyle s=\frac{p}{3}\left(f(a)+f(b)+2\sum_{k=1}^{m-1} f(x_{2k})+4\sum_{k=0}^{m-1} f(x_{2k+1})\right)\)
Je fais ce calcul en 2 fois :
1. Dans un premier temps avec la boucle je calcule \(\displaystyle s=\sum_{k=1}^{m-1} f(x_{2k}) \;+\;2\sum_{k=0}^{m-1}f(x_{2k+1})\) via \(\displaystyle s= \sum_{k=1}^{m-1} f(x_{2k}) \;+\;\sum_{k=0}^{m-1}2f(x_{2k+1}) \)

2. Dans un deuxième temps, j'apporte le correctif : \(\displaystyle s=\frac{p}{3}\left(f(a)+f(b)+2s\right)\)

Certains d'entre vous m'objecteront que j'ai écrit au dessus  que les coefficients des sommes sont 2 et 4  pour k pair et impair (et non pas 1 et 2) et que je ne fais pas le distinguo entre pair et impair...
C'est exact...
Quoique pour le pair/impair ça ne l'est pas, exact :
je calcule en effet \(\displaystyle s = \sum_{k=0}^{2m-1}(1+k\%2)\times f(x_k)\)
Et le 1+k%2 vaut 1 si k est pair et 2 si k est impair, : cette astuce me permet d'effectuer le calcul dans la boucle d'une seule traite, sans utiliser if... else et en allant de 0 à 2m - 1 = nb-1
Toutefois, le s à la sortie de la boucle est quand même 2 fois trop petit d'où le +2s du correctif et non pas seulement le +s.
Toutes les mentions Decimal, (que je ne suis pas sûr de maîtriser encore totalement); sont là pour améliorer la représentation décimale, en Python, des nombres à virgule, voir  à propos du module decimal :
http://docs.python.org/release/2.4.3/wh … node9.html
ou encore :
http://docs.python.org/library/decimal.html

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#5 11-07-2010 18:16:09

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 11 078

Re : [Python] Approximations de Pi...

Bonsoir,


Mise à jour : une erreur s'était glissée à la dernière minute, après les tests, que j'ai rectifiée...
C'était la ligne :
print "Valeur connue de pi :........... etc...

Avec mes excuses

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

Réponse rapide

Veuillez composer votre message et l'envoyer

Les questions suivantes sont faites pour éviter le spam. Si vous voulez ne plus les avoir, inscrivez-vous!

Quel est le résultat de 79+85?

Quel est le 7 ième chiffre de 6339649?

Pied de page des forums

[ Générées en 0.129 secondes, 10 requêtes exécutées - Utilisation de la mémoire : 2.52 MiB (pic d'utilisation : 2.84 MiB) ]