Manual Julia
Manual Julia
2024-01-03
Tabla de contenidos
Prefacio 7
Licencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1 Introducción 8
1.1 ¿Por qué Julia? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2 ¿Qué pretende ser Julia? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3 ¿Qué es Julia? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.3.1 Comparativa de rapidez de Julia con otros lenguajes . . . . . . . . . . 9
1.4 Algunas razones más para pensárselo . . . . . . . . . . . . . . . . . . . . . . . 9
1.5 Instalación de Julia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.6 El REPL de Julia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.7 El gestor de paquetes de Julia . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.8 Entornos de desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.9 IDEs para Julia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.9.1 Visual studio code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.9.2 Jupyter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.9.3 Pluto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2
2.13.6 Raíces, exponenciales y logaritmos . . . . . . . . . . . . . . . . . . . . 23
2.13.7 Ejemplo de raíces, exponenciales y logaritmos . . . . . . . . . . . . . . 24
2.13.8 Funciones trigonométricas . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.13.9 Ejemplo de funciones trigonométricas . . . . . . . . . . . . . . . . . . 25
2.13.10 Funciones trigonométricas inversas . . . . . . . . . . . . . . . . . . . . 25
2.13.11 Ejemplo de funciones trigonométricas inversas . . . . . . . . . . . . . . 26
2.14 Precedencia de operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.15 Operaciones con cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.15.1 Acceso a caracteres Unicode . . . . . . . . . . . . . . . . . . . . . . . . 27
2.15.2 Ejemplo de acceso a caracteres Unicode . . . . . . . . . . . . . . . . . 27
2.15.3 Acceso a índices en cadenas . . . . . . . . . . . . . . . . . . . . . . . . 28
2.15.4 Ejemplo de acceso a índices en cadenas . . . . . . . . . . . . . . . . . 28
2.15.5 Subcadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.16 Concatenación de cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.16.1 Interpolación de cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.16.2 Otras operaciones comunes con cadenas . . . . . . . . . . . . . . . . . 30
2.16.3 Otras operaciones comunes con cadenas . . . . . . . . . . . . . . . . . 30
2.16.4 Ejemplo de otras operaciones con cadenas . . . . . . . . . . . . . . . . 30
2.17 Entrada y salida por terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.17.1 Conversión de cadenas en números . . . . . . . . . . . . . . . . . . . . 32
3 Estructuras de control 33
3.1 Condicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.1.1 Ejemplo de condicional . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.1.2 Operador condicional . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.2 Bucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.3 Bucles iterativos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.3.1 Bucles iterativos con rangos . . . . . . . . . . . . . . . . . . . . . . . . 34
3.3.2 Ejemplo de bucles iterativos con rangos . . . . . . . . . . . . . . . . . 35
3.3.3 Bucles iterativos anidados . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.4 Bucles condicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.4.1 Interrupción de bucles . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.4.2 Salto de bucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3
4.4.2 Ejemplo de acceso a los elementos de un vector . . . . . . . . . . . . . 43
4.4.3 Acceso a múltiples elementos de un vector . . . . . . . . . . . . . . . . 43
4.4.4 Modificación de los elementos de un vector . . . . . . . . . . . . . . . 44
4.4.5 Añadir elementos a un vector . . . . . . . . . . . . . . . . . . . . . . . 44
4.4.6 Recorrer un vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.4.7 Operaciones con vectores numéricos . . . . . . . . . . . . . . . . . . . 45
4.4.8 Ordenación de vectores . . . . . . . . . . . . . . . . . . . . . . . . . . 46
4.4.9 Ejemplo de ordenación de vectores . . . . . . . . . . . . . . . . . . . . 46
4.4.10 Extensión de funciones a vectores . . . . . . . . . . . . . . . . . . . . . 47
4.4.11 Ejemplo de extensión de funciones a vectores . . . . . . . . . . . . . . 48
4.4.12 Filtrado de vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.4.13 Ejemplo de filtrado de vectores . . . . . . . . . . . . . . . . . . . . . . 48
4.4.14 Álgebra lineal con vectores . . . . . . . . . . . . . . . . . . . . . . . . 49
4.4.15 Ejemplo de álgebra lineal con vectores . . . . . . . . . . . . . . . . . . 49
4.5 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4.5.1 Acceso a los elementos de una matriz . . . . . . . . . . . . . . . . . . . 50
4.5.2 Ejemplo de acceso a los elementos de una matriz . . . . . . . . . . . . 51
4.5.3 Acceso a múltiples elementos de una matriz . . . . . . . . . . . . . . . 51
4.5.4 Ejemplo de acceso a múltiples elementos de una matriz . . . . . . . . 51
4.5.5 Modificación de los elementos de una matriz . . . . . . . . . . . . . . . 52
4.5.6 Concatenación de matrices . . . . . . . . . . . . . . . . . . . . . . . . 52
4.5.7 Ejemplo de concatenación de matrices . . . . . . . . . . . . . . . . . . 53
4.5.8 Concatenación de vectores . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.5.9 Ejemplo de concatenación de vectores . . . . . . . . . . . . . . . . . . 54
4.5.10 Recorrido de matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.5.11 Operaciones con matrices numéricas . . . . . . . . . . . . . . . . . . . 55
4.5.12 Extensión de funciones a matrices . . . . . . . . . . . . . . . . . . . . 55
4.5.13 Ejemplo de extensión de funciones a matrices . . . . . . . . . . . . . . 56
4.5.14 Álgebra lineal con matrices . . . . . . . . . . . . . . . . . . . . . . . . 56
4.5.15 Ejemplo de álgebra lineal con matrices . . . . . . . . . . . . . . . . . . 57
4.5.16 Álgebra lineal con matrices . . . . . . . . . . . . . . . . . . . . . . . . 57
4.5.17 Ejemplo de álgebra lineal con matrices . . . . . . . . . . . . . . . . . . 58
4.5.18 Álgebra lineal con matrices . . . . . . . . . . . . . . . . . . . . . . . . 59
4.5.19 Ejemplos de Álgebra lineal con matrices . . . . . . . . . . . . . . . . . 59
4.5.20 Copia de tipos de datos compuestas . . . . . . . . . . . . . . . . . . . 60
4.5.21 Ejemplo de copia de tipos de datos compuestos . . . . . . . . . . . . . 60
4.6 Tuplas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.6.1 Tuplas con nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.6.2 Acceso a los elementos de una tupla . . . . . . . . . . . . . . . . . . . 62
4.6.3 Asignación múltiple de tuplas . . . . . . . . . . . . . . . . . . . . . . . 62
4.6.4 Ejemplo de asignación múltipe de tuplas . . . . . . . . . . . . . . . . . 63
4.7 Diccionarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.7.1 Ejemplo de diccionarios . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.7.2 Comprensión de diccionarios . . . . . . . . . . . . . . . . . . . . . . . 64
4.7.3 Ejemplo de comprensión de diccionarios . . . . . . . . . . . . . . . . . 64
4.7.4 Acceso a los elementos de un diccionario . . . . . . . . . . . . . . . . . 65
4
4.7.5 Ejemplo de acceso a los elementos de un diccionario . . . . . . . . . . 65
4.7.6 Recorrido de las claves y valores de un diccionario . . . . . . . . . . . 66
4.7.7 Ejemplo de recorrido de las claves y valores de un diccionario . . . . . 66
4.7.8 Añadir elementos a un diccionario . . . . . . . . . . . . . . . . . . . . 67
4.7.9 Eliminar elementos de un diccionario . . . . . . . . . . . . . . . . . . . 67
4.8 Conjuntos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.8.1 Ejemplo de construcción de conjuntos . . . . . . . . . . . . . . . . . . 68
4.8.2 Añadir elementos a un conjunto . . . . . . . . . . . . . . . . . . . . . 69
4.8.3 Ejemplo de añadir elementos a un conjunto . . . . . . . . . . . . . . . 69
4.8.4 Eliminar elementos de un conjunto . . . . . . . . . . . . . . . . . . . . 69
4.8.5 Recorrido de los elementos de un conjunto . . . . . . . . . . . . . . . . 70
4.8.6 Pertenencia e inclusión de conjuntos . . . . . . . . . . . . . . . . . . . 70
4.8.7 Ejemplos de pertenencia e inclusión de conjuntos . . . . . . . . . . . . 71
4.8.8 Álgebra de conjuntos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.8.9 Ejemplo de álgebra de conjuntos . . . . . . . . . . . . . . . . . . . . . 71
5 Funciones 73
5.1 Creación de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
5.1.1 Ejemplo de creación de funciones . . . . . . . . . . . . . . . . . . . . . 73
5.2 Parámetros y argumentos de una función . . . . . . . . . . . . . . . . . . . . 73
5.2.1 Paso de argumentos a una función . . . . . . . . . . . . . . . . . . . . 74
5.2.2 Ejemplo de paso de argumentos a una función . . . . . . . . . . . . . . 74
5.2.3 Argumentos por defecto . . . . . . . . . . . . . . . . . . . . . . . . . . 75
5.2.4 Funciones con un número variable de argumentos . . . . . . . . . . . . 75
5.2.5 Parámetros con tipo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
5.2.6 Ejemplo de parámetros con tipo . . . . . . . . . . . . . . . . . . . . . 76
5.2.7 Paso de argumentos por asignación . . . . . . . . . . . . . . . . . . . . 76
5.2.8 Ámbito de los parámetros de una función . . . . . . . . . . . . . . . . 77
5.2.9 Ejemplo del ámbito de los parámetros de una función . . . . . . . . . 77
5.3 Retorno de una función . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
5.3.1 Ejemplo de retorno de una función . . . . . . . . . . . . . . . . . . . . 78
5.4 Funciones compactas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
5.5 Funciones como objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
5.6 Funciones anónimas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
5.7 Funciones asociadas a operadores . . . . . . . . . . . . . . . . . . . . . . . . . 80
5.8 Funciones recursivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
5.8.1 Ejemplo de funciones recursivas . . . . . . . . . . . . . . . . . . . . . . 81
6 Gráficos 82
6.1 Paquetes gráficos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.2 Gráficos con el paquete Plots.jl . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.2.1 Backends de Plot.jl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
6.2.2 Gráfica de una función de una variable . . . . . . . . . . . . . . . . . . 84
6.2.3 Gráficas de varias funciones . . . . . . . . . . . . . . . . . . . . . . . . 84
6.2.4 Añadir puntos a una gráfica . . . . . . . . . . . . . . . . . . . . . . . . 85
6.2.5 Ventana de graficación . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
5
6.2.6 Restringir la gráfica al dominio . . . . . . . . . . . . . . . . . . . . . . 87
6.2.7 Ejemplo de restringir la gráfica al dominio . . . . . . . . . . . . . . . . 87
6.2.8 Gráficas paramétricas . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
6.2.9 Personalización de gráficos . . . . . . . . . . . . . . . . . . . . . . . . . 89
6.2.10 Ejemplo de personalización de gráficos . . . . . . . . . . . . . . . . . . 89
6.2.11 Gráficos en el espacio real . . . . . . . . . . . . . . . . . . . . . . . . . 90
6.3 Gráficos con Makie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6.3.1 Backends de Makie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6.3.2 Figuras, ejes y objetos gráficos . . . . . . . . . . . . . . . . . . . . . . 92
6.3.3 Diagrama de puntos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
6.3.4 Diagrama de líneas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
6.3.5 Superficies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.3.6 Leyenda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.4 Gráficos con GadFly.jl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
6.5 Gráficos con VegaLite.jl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
6
Prefacio
Licencia
Esta obra está bajo una licencia Reconocimiento – No comercial – Compartir bajo la misma
licencia 3.0 España de Creative Commons. Para ver una copia de esta licencia, visite https:
//creativecommons.org/licenses/by-nc-sa/3.0/es/.
Con esta licencia eres libre de:
Al reutilizar o distribuir la obra, tiene que dejar bien claro los términos de la licencia de
esta obra.
Estas condiciones pueden no aplicarse si se obtiene el permiso del titular de los derechos de
autor.
Nada en esta licencia menoscaba o restringe los derechos morales del autor.
7
1 Introducción
Julia es otro lenguaje de programación más, orientado a cálculo científico el análisis de datos
similar a Python, R o Matlab.
¿De veras necesitamos aprender otro lenguaje más?
• Open source.
• With the speed of C.
• Obvious, familiar mathematical notation like Matlab.
• As usable for general programming as Python.
• As easy for statistics as R.
• As natural for string processing as Perl.
• As powerful for linear algebra as Matlab.
• As good at gluing programs together as the shell.
• Dirt simple to learn, yet keeps the most serious hackers happy.
• Julia es un lenguaje de alto nivel con una sintaxis fácil de aprender (similar a Python,
R o Matlab) que permite escribir símbolos matemáticos en las expresiones (UTF-8).
• Julia es un lenguaje muy veloz (equiparable a C en muchas tareas.)
• Lenguaje dinámico (tipado dinámico y despacho múltiple).
• De propósito general, pero orientado a la computación científica y el análisis de grandes
volúmenes de datos.
• Creado en 2019 en el MIT por el equipo del profesor Edelman.
• Última versión: 1.7 (bastante maduro).
• Desarrollado por una gran comunidad científica.
• Repositorio de paquetes de código abierto con más de 3000 paquetes en dominios muy
diversos.
8
1.3.1 Comparativa de rapidez de Julia con otros lenguajes
La mejor manera de instalar Julia es mediante la aplicación juliaup que permite instalar
diferentes versiones de Julia en diferentes sistemas operativos. En la propia página web de
Julia se ofrecen instrucciones detalladas para instalarla en cada sistema operativo.
La aplicación juliaup además de instalar Julia y añadir el ejecutable al PATH del sistema,
permite otras operaciones como:
• julia status: Muestra todas las versiones de Julia instaladas en el sistema y cuál es
la activa por defecto, así como y el canal activo.
9
• julia list: Da una lista de los canales (repositorios) disponibles para descargar Julia.
Para instalar Julia hay que añadir al menos un canal por lo que si no aparece ninguno
previamente abrá que añadirlo mediante el siguiente comando. El canal con la última
versión estable de Julia es release.
• julia add version|canal: Añade el canal canal a la lista de canales disponibles o
instala una versión específica de Julia en el sistema. Si no se especifica la versión, se
instalará la última versión estable.
• julia update: Actualiza la versión de Julia activa a la última versión estable en todos
los canales configurados.
• julia remove version: Elimina la versión version de Julia del sistema.
Una vez instalado julia, se puede comprobar que la instalación ha sido correcta abriendo u
```bash
prompt> julia
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.10.2 (2024-03-01)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia>
julia> 2 + 3
5
1
REPL es el acrónimo de Read, Evaluate, Print and Loop.
10
1.7 El gestor de paquetes de Julia
Como en otros lenguajes, es posible crear módulos o paquetes con código que puede ser
reutilizado. Julia tiene un potente gestor de paquetes que facilita la búsqueda, instalación,
actualización y eliminación de paquetes.
Por defecto el gestor de paquetes utiliza el repositorio de paquetes oficial pero se pueden
instalar paquetes de otros repositorios.
Para entrar en el modo de gestión de paquetes hay que teclear ]. Esto produce un cambio
en el prompt del REPL de Julia.
Los comandos más habituales son:
Ejemplo
11
con los de otras aplicaciones.
Básicamente, un entorno de desarrollo es un directorio con código de Julia que contiene
dos ficheros Project.toml y Manifest.toml que contienen los paquetes instalados en el
entorno y sus dependencias.
Para crear y activar un entorno de desarrollo se utilizan los siguiente comandos en el modo
de gestión de paquetes:
Ejemplo
(app) pkg> add CSV # Instalar última versión del paquete CSV
...
(app) pkg> add [email protected]; # Instalar la versión 1.3.0 del paquete DataFrames
...
(app) pkg> status
Project app v0.1.0
Status `~/app/Project.toml`
[336ed68f] CSV v0.10.4
[a93c6f00] DataFrames v1.3.0
12
1.9 IDEs para Julia
13
1.9.2 Jupyter
1.9.3 Pluto
Pluto es entorno de desarrollo propio de Julia similar a Jupyter. Pluto permite crear note-
books reactivos cuyas celdas se actualizan cada vez que se produce un cambio en el estado
del programa.
Para usarlo basta instalar el paquete Pluto.jl.
julia> Pkg.add("Pluto");
14
julia> using Pluto
julia> Pluto.run()
[ Info: Loading...
� Info:
� Opening http://localhost:1234/?secret=a63iBsIL in your default browser... ~ have fun!
� Info:
� Press Ctrl+C in this terminal to stop Pluto
�
Opening in existing browser session.
15
2 Tipos de datos y variables
julia> typeof(3)
Int64
julia> typeof(3/2)
Float64
julia> typeof(3//2)
Rational{Int64}
julia> typeof(�)
Irrational{:�}
julia> typeof(3+2im)
Complex{Int64}
16
2.3 Jerarquía de tipos de datos numéricos
Símbolo Descripción
pi o � Número irracional 𝜋
� (\euler + TAB) Número irracional 𝑒
Inf Infinito
NaN Valor no numérico
Missing Valor desconocido
julia> �
� = 3.1415926535897...
julia> 1 / 0
Inf
julia> 0 / 0
17
NaN
julia> 0 * Inf
NaN
julia> typeof('a')
Char
julia> typeof("julia")
String
julia> typeof("a")
String
julia> typeof(true)
Bool
julia> typeof(false)
Bool
18
2.8 Variables
Como lenguaje de tipado dinámico, no es necesario declarar una variable antes de usarla.
Su tipo se infiere directamente del valor asociado.
julia> x = 1
1
julia> typeof(x)
Int64
julia> x = "julia"
"julia"
julia> typeof(x)
String
No obstante, para variables de ámbito local, por ejemplo en funciones, es posible fijar el
tipo de una variable indicándolo detrás de su nombre con el operador ::.
x::Int64
Julia reconoce la codificación Unicode (UTF-8), lo que permite utilizar caracteres con tildes,
letras griegas, símbolos matemáticos y hasta emoticonos en los nombres de variables o
funciones. Para ello se utilizan códigos especiales (en muchos casos son los mismos que en
LaTeX), pulsando después la tecla de tabulación.
julia> � = 1
1
julia> � = 2
2
julia> � + �
3
julia> � = "julia"
"julia"
19
2.9.1 Caracteres Unicode
Los operadores pueden necesitar paréntesis, como por ejemplo (f � g)(x) para la compo-
sición de g con f.
Operador Descripción
x + y Suma
x - y Resta
x * y Producto
x / y División
x ÷ y Cociente división entera
x % y Resto división entera
x ^ y Potencia
20
Operador Descripción
== Igualdad
!=, � Desigualdad
< Menor que
<=, � Menor o igual que
> Mayor que
>=, � Mayor o igual que
Operador Descripción
!x Negación
x && y Conjunción (y)
x || y Disyunción (o)
Función Descripción
round(x) Devuelve el entero más próximo a x
round(x, digits = n) Devuelve al valor más próximo a x con n decimales
floor(x) Redondea x al próximo entero menor
ceil(x) Redondea x al próximo entero mayor
trunc(x) Devuelve la parte entera de x
julia> round(2.7)
3.0
julia> floor(2.7)
2.0
julia> floor(-2.7)
-3.0
julia> ceil(2.7)
21
3.0
julia> ceil(-2.7)
-2.0
julia> trunc(2.7)
2.0
julia> trunc(-2.7)
-2.0
julia> round(2.5)
2.0
Función Descripción
div(x,y), x÷y Cociente de la división entera
fld(x,y) Cociente de la división entera redondeado hacia abajo
cld(x,y) Cociente de la división entera redondeado hacia arriba
rem(x,y), x%y Resto de la división entera. Se cumple x == div(x,y)*y + rem(x,y)
mod(x,y) Módulo con respecto a y. Se cumple x == fld(x,y)*y + mod(x,y)
gcd(x,y...) Máximo común divisor positivo de x, y,…
lcm(x,y...) Mínimo común múltiplo positivo de x, y,…
julia> div(5,3)
1
julia> cld(5,3)
2
julia> 5%3
2
julia> -5%3
-2
22
julia> mod(5,3)
2
julia> mod(-5,3)
1
julia> gcd(12,18)
6
julia> lcm(12,18)
36
Función Descripción
abs(x) Valor absoluto de x
sign(x) Devuelve 1 si x es positivo, -1 si es negativo y 0 si es 0.
julia> abs(2.5)
2.5
julia> abs(-2.5)
2.5
julia> sign(-2.5)
-1.0
julia> sign(0)
0
julia> sign(2.5)
1.0
Función Descripción
sqrt(x), √x Raíz cuadrada de x
cbrt(x), �x Raíz cúbica de x
exp(x) Exponencial de x
log(x) Logaritmo neperiano de x
23
Función Descripción
log(b,x) Logaritmo en base b de x
log2(x) Logaritmo en base 2 de x
log10(x) Logaritmo en base 10 de x
julia> sqrt(4)
2.0
julia> cbrt(27)
3.0
julia> exp(1)
2.718281828459045
julia> exp(-Inf)
0.0
julia> log(1)
0.0
julia> log(0)
-Inf
julia> log(-1)
ERROR: DomainError with -1.0:
log will only return a complex result if called with a complex argument.
...
julia> log(-1+0im)
0.0 + 3.141592653589793im
julia> log2(2^3)
3.0
Función Descripción
hypot(x,y) Hipotenusa del triángulo rectángulo con catetos x e y
sin(x) Seno del ángulo x en radianes
24
Función Descripción
sind(x) Seno del ángulo x en grados
cos(x) Coseno del ángulo x en radianes
cosd(x) Coseno del ángulo x en grados
tan(x) Tangente del ángulo x en radianes
tand(x) Tangente del ángulo x en grados
sec(x) Secante del ángulo x en radianes
csc(x) Cosecante del ángulo x en radianes
cot(x) Cotangente del ángulo x en radianes
julia> sin(�/2)
1.0
julia> cos(�/2)
6.123233995736766e-17
julia> cosd(90)
0.0
julia> tan(�/4)
0.9999999999999999
julia> tand(45)
1.0
julia> tan(�/2)
1.633123935319537e16
julia> tand(90)
Inf
Función Descripción
asin(x) Arcoseno (inversa del seno) de x en radianes
asind(x) Arcoseno (inversa del seno) de x en grados
25
Función Descripción
acos(x) Arcocoseno (inversa del coseno) de x en radianes
acosd(x) Arcocoseno (inversa del coseno) de x en grados
atan(x) Arcotangente (inversa de la tangente) de x en radianes
atand(x) Arcotangente (inversa de la tangente) de x en grados
asec(x) Arcosecante (inversa de la secante) de x en radianes
acsc(x) Arcocosecante (inversa de la cosecante) de x en radianes
acot(x) Arcocotangente (inversa de la cotangente) de x en radianes
julia> asin(1)
1.5707963267948966
julia> asind(1)
90.0
julia> acos(-1)
3.141592653589793
julia> atan(1)
0.7853981633974483
julia> atand(tan(�/4))
45.0
26
2.15 Operaciones con cadenas
Las cadenas son secuencias de caracteres alfanuméricos del tipo char entre dobles comillas.
Cada carácter tiene asociado un índice entero. El primer carácter de la cadena tiene índice
1.
Índice 1 2 3 4 5
Cadena j u l i a
julia> c = "julia"
"julia"
julia> c[2]
'u': ASCII/Unicode U+0075 (category Ll: Letter, lowercase)
Sin embargo, como Julia permite caracteres Unicode, el índice de un carácter en una cadena,
no siempre se corresponde con su posición en la cadena. Ello es debido a que la codificación
UTF-8 no utiliza el mismo número de bytes para representar los caracteres Unicode. Mien-
tras que los caracteres habituales del código ASCII (letras romanas y números árabes) solo
necesitan un byte, otros caracteres como los símbolos matemáticos requieren más.
Índice 1 4 5 6 9
Cadena � x � y
julia> c[1]
'�': Unicode U+2200 (category Sm: Symbol, math)
julia> c[2]
ERROR: StringIndexError: invalid index [2],
valid nearby indices [1]=>'�', [4]=>'x'
27
Stacktrace:
[1] string_index_err(s::String, i::Int64)
@ Base ./strings/string.jl:12
[2] getindex_continued(s::String, i::Int64, u::UInt32)
@ Base ./strings/string.jl:233
[3] getindex(s::String, i::Int64)
@ Base ./strings/string.jl:226
[4] top-level scope
@ REPL[128]:1
julia> firstindex(c)
1
julia> lastindex(c)
9
julia> c[9]
'y': ASCII/Unicode U+0079 (category Ll: Letter, lowercase)
julia> nextind(c,1)
4
2.15.5 Subcadenas
Para obtener subcadenas se usan también los corchetes indicando los índices de inicio y fin
separados por :.
28
• s[i:j]: Devuelve la subcadena que va desde el índice i al índice j, ambos incluidos.
julia> c = "julia"
"julia"
julia> c[2:4]
"uli"
julia> SubString(c, 2, 4)
"uli"
julia> a = "Hola"
"Hola"
julia> b = "Julia"
"Julia"
julia> a * b
"HolaJulia"
julia> b ^ 3
"JuliaJuliaJulia"
29
julia> s = "Julia"
"Julia"
julia> length(c)
10
30
julia> findfirst("a", c)
4:4
julia> findlast("Ju", c)
6:7
julia> findlast("x", c)
julia> occursin("Julia", c)
true
julia> occursin("julia", c)
false
julia> uppercase(c)
"HOLA JULIA"
• readline(): Devuelve en una cadena una línea de texto introducida por el usuario en
la terminal (hasta el carácter de cambio de línea \n)
31
Hola Alf
La función readline() siempre devuelve una cadena aún cuando se pregunte al usuario por
un valor numérico. Para convertir una cadena en un dato numérico se utiliza la siguiente
función:
• parse(tipo, c): Covierte la cadena c a un número del tipo numérico tipo, siempre
que puedad realizarse la conversión.
julia> typeof(edad)
Int64
32
3 Estructuras de control
3.1 Condicionales
if condición 1
bloque código 1
elseif condición 2
bloque código 2
…
else
bloque código n
end
julia> x = -1
-1
julia> if x > 0
signo = "positivo"
elseif x < 0
signo = "negativo"
else
signo = "nulo"
end
"negativo"
33
julia> x > 0 ? signo = "positivo" : signo = "negativo"
"negativo"
3.2 Bucles
Ejecuta el bloque de código tantas veces como elementos tenga la secuencia. En cada itera-
ción el iterador toma como valor el siguiente elemento de la secuencia.
julia> c = "Julia"
"Julia"
julia> for i in c
println(i)
end
J
u
l
i
a
34
3.3.2 Ejemplo de bucles iterativos con rangos
while condición
bloque código
end
35
Repite la ejecución del bloque de código mientras que la condición sea cierta.
julia> x = 3
3
julia> x=3
3
36
println(i)
end
1
3
5
7
9
37
4 Tipos de datos compuestos
• Arrays
– Vectores
– Matrices
• Tuplas
• Diccionarios
• Conjuntos
4.2 Arrays
julia> [1, 2, 3]
3-element Vector{Int64}:
1
2
3
38
4.3 Arrays multidimensionales
Los arrays pueden estructurar sus elementos en múltiples dimensiones. Dependiendo el nú-
mero de dimensiones tenemos distintos tipos de arrays:
• zeros(dim): Devuelve un array de la dimensiones indicadas por la tupla dim con todos
sus elementos ceros.
• ones(dim): Devuelve un array de la dimensiones indicadas por la tupla dim con todos
sus elementos unos.
• fill(a, dim): Devuelve un array de la dimensiones indicadas por la tupla dim con
todos sus elementos iguales a.
39
• rand(dim): Devuelve un array de la dimensiones indicadas por la tupla dim con todos
sus elementos números aleatorios entre 0 y 1.
• trues(dim): Devuelve un array de la dimensiones indicadas por la tupla dim con todos
sus elementos true.
• falses(dim): Devuelve un array de la dimensiones indicadas por la tupla dim con
todos sus elementos false.
julia> fill(�, 2, 2)
2×2 Matrix{Irrational{:�}}:
� �
� �
• reshape(A, dim): Devuelve el array que resulta de redimiensionar el array A con las
dimensiones indicadas por la tupla dim.
• permutedims(A): Devuelve el array de resulta de trasponer el array A.
Á Advertencia
El array resultante debe tener los mismos elementos que el array original, por lo que
si las dimensiones no son compatibles se produce un error.
40
4.3.5 Ejemplo de redimensionamiento de arrays
julia> v = [1, 2, 3, 4, 5, 6]
6-element Vector{Int64}:
1
2
3
4
5
6
julia> reshape(v, 2, 3)
2×3 Matrix{Int64}:
1 3 5
2 4 6
julia> reshape(v, 3, 2)
3×2 Matrix{Int64}:
1 4
2 5
3 6
• [exp for i = ite]: Devuelve el vector cuyos elementos resultan de evaluar a expre-
sión exp para cada valor i del iterador ite.
• [exp for i = ite if cond]: Devuelve el vector cuyos elementos resultan de evaluar
a expresión exp para cada valor i del iterador ite que cumpla la condición cond.
41
16
4.4 Vectores
julia> v = [1, 2, 3]
3-element Vector{Int64}:
1
2
3
julia> length(v)
3
julia> eltype(v)
Int64
julia> ndims(v)
1
julia> size(v)
(3,)
julia> eachindex(v)
Base.OneTo(3)
42
4.4.1 Acceso a los elementos de un vector
El acceso a los elementos de un vector es mediante índices. Cada elemento del vector tiene
asociado un índice entero que se corresponde con su posición desde 1 hasta el número de
elementos.
Á Advertencia
Las palabras reservadas begin y end se utilizan para referirse al primer y último índice de
un vector.
julia> v = [2, 4, 6]
3-element Vector{Int64}:
2
4
6
julia> v[2]
4
julia> v[end]
6
julia> v[4]
ERROR: BoundsError: attempt to access 3-element Vector{Int64} at index [4]
Stacktrace:
[1] getindex(A::Vector{Int64}, i1::Int64)
@ Base ./array.jl:861
[2] top-level scope
@ REPL[4]:1
Es posible extraer varios elementos de un vector a la vez indicando los índices mediante un
rango o un vector de enteros.
• v[i:j]: Devuelve un vector con los elementos del vector v desde el índice i al j.
43
• v[u]: Devuelve un vector con los elementos del vector v correspondientes a los índices
del vector u.
julia> v[2:3]
2-element Vector{Int64}:
4
6
julia> v[[2,4,3]]
3-element Vector{Int64}:
4
8
6
También es posible modificar un vector asignando nuevos elementos mediante los índices.
julia> v = [2, 4, 6]
3-element Vector{Int64}:
2
4
6
julia> v[2] = 0
0
julia> v
3-element Vector{Int64}:
2
0
6
44
julia> v = [];
julia> push!(v, 1)
1-element Vector{Any}:
1
julia> v
3-element Vector{Any}:
1
2
3
Una operación habitual es recorrer los elementos de un vector para hacer cualquier operación
con ellos. Existen dos posibilidades: recorrer el vector por índice o por valor.
45
• argmin(v): Devuelve el índice del menor elemento del vector v.
• argmax(v): Devuelve el índice del mayor elemento del vector v.
• sum(v): Devuelve la suma de los elementos del vector v.
• prod(v): Devuelve el producto de los elementos del vector v.
• unique(v): Devuelve un vector con los elementos de v sin repetir.
julia> maximum(v)
4
julia> argmax(v)
1
julia> sum(v)
9
julia> prod(v)
24
julia> sort(v)
3-element Vector{Int64}:
2
3
4
julia> reverse(v)
3-element Vector{Int64}:
3
2
46
4
julia> v
3-element Vector{Int64}:
4
2
3
julia> reverse!(v)
3-element Vector{Int64}:
3
2
4
julia> v
3-element Vector{Int64}:
3
2
4
Si una función recibe un parámetro del tipo de los elementos de un vector, se puede aplicar
la función a cada uno de los elementos del vector, extendiendo la llamada de la función
sobre los elementos del vector. Para ello basta con añadir un punto entre el nombre de la
función y el paréntesis de los argumentos.
• f.(v): Devuelve el vector que resulta de aplicar la función f a cada uno de los ele-
mentos del vector v.
Á Advertencia
En la llamada a la función hay que pasarle com argumentos tantos vectores como
parámetros tenga la función. Si los vectores son de distinto tamaño, se reciclan los de
menor tamaño.
Á Advertencia
La extensión de funciones también funciona con operadores, poniendo el punto delante del
operador.
47
4.4.11 Ejemplo de extensión de funciones a vectores
julia> sqrt.(v)
3-element Vector{Float64}:
1.0
2.0
3.0
julia> v .^ 2
3-element Vector{Int64}:
1
16
81
julia> log.(base, v)
3-element Vector{Float64}:
0.0
1.3862943611198906
0.9542425094393249
Otra operación bastante común son los filtros de vectores. Se puede filtrar un vector a partir
de un vector de booleanos del mismo tamaño.
• v[u]: Devuelve el vector con los elementos que tienen el mismo índice que los valores
true del vector booleano u.
Esto permite aplicar filtros a partir de condiciones que devuelvan un vector de booleanos.
48
julia> v .% 2 .== 0 # Condición
4-element BitVector:
0
1
0
1
using LinearAlgebra
julia> u + v
3-element Vector{Int64}:
2
2
5
julia> 2u
3-element Vector{Int64}:
2
4
6
49
julia> dot(u, v) # Producto escalar
7
4.5 Matrices
julia> A = [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> length(A)
6
julia> eltype(A)
Int64
julia> ndims(A)
2
julia> size(A)
(2, 3)
El acceso a los elementos de una matriz es mediante índices. Cada elemento de la matriz
tiene asociado un par de índices enteros que se corresponde la fila y la columna que ocupa.
50
• A[i, j]: Devuelve el elemento de la matriz A con índice de fila i e índice de columna
j.
Á Advertencia
También se puede acceder a los elementos de una matriz mediante un único índice. En ese
caso se obtiene el elemento con ese índice en el vector que resulta de concatenar los elementos
de la matriz por columnas.
julia> A = reshape(1:6, 2, 3)
2×3 reshape(::UnitRange{Int64}, 2, 3) with eltype Int64:
1 3 5
2 4 6
julia> A[2, 1]
2
julia> A[4]
4
Es posible extraer varios elementos de una matriz a la vez indicando los índices de las filas
y las columnas mediante un rango o un vector de enteros.
• A[i:j, k:l]: Devuelve una matriz con los elementos desde el índice de fila i al j y
el índice de columna k al l de la matriz A.
• A[u, w]: Devuelve una matriz con los elementos correspondientes a los índices de fila
del vector u y los índices de columna del vector w de la matriz A.
julia> A = reshape(1:9, 3, :)
3×3 reshape(::UnitRange{Int64}, 3, 3) with eltype Int64:
1 4 7
2 5 8
3 6 9
51
julia> A[1:2, 2:3]
2×2 Matrix{Int64}:
4 7
5 8
También es posible modificar una matriz asignando nuevos elementos mediante los índices
de fila y columna.
julia> A = zeros(2, 3)
2×3 Matrix{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0
julia> A[2,3] = 1
1
julia> A
2×3 Matrix{Float64}:
0.0 0.0 0.0
0.0 0.0 1.0
Dos o más matrices pueden concatenarse horizontal o verticalmente siempre que sus dimen-
siones sean compatibles.
52
• [A; B]: Devuelve la matriz que resulta de concatenar verticalmente las matrices A y
B. Ambas matrices deben tener el mismo número de columnas.
julia> A = zeros(2, 2)
2×2 Matrix{Float64}:
0.0 0.0
0.0 0.0
julia> B = ones(2, 1)
2×1 Matrix{Float64}:
1.0
1.0
julia> C = ones(1, 3)
1×3 Matrix{Float64}:
1.0 1.0 1.0
julia> D = [A B]
2×3 Matrix{Float64}:
0.0 0.0 1.0
0.0 0.0 1.0
julia> [D ; C]
3×3 Matrix{Float64}:
0.0 0.0 1.0
0.0 0.0 1.0
1.0 1.0 1.0
53
4.5.9 Ejemplo de concatenación de vectores
julia> hcat(v...)
3×2 Matrix{Int64}:
1 4
2 5
3 6
julia> vcat(v...)
2×3 Matrix{Int64}:
1 2 3
4 5 6
Una operación habitual es recorrer los elementos de una matriz para hacer una operación
con ellos. El recorrido se suele hacer con dos bucles iterativos anidados.
julia> A = [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
54
julia> for j = 1:size(A, 2), i = 1:size(A, 1) # Recorrido por columnas
println(A[i, j])
end
1
4
2
5
3
6
julia> A = [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> minimum(A)
1
julia> argmax(A)
CartesianIndex(2, 3)
julia> sum(A)
21
julia> prod(A)
720
Al igual que para vectores, se puede aplicar una una función a todos los elementos de una
matriz. Para ello basta con añadir un punto entre el nombre de la función y el paréntesis
de los argumentos.
• f.(A): Devuelve la matriz que resulta de aplicar la función f a cada uno de los
elementos de la matriz A.
55
Á Advertencia
En la llamada a la función hay que pasarle como argumentos tantos vectores como
parámetros tenga la función. Si las matrices son de distinto tamaño, se reciclan las de
menor tamaño.
La extensión de funciones también funciona con operadores, poniendo el punto delante del
operador.
julia> A = [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> sqrt.(A)
2×3 Matrix{Float64}:
1.0 1.41421 1.73205
2.0 2.23607 2.44949
julia> A .+ 1
2×3 Matrix{Int64}:
2 3 4
5 6 7
56
4.5.15 Ejemplo de álgebra lineal con matrices
julia> A = [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> B = [1 1 1; 2 2 2]
2×3 Matrix{Int64}:
1 1 1
2 2 2
julia> A + B
2×3 Matrix{Int64}:
2 3 4
6 7 8
julia> C = A'
3×2 adjoint(::Matrix{Int64}) with eltype Int64:
1 4
2 5
3 6
julia> A * C
2×2 Matrix{Int64}:
14 32
32 77
julia> C * A
3×3 Matrix{Int64}:
17 22 27
22 29 36
27 36 45
57
• inv(A): Devuelve la matriz inversa de la matriz cuadrada A.
• A \ B: Devuelve el vector x solución del sistema de ecuaciones 𝐴𝑥 = 𝐵, donde A es
una matriz cuadrada y B es un vector del mismo tamaño que el número de filas o
columnas de A.
using LinearAlgebra
julia> Matrix(I, 3, 3)
3×3 Matrix{Bool}:
1 0 0
0 1 0
0 0 1
julia> A = [1 2 3; 0 1 0; 1 0 1]
3×3 Matrix{Int64}:
1 2 3
0 1 0
1 0 1
julia> diag(A)
3-element Vector{Int64}:
1
1
1
julia> norm(A)
4.123105625617661
julia> tr(A)
3
julia> det(A)
-2.0
julia> inv(A)
3×3 Matrix{Float64}:
-0.5 1.0 1.5
0.0 1.0 0.0
0.5 -1.0 -0.5
julia> B = [10, 2, 4]
3-element Vector{Int64}:
58
10
2
4
using LinearAlgebra
julia> A = [1 2; 3 1]
2×2 Matrix{Int64}:
1 2
3 1
julia> eigvals(A)
2-element Vector{Float64}:
-1.4494897427831779
3.4494897427831783
julia> eigvecs(A)
2×2 Matrix{Float64}:
-0.632456 0.632456
0.774597 0.774597
julia> B = [1 2; 2 1]
2×2 Matrix{Int64}:
1 2
2 1
59
julia> factorize(B)
LU{Float64, Tridiagonal{Float64, Vector{Float64}}}
L factor:
2×2 Matrix{Float64}:
1.0 0.0
0.5 1.0
U factor:
2×2 Matrix{Float64}:
2.0 1.0
0.0 1.5
En Julia cuando se asigna una variable de un tipo de datos compuesto a otra variable, no
se hace una copia de la estructura de datos referenciada por la primera variable, sino que se
la nueva variable apunta a la misma dirección de memoria de la estructura de datos (copia
por referencia). El resultado son dos variables que apuntan a la misma estructura de datos
y cualquier cambio en una de ellas se verá reflejado en la otra.
Para hacer copias por valor de un tipo de datos compuesto debe usarse explícitamente la
siguiente función:
julia> u[2] = 0;
julia> u
3-element Vector{Int64}:
1
0
3
julia> v
3-element Vector{Int64}:
1
2
60
3
julia> u[2]=0;
julia> v
3-element Vector{Int64}:
1
0
3
4.6 Tuplas
Una tupla es una colección ordenada de tamaño fijo que puede contener elementos de dis-
tintos tipos.
Generalmente se usan para pasar parámetros o devolver valores de funciones.
Se crean escribiendo sus elementos separados por comas entre paréntesis.
Á Advertencia
Las tuplas son inmutables, es decir, una vez creadas no pueden cambiarse sus elemen-
tos.
julia> typeof(t)
Tuple{Int64, String, Int64}
Es posible asignar un nombre a cada uno de los elementos de la tupla. Para ello cada
elemento de la tupla con nombre debe escribirse con la sintaxis nombre = valor.
61
julia> t = (día = 1, mes = "enero", año = 2020)
(día = 1, mes = "enero", año = 2020)
julia> typeof(t)
NamedTuple{(:día, :mes, :año), Tuple{Int64, String, Int64}}
Á Advertencia
La ventaja de usar tuplas con nombres es que podemos acceder a sus elementos por nombre,
además de por índice.
Como las tuplas tienen orden, podemos acceder a sus elementos mediante índices, al igual
que con los arrays de una dimensión.
Si la tupla tiene nombres también es posible acceder a sus elementos mediante los nombres.
julia> t[2]
"enero"
julia> t.año
2020
julia>
Es posible asignar los elementos de una tupla a distintas variables en una sola asignación.
x, y, ... = t: Asigna a las variables x, y, etc los elementos de la tupla t en orden. Si el
número de variables es menor que el tamaño de la tupla, los últimos elementos quedan sin
asignar.
x, y... = t: Asigna el primer elemento de la tupla t a la variable x y la tupla con los
elementos restantes a la variable y.
62
4.6.4 Ejemplo de asignación múltipe de tuplas
julia> d, m, a = t
(1, "enero", 2020)
julia> d
1
julia> m
"enero"
julia> a
2020
julia> d, ma... = t
(1, "enero", 2020)
julia> d
1
julia> ma
("enero", 2020)
4.7 Diccionarios
Un diccionario es una colección asociativa sin orden cuyos elementos son pares formados
por una clave y un valor asociado a la clave.
Se parecen a las tuplas con nombre, pero, a diferencia de estas, son mutables, es decir, su
contenido se puede alterar.
Se construyen con la siguiente constructor:
• Dict(k1 => v1, ...): Crea un diccionario con los pares indicados en formato clave
=> valor.
Á Advertencia
En un diccionario no pueden existir dos pares con la misma clave, de modo que si se
repite una clave se sobrescribe el par anterior.
63
4.7.1 Ejemplo de diccionarios
julia> d = Dict("ES" => "Euro", "US" => "Dollar", "CN" => "Yuan")
Dict{String, String} with 3 entries:
"CN" => "Yuan"
"ES" => "Euro"
"US" => "Dollar"
julia> typeof(d)
Dict{String, String}
Al igual que para arrays se puede usar la técnica de compresión para generar diccionarios a
partir de uno o varios iteradores.
• Dict(kexp => vexp for i = ite): Devuelve el diccionario cuyos pares están forma-
dos por la claves y valores resultan de evaluar las expresiones kexp y vexp respectiva-
mente, para cada valor i del iterador ite.
• Dict(kexp => vexp for i = ite if cond): Devuelve el diccionario cuyos pares es-
tán formados por la claves y valores resultan de evaluar las expresiones kexp y vexp
respectivamente, para cada valor i del iterador ite que cumpla condición cond.
64
julia> Dict((i, j) => i + j for i = 1:2, j = 3:4)
Dict{Tuple{Int64, Int64}, Int64} with 4 entries:
(2, 4) => 6
(1, 3) => 4
(1, 4) => 5
(2, 3) => 5
Para acceder a los valores de un diccionario se utilizan sus claves asociadas entre corchetes.
Á Advertencia
• haskey(d, k): Devuelve true la clave k está en diccionario d y false en caso contra-
rio.
• get(d, k, v): Devuelve el valor asociado a la clave k en el diccionario d o el valor v
si la clave k no existe.
• get!(d, k, v): Devuelve el valor asociado a la clave k en el diccionario d. Si la clave
k no existe en el diccionario d añade el par con la clave k y el valor v y devuelve el
valor v.
julia> d = Dict("ES" => "Euro", "US" => "Dollar", "CN" => "Yuan")
Dict{String, String} with 3 entries:
"CN" => "Yuan"
"ES" => "Euro"
"US" => "Dollar"
julia> d["ES"]
"Euro"
julia> d["JP"]
ERROR: KeyError: key "JP" not found
Stacktrace:
[1] getindex(h::Dict{String, String}, key::String)
@ Base ./dict.jl:481
65
[2] top-level scope
@ REPL[22]:1
julia> d
Dict{String, String} with 4 entries:
"CN" => "Yuan"
"ES" => "Euro"
"JP" => "Yen"
"US" => "Dollar"
Las siguientes funciones permiten obtener todas las claves, valores y pares de un dicciona-
rio.
julia> d = Dict("ES" => "Euro", "US" => "Dollar", "CN" => "Yuan")
Dict{String, String} with 3 entries:
"CN" => "Yuan"
"ES" => "Euro"
"US" => "Dollar"
julia> keys(d)
KeySet for a Dict{String, String} with 3 entries. Keys:
"CN"
"ES"
"US"
julia> values(d)
ValueIterator for a Dict{String, String} with 3 entries. Values:
"Yuan"
66
"Euro"
"Dollar"
67
• delete!(d, k): Elimina el par cuya clave es k del diccionario d.
julia> d = Dict("ES" => "Euro", "US" => "Dollar", "CN" => "Yuan")
Dict{String, String} with 3 entries:
"CN" => "Yuan"
"ES" => "Euro"
"US" => "Dollar"
4.8 Conjuntos
Un conjunto es una colección de elementos del mismo tipo sin orden y sin repeticiones.
Se construyen con la siguiente constructor:
Al igual que para arrays el tipo se infiere automáticamente a partir de los tipos de sus
elementos. Si los elementos son de distintos tipos se convierten al tipo más específico de la
jerarquía de tipos del que los tipos de los elementos son subtipos.
Á Advertencia
Un conjunto no puede tener elementos repetidos, por lo que si el array contiene ele-
mentos repetidos solo se incluyen una vez.
julia> Set()
Set{Any}()
68
julia> typeof(c)
Set{Any}
Á Advertencia
Si el elemento que se quiere añadir es de distinto tipo que los elemento del conjunto y
no puede convertirse a este tipo, se produce un error.
julia> c = Set(1:3)
Set{Int64} with 3 elements:
2
3
1
julia> push!(c, 4)
Set{Int64} with 4 elements:
4
2
3
1
69
julia> c = Set(1:3)
Set{Int64} with 3 elements:
2
3
1
julia> delete!(c, 2)
Set{Int64} with 2 elements:
3
1
Un conjunto puede utilizarse también como un iterador para recorrer sus elementos.
julia> c = Set(1:3)
Set{Int64} with 3 elements:
2
3
1
julia> for i = c
println(i)
end
2
3
1
70
4.8.7 Ejemplos de pertenencia e inclusión de conjuntos
julia> a = Set(1:3);
julia> in(2, a)
true
julia> 3 � a
false
julia> a � b
false
julia> a � b
true
julia> isdisjoint(a, b)
false
Existen versiones de estas funciones acabadas en ! que sobreescriben el conjunto dado como
primer argumento con el resultado de la operación.
julia> a = Set(1:3)
Set{Int64} with 3 elements:
2
3
1
julia> b = Set(2:2:6)
Set{Int64} with 3 elements:
4
6
71
2
julia> union(a, b)
Set{Int64} with 5 elements:
4
6
2
3
1
julia> intersect(a, b)
Set{Int64} with 1 element:
2
julia> setdiff(a, b)
Set{Int64} with 2 elements:
3
1
72
5 Funciones
Una función asocia un nombre a un bloque de código de manera que cada vez que se invoca
a la función se ejecuta el bloque de código asociado.
Para crear una función se utiliza la siguiente sintaxis
function nombre(parámetros)
bloque de código
end
Ĺ Nota
Para invocar una función basta con escribir su nombre y pasarle entre paréntesis los valores
de los parámetros (argumentos) separados por comas.
julia> saludo()
¡Bienvenido!
julia> typeof(saludo)
typeof(saludo) (singleton type of function saludo, subtype of Function)
Una función puede recibir valores cuando se invoca a través de unas variables conocidas
como parámetros que se definen entre paréntesis y separados por comas en la declaración
73
de la función. En el cuerpo de la función se pueden usar estos parámetros como si fuesen
variables.
Los valores que se pasan a la función en una llamada o invocación concreta de ella se conocen
como argumentos y se asocian a los parámetros de la declaración de la función.
julia> calificacion(7)
Aprobado
Cuando una función tiente parámetros posicionales y como nominales, los posicionales deben
indicarse primero y los nominales después, separando ambos tipos de parámetros por punto
y coma ;.
74
5.2.3 Argumentos por defecto
En la definición de una función se puede asignar a cada parámetro un argumento por defecto,
de manera que si se invoca la función sin proporcionar ningún argumento para ese parámetro,
se utiliza el argumento por defecto.
El valor por defecto de un parámetro se indica con la siguiente sintaxis parámetro =
valor.
Julia permite definir funciones que pueden llamarse con un número variable de argumentos.
Para que una función pueda recibir un número variable de argumentos hay que poner tres
puntos suspensivos ... al final de último parámetro posicional.
Cuando se llame a la función los argumentos se irán asociando a los parámetros posicionales
en orden y el último parámetro se asociará a una tupla con el resto de argumentos en la
llamada.
julia> media(1, 2, 3, 4)
Media de (1, 2, 3, 4)
2.5
Aunque Julia es un lenguaje de tipado dinámico también permite fijar el tipo de los paráme-
tros de una una función. Esto permite definir diferentes variantes (métodos) de una misma
75
función dependiendo del tipo de los argumentos, así como detectar errores cuando se llama
a la función con argumentos de distinto tipo.
Para indicar el tipo de los parámetros de una función se utiliza la sintaxis parametro::tipo.
Á Advertencia
julia> sumar(1, 2)
3
En Julia los argumentos se pasan a una función por asignación, es decir, se asignan a los
parámetros de la función como si fuesen variables locales. De este modo, cuando los argu-
mentos son objetos mutables (arrays, diccionarios, etc.) se pasa al parámetro una referencia
al objeto, de manera que cualquier cambio que se haga en la función mediante el parámetro
asociado afectará al objeto original y serán visibles fuera de ella.
76
julia> primer_curso = [];
julia> primer_curso
2-element Vector{Any}:
"Álgebra Lineal"
"Programación"
Los parámetros y las variables declaradas dentro de una función son de ámbito local, mientras
que las variable definidas fuera de funciones son de ámbito ámbito global.
Tanto los parámetros como las variables del ámbito local de una función sólo están accesibles
durante la ejecución de la función. Es decir, cuando termina la ejecución de la función estas
variables desaparecen y no son accesibles desde fuera de la función.
Si en el ámbito local de una función existe una variable que también existe en el ámbito
global, durante la ejecución de la función la variable global queda eclipsada por la variable
local y no es accesible hasta que finaliza la ejecución de la función.
julia> saludo("Alf")
¡Hola Alf, bienvenido a Julia!
julia> lenguaje
"Python"
julia> nombre
ERROR: UndefVarError: nombre not defined
77
5.3 Retorno de una función
Una función devuelve siempre el valor de la última expresión evaluada en su cuerpo. Sin
embargo, puede devolverse cualquier otro valor indicándolo detrás de la palabra reservada
return. Cuando el flujo de ejecución de la función alcanza esta palabra, la ejecución de la
función termina y se devuelve el valor que la acompaña.
Si una función no devuelve ningún valor se puede escribir la palabra return sin nada más.
Cuando se desea devolver más de un valor se puede pueden indicar separados por comas y
la función devolverá la tupla formada por esos valores.
julia> area_triangulo(3, 4)
6.0
julia> area_perimetro_circulo(1)
(3.141592653589793, 6.283185307179586)
Cuando el cuerpo de una función es una única expresión se puede definir la función de forma
mucho más compacta de la siguiente manera:
nombre(parametros) = expresión
julia> area_triangulo(b, a) = b * a / 2
area_triangulo (generic function with 1 method)
78
julia> area_triangulo(3, 4)
6.0
julia> valor_absoluto(-1)
1
En Julia las funciones son objetos como el resto de tipos de datos, de manera que es posible
asignar una función a una variable y luego utilizar la variable para hacer la llamada a la
función, pasar una función como argumento de otra función, o que una función devuelva
otra función.
julia> suma(x, y) = x + y
suma (generic function with 1 method)
julia> adicion(1, 2)
3
julia> calculadora(suma, 1, 2)
3
Julia permite también definir funciones sin nombre. Para ello se utiliza la siguiente sinta-
xis.
El principal uso de las funciones anónimas es para pasarlas como argumentos de otras
funciones.
79
ulia> calculadora(operador, x, y) = operador(x, y)
calculadora (generic function with 1 method)
En Julia los operadores tienen asociadas funciones que son llamadas por el intérprete cuando
se evalúa una expresión con operadores.
julia> � = +
+ (generic function with 208 methods)
julia> �(1, 2, 3)
6
Una función recursiva es una función que en su cuerpo contiene alguna llama a si misma.
La recursión es una práctica común en la mayoría de los lenguajes de programación ya que
permite resolver las tareas recursivas de manera más natural.
Para garantizar el final de una función recursiva, las sucesivas llamadas tienen que reducir
el grado de complejidad del problema, hasta que este pueda resolverse directamente sin
necesidad de volver a llamar a la función.
¾ Precaución
La recursión es una técnica que suele ser poco eficiente computacionalmente y conviene
evitarla siempre que sea posible.
80
5.8.1 Ejemplo de funciones recursivas
julia> factorial(4)
24
julia> fib(10)
55
81
6 Gráficos
Existen muchos paquetes para la representación gráfica en Julia. Los más usados son:
• Plots.jl
• Makie.jl
• GadFly.jl.
• VegaLite.jl
Plots.js es el paquete más usado por disponer de más posibilidades gráficas y ser bastante
sencillo de usar.
Implementa una interfaz para otras librerías gráficas (backends), por lo que en algunas
ocasiones puede ser bastante lento al tener que llamar a otras librerías.
82
6.2.1 Backends de Plot.jl
• GR. Es el backend pro defecto. Es bastante rápida y permite tanto gráficos 2D como
3D no interactivos. Se inicializa con la función gr(). (Ver ejemplos)
• PlotlyJS. Es más lenta pero permite gráficos 2D y 3D interactivos con un montón de
funcionalidades. Se inicializa con la función plotlyjs(). (Ver ejemplos)
• PyPlot. Utiliza la librería gráfica Matplotlib de Python por lo que es bastante lenta.
Sin embargo, tiene ofrece todas las posibilidades de Matplotlib que es bastante madura.
Se inicializa con la función pyplot(). (Ver ejemplos)
• PGFPlotsX. Utiliza la librería PGF/TikZ de LaTeX por lo que genera gráficos de muy
alta calidad tanto en 2D como 3D, especialmente para publicaciones.Se inicializa con
la función pgfplotsx(). (Ver ejemplos)
83
• UnicodePlots. Permite dibujar gráficos en la terminal. Los gráficos son de poca calidad
pero funciona con gran rapidez. Se inicializa con la función unicodeplots(). (Ver
ejemplos)
• plot(f, min, max): Dibuja la gráfica de la función de una variable f para argumentos
desde xmin a xmax.
using Plots
f(x) = exp(-x^2 / 2)
plot(f, -3, 3)
• plot!(f, xmin, xmax): Añade la gráfica de la función de una variable f para argu-
mentos desde xmin a xmax al último gráfico realizado.
using Plots
f(x) = sin(x)
g(x) = cos(x)
84
plot(f, -0, 2�)
plot!(g)
using Plots
f(x) = sin(x)
g(x) = cos(x)
plot(f, -0, 2�)
plot!(g)
x = [�/4, 5�/4]
y = sin.(x)
scatter!(x, y)
85
6.2.5 Ventana de graficación
Es posible restringir el área de graficación (rango de valores de los ejes) de una función
añadiendo los parámetros xlims =(xmin, xmax) para establecer el rango del eje x o ylims
= (ymin, ymax) para establecer el rango del eje y.
using Plots
f(x) = 1 / x
plot(f, -1, 1, ylims = (-10, 10))
86
6.2.6 Restringir la gráfica al dominio
Cuando una función no está definida para algún valor del rango de valores del eje x dado, la
gráfica muestra una línea recta desde el punto de la gráfica anterior hasta el punto siguiente
al punto donde la función no existe.
Este comportamiento no es deseable puesto que si la función no existe en un punto no
debería existir gráfica para ese punto.
La siguiente función del paquete MTH229 se encarga de evitar esto.
• rangeclamp(f): Devuelve una función idéntica a la función f excepto para los puntos
donde la función no existe o es infinito que devuelve NaN.
using Plots
using MTH229
f(x) = 1 / x
plot(rangeclamp(f), -1, 1)
87
6.2.8 Gráficas paramétricas
La función plot también permite dibujar gráficas de funciones paramétricas pasándole las
funciones de las coordenadas x e y.
• plot(f, g, min, max): Dibuja la gráfica de la función paramétrica (𝑓(𝑡), 𝑔(𝑡)) para
valores del parámetro t entre min y max.
using Plots
f(x) = sin(x)
g(x) = sin(2x)
plot(f, g, 0, 2�)
88
6.2.9 Personalización de gráficos
Los siguientes parámetros pueden añadirse a la función plot para modificar el aspecto de
los gráficos.
using Plots
f(x) = sin(x)
plot(f, -�, �, title = "Gráfica del seno", xlab = "x", ylab = "f(x) = sen(x)",
color = "green", linewidth = 3, linestyle = :dash, legend = false)
89
6.2.11 Gráficos en el espacio real
using Plots
xs = ys = range(1, stop=10, length=100)
f(x, y) = sin(x) + cos(y)
surface(xs, ys, f)
90
6.3 Gráficos con Makie
Al igual que el paquete Plots, Makie utiliza distintos backends para construir el gráfico
según la salida que se quiera.
91
6.3.2 Figuras, ejes y objetos gráficos
Un gráfico con Makie es básicamente una figura (Figure) que contiene uno o varios ejes
(Axis) que, a su vez, contienen objetos gráficos como puntos o lineas.
Para crear una figura se utiliza la función
using GLMakie
fig = Figure(backgroundcolor = :gray, resolution = (400, 300))
92
fig = Figure()
ax = Axis(fig[1,1], title = "Ejes 2D", xlabel = "Eje x", ylabel = "Eje y")
fig
fig = Figure()
ax = Axis3(fig[1,1], title = "Ejes 3D", xlabel = "Eje x", ylabel = "Eje y", zlabel = "Ej
fig
93
fig = Figure()
ax = Axis3(fig[1,1], title = "Ejes 3D rotados", xlabel = "Eje x", ylabel = "Eje y", zlab
fig
94
6.3.3 Diagrama de puntos
• scatter!(ax, xs, ys): Dibuja los ejes dados en ax los puntos con coordenadas dadas
por los vectores xs e ys.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de puntos")
xs = [1, 2, 3]
ys = [2, 3, 1]
Makie.scatter!(ax, xs, ys)
fig
95
Los siguientes parámetros pueden añadirse a la función anterior para modificar el aspecto
del diagrama de puntos.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de puntos")
xs = [1, 2, 3]
ys = [2, 3, 1]
Makie.scatter!(ax, xs, ys, marker = :utriangle, color= :red, markersize = 20)
fig
96
6.3.4 Diagrama de líneas
• lines!(ax, xs, ys): Dibuja en los ejes dados por ax una línea en el plano que une
los puntos con coordenadas dadas por los vectores xs e ys.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas")
xs = range(0, 2pi, length = 100)
ys = sin.(xs)
lines!(ax, xs, ys)
fig
97
Si se añade un tercer vector de coordenadas zs sobre unos ejes 3D, se obtiene un diagrama de
líneas en 3D. De esta forma se pueden representar, por ejemplo, la trayectorias de funciones
vectoriales.
fig = Figure()
ax = Axis3(fig[1, 1], title = "Diagrama de líneas 3D")
ts = range(0, 6pi, length = 200)
xs = cos.(ts)
ys = sin.(ts)
zs = ts/4
lines!(ax, xs, ys, zs)
fig
98
En lugar de pasar las coordenadas de los puntos en vectores separados, se pueden pasar empa-
quetadas en tuplas mediante las estructuras Point(x,y) para el plano real o Point3(x,y,z)
para el espacio real, del paquete GeometryBasics.jl.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de lineas")
ts = range(0, 2pi, length = 200)
points = Point.(cos.(ts), sin.(2ts))
lines!(ax, points)
fig
99
fig = Figure()
ax = Axis3(fig[1, 1], title = "Diagrama de líneas 3D")
ts = range(0, 6pi, length = 200)
f(t) = [cos(t), sin(t), t/4]
points = Point3.(f.(ts))
lines!(ax, points)
fig
100
En el caso de figuras en 3D, es preferible utilizar los backend GLMakie.jl o WGLMakie.jl ya
que permiten interaccionar con el el gráfico para visualizarlo desde distintas perspectivas.
fig = Figure()
ax = Axis3(fig[1, 1], title = "Diagrama de líneas 3D")
ts = range(0, 6pi, length = 200)
f(t) = [cos(t), sin(t), t/4]
points = Point3.(f.(ts))
lines!(ax, points)
fig
101
También es posible pasar a la función lines! un rango de valores y una función a dibujar.
Esto simplifica la creación de gráficas de funciones.
• lines(ax, rango, función): Dibuja en los ejes dados por ax la gráfica de la función
dada en función en el intervalo dado por rango. El intervalo del rango se especifica
con la sintaxis li..ls, donde li es el límite inferior y ls el límite superior.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas")
lines!(ax, 0..2pi, cos)
fig
102
Para añadir nuevas líneas al los ejes, basta con volver a usar la función lines!.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas")
lines!(ax, 0..2pi, cos)
lines!(ax, 0..3pi, sin)
fig
103
Los siguientes parámetros pueden añadirse a la función anterior para modificar el aspecto
del diagrama de puntos.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas")
lines!(ax, 0..2pi, cos, linewidth = 5, linestyle = :dash, color = :red)
lines!(ax, 0..2pi, sin, linestyle = :dot, color = :green)
fig
104
6.3.5 Superficies
• surface!(ax, xs, ys, zs): Dibuja en los ejes 3D dados por ax la superficie que se
obtiene al unir los puntos con coordenadas 𝑥 dadas por el vector xs, coordenadas y
dadas por el vector ys y coordenadas 𝑧 dadas por el vector zs.
using WGLMakie
WGLMakie.activate!()
fig = Figure()
ax = Axis3(fig[1, 1], title = "Superficie")
xs = ys = LinRange(0, 10, 100)
zs = [cos(x) * sin(y) for x in xs, y in ys]
WGLMakie.surface!(ax, xs, ys, zs)
fig
6.3.6 Leyenda
Si tenemos más de una serie de datos representada en un diagrama, conviene añadir una
leyenda para identificar cada serie. Podemos añadir una leyenda con la función
105
• axislegend(ax): Añade una leyenda a los ejes dados en ax, con las etiquetas de cada
serie de datos incluida en los ejes. Para ello es necesario etiquetar cada serie de datos
pasándole el parámetro label = etiqueta a la función que crea el objeto gráfico que
representa la serie.
fig = Figure()
ax = Axis(fig[1, 1], title = "Diagrama de líneas con leyenda")
lines!(ax, 0..2pi, cos, label = "Coseno")
lines!(ax, 0..2pi, sin, label = "Seno")
axislegend()
current_figure()
VegaLite.jl es un paquete que genera gráficos estáticos por medio de las librerías de Javas-
cript de la gramática de gráficos Vega.
Dispone de muchas más opciones de personalización de gráficos que GadFly.jl.
106
107
7 Cálculo simbólico
7.1 Symbolics.jl
108
7.1.1 Variables y expresiones simbólicas
using Symbolics
julia> @variables x y
2-element Vector{Num}:
x
y
julia> z = x^2 - y
x^2 - y
julia> typeof(z)
Num
Se pueden realizar operaciones algebraicas con expresiones simbólicas utilizando los mismos
operadores del Álgebra numérica.
using Symbolics
julia> @variables x y;
julia> (x + 1) + (x + 2)
3 + 2x
109
2×2 Matrix{Num}:
x + y 2x
-y y - x
using Symbolics
@variables x y;
julia> simplify(2(x+y))
2x + 2y
julia> simplify(2(x+y))
2x + 2y
Para sustituir una variable simbólica en una expresión se utiliza la siguiente función:
• substitute(e, d): Realiza la sustitución de las claves por los valores del diccionario
d en la expresión simbólica e.
110
using Symbolics
@variables x y;
Á Advertencia
using Symbolics
@variables x y;
julia> Symbolics.solve_for(x + y ~ 0, x)
-y
111
using Symbolics
julia> @variables x y;
julia> Symbolics.derivative(exp(x*y), x)
y*exp(x*y)
Para obtener la función derivada, una vez aplicado el operador diferencial a una función, es
necesario aplicar la siguiente función:
using Symbolics
@variables x y;
julia> Dx = Differential(x)
(::Differential) (generic function with 2 methods)
julia> expand_derivatives(f1(x))
2x*cos(x^2)
julia> Dy = Differential(y)
(::Differential) (generic function with 2 methods)
112
julia> expand_derivatives(Dx(Dy(cos(x*y))))
-sin(x*y) - x*y*cos(x*y)
Para calcular el vector gradiente de una función de varias variables se utiliza la siguiente
función:
using Symbolics
@variables x y;
113
8 Análisis de datos
• DataFrame(x1=v1, x2=v2, ...): Devuelve el DataFrame que formado por las colum-
nas de los vectores v1, v2, etc, con los nombres x1, x2, etc, respectivamente.
using DataFrames
114
8.1.2 Creación de DataFrames desde una url
Para crear una DataFrame a partir de un fichero csv en la nube, se utiliza la siguiente
función del paquete CSV.jl:
julia> df = CSV.read(download("https://raw.githubusercontent.com/asalber/manual-python/m
14×6 DataFrame
Row � nombre edad sexo peso altura colesterol
� String Int64 String1 Int64? String7 Int64?
�������������������������������������������������������������������������������������
1 � José Luis Martínez Izquierdo 18 H 85 1,79 182
2 � Rosa Díaz Díaz 32 M 65 1,73 232
3 � Javier García Sánchez 24 H missing 1,81 191
4 � Carmen López Pinzón 35 M 65 1,70 200
5 � Marisa López Collado 46 M 51 1,58 148
6 � Antonio Ruiz Cruz 68 H 66 1,74 249
7 � Antonio Fernández Ocaña 51 H 62 1,72 276
8 � Pilar Martín González 22 M 60 1,66 missing
9 � Pedro Gálvez Tenorio 35 H 90 1,94 241
10 � Santiago Reillo Manzano 46 H 75 1,85 280
11 � Macarena Álvarez Luna 53 M 55 1,62 262
12 � José María de la Guía Sanz 58 H 78 1,87 198
13 � Miguel Angel Cuadrado Gutiérrez 27 H 109 1,98 210
14 � Carolina Rubio Moreno 20 M 61 1,77 194
115
9 Otras aplicaciones
116