È possibile richiamare Mathematica quando si utilizza Python tramite ExternalEvaluate?

Aug 28 2020

ExternalEvaluaterende possibile chiamare codice Python da Mathematica. Il client Wolfram per Python rende possibile chiamare Mathematica da Python.

Quando si utilizza ExternalEvaluate, è possibile chiamare di nuovo per lo stesso kernel di Mathematica?

Ad esempio, supponiamo che io abbia una funzione Python nintche esegue l'integrazione numerica. Prende un'altra funzione come argomento: la funzione da integrare. C'è un modo per utilizzare la funzione Python nintattraverso ExternalEvaluate/ ExternalFunctionper integrare una funzione fdefinita in Mathematica?

Per essere chiari, questo è solo un esempio per aiutare a spiegare il problema. In realtà non sto cercando di fare l'integrazione numerica, e in questo momento le prestazioni (che sarebbe un grosso problema per l'integrazione numerica pratica) non mi preoccupano.

Risposte

7 RiccardoDiVirgilio Aug 30 2020 at 16:20

Sono Riccardo Di Virgilio, uno degli sviluppatori di ExternalEvaluate e wolframclientforpython.

C'è un modo per fare quello che vuoi, anche se la funzione non è documentata o esposta, quindi il codice che ti sto dando potrebbe non funzionare nelle versioni future.

prova a eseguirlo in 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"

Quindi fondamentalmente abbiamo un logger Python standard che può inviare messaggi al kernel originale. Il kernel riceve il messaggio e continua ad aspettare il risultato del calcolo.

Se stai scrivendo qualcosa di complesso ti consiglio di dare un'occhiata al codice di valutazione esterna, che è pubblico.

https://github.com/WolframResearch/WolframClientForPython/blob/master/wolframclient/utils/externalevaluate.py

https://github.com/WolframResearch/WolframClientForPython/blob/master/wolframclient/language/side_effects.py

1 MichaelChen Sep 05 2020 at 01:29

Sì. È menzionato nel documento di ExternalEvaluate

Il comando "cmd"può contenere un'espressione di modello inline <*expr*>. Questo valuta expr prima di "cmd"essere inviato al valutatore esterno.

che potremmo usare TemplateExpressionnella stringa passata a ExternalEvaluate. Un esempio di base:

ExternalEvaluate["Python", "<* Range@5 *>"]

Tuttavia, questo metodo non riesce quando si tenta di definire una funzione in sessione python, perché la <* expr *>si valuta prima che la "cmd"viene inviato al valutatore esterno.

Una soluzione a questo problema è definire la funzione in Mathematica con SetDelayed, quindi chiamare la funzione in Python con <* *>. Un esempio è dimostrato in questa mia risposta .

wuyudi Aug 29 2020 at 10:04

Forse con questo? https://reference.wolfram.com/language/WolframClientForPython/

Utilizzo:

Per le funzioni definite in Mathematica:

Due strade:

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]]

Avviso FullForm è necessario.

2.

def sinPlusCos(x):
    return Eval(Eval(wlexpr("Sin@#+Cos@#&"))(x))

Usa wlexpr e pure function.

In Mathematica, ecco un piccolo esempio:

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)" può essere sostituito da altre cose, ad esempio: "sin(2.5)"

{Null, Null, Null, Null, Null, 0.598472}