Problème avec un programme Python

Bonjour,
j'ai ce code en langage Python :
from math import *

# Calcul de distance
def distance(x1,x2,y1,y2) :
    return sqrt((x2-x1)**2+(y2-y1)**2)
    
# la longueur de la courbe sur l'intervalle [a,b] n étant le nombre de points
def LongueurCourbe(f,a,b,n):
    longueur=0
    x1,y1= a,f(a)
    h=(b-a)/n
   
    for i in range(n) :
        x2=h+x1
        y2=f(x2)
        longueur=longueur+distance(x1,x2,y1,y2)
        x1,y1= x2,y2
        print(x1,y1)
        
    return(longueur)
    
#la fonction que l'on peut changer à loisir
print(2*LongueurCourbe(lambda x : sqrt(1-x**2),0,1,10))
et j'obtiens ceci :
0.1 0.99498743710662
0.2 0.9797958971132712
0.30000000000000004 0.9539392014169457
0.4 0.916515138991168
0.5 0.8660254037844386
0.6 0.8
0.7 0.714142842854285
0.7999999999999999 0.6000000000000001
0.8999999999999999 0.43588989435406755
0.9999999999999999 1.4901161193847656e-08
3.132264589468792
J'ai eu beau passer de Pyzo à Anaconda à Python 3 voir 2... le change ce qui conduit même à une erreur lorsque je prends 20 subdivisions :
0.05 0.998749217771909
0.1 0.99498743710662
0.15000000000000002 0.9886859966642595
0.2 0.9797958971132712
0.25 0.9682458365518543
0.3 0.9539392014169457
0.35 0.9367496997597597
0.39999999999999997 0.9165151389911681
0.44999999999999996 0.8930285549745877
0.49999999999999994 0.8660254037844386
0.5499999999999999 0.8351646544245033
0.6 0.8
0.65 0.7599342076785331
0.7000000000000001 0.714142842854285
0.7500000000000001 0.6614378277661476
0.8000000000000002 0.5999999999999998
0.8500000000000002 0.5267826876426366
0.9000000000000002 0.4358898943540669
0.9500000000000003 0.3122498999199191
Traceback (most recent call last):
  File "/Users/jeanericrichard/Documents/newmaths/algorithmique/python/docaccompeduscol/longueurcourbe.py", line 32, in <module>
    print(2*LongueurCourbe(lambda x : sqrt(1-x**2),0,1,20))
  File "/Users/jeanericrichard/Documents/newmaths/algorithmique/python/docaccompeduscol/longueurcourbe.py", line 18, in LongueurCourbe
    y2=f(x2)
  File "/Users/jeanericrichard/Documents/newmaths/algorithmique/python/docaccompeduscol/longueurcourbe.py", line 32, in <lambda>
    print(2*LongueurCourbe(lambda x : sqrt(1-x**2),0,1,20))
ValueError: math domain error
car impossible de calculer l'image de 1,00000000003 par sqrt(1-x**2)...

Que se passe-t-il ??? Pourquoi le h ajouté n'est pas fixe ??? Que faire ???
Jean-éric

Réponses

  • En utilisant une fraction cela semble marcher chez moi.

    from fractions import *
    h=Fraction((b-a),n)69828
  • Une solution plus radicale serait de fixer x2 = b si i == n-1.
  • Il doit se passer que le h, qui vaut 1/20, est converti en flottant en base 2 et qu'il y a des erreurs d'arrondi parce que 20 n'est pas une puissance de 2.

    Remèdes :
    1. ne prendre un nombre de subdivision égal à une puissance de 2 (pas top) ;
    2. définir la fonction par lambda x: sqrt(1-(min(1,x)**2) (elle renverra 0 si on lui demande de l'évaluer en un x>1).
  • Merci Roumegaire, cela marche très bien avec le module Fractions !

    Mais cela n'explique pas vraiment d'où vient le problème initial !

    Bonn soirée.
  • Ok, Math Coss, tu as l'explication, j'ai compris : vive le binaire ! Merci aussi à toi.
Connectez-vous ou Inscrivez-vous pour répondre.