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

#1 29-11-2010 19:11:30

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

traitement de fonctions mathématiques.

Bonjour,

Etudiant en maths-info, j'ai un rapport à rendre dans le cadre de la programmation. Ayant vraiment peu d'expérience dans ce domaine là j'aurai besoin de votre avis par rapport à ce que j'ai fait et si possible éventuellement une ouverture pour me permettre de débloquer mes problèmes et d'avancer.

Le sujet est le suivant :

Écrire un programme opmath qui permet de réaliser diverses opérations de traitement sur une fonction mathématique dont l'expression f(x) est entrée par l'utilisateur. Le principe de fonctionnement est similaire à celui du programme stat dans lequel l'opération de traitement était spécifiée sous la forme d'un mot-clé dans la commande saisie par l'utilisateur. Néanmoins, à la différence de stat, le programme doit pouvoir correctement gérer un nombre variable d'arguments pour les différentes opérations. Voici les opérations qui doivent être réalisables :

    * def expression : définir expression comme la fonction mathématique à utiliser pour les opérations suivantes (cf. exemple ci-dessous). La même fonction mathématique sera utilisée tant que l'utilisateur n'aura pas défini une nouvelle fonction avec la commande def
    * val x : évaluer la fonction courante f(x) pour la valeur x
    * root xmin xmax : déterminer toutes les racines de la fonction courante f(x) sur l'intervalle [xmin, xmax]. Pour cela, le plus simple est d'utiliser la technique de la dichotomie jusqu'à obtenir une précision donnée (généralement 10e-6 est largement suffisant). Le programme doit être capable de gérer le cas des racines multiples sur l'intervalle.
    * min xmin xmax : déterminer toutes les valeurs de x qui fournissent la valeur minimale de la fonction courante f(x) sur l'intervalle [xmin, xmax]
    * max xmin xmax : déterminer toutes les valeurs de x qui fournissent la valeur maximale de la fonction courante f(x) sur l'intervalle [xmin, xmax]
    * area xmin xmax : déterminer l'aire comprise sous la fonction courante f(x) pour l'intervalle [xmin, xmax]. Pour cela, le plus simple est d'utiliser la méthode des trapèzes avec un pas d'échantillonnage donné (généralement, utiliser 10e6 échantillons sur l'intervalle est largement suffisant)

Exemple d'exécution :

================================================================================
OPMATH : perform miscellaneous processing on a mathematical function
================================================================================
Note : enter an empty line to stop the interaction loop
<> Enter command : def x*x - 1
f(x) = x*x - 1
<> Enter command : val 2.0
f(2.0) = 3.0
<> Enter command : min -2.0 3.0
min in [-2.0,3.0] : f(0.0) = -1.0
<> Enter command : max -2.0 3.0
max in [-2.0,3.0] : f(3.0) = 8.0
<> Enter command : root -2.0 3.0
root in [-2.0,3.0] : f(-1.0) = f(1.0) = 0.0
<> Enter command : area 0.0 3.0
area under [0.0,3.0] : 6.0
<> Enter command : def cos(x)
f(x) = cos(x)
<> Enter command :



Mon programme est le suivant: ( sachant que je ne me suis arrêté que à "val x"):

f=none

while 1:
    command = raw_input("Enter command: ")
    if not command:
        print "End of program."
        break
    if command.startswith('def '):
        f = command.lstrip('def ')
        print "f(x)=%s" % f
    elif command.startswith('val '):
        x = float(command.lstrip('val '))
        try:
            print "f(%f)=%f" % (x,eval(f))
        except TypeError:
            print "No function defined.
    else:
         print "Unknown command."
       


J'ai plusieurs problèmes:
-le programme fonctionne trés bien pour le premier exemple: x*x-1
- je ne sais pas comment faire pour implanter plusieurs fonctions , c'est à dire mettre une fonction au hasard et calculer ses images.
- la seconde chose , je ne sais pas comment calculer le min et le max sur un intervalle donné.

Merci de bien vouloir me répondre si possible, et de m'apporter une aide qui me permettrait d'avancer dans mon programme.

Cordialement

Dernière modification par zarnac (14-01-2011 15:13:11)

Hors ligne

#2 29-11-2010 19:33:42

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

Re : traitement de fonctions mathématiques.

Bonsoir zarnac,

Je ne connaissais pas opmath...
Pour l'instant, j'ai peu de temps pour faire une recherche sur les mots-clé de ce langage, j'espère que tu n'es pas trop pressé...

* min xmin xmax : déterminer toutes les valeurs de x qui fournissent la valeur minimale de la fonction courante f(x) sur l'intervalle [xmin, xmax]
    * max xmin xmax : déterminer toutes les valeurs de x qui fournissent la valeur maximale de la fonction courante f(x) sur l'intervalle [xmin, xmax]

Alors ça, c'est vaste : la fonction "courante" peut-elle être n'importe quoi ou y a-t-il des restrictions ?
Parce que ces extrema :
1. il faut encore qu'ils existent
2. Encore faut-il qu'on puisse trouver les valeurs de x (exactes ou approchées)
La fonction minimum ou maximum parmi deux nombres existe-t-elle à l'état natif ?
En python : min(2,3)--> 2...
Parce que sinon, il va falloir aussi écrire ça...
Les boucles for, while ou do... loop existent-elles en opmath ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#3 29-11-2010 20:11:59

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

Re : traitement de fonctions mathématiques.

Re,

================================================================================
OPMATH : perform miscellaneous processing on a mathematical function
================================================================================
Note : enter an empty line to stop the interaction loop
<> Enter command : def x*x - 1
f(x) = x*x - 1
<> Enter command : val 2.0
f(2.0) = 3.0
<> Enter command : min -2.0 3.0
min in [-2.0,3.0] : f(0.0) = -1.0
<> Enter command : max -2.0 3.0
max in [-2.0,3.0] : f(3.0) = 8.0
<> Enter command : root -2.0 3.0
root in [-2.0,3.0] : f(-1.0) = f(1.0) = 0.0
<> Enter command : area 0.0 3.0
area under [0.0,3.0] : 6.0
<> Enter command : def cos(x)
f(x) = cos(x)
<> Enter command :

Où je n'y comprends rien où il m'apparaît que là tu as toutes les réponses à tes questions, non ?
Ça par exemple :
root in [-2.0,3.0] : f(-1.0) = f(1.0) = 0.0, c'est que le programme doit réaliser ou bien est-ce que la fonction root est déjà existante dans ton langage ?

Tiens au fait, après recherche, on dirait que OPMATH n'est pas un langage, parce que tous les liens que j'ai trouvés sur let aboutissent à Python...
Et puis j'ai pu constater que tu "répartissais tes œufs" entre beaucoup de paniers :
http://www.developpez.net/forums/d10059 … ematiques/
http://www.developpez.net/forums/d85768 … ere-annee/
Pourquoi n'y retournes-tu pas ?
http://www.commentcamarche.net/forum/af … ion-python
La mise en concurrence est généralement mal vue, tu ne savais pas ?
J'ai même trouvé un de tes "confrères" :
http://www.infos-du-net.com/forum/27327 … ame-python

J'en arrive à la conclusion que OPMATH n'est pas un langage mais un acronyme traduisant : ""perform miscellaneous processing on a mathematical function", mais que tu dois développer en Python...

La grosse question est le choix entre Python 2.x et Python 3.x....

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#4 29-11-2010 22:59:47

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

Re : traitement de fonctions mathématiques.

RE,

C'est du Python, oui ou non ?

Ce qui signifie, si oui, que tu dois écrire un programme comprenant une seule fonction à la fois.
Ton programme sera résident en mémoire, et interagiras avec en ligne de commande :
- soit depuis la console Dos
- soit depuis IDLE ou toute autre interface Windows...

Ca doit pouvoir se faire : Kango sur Développez.net, qui est bien plus fort que moi, t'a donné (enfin au dénommé agui) une base que j'ai comprise...
Mais maintenant, il va falloir phosphorer, et je n'aurais pas vraiment le temps avant 2/3 jours.
S'il s'agissait simplement d'écrire un programme possédant toutes ces fonctions demandées et que tu puisses appeler l'une ou l'autre via un menu, ce serait plus simple (j'ai fait bien plus complexe, notamment le logiciel de calculs financiers présent dans ce sous-forum.)

Pour l'aire de la fonction courante par la méthode des trapèzes, va voir mon programme : Approximations de Pi : je calcule l'aire entre 2 bornes, d'une fonction que j'ai oubliée, et qui donne Pi.
Je l'ai fait avec 4 méthodes dont celle-ci.
Regarde et essaie d'adapter à n'importe quelle autre fonction.

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#5 29-11-2010 23:42:41

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

Re : traitement de fonctions mathématiques.

Re bonjour,
Le programme est du python .

Je te remercie Yoshi, ce travail n'est qu'à rendre pour dans 3 semaines.

Le programme est du python .
Donc j'aurai le temps d'y travailler d'ici là , je pourrai éventuellement mettre ce que j'ai fait ici .

Si tu as le temps d'y regarder un peu plus afin de m'apporter davantage d'indices.
Tu m'auras été d'une grande aide jusqu'à la fin.

Dernière modification par zarnac (14-01-2011 15:13:25)

Hors ligne

#6 03-12-2010 10:59:01

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

Re : traitement de fonctions mathématiques.

Bonjour,

Je commence à réfléchir à ton sujet dont la difficulté me paraît disproportionnée à ton niveau si tu es débutant.
J'ai pris connaissance des réponses qu'on t'a apportées sur developpez.net et je dois sire que si ça te fait avancer, chapeau.
Moi, pas d'un pouce...
Sauf que ça confirme ce que je pensais : la mise au point de l'interface, c'est secondaire, i.e ça n'arrivera qu'en 2e lieu...
Il faut se consacrer à la mise au point des fonctions root, xmin, xmax...

Alors question supplémentaire : dans l'esprit de celui qui a donné le sujet, que signifie "fonction courante" .
- Fonction en cours, celle que tu as rentré toi ?
- Fonction usuelle des mathématiques ?

Parce que pour rechercher les racines de l'équation f(x) =0, encore faut-il qu'il y en ait...
Exemple tout bête :   f(x)=x²+2x+6..
Ou alors, on part d'une principe que on ne fait cette recherche que si l'on sait que ces racines existent, qu'il y a bien un xmin, un xmax ou les deux...
Sinon, on est marrons...

En ce qui concerne les racines par exemple, donc les x tels que f(x) =0, je ne vois pas d'autre moyen que de passer par le théorème des gendarme, c'est à dire rechercher x1 et x2 tels que f(x1)<0 et f(x2) >0 et après on affine...
Mais on veut tous ces zéros..
Je pense donc qu'il faut balayer la totalité (au premier essai) de l'intervalle [a ; b] de travail, recenser tous les couples (x1 ; x2) et les stocker dans une liste.
Le balayage doit pouvoir se faire la 1ere fois avec un pas de (b-a)/10.
Python n'accepte, pour les boucles for que des limites ou des pas entiers, mais on peut contourner la difficulté soit avec while et un compteur s'incrémentant à chaque tour de (b-a)/10, soir une boucle for du type :

x1,x2, pas,couples=0,(b-a)/10.0,[]
for i in xrange(10):
    x1+=pas*i
    x2+=pas*(i+1)
    if f(x1)<0 and f(x2)>0:
        couples.append((x1,x2))   

Mais il faut qu'on puisse aller jusqu'à 10^-6 de précision, donc il faut reproduire cette boucle 6 fois,
et à chaque tour le pas doit devenir (x2-x1)/10...

Ce ne sont là que des idées qui demandent à être précisées et débuguées...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#7 03-12-2010 21:44:59

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

Re : traitement de fonctions mathématiques.

Je pense que ce sont des fonctions usuelles, (partons sur ce cas )
Je pense qu'il faut simplement que ca fonctionne pour x*x-1 et cos(x)
ca sera déjà pas mal .

Je suis dans une ***** noire.

Pour cos (x) , il faut simplement que j'ajoute en début de script

from math import cos

Donc le problème est plus ou moins régler pour calculer les images d'une fonction.

Dernière modification par zarnac (03-12-2010 21:48:05)

Hors ligne

#8 04-12-2010 13:02:39

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

Re : traitement de fonctions mathématiques.

Re,

J'ai créé une fonction def root(f,a,b) dans un programme qui me trouve, pour l'instant, un encadrement à 0.01 près des 3 racines de f(x)=x**3-2*x+1...
Il me reste à automatiser la recherche jusqu'à 10^-6...
Si tu veux tripatouiller aussi :

#!/usr/bin/env python
# -*- coding: Latin-1 -*-

from __future__ import division
from math import cos,sin,tan,sqrt,exp,log,pi

def root(f,a,b):
    cadre=[]  
    for i in xrange(1):
        fin=10*int((b-a)/0.1)
        pas=0.01
        for j in xrange(fin):
            x1=a+pas*j
            x=x1
            f1=eval(f)
            x2=a+pas*(j+1)
            x=x2
            f2=eval(f)
            if (f1<=0 and f2>0) or (f1>=0 and f2 <0):                        
                cadre.append((x1,x))          
    return cadre

def minimaxi(f,a,b):
     return xmin,xmax

def area(f,a,b):
    return aire

f='x**3-2*x+1'
a,b=-2,2
L=root(f,a,b)
print L

Pour l'instant, ce n'est pas non plus ce qui est demandé en ce qui concerne la forme, mais on verra après : je vais chercher à faire en sorte de partir d'un pas de 0.1, et d'avoir une première boucle où i, parcourt les valeurs de 0 à 5, modifiant le pas à chaque tou 10**-1, 10**-2, 10**-3...
Pour être sûr d'avoir des décimales correctes j'utiliserais après le module decimal...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#9 04-12-2010 13:16:55

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

Re : traitement de fonctions mathématiques.

Re

Merci à toi Yoshi,

Je fais actuellement des recherches de mon côté.

Je suis parfaitement d'accord avec ton raisonnement et je comprends très bien ce que tu veux faire. Je ne sais juste pas l'écrire .

En gros tu détermines a et b qui sont les bornes de l'intervalle [a,b] et on cherche à calculer entre a et b toutes les images , donc après oui il faut déterminer un pas c'est sur et enfin une fois la liste déterminer ( les images) , on recherche le minimum et le maximum.

tabuler la fonction en gros.

Pas évident ...

Dernière modification par zarnac (04-12-2010 13:53:20)

Hors ligne

#10 04-12-2010 14:19:19

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

Re : traitement de fonctions mathématiques.

pour le min et le max j'ai modifié un programme que j'ai trouvé sur internet, il ne correspond pas tout à fait à la mise en page de ce qu'on nous demande mais l'idée est là je pense:

from math import cos,sin,tan,sqrt,exp,log,pi
def f(x):
    return 3.0*x+x**2
import random
a=-5.0
b=5.0
N=50
minimum=f(a)
maximum=f(b)
for k in range(N):
    x=random.uniform(a,b)
    if f(x)>maximum:
        maximum=f(x)
    if f(x)<minimum:
        minimum=f(x)
print maximum
print minimum

Dernière modification par zarnac (04-12-2010 14:21:28)

Hors ligne

#11 04-12-2010 21:11:58

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

Re : traitement de fonctions mathématiques.

Re,

Je ne me disperse pas, je continue obstinément à suivre mon "chemin de petit bonhomme" comme chantait Brassens...
Donc v'la un morceau opérationnel :

#!/usr/bin/env python
# -*- coding: Latin-1 -*-

from __future__ import division
from math import cos,sin,tan,sqrt,exp,log,pi

def root(f,a,b):
    encadre,encadre_A,lb=[(a,b)],[],1
    for i in xrange(6):
        pas=10**(-i-1)
        for j in xrange(lb):
            c,d=encadre[j]
            fin=10*int((d-c)/pas)
            for k in xrange(fin):
                x1=c+pas*k
                x=x1
                f1=eval(f)
                x2=c+pas*(k+1)
                x=x2
                f2=eval(f)
                if (f1<=0 and f2>0) or (f1>=0 and f2 <0):                        
                    encadre_A.append((round(x1,i+1),round(x2,i+1)))
        encadre=encadre_A
        encadre_A=[]
        if i==0:
            lb=len(encadre)
    print 'root'+'s'*(lb>1)+' :',
    for i in xrange(lb):
        a,b=encadre[i]
        print round(a,6),
    return

def minimaxi(f,a,b):
     return xmin,xmax

def area(f,a,b):
    return aire

f='x**3-2*x+1'
a,b=-2,2
root(f,a,b)

roots : -1.618034 0.618033 1.0

Je vais essayer demain de faire un peu mieux au niveau de la construction, m'enfin, ça fonctionne...
J'ai été obligé d'utiliser deux listes : je démarre avec une liste contenant le couple (a,b) et une vide...
Le 1er passage sert à déterminer le nombre de solutions
i commande la précision
lb est le nombre de solutions, donc de couples ou intervalles...
j parcourt les intervalles 1 par 1
k est le nombre d'essais, mais il y en a beaucoup d'inutiles, c'est ça que je veux revoir notamment.
Après je passerai aux autres fonctions...

Essaie ça et dis-moi si tu trouves une faille...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#12 05-12-2010 12:23:26

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

Re : traitement de fonctions mathématiques.

Re Bonjour,

ça fonctionne très bien.

J"ai une question:

- Le résultat au final du programme donne quoi ,i.e

roots : -1.618034 0.618033 1.0

roots correspond aux racines cherchées sur l'intervalle xmin xmax de f'x)? Donc là tu as déterminé les racines?

dernière question:

def minimaxi(f,a,b):
     return xmin,xmax

def area(f,a,b):
    return aire

Je ne vois pas où cela intervient au final. Je vois très bien pour root mais ensuite xmin xmax et l'aire.

Merci.

Dernière modification par zarnac (05-12-2010 12:57:42)

Hors ligne

#13 05-12-2010 13:05:16

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

Re : traitement de fonctions mathématiques.

Re,

Je finis...
Aire, c'est fait, xmax,xmin, j'ai encore un souci : résultats incohérents,
je dois trouver pourquoi :

#!/usr/bin/env python
# -*- coding: Latin-1 -*-

from __future__ import division
from math import cos,sin,tan,sqrt,exp,log,pi

def root(f,a,b):
    encadre,encadre_A,lb=[(a,b)],[],1
    for i in xrange(6):
        pas=10**(-i-1)
        for j in xrange(lb):
            c,d=encadre[j]
            fin=10*int((d-c)/pas)
            for k in xrange(fin):
                x1=c+pas*k
                x=x1
                f1=eval(f)
                x2=c+pas*(k+1)
                x=x2
                f2=eval(f)
                if (f1<=0 and f2>0) or (f1>=0 and f2 <0):                        
                    encadre_A.append((round(x1,i+1),round(x2,i+1)))
                    if i>0:
                        break
        encadre=encadre_A
        encadre_A=[]
        if i==0:
            lb=len(encadre)
    print 'root'+'s'*(lb>1)+' :',
    for i in xrange(lb):
        a,b=encadre[i]
        print round(a,6),


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

def area(f,a,b):
    nbi=10**6
    pas=abs((b-a))/nbi
    k=pas/2
    S=0
    for i in xrange(nbi):
        x=a+pas*i
        f1=eval(f)
        x=a+pas*(i+1)
        f2=eval(f)
        S+=(f1+f2)*k
    print "area : ",round(S,4)


f='x**3-2*x+1'
a,b=-2,2
root(f,a,b)
print
a,b=-1.6,0.6
area(f,a,b)
print
a,b=-2,2
minimaxi(f,a,b)

area est un peu long, mais peux pas faire mieux pour l'instant...

Travaux toujours en cours, donc..
Tu pourrais chercher un peu aussi, en dehors d'Internet...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#14 05-12-2010 13:47:15

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

Re : traitement de fonctions mathématiques.

Oui c'est en cours...
j'ai juste besoin de temps pour comprendre ce que tu as fait.

Je remets au propre la première partie, (ie définir une fonction et calculer ses images).

Hors ligne

#15 05-12-2010 14:59:11

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

Re : traitement de fonctions mathématiques.

RE,

Au sens strict du terme, puisqu'il n'y a plus de return (l'affichage étant intégré), je n'ai plus écrit des "fonctions", mais des "procédures", comme ça, il n'y aura plus de confusion entre "fonctions courantes" mathématiques et fonctions pythonesques...

Je n'ai pas eu le temps d'affiner encore, ni de chercher pourquoi mon xmin est faux...
Les procédures root et area sont correctes : j'ai juste besoin de "formater l'affichage" pour que celui-ci soit identique aux exmples donnés dans ton post #1 ce qui est déjà fait pour la procédure minimaxi(f,a,b) : hélas je le redis : on devrait avoir xmin =-2 et f(-2)=-3...
Donc, il y a une erreur quelque part, faut que je trouve le temps de chercher pourquoi (pas avant quelques heures).


Arx Tarpeia Capitoli proxima...

Hors ligne

#16 05-12-2010 19:41:36

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

Re : traitement de fonctions mathématiques.

Bonsoir,

Voilà, corrigé, y compris l'affichage de sortie :

#!/usr/bin/env python
# -*- coding: Latin-1 -*-

from __future__ import division
from math import cos,sin,tan,sqrt,exp,log,pi

def root(f,a,b):
    encadre,encadre_A,lb=[(a,b)],[],1
    for i in xrange(6):
        pas=10**(-i-1)
        for j in xrange(lb):
            c,d=encadre[j]
            fin=10*int((d-c)/pas)
            for k in xrange(fin):
                x1=c+pas*k
                x=x1
                f1=eval(f)
                x2=c+pas*(k+1)
                x=x2
                f2=eval(f)
                if (f1<=0 and f2>0) or (f1>=0 and f2 <0):                        
                    encadre_A.append((round(x1,i+1),round(x2,i+1)))
                    if i>0:
                        break
        encadre=encadre_A
        encadre_A=[]
        if i==0:
            lb=len(encadre)  
    print 'root'+'s'*(lb>1)+" in ["+str(a)+","+str(b)+"] : ",
    for i in xrange(lb):
        a,b=encadre[i]
        print "f("+str(round(a,6))+") =",
    print 0

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

def area(f,a,b):
    nbi=10**6
    pas=abs((b-a))/nbi
    k=pas/2
    S=0
    for i in xrange(nbi):
        x=a+pas*i
        f1=eval(f)
        x=a+pas*(i+1)
        f2=eval(f)
        S+=(f1+f2)*k
    print "area under ["+str(a)+","+str(b)+"] :",round(S,4)

f='x**3-2*x+1'
a,b=-2.0,2.0
root(f,a,b)
print
a,b=-1.6,0.6
area(f,a,b)
print
a,b=-2.0,2.0
minimaxi(f,a,b)

Résultat :

>>> ================================ RESTART ================================
>>>
roots in [-2.0,2.0] :  f(-1.618034) = f(0.618033) = f(1.0) = 0

area under [-1.6,0.6] : 2.794

min in [-2.0,2.0] : f(-2.0) = -3.0
max in [-2.0,2.0] : f(2.0) = 5.0
>>>

Voilà l'image de la courbe :
                         101205064334510023.png

A toi de jouer...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#17 05-12-2010 22:14:47

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

Re : traitement de fonctions mathématiques.

Re,

Remords de conscience : explication de texte pour la procédure root :
Je commence par initialiser deux listes :
* une vide que je remplirais avec le(s) couple(s) de valeurs encadrant le(s) zéro(s)
* une autre avec (a,b) - les bornes de l'intervalle qui sont bien un couple de valeurs encadrant...etc
J'initialise aussi une variable lb à 1 (1 couple) qui me servira à stocker le nombre exact de couples trouvés après un premier parcours d'intervalles de 0.1 de large entre a et b...
Donc première boucle : i sert à calculer ce que j'appelle le pas, c'est à dire la largeur de mes intervalles de base.
Quand i = 0, mon pas est de 10^{1}=0.1
2e boucle : celle-là a une longueur de 1 au départ : je sais qu'il y au moins une racine entre -2 et +2, mais passera à 3 quand j'aurais fin la totalité du premier passage et que i sera incrémenté de 0 à 1, le pas devenant 0.01... Pourquoi ? parce que, grâce au théorème des gendarmes, j'aurai trouvé 3 couples c et d tels que f(c)<=0 et f(d)>0 OU f(c)>=0 et f(d)<0...
Dpnc, 2e boucle je récupère c et d dans la liste encadre, en fait je vais récupérer un par un tous les couples (c,d) avec  c,d=encadre[j]
A chaque couple (c,d) correspond en fait un intervalle [c ; d] de longueur d-c que je vais partager en tranches fines de 0.1 de large, puis 0.01, puis 0.001 jusqu'à 0.000001 qui me donnera la précision souhaitée pour l'encadrement de mes racines...
Donc ces mini intervalles seront respectivement et successivement dans ma 3e boucle :
[c;c+0.1], [c+0.1;c+0.2], [c+0.2;c+0.3]...
[c;c+0.01], [c+0.01;c+0.02], [c+0.02;c+0.03]...
Soit en fait, pour k de 0 à nombre d'intervalles-1
[c+pas*k;c+pas*(k+1)] : lorsque k vaut 0 je me retrouve bien avec [c;c+pas]
Combien y a-t-il d'intervalles (variable fin) :
Entre d et c : largeur totale : d-c, largeur du mini intervalle : pas.
Donc fin =(d-c)/pas... Oui, mais voilà, même si en maths le résultat est entier, en informatique, il est décimal et donc je dois le transformer en entier via int (ce qui me donne une idée d'ailleurs pour éviter ce int)
Si les 2 valeurs testées collent avec le théorème des gendarmes, je les stocke dans la 2e liste...
Si mon premier tour avec i =0 est passé alors dès que j'ai un encadrement plus fin à l'intérieur de l'encadrement sélectionné je peux sortir de la boucle k, pas d'autres tests nécessaires, je peux sélectionner tout de suite l'encadrement suivant et l'affiner...
En sortie de boucle j, quand j'ai affiné tous les intervalles pour une précision donnée (boucle i), alors je transfère le contenu de la liste contenant les valeurs affinées dans la liste contenant les valeurs précédentes, et je vide la première pour pouvoir la remplir avec les valeurs affinées avec la nouvelle précision...

L'affichage : je raffine un peu en faisant ajouter 1 s à root s'il y a plus d'une solution...
Après :
* str() transforme un nombre en chaîne ce qui permet
  1. D'utiliser la longueur exacte du nombre,
  2. De concaténer les chaînes sans garder l'espace qui serait dû à la virgule :
      print "f(",a,")" affiche f( a ) et moi je veux f(a)...

Maintenant, je vais pouvoir penser à améliorer ce code qui est moche : premier jet dans l'urgence...

Questions supplémentaires ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#18 05-12-2010 22:34:36

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

Re : traitement de fonctions mathématiques.

Normalement avec la première partie que j'ai faite c'est-à-dire:

def main(f,a,b):
    from math import cos,sin,tan,sqrt,exp,log,pi
f = None
while 1:
    command = raw_input("Enter command: ")
    if not command:
        print "End of program."
        break
    if command.startswith('def '):
        f = command.lstrip('def ')
        print "f(x)=%s" % f
    elif command.startswith('val '):
        x = float(command.lstrip('val '))
        try:
            print "f(%f)=%f" % (x,eval(f))
        except TypeError:
            print "No function defined."
    else:
        print "Unknown command."

Qui devrait être en fait le programme de base puisqu'on définit une fonction pour toutes ces applications (area, min, max ...)

donc en gros , il faut que je refasse ce programme en deux parties dont la première
-def f(x)
-val (a,b)      =>cherche les images de la fonction.

Hors ligne

#19 06-12-2010 12:33:57

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

Re : traitement de fonctions mathématiques.

Re,

Cette ligne ne sert qu'à calculer une image :

try:
            print "f(%f)=%f" % (x,eval(f))

Calcul basique..
Parce que pour les calculs évolués, les "eval" sont déjà intégrés dans les procédures écrites et je ne vois pas comment on se pourrait se passer des eval() dans ces procédures...
Je pense donc qu'on pourrait ruser comme suit
Par exemple, à  l'invite de  :
command =raw_input('<> Enter command :')
si tu tapes root(f,-2.0,3.0) tu as command="root(f,-2.0,3.0)"
Donc tu enchaînes par exec(command) qui va exécuter la commande comprise dans la chaîne...

MAIS, toi, tu ne dois taper que root -2.0 3.0, ce qui va nécessiter un traitement préalable...
Le résultat du raw_input est une chaîne de caractères...


Donc, il faut seulement entrer command ="root -2.0 3.0"
Et je vais alors transformer la chaîne command, entrée par raw_input, en liste par

 command=command.split(' ')

et j'obtiens : ['root', '-2.0', '3.0'] à la place de "root -2.0 3.0"
Liste que je dois  retransformer en la chaîne : "root(f,-2.0,3.0)" pour pouvoir l'exécuter :

command=command[0]+'(f'+','+command[1]+','+command[2]+')'

--> j'obtiens "root(f,-2.0,3.0)"
Et maintenant, j'ajoute la ligne :

exec(command)

...
Ton interface deviendrait donc  ça :

f = None
while 1:
    command = raw_input("Enter command: ")
    if not command:
        print "End of program."
        break
    if command.startswith('def '):
        f = command.lstrip('def ')
        print "f(x)=%s" % f
    elif command.startswith('val '):
        x = float(command.lstrip('val '))
        try:
            print "f(%f)=%f" % (x,eval(f))
        except TypeError:
            print "No function defined."
    elif command[:command.find(' ')] in "root mini maxi area":
        command=command.split(' ')
        command=command[0]+'(f,'+command[1]+','+command[2]+')'
        try:
            exec(command)
        except TypeError:
            print "No function defined."
    else:
        print "Unknown command."

Tu ne dois pas mettre pas les import dans une def : ils seraient valables localemnt dans la def à condition de l'appeler aussi avant : perte de temps. Laisse-les à l'extérieur, en tout début de programme, ainsi que je l'ai fait...

J'ai aussi modifié, simplifié mon code, et coupé la def minimaxi en deux, pour avoir mini ET maxi indépendants :

#!/usr/bin/env python
# -*- coding: Latin-1 -*-

from __future__ import division
from math import cos,sin,tan,sqrt,exp,log,pi

def root(f,a,b):
    encadre,encadre_A,lb,pas=[(a,b)],[],1,1
    for i in xrange(1,8):
        pas*=0.1
        for j in xrange(lb):
            c,d=encadre[j]          
            x1,x=c,c
            f1=eval(f)
            while not x1+pas>b:
                x2=x1+pas
                x=x2
                f2=eval(f)
                if (f1<=0 and f2>0) or (f1>=0 and f2 <0):                        
                    encadre_A.append((x1,x2))
                    if i>1:
                        break
                x1,x=x2,x2
                f1=f2
        encadre=encadre_A
        encadre_A=[]
        if i==1:
            lb=len(encadre)  
    print 'root'+'s'*(lb>1)+" in ["+str(a)+","+str(b)+"] : ",
    for i in xrange(lb):
        a,b=encadre[i]
        print "f("+str(round(a,6))+") =",
    print 0

def maxi(f,a,b):
    xmax,maxi=0,-100
    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=0,100
    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          

def area(f,a,b):
    n=6
    nbi=10**n
    pas=abs((b-a))*10**(-n)
    k=pas/2
    S=0
    x=a
    f1=eval(f)
    for i in xrange(1,nbi):      
        x+=pas
        f2=eval(f)
        S+=(f1+f2)*k
        f1=f2
    print "area under ["+str(a)+","+str(b)+"] :",round(S,6)

Pour les parties où j'utilise x1,x2,f1,f2, il m'est venu à l'esprit que les mini-intervalles étaient jointifs, et donc que la borne supérieure du mini-intervalle en cours deviendrait la borne inférieure du min intervalle suivant.
Donc, avant d'entrer dans la boucle, j'amorce la pompe, en calculant les valeurs de départ x1,f1, j'entre dans la boucle et je calcule les valeurs de l'autre borne...
Avant tout nouveau tour de boucle je dis au programme que x1=x2 et f1=f2 : la borne supérieure du mini-intervalle en cours devient a borne inférieure du min intervalle prochain.
J'économise donc 1 calcul sur 2
En outre, au lieu de faire x2=c+pas*(k+1) je fais simplement x2=x1+pas, ce qui économise à chaque tour une addition et une multiplication...
De même pour le pas : au lieu de recalculer la puissance dix à chaque fois, je calcule pas=pas*0.1 à chaque itération...

L'interface modifiée au dessus s'ajoute à la suite de ce code...

@+

[EDIT]
Je ne peux utiliser max et min pour désigner les procédures : ce sont des mots réservés : je déclenche une erreur de syntaxe. Je conserve donc mini et maxi...

J'ai ajouté l'interface ci-dessus modifiée ce matin, au programme corrigé que j'ai mis aussi ci-dessus : ça fonctionne ainsi que je l'ai écrit.
Précision pour sortir, il faut entrer une ligne vide est-il précisé en Anglais, c'est plutôt "Appuyer sur Entrée" qu'il faut faire.
Essaie le tout et tu verras...

Dernière modification par yoshi (06-12-2010 16:15:08)


Arx Tarpeia Capitoli proxima...

Hors ligne

#20 06-12-2010 19:18:15

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

Re : traitement de fonctions mathématiques.

Re,

ok...
Pour être clair, voilà ce que c
ça donne complet :

#!/usr/bin/env python
# -*- coding: Latin-1 -*-

from __future__ import division
from math import cos,sin,tan,sqrt,exp,log,pi

def root(f,a,b):
    encadre,encadre_A,lb,pas=[(a,b)],[],1,1
    for i in xrange(1,8):
        pas*=0.1
        for j in xrange(lb):
            c,d=encadre[j]          
            x1,x=c,c
            f1=eval(f)
            while not x1+pas>b:
                x2=x1+pas
                x=x2
                f2=eval(f)
                if (f1<=0 and f2>0) or (f1>=0 and f2 <0):                        
                    encadre_A.append((x1,x2))
                    if i>1:
                        break
                x1,x=x2,x2
                f1=f2
        encadre=encadre_A
        encadre_A=[]
        if i==1:
            lb=len(encadre)  
    print 'root'+'s'*(lb>1)+" in ["+str(a)+","+str(b)+"] : ",
    for i in xrange(lb):
        a,b=encadre[i]
        print "f("+str(round(a,6))+") =",
    print 0

def maxi(f,a,b):
    xmax,maxi=0,-100
    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=0,100
    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          

def area(f,a,b):
    n=6
    nbi=10**n
    pas=abs((b-a))*10**(-n)
    k=pas/2
    S=0
    x=a
    f1=eval(f)
    for i in xrange(1,nbi):      
        x+=pas
        f2=eval(f)
        S+=(f1+f2)*k
        f1=f2
    print "area under ["+str(a)+","+str(b)+"] :",round(S,5)

f = None
while 1:
    command = raw_input("Enter command: ")
    if not command:
        print "End of program."
        break
    if command.startswith('def '):
        f = command.lstrip('def ')
        print "f(x)=%s" % f
    elif command.startswith('val '):
        x = float(command.lstrip('val '))
        try:
            print "f(%f)=%f" % (x,eval(f))
        except TypeError:
            print "No function defined."
    elif command[:command.find(' ')] in "root mini maxi area":
        command=command.split(' ')
        command=command[0]+'(f,'+command[1]+','+command[2]+')'
        try:
            exec(command)
        except TypeError:
            print "No function defined."
    else:
        print "Unknown command."

Fonctionnement :

IDLE 2.6.4     
>>> ================================ RESTART ================================
Enter command: def x**3-2*x+1
f(x)=x**3-2*x+1
Enter command: root -2.0 3.0
roots in [-2.0,3.0] :  f(-1.618034) = f(0.618034) = f(1.0) = 0
Enter command: maxi -1.6 0.6
max in [-1.6,0.6] : f(-0.8165) = 2.08866210787
Enter command:
End of program.

Si tu as des questions, n'hésite pas...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#21 07-12-2010 20:21:56

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

Re : traitement de fonctions mathématiques.

Re,

1. Si min et max marchent tant mieux, remplace...

2. from __future__ import division. Google ne sait pas de quoi il parle..
   Avant les version 3.x, Python se comporte ainsi : 5/2 = 2, mais 5.0/2 ou 5/2.0 = 2.5.
   La mention from __future__ est inutile... Je pensais m'en servir, mais je ne l'ai pas fait.
   A partir des versions 3.x 5/2 = 2.5 et 5//2 = 2.
   Je n'ai utilisé nulle part de double slash pour la division.
   J'ai enlevé chez moi l'import from __future__ pour tester et il n'y a pas d'erreur de syntaxe : attention 2 underscore de chaque côté, sinon erreur...

3. Pour l'aire,il me semble qu'il était demandé qu'elle soit calculée à partir de 10^6 trapèzes
   Le from __future__ = depuis le futur = pour avoir le comportement de la division des versions 3.x dans les versions 2.x) importe dans Python, la division.

4. Pourquoi veux-tu que ton min et ton max soient des entiers ? Et si ce n'est pas vrai ?
    Pour avoir un résultat entier quel qu'il soit, à la fin, tu as deux solutions, soit tu prends la partie entière du résultat ;
   int(resultat), soit tu arrondis à 0 chiffres après la virgule : round(résultat,0)

5. str.
   print "f(",2,")"    affiche  f( 2 ) avec des espaces comme tu vois, à cause de la virgule dans le print (essaie !)
   print "f("+str(2)+")" affiche f(2) sans les espaces parce que pas de virgule mais str(2) est un string donc je peux concaténer sans espaces.

6. Je n'ai pas compris ce que tu veux avec ton problème d'affichage OPMATH=====
    author, version... etc...

7. Je viens de découvrir un bug dans la recherche de racines : il y a un cas où le théorème des gendarmes ne fonctionne pas : essaie avec x**3-3*x+2 et tu verras . Je vais réfléchir à une parade...

C'est suffisant comme explications ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#22 07-12-2010 21:17:31

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

Re : traitement de fonctions mathématiques.

Re,

En effet, en enlevant le from_future_import division, cela ne pose aucun problème.

en ce qui concerne l'affichage de ce que je veux:
lorsque j'exécute le programme, je dois avoir:

=======================================================================
OPMATH : perform miscellaneous processing on a mathematical function
=======================================================================
Note : enter an empty line to stop the interaction loop
<> Enter command : def x*x - 1
f(x) = x*x - 1
<> Enter command : val 2.0
f(2.0) = 3.0
<> Enter command : min -2.0 3.0
min in [-2.0,3.0] : f(0.0) = -1.0
<> Enter command : max -2.0 3.0
max in [-2.0,3.0] : f(3.0) = 8.0
<> Enter command : root -2.0 3.0
root in [-2.0,3.0] : f(-1.0) = f(1.0) = 0.0
<> Enter command : area 0.0 3.0
area under [0.0,3.0] : 6.0
<> Enter command : def cos(x)
f(x) = cos(x)
<> Enter command :

ce sont les premières lignes qui m'intéressent , j'ai appliqué un modèle comme nous faisait faire notre prof c'est-à-dire en début du programme j'ai mis:

# ======================================================================
# OPMATH
# ======================================================================
"""OPMATH : perform miscellaneous processing on a mathematical function"""
__author__  = "binome1 - binome2
__version__ = "1.0"
__date__    = "2011-01-04"
__usage__   = """
Note : enter an empty line to stop the interaction loop"""
# ======================================================================
etc ...

Mais ça ne m'affiche rien.

Sinon oui , j'ai compris tes explications merci.

Hors ligne

#23 07-12-2010 21:36:26

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

Re : traitement de fonctions mathématiques.

Re,

J'abandonne le théorème des gendarmes : c'est leur suggestion de la dichotomie qui m'y a conduit...
Je vais revenir aux sources : je vais balayer la totalité de l'intervalle par pas de plus en plus fin jusqu'à ce que je trouve une (ou plusieurs) valeur(s) de x telle(s) que f(x)<=10^-6...

@+

[Edit]
Tu veux que s'affichent aussi:
Author = ...
Version = ...
Usage = ...
ou pas ?


Arx Tarpeia Capitoli proxima...

Hors ligne

#24 07-12-2010 22:01:06

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

Re : traitement de fonctions mathématiques.

Re,

Bin alors où est le problème ?

zanarc a écrit :

Mais ça ne m'affiche rien.

Sinon rajoute avant le f=none :

print '================================================================================'
print 'OPMATH : perform miscellaneous processing on a mathematical function'
print '================================================================================'
# Author = Binôme1-Binôme2
# Version
# Usage
print 'Note : enter an empty line to stop the interaction loop'

Modifie le raw_input ainsi :
command=raw_input("<> Enter a command :")
ainsi tu auras le <> à l'affichage, un espace après, ainsi qu'un espace avant les deux points...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#25 08-12-2010 14:19:41

zarnac
Membre
Inscription : 29-11-2010
Messages : 39

Re : traitement de fonctions mathématiques.

Impeccable merci.

@+

Hors ligne

Pied de page des forums