Julia est un langage de programmation performant doté de nombreux outils d'analyse numérique intégrés. Facile à utiliser, il bénéficie d'un écosystème en pleine expansion de packages utiles pour le calcul scientifique, l'apprentissage automatique et bien d'autres domaines. À l'instar de JMP, Julia est un outil précieux pour les scientifiques, les chercheurs et les ingénieurs.
Julia est réputée pour sa facilité d'interopérabilité avec d'autres langages de programmation, et je me demandais s'il serait difficile d'appeler du code Julia depuis JSL. Si c'est possible (et ça l'est !), j'entrevois un grand potentiel pour cette fonctionnalité. On pourrait créer des interfaces utilisateur JMP interactives qui appellent des programmes Julia très performants. On pourrait construire des modèles en Julia et visualiser les résultats dans JMP, ou inversement. On pourrait automatiser les parties les plus lentes d'un flux de travail JMP en les exécutant dans Julia.
Je vais présenter deux méthodes pour appeler Julia depuis JSL. La première utilise JSL pour appeler Python, qui à son tour appelle Julia. La seconde consiste à intégrer Julia dans une bibliothèque de liens dynamiques (DLL) écrite en C.
Notez que je ne traiterai pas en détail de la programmation en Julia. Si vous souhaitez en savoir plus sur Julia, consultez sa documentation . Des ressources d'apprentissage sont également disponibles sur Académie Julia .
Appeler Julia via Python
Python dans JSL
JMP 14 a ajouté des commandes JSL pour interagir directement avec Python. Voici un exemple simple tiré de l'index des scripts :
// Initialize the Python interface
PythonInit();
// Submit some Python code to run as a JSL string
PythonSubmit("\[message = 'The quick brown fox jumps over the lazy dog']\");
// message is now a variable in Python and can be accessed from JSL with PythonGet()
getStr = PythonGet(message);
Show(getStr);
// Terminate the Python interface
PythonTerm();
PyJulia
Si l'on peut appeler Julia depuis Python, on peut aussi l'appeler depuis JSL. PyJulia est une bibliothèque Python qui permet justement cela. Configurons-la. Remarque : J'ai réussi à l'utiliser avec Julia 1.5.4, Python 3.9.5, PyJulia 0.5.7 et JMP 16.1 sur Mac.
En supposant une installation Python fonctionnelle, la configuration est la suivante :
Si ce n'est pas déjà fait, installez Julia. Pour obtenir des instructions, consultez la page Instructions spécifiques à la plateforme pour les binaires officiels . La dernière version est disponible au téléchargement sur la page de téléchargement de Julia .
Ensuite, suivez les instructions pour installer PyJulia.
Si vous êtes capable d'utiliser les instructions d'utilisation de PyJulia dans une session Python normale, vous êtes prêt à partir !
PyJulia dans JSL
En JSL, vous devez d'abord initialiser Julia dans votre session Python. Veillez à indiquer le chemin d'accès à votre exécutable Julia comme argument mot-clé d'exécution, comme ci-dessous.
Python Init();
// Initialize julia
Python Submit(
"\[
from julia import Julia
Julia(runtime="/usr/local/bin/julia")
]\");
À partir de là, vous pouvez utiliser Soumettre Python pour exécuter n'importe quel code Julia.
// Import the main module. This is Julia's workspace.
Python Submit("\[
from julia import Main
Main.xs = [1,2,3] # xs belongs to julia
sines = Main.eval("sin.(xs)") # This returns the sine of each element in xs
]\");
show(PythonGet(sines)); // [0.841470984807897 0.909297426825682 0.141120008059867]
Si vous avez installé d'autres packages Julia, vous pouvez y accéder via l'importation Python. J'ai utilisé ici Pandas.jl, DataFrames.jl et Lasso.jl pour effectuer un ajustement lasso sur la taille dans le fichier Big Class.jmp. J'ai ensuite utilisé JMP Graph Builder pour tracer les valeurs réelles en fonction des valeurs prédites.
// Convert datatable to julia dataframe
// Must convert it to a julia Pandas dataframe first
dt = open("$SAMPLE_DATA/Big Class.jmp");
Pythonsend(dt);
Python Submit(
"\[
from julia import Pandas
from julia import DataFrames
from julia import Lasso
Main.dt = dt
predicted = Main.eval("""
using Lasso
df = DataFrames.DataFrame(Pandas.DataFrame(dt))
m = fit(LassoModel, @formula(height ~ sex + weight), df)
predict(m, df)
""")
]\");
// Back to JMP where we plot Actual vs. Predicted
predicted = pythonget("predicted");
dt << newColumn("Predicted height", <
<SETVALUES></SETVALUES>
<P class="lia-align-center" style="text-align: center;" style="text-align: center;"><FONT size="2"><EM>Graphique comparant les résultats réels et les résultats prédits obtenus avec Graph Builder et calculés en Julia</EM></FONT></P> <P><SPAN class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="plot.png" style="width: 385px;"><span class="lia-inline-image-display-wrapper" image-alt="plot.png" style="width: 385px;"><img src="https://us.v-cdn.net/6038925/uploads/images/41854i1D3222BA026053FF/plot.png" role="button" title="plot.png" alt="plot.png" /></span><SPAN class="lia-inline-image-caption" onclick="event.preventDefault();">plot.png</SPAN></SPAN></P> <BR /> <P><FONT size="5">Intégration de Julia dans une DLL</FONT><BR /> Il est également possible d' <A href="https://docs.julialang.org/en/v1/manual/embedding/" target="_self" rel="nofollow noopener noreferrer">intégrer Julia</A> dans du code C. Je partagerai quelques exemples simples, mais je suis certain qu'une personne plus familière avec le C pourrait approfondir le sujet.</P> <P><STRONG><FONT size="4">ChargerDLL</FONT></STRONG><BR /> L'élément clé ici est la fonction <FONT face="courier new,courier">ChargerDLL</FONT> de JSL. <A href="https://www.lexjansen.com/nesug/nesug10/ad/ad04.pdf" target="_blank" rel="noopener nofollow noreferrer">Ce document</A> constitue une excellente ressource pour apprendre à utiliser <FONT face="courier new,courier">ChargerDLL</FONT> . À titre d'exemple simple, prenons la fonction C suivante, située dans un fichier nommé test.c.</P> // test.c
double myMultiply(double num1, double num2)
{
return num1 * num2;
} Et compiler en une DLL
# On Mac
gcc -shared -o test.dylib test.c
# On Windows
gcc -shared -o test.dll test.c
Ensuite, dans JMP, nous pouvons appeler la fonction C
dll = loadDLL(convertfilepath("/path/to/my/test.dylib"));
dll << declareFunction("myMultiply",
Convention( STDCALL ),
Arg(Double, "num1"),
Arg(Double, "num2"),
Returns( Double )
);
show(dll << myMultiply(Pi(), 100));
dll << unloadDLL; Julia DLL
Examinons maintenant une DLL contenant du code Julia. Nous allons créer une fonction qui calcule le sinus de son entrée, exprimée en degrés.
// call_julia.c
#include
double sineInDegrees(double degrees)
{
// required: setup the Julia context
jl_init();
// You can evaluate Julia code from strings
jl_value_t *factor = jl_eval_string("pi/180");
double factor_unboxed = jl_unbox_float64(factor);
double radians = degrees * factor_unboxed;
// You can call Julia functions directly
jl_function_t *func = jl_get_function(jl_base_module, "sin");
jl_value_t *argument = jl_box_float64(radians);
jl_value_t *ret = jl_call1(func, argument);
double ret_unboxed = jl_unbox_float64(ret);
jl_atexit_hook(0);
return ret_unboxed;
}
Pour compiler sur Mac, exécutez la commande ci-dessous, en remplaçant `$JULIA_DIR` par une variable d'environnement indiquant le chemin d'accès à votre exécutable Julia. Dans mon cas, il s'agissait de `/Applications/Julia-1.7.app/Contents/Resources/julia`. Je n'ai pas testé cette procédure sous Windows, mais une méthode similaire devrait fonctionner.
# On Mac
gcc -shared -o call_julia.dylib call_julia.c -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib -Wl,-rpath,$JULIA_DIR/lib -ljulia
Nous pouvons maintenant appeler sinusEnDegrés en JSL !
dll = loadDLL(convertfilepath("/path/to/my/call_julia.dylib"));
dll << declareFunction("sineInDegrees",
Convention( STDCALL ),
Arg( Double, "degrees" ),
Returns( Double )
);
show(dll << sineInDegrees(90)); // 1
dll << unloadDLL; Conclusion
Les interfaces Python et ChargerDLL de JSL nous permettent d'aller au-delà de JMP et d'appeler Julia. Il a fallu quelques essais et erreurs pour y parvenir, mais une fois configurée, elle fonctionne très bien. J'ai présenté quelques exemples simples dans cet article, mais je vois un fort potentiel pour créer des applications nouvelles et intéressantes en combinant JMP et Julia.
Merci de votre lecture. J'espère vous avoir apporté des informations utiles et avoir suscité votre curiosité.
Note sur les versions
Je n'ai réussi à faire fonctionner Julia via Python qu'avec Julia 1.5 et la version bêta de Julia 1.8 sur Mac. Sous Windows, je n'ai pas réussi, mais je n'ai pas testé autant de versions que sur Mac. J'ai utilisé JMP 16 pour tous mes tests.