Partage
  • Partager sur Facebook
  • Partager sur Twitter

Aide : algo [METHODE de Lagrange Recursive]

ça ne fonctionne pas

Sujet résolu
    16 mai 2015 à 13:07:26

    Bonjour à tous ,

    c'est mon premier post sur ce forum ! en faite je fais du python depuis quelques semaines, mais c'est la premiere fois que j'essaye d'utiliser l'ordi pour faire un programm( en effet je me contentatais de faire des exo theoriques et sur feuille )

    Donc , le programme que j'ai fais devrais pouvoir rechercher les zeros d'une fonction à une aproximation prés , je voulais le faire d'une façon recursive .  Je vous montre le code qui semble bien marcher ( quand j'essaye de voir ce qui se passe par la pensée , tout semble fonctionner , mais dans la pratique ça ne marche pas , je ne sais pas pourquoi  ; en effet le programme tourne ( quand j'essaye de l'executer avec F9 ( je suis sous spyder et pas de reponse ! ) Voila :

    ******PS: je suppose que f(a) et f(b) sont de signes opposé , c'est just ce cas que je traite dans l'exo!!!!!****

    <
    
     
    
    def newtown(f,a,b,n):
    
        
    
        if abs(a-b) <= 1/ (2**(n)) :
    
            return(f(a))
    
        else:
    
            if f(a)*f(a-(b-a)/(f(a)-f(b))*f(a)) >=0:
    
                return newtown(f,a-(b-a)/(f(a)-f(b))*f(a),b,n)
    
            else:
    
                return newtown(f,a,a-(b-a)/(f(a)-f(b))*f(a))
    
                
    
    f=lambda x:x**(3)
    
    print(newtown(f,-1,1,2))


      

    -
    Edité par Moni93 16 mai 2015 à 13:11:38

    • Partager sur Facebook
    • Partager sur Twitter
      16 mai 2015 à 17:04:09

      J'avoue être un peu perdu dans ton algorithme. Je ne suis pas un dieu des maths, mais je suis un peu perturbé par le fait que tu nous dis utiliser la méthode de Lagrange, et ta fonction d'appelle newton. :/

      Je trouve ceci pour Lagrange: http://www.bibmath.net/dico/index.php?action=affiche&quoi=./l/lagrangemeth.html Je n'y trouve pas les conditions que tu décris. Pourrais-tu nous décrire en terme mathématique ton algorithme, et on t'aidera pour le code.

      Avec le site sus-mentionné, j'ai inventé un critère de précision en m'inspirant de ce que tu avais fourni et j'ai ce code

      f = lambda x: x**3 + 1
      

      def lagrange(f, a, b, n):

      if abs(f(a)) <= 1 / (2**n) :
          return a
      
      a, b = a - ( (a - b) / (f(a) - f(b)) * f(a) ), a
      return lagrange(f, a, b, n)
      

      print(lagrange(f, -4, 2, 4)) # -0.9948853081438901

      </pre>

      -
      Edité par Dan737 16 mai 2015 à 17:04:27

      • Partager sur Facebook
      • Partager sur Twitter
        17 mai 2015 à 15:19:05

        En faite je me suis trompé de nom ; ça s'appelle méthode de lagrange , en gros : on supposera que la fonction possede vraiment un zero entre a et b et donc forcement f(a) *f(b) <=0  l'idee c'est de traçer la droite qui passe par les points ( a,f(a)) et (b,f(b))   , ainsi  tu retrouves le point d'intersection de cette droie avec l'axe des abscisses  ( on appellere m l'abscisse de ce point )  ( ce point se situe dans le segment (AB) ( ou A(a,0) et B(b,0)

        maintenant tu as deux cas à traiter ; 

        si  f(a) * f(m) >=0 ça veut dire que (a,f(a)) et (m,f(m)) sont dans la meme partie du plan , donc dans ce cas tu refais le meme truc pour f(m) et f(b) , i.e tu traces la droite passant par (m,f(m)) et (b,f(b)) et tu retrouves son intersecton avec l'axe des abcisses  ET AINSI DE SUITE

        si f(a)*f(m)<= , ca veut dire que (m,f(m)) et (b,f(b)) sont dans la meme partie du plant, donc tu traites ce cas mais pour f(a) et f(m) au lieu de f(m) et f(b)      

        ainsi du point de vue algorihmique tu cherches Xn a partie De Xn-1  DE la façon suivante

        Ainsi voila l'idée  , le programme a pour parammetres d'entrée  ta fonction f  les les abscisses a et b , et n pour la precision de zero , en gros des que tu trouves dans une bande de leur 2^n  tu dis que c'est bon j'ai trouvé le zero de la fonction 

        ainsi du point de vue algorihmique tu cherches Xn a partie De Xn-1  DE la façon suivante  

        si f(Xn-1)*f(b)<=0 alors Xn=Xn-1-(b-Xn-1)/(f(Xn-1)-f(b))*f(Xn-1)

        si non   Xn=a-(Xn-1-a)/(f(a)-f(Xn-1))*f(a)

        (hors sujet : Aidez moi sur un truc que j'ai copié la premiere ligne en noir , toute l'écriture aprés s'affiche en noir , d'ailleur regardez je n'arrive plus de me debarasser de ca ! comment faire)

        • Partager sur Facebook
        • Partager sur Twitter
          18 mai 2015 à 10:30:31

          Ok, alors au vu de ton explication de la méthode, moi je trouve que la droite qui relie les points \((a, f(a))\) et \((b, f(b))\) a pour équation

          \[ y = \frac{f(b) - f(a)}{b - a} \times (x - a) + f(a) \]

          Ainsi lorsque \(y=0\), on a pour x \[x = \frac{f(a) \times (b - a)}{f(a) - f(b)} + a\] Pour ce qui est de la précision du zéro, ça me parait compliqué de regarder l'écart entre a et b. A chaque itération tu trouves un nouveau x qui va remplacer soit a ou b selon la position de f(x). De plus il est tout à fait possible qu'une des deux bornes ne bougent pas alors que x est tout près du 0. Le mieux est de voir si f(x) s'approche suffisamment de 0 pour dire que x est la réponse.

          Voici mon code:

          def lagrange(f, a, b, n):
          
          x = f(a) * (b - a) / (f(a) - f(b)) + a
          if abs(f(x)) <= 1 / (2**n) :
              return x
          
          if f(x) * f(a) < 0:
              return lagrange(f, a, x, n)
          elif f(x) * f(b) < 0:
              return lagrange(f, x, b, n)
          else:
              raise ValueError("f(x), f(a) et f(b) sont dans le même demi-plan")
          

          print(lagrange(lambda x: x3, -4, 2, 10)) print(lagrange(lambda x: x3 - 27, 2, 4, 10))

          </pre> Le problème avec cette méthode est que comme elle ne converge pas rapidement vers le 0, tu peux arriver à la limite d'appels récursifs si tu veux une grande précision. Pour éviter ce problème il faut la transformer en fonction non-récursive.
          def lagrange_non_recursive(f, a, b, n):
          
          x = f(a) * (b - a) / (f(a) - f(b)) + a
          while abs(f(x)) > 1 / (2**n):
              if f(x) * f(a) < 0:
                  b = x
              elif f(x) * f(b) < 0:
                  a = x
              x = f(a) * (b - a) / (f(a) - f(b)) + a
          return x
          
          </pre>

          -
          Edité par Dan737 18 mai 2015 à 10:44:19

          • Partager sur Facebook
          • Partager sur Twitter
            20 mai 2015 à 20:02:56

            Merci pour ta réponse !  tout est clair maintenant !
            • Partager sur Facebook
            • Partager sur Twitter

            Aide : algo [METHODE de Lagrange Recursive]

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown