Julia es un lenguaje de programación de alto rendimiento con numerosas herramientas útiles para el análisis numérico. Es fácil de escribir y cuenta con un ecosistema en rápido crecimiento de paquetes útiles para la computación científica, el aprendizaje automático y mucho más. Julia, al igual que JMP, es una herramienta invaluable para científicos, investigadores e ingenieros.
Julia tiene fama de ser fácilmente interoperable con otros lenguajes de programación, y tenía curiosidad por saber qué tan difícil sería llamar a Julia desde JSL. Si fuera posible (¡y lo es!), veo un gran potencial en llamar a Julia desde JSL. Se podrían crear interfaces de usuario interactivas para JMP que llamen a programas Julia de alto rendimiento. Se podrían crear modelos en Julia y graficar los resultados en JMP, o viceversa. Se podrían realizar las partes más lentas del flujo de trabajo de JMP en Julia.
Voy a explicar dos métodos para llamar a Julia desde JSL. El primer método utiliza JSL para llamar a Python y, a su vez, llamar a Julia. En el segundo método, integramos Julia en una biblioteca de vínculos dinámicos (DLL) escrita en C.
Tenga en cuenta que no abordaré en profundidad la programación en Julia. Si desea obtener más información sobre Julia, consulte su documentación . También hay materiales de aprendizaje disponibles en Academia Julia .
Llamar a Julia a través de Python
Python en JSL
JMP 14 añadió comandos JSL para interactuar directamente con Python. Aquí hay un ejemplo sencillo del índice de 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 podemos llamar a Julia desde Python, también podemos hacerlo desde JSL. PyJulia es un paquete de Python que permite precisamente eso. Vamos a configurarlo. Nota: Logré usar Julia 1.5.4, Python 3.9.5, PyJulia 0.5.7 y JMP 16.1 en Mac.
Suponiendo que Python esté instalado y funcionando correctamente, la configuración es la siguiente:
Si aún no lo has hecho, instala Julia. Para obtener instrucciones, visita las Instrucciones específicas de la plataforma para los binarios oficiales . Puedes descargar la última versión en la página de descargas de Julia .
A continuación, siga las instrucciones para instalar PyJulia.
Si puedes seguir las instrucciones de uso de PyJulia en una sesión normal de Python, ¡ya puedes empezar!
PyJulia en JSL
Ahora, en JSL, primero debes inicializar Julia en tu sesión de Python. Asegúrate de pasar la ruta a tu ejecutable de Julia como argumento de palabra clave de tiempo de ejecución, como se muestra a continuación.
Python Init();
// Initialize julia
Python Submit(
"\[
from julia import Julia
Julia(runtime="/usr/local/bin/julia")
]\");
Desde aquí, puedes usar Python Enviar para ejecutar cualquier código 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 tienes otros paquetes de Julia instalados, puedes acceder a ellos mediante la importación de Python. Aquí he usado Pandas.jl, DataFrames.jl y Lasso.jl para realizar un ajuste Lasso de altura en Big Class.jmp. Luego, uso JMP Graph Builder para graficar los valores reales frente a los predichos.
// 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>Gráfico de Graph Builder que muestra los resultados reales frente a los predichos, calculados 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">Cómo integrar Julia en una DLL</FONT><BR /> También es posible <A href="https://docs.julialang.org/en/v1/manual/embedding/" target="_self" rel="nofollow noopener noreferrer">integrar Julia</A> en código C. Compartiré algunos ejemplos sencillos, pero estoy seguro de que alguien con más conocimientos de C podría profundizar más en el tema.</P> <P><STRONG><FONT size="4">Cargar DLL</FONT></STRONG><BR /> La clave aquí es la función <FONT face="courier new,courier">Cargar DLL</FONT> de JSL. Un excelente recurso para aprender a usar <FONT face="courier new,courier">Cargar DLL</FONT> es <A href="https://www.lexjansen.com/nesug/nesug10/ad/ad04.pdf" target="_blank" rel="noopener nofollow noreferrer">este documento</A> . Como ejemplo sencillo, podemos tomar la siguiente función en C de un archivo llamado test.c.</P> // test.c
double myMultiply(double num1, double num2)
{
return num1 * num2;
} Y compilar en una DLL
# On Mac
gcc -shared -o test.dylib test.c
# On Windows
gcc -shared -o test.dll test.c
Luego, en JMP, podemos llamar a la función 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
Ahora vamos a analizar una DLL con código Julia integrado. Crearemos una función que calcula el seno de su entrada, expresada en grados.
// 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;
}
Para compilar en Mac, ejecuta el siguiente comando, donde $JULIA_DIR es una variable de entorno con la ruta al archivo ejecutable de Julia. En mi caso, era /Applications/Julia-1.7.app/Contents/Resources/julia. No lo he probado en Windows, pero debería funcionar algo similar.
# 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
¡Ahora podemos llamar a seneInDegrees 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; Conclusión
Las interfaces de Python y Cargar DLL de JSL nos permiten ir más allá de JMP y llamar a Julia. Fueron necesarias algunas pruebas para que funcionara, pero una vez configurado, funciona bastante bien. He mostrado algunos ejemplos sencillos en esta publicación, pero veo el potencial para crear aplicaciones nuevas e interesantes combinando JMP y Julia.
Gracias por leer. Espero haberles dejado informados y con ganas de explorar.
Una nota sobre las versiones
Solo logré que Julia funcionara con Python usando Julia 1.5 y la versión beta 1.8 en Mac. No tuve éxito al usar Julia con Python en Windows, pero no probé tantas versiones como en Mac. Utilicé JMP 16 para todas mis pruebas.