Jornada Virtual de Doctorandos MSO 2021

Hands-on Julia

¿Qué es Julia?


Lo primero de todo, bienvenidos a este curso introductorio de optimización en Julia. En esta pequeña guía se tratará de explicar, de la manera más sencilla posible, cómo instalar todas las herramientas software que nos harán falta. Empezando por Julia.

Bueno... Julia como tal es un lenguaje de programación. Esto quiere decir que no se instala el lenguaje, sino que se instala un compilador, como se haría con C, Java, Fortran... y después se programa usando el editor de texto plano favorito o la terminal.

Julia es un lenguaje compilado en tiempo de ejecución, o JIT por sus siglas en inglés (Just In Time), que es una metodología que mezcla las metodologías de compilación AOT (Ahead-Of-Time) y de la interpretación. En oposición a los lenguajes clásicos que requieren compilación, como C, donde primero se inspecciona todo el código, se resuelven los problemas de gramática que pueda haber, se compila en un archivo ejecutable, y se lanza este.

Esto no es ni mejor, ni peor. Para cada uso es recomendable emplear un tipo de programación distinta. Tal vez para programación matemática, sí sea recomendable usar este tipo de lenguajes, pues permite evaluar las funciones según se escriben, en lugar de tener que escribir todo el programa para realizar las pruebas. Julia se diseñó directamente pensando en obtener un lenguaje que fuera sencillo de interpretar para la programación de problemas matemáticos (estilo Python), pero a su vez buscando la rapidez de los lenguajes de programación compilados.

Instalación de julia


En esta guía mostraremos cómo realizar la instalación necesaria en sistemas Windows y Linux. Aunque también se puede ejecutar desde sistemas Mac o FreeBSD. Primero hay que descargar el archivo necesario para cada sistema. Bien de su página de descargas: aquí. O bien clicando en el logo de los respectivos sistemas operativos aquí debajo si se dispone de una arquitectura de 64 bits.

Aunque existe la posibilidad de compilar el código fuente, se recomienda usar los ficheros binarios ya compilados. Sólo en casos de escasez de espacio en el disco duro, para evitar duplicidad en ciertas librerías generales, como OpenBLAS, sería beneficiosa la instalación manual. Por ello, aquí nos centraremos en la instalación recomendada.

Windows logo   Windows

Si se decide descargar la versión más reciente desde la web, elegir la descarga de Windows, escogiendo la arquitectura correspondiente a nuestro sistema (32 o 64 bits). En caso de duda, la versión de 32 bits se ejecuta en ambas arquitecturas, por lo que es la opción robusta, aunque la mayoría de sistemas ya son de 64 bits.

Una vez finalizada la descarga, lanzar el programa ejecutable. Seleccionar la ruta donde se desea guardar el programa, y en la siguiente pantalla, seleccionar la casilla Add Julia to PATH. Dando a siguiente se instalará el programa. Cuando finalice la instalación, se habrá generado una nueva aplicación en el menú de aplicaciones llamada Julia 1.6.0.

Tux logo   Linux

Si se decide descargar la versión más reciente desde la web, elegir la descarga de Generic Linux on x86, escogiendo la arquitectura correspondiente a nuestro sistema (32 o 64 bits). En caso de duda, la versión de 32 bits se ejecuta en ambas arquitecturas, por lo que es la opción robusta. En el caso de las descargas de binarios para Linux permite elegir entre una opción normal sin añadidos, o bien una versión basada en musl. Esto hace referencia a la biblioteca estándar de C, escoger la versión normal salvo que se sepa a ciencia cierta que la librería "libc" en el sistema es la librería musl.

Una vez que se dispone del fichero de binarios, se debe descomprimir en la ubicación que se desee.

$ mv julia-1.6.0-linux-x86_64.tar.gz /ruta/que/se/desee
$ cd /ruta/que/se/desee
$ tar -zxf julia-1.6.0-linux-x86_64.tar.gz

Esto habrá generado un nuevo directorio:

/ruta/que/se/desee/julia-1.6.0/bin

La ruta del archivo ejecutable se debe pasar al sistema operativo, para que la encuentre y poder ejecutar desde la terminal las ordenes de compilación. Esto se puede realizar fácilmente de dos maneras:

  • Generar un enlace simbólico del ejecutable en una carpeta que ya esté en el PATH del sistema, por ejemplo:

    $ ln -s /ruta/que/se/desee/julia-1.6.0/bin/julia /usr/bin/

    En la mayoría de casos se requieren permisos de superusuario para realizar este paso de creación de enlace simbólico. Habrá que realizar la última orden con el prefijo sudo.

  • O bien crear un alias que apunte al ejecutable con la ruta completa. La generación de este alias depende del shell del sistema operativo. En la mayoría de los casos se usa bash (GNU Bourne-Again Shell), por lo que habrá que modificar el fichero .bashrc con el editor de texto favorito. Por ejemplo:

    $ cd ~ $ vi .bashrc

    Añadir al fichero la línea de generación del alias:

    alias julia=/ruta/que/se/desee/julia-1.6.0/bin/julia

    Guardar el fichero, y recargar el entorno del shell.

    $ source ~/.bashrc

Una vez instalado julia, se procederá prácticamente igual en ambos sistemas. Lo primero es abrir el REPL de julia.

REPL es un acrónimo de Read-Evaluate-Print-Loop. Es el shell de ejecución de las órdenes de Julia. Se puede iniciar bien desde un terminal del sistema llamando a la orden julia, si se ha incluido en el PATH de ejecución; o bien (sólo en Windows) ejecutando el programa Julia 1.6.0 en la lista de aplicaciones, si se ha usado el instalador.

En ambos casos el resultado será una ventana que nos mostrará el shell de julia:

$ julia
               _
   _       _ _(_)_     | Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   | Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  | Version 1.6.0 (2021-03-24)
 _/ |\__'_|_|_|\__'_|  | Official https://julialang.org/ release
|__/                   |
julia>

Este shell puede trabajar en distintos modos, donde los principales son:

Instalación de paquetes extra


Por lo tanto, para añadir los paquetes que nos harán falta en el curso, se debe entrar en el modo Gestión de paquetes, y escribir las órdenes:

add DifferentialEquations
add JuMP
add Ipopt
add Cbc
add Pavito
add Plots

Esto instalará los paquetes que vamos a usar. Respetivamente:

Hay que tener en cuenta que, al ser de código abierto, los paquetes de los solvers ya incluyen directamente los algoritmos, y no hay que realizar ninguna tarea adicional para usarlos. No ocurre lo mismo con software propietario (ver sección Extras optimización).

Para ver más información de cada paquete, se puede buscar directamente en internet añadiendo la extensión .jl al nombre (es la extensión que se debe usar para los archivos de código Julia). Cada paquete dispone de una página en GitHub con una documentación detallada sobre su uso.

Opcionalmente, julia se puede ejecutar usando una interfaz web, como Jupyter. Aunque durante estas jornadas usaremos la opción del paquete Pluto.jl, una alternativa a Jupyter escrita completamente en Julia. Si se desea usar (es totalmente opcional), instalarlo mediante el gestor de paquetes. Para añadir funcionalidad a esta interfaz web, se puede instalar adicionalmente PlutoUI.jl.

julia> ]
(@v1.6) pkg> add Pluto
(@v1.6) pkg> add PlutoUI
(@v1.6) pkg> tecla retorno
julia> import Pluto
julia> Pluto.run()

Se abrirá una ventana del explorador automáticamente, donde se podrá proceder a programar usando código Julia como si se tratara de un terminal.

Para más información, entrar en la web del paquete Pluto.jl

Extras de optimización


Con los paquetes instalados hasta ahora, la funcionalidad del equipo es la necesaria para el curso. No obstante, se puede aumentar su eficiencia mediante la utilización de solvers mixto-entero propietarios, como CPLEX o Gurobi.

Así mismo, Ipopt se instala por defecto con el solver lineal mumps, pero normalmente funciona más rápido usando los algoritmos que ofrece la Harwell Subroutine Library [6].

En el primer caso, para realizar el uso de los algoritmos de resolución mixto-entero propiertario, hay que instalar el solver de manera independiente en el sistema. Existen tanto versiones de prueba gratuitas, como licencias académicas para cada uno. Seguir las instrucciones en cada caso: CPLEX, Gurobi. No olvidar hacer accesibles por el sistema las librerías, añadiendo sus carpetas a la rutas necesarias siguiendo las instrucciones de instalación de cada uno.

Después de instalar el programa, añadir el respectivo paquete de interfaz, i.e.

(@v1.6) pkg> add CPLEX
ó
(@v1.6) pkg> add Gurobi

Durante la instalación se buscará automáticamente qué versión está instalada, y se enlazará con ella.

En caso de instalar el paquete antes que el programa, la instalación del paquete dará error. En ese caso no es necesario desinstalarlo, basta con instalar el solver adecuado siguiente sus instrucciones y después volver a ejecutar la configuración del paquete con la orden build, i.e.

(@v1.6) pkg> build CPLEX
ó
(@v1.6) pkg> build Gurobi


Para poder llamar a la librería de HSL [6] desde Ipopt hay que tener la librería compilada independiente de julia.

Hay que tener en cuenta que, tanto en Windows como en Linux, se debe emplear el compilador de GNU. Después, renombrar o crear un enlace simbólico de la librería libcoinhsl.so a libhsl.so.

Por último, hacerla accesible por el sistema, esto es añadir la ruta al PATH en windows, o bien a la variable LD_LIBRARY_PATH en Linux, v.gr.:

$ export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/ruta/de/hsl/lib"

Con esto quedaría una instalación funcional de julia en nuestro sistema. Se puede comprobar que los paquetes estén correctamente instalados ejecutando la orden test más el nombre del paquete desde el terminal de julia en el modo de Gestión de paquetes.Por ejemplo:

julia> ]
(@v1.6) pkg> test DifferentialEquations
Después de realizar los cálculos, mostrará por pantalla varios mensajes del estilo:
Test Summary:         | Pass  Total
Default ODE Algorithm |   21     21

Test Summary:         | Pass  Total
Default DAE Algorithm |    1      1

La primera vez que se usa un paquete, este se debe configurar, por lo que puede tardar unos minutos en iniciar la ejecución dependiendo de la arquitectura del sistema.

Creado con ♥ por el departamento de ingeniería de sistemas y automática de la UVa.
Basado en las plantillas de w3.css