OVH Cloud OVH Cloud

Python et le Calcul Formel

10 réponses
Avatar
Charles Lesire
Bonjour,

Est-il possible de faire du calcul formel avec Python ?

J'explique le problème auquel je me suis confronté en codant cet aprem' :

J'ai une fonction f, et j'ai définit la fonction troncature
def troncature(f,I,x):
if x > I[0] and x < I[1]:
return f(x)
else:
return 0
qui tronque la fonction 'f' sur l'intervalle 'I'.

Maintenant je veux effectivement tronquer f, i.e. écrire un truc du genre

f = lambda x: troncature(f,[0,1],x)

sans redéfinir en dur la fonction f (de façon dynamique donc), et quand
j'exécute, ben ça déconne, car en fait je viens de définir une fonction
récursive (et qui finit pas en prime).

Une idée / solution ? (et éventuellement un choix d'un autre langage)

Merci :)
Charles

10 réponses

Avatar
noone
Le Mon, 20 Sep 2004 20:03:07 +0200, Charles Lesire a écrit :

Bonjour,

Est-il possible de faire du calcul formel avec Python ?

J'explique le problème auquel je me suis confronté en codant cet aprem' :

J'ai une fonction f, et j'ai définit la fonction troncature
def troncature(f,I,x):
if x > I[0] and x < I[1]:
return f(x)
else:
return 0
qui tronque la fonction 'f' sur l'intervalle 'I'.

Maintenant je veux effectivement tronquer f, i.e. écrire un truc du genre

f = lambda x: troncature(f,[0,1],x)

sans redéfinir en dur la fonction f (de façon dynamique donc), et quand
j'exécute, ben ça déconne, car en fait je viens de définir une fonction
récursive (et qui finit pas en prime).

Une idée / solution ? (et éventuellement un choix d'un autre langage)

Merci :)
Charles



Bonsoir,

pour la librairie de calcul formel il y a GIAC
http://www-fourier.ujf-grenoble.fr/~parisse/giac_fr.html
(sous licence GNU/GPL)

par contre c'est une librairie C++ donc il faut pouvoir la lier avec
Python...

Je ne suis pas spécialiste mais...
http://www.boost.org/libs/python/doc/
doit permettre de faire un binding.

Si cela fonctionne (utilisation de giac avec python... ou perl
d'ailleurs) n'hésitez à envoyer votre projet à l'auteur de giac.

@+

PS : il y a sur le site de GIAC un exemple d'utilisation en C++... et là
c'est beaucoup + simple !
http://www-fourier.ujf-grenoble.fr/~parisse/casflan/node4.html

Avatar
Xavier Combelle
[...]
sans redéfinir en dur la fonction f (de façon dynamique donc), et quand
j'exécute, ben ça déconne, car en fait je viens de définir une fonction
récursive (et qui finit pas en prime).


fort surpris de trouver un

Une idée / solution ? (et éventuellement un choix d'un autre langage)
La solution la plus simple que j'ai trouvé c'est de donner deux noms

différents.
An cherchant un peu, j'ai réussit à faire qqchose qui ressemblait un
peu à ce dont tu avais besoin.

def troncature(f,I,x):
if x > I[0] and x < I[1]:
return f(x)
else:
return 0
def f(x):
return x
print f
def g(f):
def ff(x):
return troncature(f,[0,1],x)
return ff
f = g(f)
print f(-.5),f(-.25),f(0),f(0.25),f(0.5),f(0.75),f(1), f(1.25),f(1.5)

Avatar
Charles Lesire
Effectivement, ça marche, mais ce que je cherche c'est une façon dynamique
(automatique) de faire ce calcul.

Je vais essayer de m'inspirer de ça !

Merci :)

"Xavier Combelle" a écrit dans le message de
news: 414f5818$0$12614$
[...]
sans redéfinir en dur la fonction f (de façon dynamique donc), et quand
j'exécute, ben ça déconne, car en fait je viens de définir une fonction
récursive (et qui finit pas en prime).


fort surpris de trouver un

Une idée / solution ? (et éventuellement un choix d'un autre langage)
La solution la plus simple que j'ai trouvé c'est de donner deux noms

différents.
An cherchant un peu, j'ai réussit à faire qqchose qui ressemblait un
peu à ce dont tu avais besoin.

def troncature(f,I,x):
if x > I[0] and x < I[1]:
return f(x)
else:
return 0
def f(x):
return x
print f
def g(f):
def ff(x):
return troncature(f,[0,1],x)
return ff
f = g(f)
print f(-.5),f(-.25),f(0),f(0.25),f(0.5),f(0.75),f(1), f(1.25),f(1.5)



Avatar
Eric Brunel
Charles Lesire wrote:
Bonjour,

Est-il possible de faire du calcul formel avec Python ?

J'explique le problème auquel je me suis confronté en codant cet aprem' :

J'ai une fonction f, et j'ai définit la fonction troncature
def troncature(f,I,x):
if x > I[0] and x < I[1]:
return f(x)
else:
return 0
qui tronque la fonction 'f' sur l'intervalle 'I'.

Maintenant je veux effectivement tronquer f, i.e. écrire un truc du genre

f = lambda x: troncature(f,[0,1],x)

sans redéfinir en dur la fonction f (de façon dynamique donc), et quand
j'exécute, ben ça déconne, car en fait je viens de définir une fonction
récursive (et qui finit pas en prime).


Je confirme: ce qu'il y a dans le lambda est évalué lorsque la lambda-fonction
est *appelée*, et non quand elle est définie. Donc quand tu appelles ta nouvelle
f (la lambda-fonction), elle appelle la fonction f définie *maintenant*, c'est à
dire encore la lambda-fonction, d'où récursivité et boucle...

Une idée / solution ? (et éventuellement un choix d'un autre langage)


Très simple: forcer à binder le nom f en local à la lambda fonction quand tu la
crée. Ca peut se faire par:

f = lambda x, f=f: troncature(f, [0,1], x)

Ce n'est pas très naturel, mais ça marche:

def troncature(f, I, x):
... if I[0] < x < I[1]:



... return f(x)
... else:
... return 0
...
def f(x): return x
...



f = lambda x, f=f: troncature(f, [0, 1], x)

f(-2)
0



f(0.5)
0.5



f(4)
0





Merci :)
Charles


Pas de mal. HTH
--
- Eric Brunel <eric (underscore) brunel (at) despammed (dot) com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com



Avatar
Xavier Combelle
Charles Lesire wrote:
Effectivement, ça marche, mais ce que je cherche c'est une façon dynamique
(automatique) de faire ce calcul.
je vois pas trop ce que tu appelles dynamique.


peut-être veux tu qq chose comme

def def_f(x):
return x
f = def_f
print f
def g(troncature,f):
def ff(x):
return troncature(f,[0,1],x)
return ff
f = g(f)

J'avoue là j'ai pas testé

Avatar
Charles Lesire
C'est bon, ça marche (à partir de ce que ton premier mail, et en définissant
g à l'intérieur de troncature !

MERCI

"Xavier Combelle" a écrit dans le message de
news: 41503806$0$12639$
Charles Lesire wrote:
Effectivement, ça marche, mais ce que je cherche c'est une façon
dynamique


(automatique) de faire ce calcul.
je vois pas trop ce que tu appelles dynamique.


peut-être veux tu qq chose comme

def def_f(x):
return x
f = def_f
print f
def g(troncature,f):
def ff(x):
return troncature(f,[0,1],x)
return ff
f = g(f)

J'avoue là j'ai pas testé




Avatar
Xavier Combelle
Charles Lesire wrote:
C'est bon, ça marche (à partir de ce que ton premier mail, et en définissant
g à l'intérieur de troncature !

MERCI



Ca donne quoi comme code la réponse? Car même si j'ai répondu à la
question, je ne la connais pas. Comme d'habitude, j'aimerais bien avoir
des programmes d'exemples qui sont syntaxiquement correct et qui
permettent de voir le résultat obtenu et le résultat attendu.

--
Xavier,
dans la série j'aimerai bien savoir ce que je suis en train de faire

Avatar
Alexandre Fayolle
Le 21-09-2004, Xavier nous disait:

Ca donne quoi comme code la réponse? Car même si j'ai répondu à la
question, je ne la connais pas. Comme d'habitude, j'aimerais bien avoir
des programmes d'exemples qui sont syntaxiquement correct et qui
permettent de voir le résultat obtenu et le résultat attendu.


Sur le groupe fr.comp.text.tex, ils appellent ça un ECM (Exemple Complet
Minimal). C'est une bonne pratique, en effet.

--
Alexandre Fayolle LOGILAB, Paris (France).
http://www.logilab.com http://www.logilab.fr http://www.logilab.org

Avatar
Charles Lesire
Alors, voilà le nouveau code de troncature :

def troncature(f,I,):
def trunc(x):
if x > I[0] and x < I[1]:
return f(x)
else:
return 0
return trunc

Puis un petit test :
def f(x): return x
f = troncature(f,[0,1])
print f(-.5),f(-.25),f(0),f(0.25),f(0.5),f(0.75),f(1), f(1.25),f(1.5)

Et voilà...

PS: ...si j'ai pas fait d'erreurs car j'ai écris le code de mémoire, le
fichir .py étant sur ma station, au boulot :)

Charles

"Alexandre Fayolle" a écrit dans le message de
news: cirbqs$1g8c$
Le 21-09-2004, Xavier nous disait:

Ca donne quoi comme code la réponse? Car même si j'ai répondu à la
question, je ne la connais pas. Comme d'habitude, j'aimerais bien avoir
des programmes d'exemples qui sont syntaxiquement correct et qui
permettent de voir le résultat obtenu et le résultat attendu.


Sur le groupe fr.comp.text.tex, ils appellent ça un ECM (Exemple Complet
Minimal). C'est une bonne pratique, en effet.

--
Alexandre Fayolle LOGILAB, Paris (France).
http://www.logilab.com http://www.logilab.fr http://www.logilab.org



Avatar
Xavier Combelle
Charles Lesire wrote:
Alors, voilà le nouveau code de troncature :
[...]
Par rapport à ce que tu écrivais initaliement:

J'ai une fonction f, et j'ai définit la fonction troncature
qui tronque la fonction 'f' sur l'intervalle 'I'.


J'ai plutôt l'impression que tu voulais créer une fonction
f_I qui est la troncature de f sur l'intervalle I.

Je crois que la technique utilisée s'appelle "closure" en anglais.
En créant dynamiquement une fonction qui utilse avec des variables qui
ont une portée locale (ici f et I), tu peux y accéder, même quand
l'espace de nommage a disparu.

Serait-il possible de repondre après la citation?



Sur le groupe fr.comp.text.tex, ils appellent ça un ECM (Exemple Complet
Minimal). C'est une bonne pratique, en effet.
Maintenant que j'ai un nom, je vais pouvoir le demander.