Bibm@th

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).

#51 14-01-2011 15:19:28

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 992

Re : traitement de fonctions mathématiques.

Re,

Doesn't matter !!
Je rajoute des commentaires et aussi des explications
Voilà :

def root(f,a,b):
    encadre,encadre_A=[(a,b)],[]  # je stocke les bornes entre lesquelles je démarre la recherche
    for i in xrange(1,8):
        pas=10**(-i)                    # Définition des pas successifs, c'est à dire la valeur de x2-x1
        for(c,d) in encadre:    # Je charge les bornes : changement de nom de variables pour l'affichage futur
            c,d=c-pas,d+pas             # Modification des bornes (1)
            x1,x,x2,cpt=c,c,c+pas,1     # Initialisations
            f1=eval(f)                  
            while x2<=d:
                x=x2
                f2=eval(f)
                if f1*f2<=0:            # Théorème des gendarmes (2)
                    encadre_A.append((x1,x2))               # Stockage des bornes
                cpt+=1
                x1,f1,x2=x2,f2,c+pas*cpt                                
        encadre,encadre_A=sorted(encadre_A),[]  # Transfert et tri avant nouvelle itération (3)
    # Enregistrement des bornes inférieures arrondies à 10**(-6)                                
    encadre=sorted(set([round(c,6) for (c,d) in encadre]))      
    # Affichage et gestion du pluriel
    print 'root'+'s'*(len(encadre)>1)+" in ["+str(a)+","+str(b)+"] : ",
    for a in encadre:
        if str(a)=="-0.0":
            a=0.0      
        print "f("+str(a)+")"
    print 0

(1) Barbichu m'avait remarqué avec ses deux racines 0.03 et 0.07 que si je fixais comme intervalle de recherche [0 ; 1] on ne les trouvait pas...
Et moi, j'avais constaté après que sur [-0.1 ; 1], ça fonctionnait : j'ai donc décidé de modifier les bornes en [c-pas ; d + pas]

(2) Oui je balaie de pas en pas tout l'intervalle [c ; d] avec x2=x1+pas à la recherche des points tels que f(x2)*f(x1)<=0 : j'accepte le cas nul, parce que sinon je rate des racines.
En principe, j'aurais dû
* déterminer 2 valeurs x1 et x2 de [c ; d] telles que y2*y1 <0
* puis majorer x1 d'un pas et minorer x2 d'un pas jusqu'à ce que le produit f(x2)*f(x1) ne soit plus négatif et à ce moment je prenais les valeurs immédiatement antérieures
C'est comme ça que devrait fonctionner le théorème des gendarmes...

Mais je me suis aperçu, que la détermination de x1 et x2 allait poser problème puisque dans l'intervalle [x1 ; x2] peuvent se trouver 2, voire 3 racines
Non, pas de dichotomie dans la procédure root...

Tu as 2 possibilités de recherche des racines :
- soit la procédure root qui m'oblige à éliminer à ne garder qu'une seule de toutes les valeurs trouvées et égales entre elles à 10^-8 près....
- soit la procédure dicho de recherche par dichotomie.

Elles sont distinctes et indépendantes : si tu veux garder pour rechercher les racines la procédure dicho, tu vires celle qui s'appelle root et tu rebaptises def dicho(f,a,a): en def root(f,a,b):
Et ça fonctionne sans problème...

(3) Lorsque j'ai détecté 2 valeurs de x1 et x2 entre lesquelles se trouvent une racine, je stocke ces valeurs, pour pouvoir les reprendre au tour suivant via for (c,d) in encadre:...
C'est là que j'ai besoin de 2 listes : la liste des valeurs du tour précédent et la liste des valeurs détectées du tour en cours.
En fin de tour (sortie de boucle for (c,d) in encadre) je procède au transfert liste en cours dans liste antérieure et je vide liste en cours, avant de redémarrer avec un pas 10 fois plus fin...

Je vais quand même reprendre ma réflexion pour faire une utilisation conforme du théorème des gendarmes : si j'y arrive (va me falloir re-réfléchir soigneusement), je reposterai le résultat de mes cogitations...

C'est plus clair ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#52 17-01-2011 09:43:02

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 992

Re : traitement de fonctions mathématiques.

Re,


Dans le Post #54, j'ai bien précisé : version revue et corrigée (du programme complet).
J'en extrais la procédure extrema que revoici :

def extrema(f,a,b):
    encadre,encadre_A=[(a,b)],[]
    for i in xrange(1,9):
        pas=10**(-i)
        for(c,d) in encadre:
            x1,x,x2,x3=c,c,c+pas,c+pas*2 # Initialisations
            f1=eval(f)                   #|
            x=x2                         #|
            f2=eval(f)                   #|> coord. des 3 premiers points
            x=x3                         #|
            f3=eval(f)                   #|
            while x2<=d:
                x4=x1+pas*3              #|
                x=x4                     #|> Coord. du 4e point
                f4=eval(f)               #|
                #détection croissance/décroissance
                if (f2-f1)*(f4-f3)<=0:
                    encadre_A.append((round((x1+x2)/2,i+1),round((x3+x4)/2,i+1)))                  
                x1,f1,x2,f2,x3,f3=x2,f2,x3,f3,x4,f4
        # Transfert et tri avant nouvelle itération        
        if len(encadre_A)>0:
            encadre,encadre_A=set(encadre_A),[]                              
    # Enregistrement des bornes inférieures arrondies à 10**(-6)                                
    encadre=sorted(set([round(c,6) for (c,d) in encadre]))      
    # Affichage et gestion du pluriel
    l=len(encadre)
    if l<2:
        mot='extremum'
    else:
        mot='extrema'
    print mot+" in ["+str(a)+","+str(b)+"] : ",
    if l==0:
        print "None"
    else:
        for a in encadre:
            x=a
            if str(a)=="-0.0":
                a,x=0.0,0.0
            print "f("+str(a)+") =",eval(f)," ",
        print

Définition de l'extremum que je vérifierai tant elle me paraît inexploitable. Peut-être ne parle-t-on pas de la même chose...
Moi, je fais fais simplement une recherche de tangente horizontale à la courbe, soit une dérivée nulle au point considéré.
Comme je n'ai pas voulu m'amuser à introduire le calcul des dérivées (je n'étais pas sorti de l'auberge !), j'ai seulement pris 4 points d'abscisses consécutives x1, x2=x1+pas, x3=x1+2*pas, x4=x3+3*pas, puis testé si le produit [tex]\frac{f(x_2)-f(x_1)}{x_2-x_1}\times \frac{f(x_4)-f(x_3)}{x_4-x_3}\leq 0[/tex].
Autrement dit  si la tangente change de signe ou devient nulle...
Alors, tu vas dire : ce n'est pas exactement ce que tu fais !_
Oui, c'est vrai parce qu'avec mon procédé, j'ai toujours [tex]x_2>x_1[/tex] et [tex]x_4 > x_3[/tex] donc [tex]x_2-x_1>0[/tex] et [tex]x_4 - x_3 >0[/tex]
Donc les coefficients directeurs des tangentes sont du signe de [tex]f(x_2)-f(x_1)[/tex] et  [tex]f(x_4)-f(x_3)[/tex] : j'économise donc le calcul des quotients.

Je ne vois aucune variable nbi, ni abs= valeur absolue.
Tu dois faire erreur : nbi est un nom transparent (pour moi) = nombre d'intervalles : la procédure où j'utilise un nombre d'intervalles est celle du calcul de l'aire comprise entre la courbe et l'axe des x et là, je m'étais expliqué sur l'erreur (théorique, hélas !) entraînant une valeur fausse pour cette aire.
Reporte-toi aussi au post #54.

C'est bon ? Sinon, pose autant de question que tu veux : ça ne me dérange pas...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#53 17-01-2011 12:36:13

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 992

Re : traitement de fonctions mathématiques.

Désolé,

Une balise tex a sauté (et un morceau de formule)...

A quoi il correspond ce produit en français?

Fichtre quel ton ! quelle acrimonie ! Je te renvoie à cette page : Code LaTeX : pas d'autre moyen d'écrire des formules sur un forum !

Il fallait lire :
l

Comme je n'ai pas voulu m'amuser à introduire le calcul des dérivées (je n'étais pas sorti de l'auberge !), j'ai seulement pris 4 points d'abscisses consécutives x1, x2=x1+pas, x3=x1+2*pas, x4=x3+3*pas, puis testé si le produit [tex]\frac{f(x2)-f(x1)}{x2-x1}\times \frac{f(x4)-f(x3)}{x4-x3}\leq 0[/tex]

Ainsi comme tu le vois, le procédé consiste à prendre 4 points consécutifs sur la courbe de coordonnées :
A(x1 ; f(x1)), B(x2 ; f(x2)), C(x3 ; f(x3)), D(x4 ; f(x4)), tels que l'écart entre x1 et x2 , x3 et x4 est successivement de 0.1, 0.01, 0.001, 0.0001.... 0.00000001

Je considère ainsi que [tex]x2=x1+h,\;x4=x3+h\;\; avec\;\;h\mapsto 0[/tex]
Et si si tu préfères, le principe est de tester si :
[tex]\frac{f(x1+h)-f(x1)}{h}\times \frac{f(x3+h)-f(x3)}{h}\leq 0\; quand\;h\mapsto 0[/tex]
Si ça te chiffonne toujours, alors considère que si je prends deux points A et B sur une courbe et que je rapproche A de B sur la courbe je me rapproche de la tangente en B, ou que (AB) tend vers la tangente en B.
Certes, B se déplace aussi, mais la longueur AB tend bel et bien vers 0, et donc vers la coïncidence des points A et B...
Je pourrais continuer les calculs jusqu'à une précision de 10^-12, mais à partir de là, il faut pour avoir des valeurs correctes utiliser le module décimal de Python et fixer la précision plus finement 10^-15, 10^-20... etc.

Je ne recherche pas de dérivée : la définition [tex]\lim_{\Delta x\, \mapsto 0} \frac{\Delta f}{\Delta x}[/tex] est simplement "adaptée" à l'informatisation (sinon, ça veut dire quoi en programmation que [tex]\Delta x \mapsto 0[/tex] ?)
Bon, je continue...
Je prends les deux droites (AB) et (CD) : le produit de leurs coefficients directeurs sera du même signe que le produit des différences d'ordonnées puisque les différences d'abscisses sont strictement positives, vu le procédé de choix des dites abscisses.
Si ce produit est négatif ou nul alors il y a changement de courbure : entre des bornes bien choisies, il y a la certitude d'avoir une tangente horizontale. Grâce à <=0 et non plus seulement <0, je crois me souvenir (ça remonte à un certain temps et je n'ai pas re-vérifié) que je trouve aussi les points d'inflexion avec tangentes horizontales...

En tous cas, si tu as des cas où la procédure échoue, je te serai reconnaissant de bien vouloir me les communiquer, que je me repenche sur le problème : ça aura échappé à ma batterie de tests.

Certes, je n'ai jamais enseigné à ce niveau, mais du point de vue de la théorie et de l' "adaptation" informatiq que j'en fais, je ne crois pas être contestable, puisqu'en principe ça marche.
Ce module extrema n'était pas demandé : ce n'est qu'un plus, réalisé pour le plaisir...
Je te concède que le seul procédé correct conduisant à des valeurs exactes n'est pas celui-là, mais bien de calculer les dérivées comme à la main, ce qui demande une analyse et une finesse qui ne sont pas réalisables (pour moi) en 8 jours : en 6 mois peut-être...
Regarde du côté du logiciel Maxima (réalisé en Python) et son interface graphique WxMaxima réalisée avec WxPyhton

Est-ce que c'est plus clair ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#54 17-01-2011 23:42:23

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 992

Re : traitement de fonctions mathématiques.

Re,

def maxi(f,a,b):
    xmax,maxi=-100,-1000
    n=4
    x,pas=a,10**(-n)
    nbi = int(abs(b-a)*10**n)
    if a+pas*(nbi-1)<b:
        nbi+=1
    for i in xrange(nbi):
        ff=eval(f)
        if ff>maxi:
            xmax,maxi=x,ff
        x+=pas
    print "max in ["+str(a)+","+str(b)+"] : f("+str(xmax)+") =",maxi
   
def mini(f,a,b):
    xmin,mini=100,1000
    n=4
    x,pas=a,10**(-n)
    nbi = int(abs(b-a)*10**n)
    if a+pas*(nbi-1)<b:
        nbi+=1
    for i in xrange(nbi):
        ff=eval(f)
        if ff<mini:
            xmin,mini=x,ff
        x+=pas
    print "min in ["+str(a)+","+str(b)+"] : f("+str(xmin)+") =",mini

Après je lance ma boucle en partant de la borne a, et à chaque itération, j'augmente la valeur de x de 10^-4 et je calcule f(x) que je compare au maxi / mini existants....
Quand j(ai fini mes nbi tours de boucle (calcul un peu bizarre de nbi à partir de 10^n, mais la boucle n'admet que des nombres entiers), j'ai stockés dans xmax et maxi ou xmin et mini les valeurs à afficher...
Pas de liste là dedans juste deux variables à chaque fois xmax et maxi, xmin et xmin et mini...
Je n'ai besoin que de conserver le maxi et le mini de f(x) en cours : pour les comparer aux valeurs de f(x) que je calcule à chaque tour...
En fait, on peut même supprimer les déclarations initiales xmax = -100 et xmin=100 : elles ne se servent à rien, mais laisser maxi et mini sinon erreur...
Pas de surprise, c'est de la programmation bête et méchante  sans astuce...

C'est bon ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#55 18-01-2011 20:00:10

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 992

Re : traitement de fonctions mathématiques.

Re,

Oui, et non... Cf ton 1er post :

Le programme doit être capable de gérer le cas des racines multiples sur l'intervalle.

C'est pourquoi, je commence par effectuer un balayage à 0.1 près qui me permet de déterminer d'abord le nombre de racines, après, dans chaque zone, j'utilise la dichotomie et elle seule, oui...

Cela dit, un petit malin peut entrer une fonction avec deux racines distantes de 0.01 et on n'en trouvera qu'une quand même...
Mais l'objet du TP était de vous faire programmer pas de construire quelque chose d'infaillible...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#56 26-01-2011 23:57:52

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 992

Re : traitement de fonctions mathématiques.

Bonsoir,

Pourquoi la suppression de tes messages depuis le 14/01/2011 ? Je n'apprécie que modérément...
Je ferme pour éviter la suppression totale.
Pour tout tuyau complémentaire, tu devras ouvrir une nouvelle discussion.

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

Pied de page des forums