Est-il possible de rappeler Mathematica lors de l'utilisation de Python via ExternalEvaluate?
ExternalEvaluatepermet d'appeler du code Python depuis Mathematica. Le client Wolfram pour Python permet d'appeler Mathematica depuis Python.
En cas d' utilisation ExternalEvaluate, il est possible d'appeler de nouveau au même noyau Mathematica?
À titre d'exemple, supposons que j'ai une fonction Python nintqui effectue une intégration numérique. Il prend une autre fonction comme argument - la fonction à intégrer. Existe-t-il un moyen d'utiliser la fonction Python nintvia ExternalEvaluate/ ExternalFunctionpour intégrer une fonction fdéfinie dans Mathematica?
Pour être clair, ce n'est qu'un exemple pour aider à expliquer le problème. Je ne cherche pas réellement à faire de l'intégration numérique, et pour le moment, les performances (ce qui serait un gros problème pour l'intégration numérique pratique) ne me préoccupent pas.
Réponses
Je suis Riccardo Di Virgilio, l'un des développeurs d'ExternalEvaluate et de wolframclientforpython.
Il existe un moyen de faire ce que vous voulez, même si la fonction n'est pas documentée ou exposée, de sorte que le code que je vous donne pourrait se rompre dans les versions futures.
essayez d'exécuter ceci dans ExternalEvaluate:
from wolframclient.language.side_effects import wl_side_effect
from wolframclient.language import wl
wl_side_effect(wl.Print(2))
wl_side_effect(wl.Print(3))
wl_side_effect(wl.Print(4))
"actual result"
Donc, fondamentalement, nous avons un enregistreur python standard qui peut renvoyer des messages au noyau d'origine. Le noyau reçoit le message et continue d'attendre le résultat du calcul.
Si vous écrivez quelque chose de complexe, je vous suggère de jeter un œil au code externalevaluate, qui est public.
Oui. Il est mentionné dans le document de ExternalEvaluate
La commande
"cmd"peut contenir une expression de modèle en ligne<*expr*>. Cela évalue expr avant d'"cmd"être envoyé à l'évaluateur externe.
que nous pourrions utiliser TemplateExpressiondans la chaîne passée à ExternalEvaluate. Un exemple basique:
ExternalEvaluate["Python", "<* Range@5 *>"]
Cependant, cette méthode échoue lorsque vous essayez de définir une fonction dans une session python, car le <* expr *>est évalué avant que le ne "cmd"soit envoyé à l'évaluateur externe.
Une solution à cela consiste à définir la fonction dans Mathematica avec SetDelayed, puis à appeler la fonction en python avec <* *>. Un exemple est démontré dans ma réponse .
Peut-être avec ça? https://reference.wolfram.com/language/WolframClientForPython/
Usage:
Pour les fonctions définies dans Mathematica:
Deux manières:
1.
from wolframclient.evaluation import WolframLanguageSession
from wolframclient.language import wl, wlexpr
session = WolframLanguageSession()
Eval = session.evaluate
def sin(x):
return Eval(Eval(wl.Sin)(x))
>>> sin(wl.Plus(wl.Pi,2))
Times[-1, Sin[2]]
Remarquez que FullForm est nécessaire.
2.
def sinPlusCos(x):
return Eval(Eval(wlexpr("Sin@#+Cos@#&"))(x))
Utilisez wlexpr et la fonction pure.
Dans Mathematica, voici un petit exemple:
ExternalEvaluate["Python", {"from wolframclient.evaluation import \
WolframLanguageSession",
"from wolframclient.language import wl, wlexpr",
"session = WolframLanguageSession()",
"Eval = session.evaluate",
"def sin(x): return Eval(Eval(wl.Sin)(x))", "sin(wl.Pi)"}]
{Null, Null, Null, Null, Null, 0}
"sin (wl.Pi)" peut être remplacé par d'autres choses, par exemple: "sin(2.5)"
{Null, Null, Null, Null, Null, 0,598472}