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.
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.
Si se decide descargar la versión más reciente desde la web, elegir la descarga de
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
.
Si se decide descargar la versión más reciente desde la web, elegir la descarga de
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 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:
Es el modo principal, y con el que arranca de manera predeterminada. Es el modo donde se ejecutan las órdenes de Julia. En el terminal se muestra al inicio de cada línea:
julia>
Se accede a este modo pulsando ]
(cerrar corchete, en el teclado estándar español AltGr + +
). El terminal cambiará de mostrar julia>
a mostrar:
(@v1.6) pkg>
Al principio se puede ver la versión de julia que se está usando, en este caso la versión 1.6. Esto indica que los paquetes instalados desde este terminal, servirán para todas las versiones de julia con este prefijo, i.e. julia 1.6.*
.
Este modo sirve para instalar paquetes que aportarán nuevas funcionalidades, actualizar los paquetes ya instalados, o eliminar paquetes que ya no sean útiles, entre otras opciones. Para ver todos los posibles comandos dentro de este modo, escribir help
, y pulsar la tecla enter.
Para salir del modo de gestión de paquetes, pulsar la tecla retroceso.
Se accede pulsando ?
(en el teclado estándar español Shift + '
) y el terminal pasará a:
help?>
En este modo, el terminal ofrece una pequeña descripción de cualquier elemento de la gramática de Julia. Basta con escribir la palabra clave, y se mostrará su descripción, y un pequeño ejemplo si se trata de una función. Por ejemplo:
help?> abs
search: abs abs2 abspath AbstractSet abstract type AbstractChar AbstractDict
abs(x)
The absolute value of x.
When abs is applied to signed integers, overflow may occur, resulting in the
return of a negative value. This overflow occurs only when abs is applied to the
minimum representable value of a signed integer. That is, when x ==
typemin(typeof(x)), abs(x) == x < 0, not -x as might be expected.
Examples
≡≡≡≡≡≡≡≡≡≡
julia> abs(-3)
3
julia> abs(1 + im)
1.4142135623730951
julia> abs(typemin(Int64))
-9223372036854775808
Una vez escrita la descripción, el terminal vuelve por defecto al modo Programación. También se puede salir sin realizar ninguna búsqueda pulsando la tecla retroceso.
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>
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
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