├── README.md
├── en_clase
├── 17 octubre Euler 2 variables.ipynb
├── 10 oct - Funciones vectoriales en Julia.ipynb
└── 8 octubre Euler.ipynb
├── Proyectos.md
├── setup.md
├── setup_es.md
└── notebooks
├── 03. Caminatas aleatorias en 2D.ipynb
├── 15. Ecuacion de calor en 2 dimensiones.ipynb
├── 16. Problemas estacionarios con valores en la frontera.ipynb
├── 12. Mas alla de Euler.ipynb
├── 04. Metodos de Monte Carlo.ipynb
├── 06. Raices de funciones uni-dimensionales.ipynb
├── 07. El metodo de Newton.ipynb
├── 08. Diferencias finitas.ipynb
├── 10. Integracion numerica.ipynb
├── 02. Caminatas aleatorias II.ipynb
├── 17. Sistemas de ecuaciones lineales.ipynb
├── 09. Interpolacion.ipynb
├── 13. Metodos tipo Runge-Kutta.ipynb
├── 14. Ecuacion de calor.ipynb
├── 11. Ecuaciones diferenciales ordinarias - metodo de Euler.ipynb
├── 05. Iteracion de punto fijo y bucles while.ipynb
└── 01. Caminatas aleatorias.ipynb
/README.md:
--------------------------------------------------------------------------------
1 | # Fisica Computacional 2019-1
2 |
3 | ¡Bienvenidos a Física Computacional, semestre 2019-1!
4 |
5 | Aquí subiremos los materiales del curso.
6 |
7 |
8 | ## Evaluación
9 |
10 | El curso se basará en notebooks que se trabajarán en clase y en casa.
11 | La mayoría de los notebooks se entregarán como tareas.
12 |
13 | Evaluación: 50% tareas; 30% exámenes (probablemente tarea-examen); 20% proyecto final (Pueden consultar la lista de proyectos elegidos [aqui](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/Proyectos.md).
14 |
15 | Pueden consultar las calificaciones de sus tareas en [Calificaciones](https://docs.google.com/spreadsheets/d/1euiucRds_oSe0I14O2XghgPl1VTe50vYXZ0T00ZJdRo/edit?usp=sharing) conforme sean calificadas. Buscar a los ayudantes para cualquier aclaración.
16 |
17 | La lista de Notebooks entregados como tarea es la siguiente:
18 |
19 | - Tarea01: [Notebook 01](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/notebooks/01.%20Caminatas%20aleatorias.ipynb)
20 | - Tarea02: [Notebook 02](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/notebooks/02.%20Caminatas%20aleatorias%20II.ipynb)
21 | - Tarea03: [Notebook 03](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/notebooks/03.%20Caminatas%20aleatorias%20en%202D.ipynb)
22 | - Tarea04: [Notebook 06](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/notebooks/06.%20Raices%20de%20funciones%20uni-dimensionales.ipynb)
23 | - Tarea05: [Notebook 07](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/notebooks/07.%20El%20metodo%20de%20Newton.ipynb)
24 | - Tarea06: [Notebook 08](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/notebooks/08.%20Diferencias%20finitas.ipynb). Se entregó el 24 de septiembre.
25 | - Tarea07: [Notebook 09](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/notebooks/09.%20Interpolacion.ipynb). Se entrega el 01 de octubre.
26 | - Tarea08: [Notebook 10](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/notebooks/10.%20Integracion%20numerica.ipynb). Se entrega el 10 de octubre.
27 | - Tarea09: [Notebook 11](https://github.com/dpsanders/FisicaComputacional2019_1/blob/master/notebooks/11.%20Ecuaciones%20diferenciales%20ordinarias%20-%20metodo%20de%20Euler.ipynb). Se entrega el 22de octubre.
28 |
29 |
30 | ## Bibliografía
31 |
32 | Se recomiendan ampliamente los libros:
33 |
34 | - *Computational Physics* de Mark Newman
35 | - *Computational Physics* de Giordano
36 | - *An Introduction to Computer Simulation Methods* de Gould & Tobochnik
37 |
38 | Para aprender Julia, ver los videos y tutoriales en
39 |
40 | https://julialang.org/learning/
41 |
42 |
43 | ## Instrucciones para clonar el repositorio
44 |
45 | - Si usas Windows, baja git-bash: https://gitforwindows.org/
46 |
47 | - Usando la terminal, cambia a algún directorio de tu máquina y pon
48 |
49 | `git clone https://github.com/dpsanders/FisicaComputacional2019_1.git`
50 |
51 | - Abres el notebook dentro de Julia
52 | - `using IJulia`
53 | - `notebook()`
54 |
55 | - Haces una copia del notebook
56 |
57 | Cuando quieras actualizar con las novedades:
58 |
59 | `git pull`
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/en_clase/17 octubre Euler 2 variables.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Recordatorio: 1 variable"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "$\\dot{x} = f(x, t)$\n",
15 | "\n",
16 | "Un paso:\n",
17 | "\n",
18 | "$$x_{n+1} = x_n + f(x_n, t_n) \\cdot h$$"
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": 1,
24 | "metadata": {},
25 | "outputs": [
26 | {
27 | "data": {
28 | "text/plain": [
29 | "paso_euler (generic function with 1 method)"
30 | ]
31 | },
32 | "execution_count": 1,
33 | "metadata": {},
34 | "output_type": "execute_result"
35 | }
36 | ],
37 | "source": [
38 | "function paso_euler(x, h, f, t)\n",
39 | " \n",
40 | " x_siguiente = x + h * f(x, t)\n",
41 | "\n",
42 | " return x_siguiente\n",
43 | "end"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": 3,
49 | "metadata": {},
50 | "outputs": [
51 | {
52 | "data": {
53 | "text/plain": [
54 | "euler (generic function with 1 method)"
55 | ]
56 | },
57 | "execution_count": 3,
58 | "metadata": {},
59 | "output_type": "execute_result"
60 | }
61 | ],
62 | "source": [
63 | "v"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "metadata": {},
69 | "source": [
70 | "## 2 variables"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "$$\\dot{x} = f(x, y)$$\n",
78 | "$$\\dot{y} = g(x, y)$$\n"
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "metadata": {},
84 | "source": [
85 | "Un paso de Euler con 2 variables consiste en **2** pasitos:\n",
86 | "\n",
87 | "$$x_{n+1} = x_n + f(x_n, y_n) \\cdot h$$\n",
88 | "$$y_{n+1} = y_n + g(x_n, y_n) \\cdot h$$"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": 6,
94 | "metadata": {},
95 | "outputs": [
96 | {
97 | "ename": "LoadError",
98 | "evalue": "syntax: invalid identifier name \"?\"",
99 | "output_type": "error",
100 | "traceback": [
101 | "syntax: invalid identifier name \"?\"",
102 | ""
103 | ]
104 | }
105 | ],
106 | "source": [
107 | "function euler2(f, g, x, y, h) # (x, h, f, t)\n",
108 | " \n",
109 | " x_siguiente = x + h * f(x, y)\n",
110 | " y_siguiente = y + h * g(x, y)\n",
111 | "\n",
112 | " return x_siguiente, y_siguiente\n",
113 | "end"
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": null,
119 | "metadata": {},
120 | "outputs": [],
121 | "source": []
122 | }
123 | ],
124 | "metadata": {
125 | "kernelspec": {
126 | "display_name": "Julia 1.0.0",
127 | "language": "julia",
128 | "name": "julia-1.0"
129 | },
130 | "language_info": {
131 | "file_extension": ".jl",
132 | "mimetype": "application/julia",
133 | "name": "julia",
134 | "version": "1.0.0"
135 | }
136 | },
137 | "nbformat": 4,
138 | "nbformat_minor": 2
139 | }
140 |
--------------------------------------------------------------------------------
/Proyectos.md:
--------------------------------------------------------------------------------
1 | Proyectos elegidos hasta ahora:
2 |
3 |
4 |
5 | - Integración con método de Romberg
6 |
José Falcón, Yamil Cahuana
7 |
8 | Jueves 06 de diciembre
9 |
10 | - Transformada Rápida de Fourier
11 |
Oscar Márquez, Jazmín Garduño
12 |
13 | Jueves 06 de diciembre
14 |
15 | - Simulación de Partícula Browniana en trampa óptica.
16 |
Mauricio Becerril, Esau Cervantes
17 |
18 | Miércoles 05 de diciembre
19 |
20 |
21 | - Modelo de Fermi-Pasta-Ulam.
22 |
Mitzi Urquiza, Héctor Morales
23 |
24 | Jueves 06 de diciembre
25 |
26 |
27 | - Simulación de la propagación de una onda en medios no homogeneos.
28 |
Andrés Vega Flores, Amor Enitz Sosa Escalante
29 |
30 | Jueves 06 de diciembre
31 |
32 |
33 | - Péndulo doble.
34 |
Carlos Cano Arista, Fernanda Ordoñez Jimenez
35 |
36 | Miércoles 05 de diciembre
37 |
38 |
39 |
40 | - Modelado de fractales observados en la naturaleza.
41 |
Ana Daniela del Río Pulido, Xareni Wang Chen
42 |
43 | Miércoles 05 de diciembre
44 |
45 |
46 | - Respuesta natural de un circuito RLC en serie.
47 |
Ruben Sánchez Duque
48 |
49 | Miércoles 05 de diciembre
50 |
51 |
52 | - Resolución de integrales utilizando el método de cuadratura de Gauss y comparación con otros métodos.
53 |
Jorge Luis Briseño, Eduardo Conde Juárez
54 |
55 | Jueves 06 de diciembre
56 |
57 |
58 | - Simulación sismológica.
59 |
María Aketzali Carrillo Torres, León Diego Carrillo Torres
60 |
61 | Jueves 06 de diciembre
62 |
63 |
64 | - Diferenciación automática.
65 |
Brandon Saúl Gómez Bravo Brandon Saúl, Manuel Emiliano Monreal Cancino
66 |
67 | Miércoles 05 de diciembre
68 |
69 |
70 | - Caracterización de sistemas cuasiestáticos.
71 |
Gabriel Carranco
72 |
73 | Miércoles 05 de diciembre
74 |
75 |
76 | - Transformada de Radón.
77 |
Eugenio Galicia, Jorge Abel Mejía
78 |
79 | Jueves 06 de diciembre
80 |
81 |
82 | - Modelo de Hodgkin-Huxley para una neurona.
83 |
Diana Zoila Vázquez Pérez
84 |
85 | Jueves 06 de diciembre
86 |
87 |
88 | - Refinamiento de Rietveld.
89 |
Carlos Tapia, Joshua Muñoz
90 |
91 | Miércoles 28 de noviembre
92 |
93 |
94 | - Trayectoria de un cohete que viaja de la Tierra a la Luna.
95 |
Tania Zanatta, Andrés Gutiérrez Valdés
96 |
97 | Miércoles 05 de diciembre
98 |
99 |
100 | - Trayectorias en un agujero negro de Kerr.
101 |
Luis Enrique Martínez Rojas
102 |
103 | Miércoles 05 de diciembre
104 |
105 |
106 | - Geodésicas en Schwarzschild y precesión de Mercurio.
107 |
Enrique David Gúzman Ramírez
108 |
109 | Miércoles 05 de diciembre
110 |
111 |
112 | - Vibración de una cuerda en un instrumentos musical.
113 |
Arturo García Zurita, Bianca Saraim Zavalza Arellano
114 |
115 | Jueves 06 de diciembre
116 |
117 |
118 | - Movimiento Planetario y Puntos de Lagrange.
119 |
Claudia Zendejas Morales.
120 |
121 | Jueves 06 de diciembre
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/setup.md:
--------------------------------------------------------------------------------
1 |
2 | ## Running Julia online: JuliaBox
3 | The easiest way to start using Julia is via the online [JuliaBox](http://www.juliabox.com) service.
4 | This provides an online version of the [Jupyter notebook](http://www.jupyter.org), which we will be using throughout. Use `Shift-Enter` to execute a cell.
5 |
6 | An alternative is [CoCalc](http://www.cocalc.com), which allows simultaneous editing of notebooks by several people.
7 |
8 | ## Installing Julia and Jupyter locally
9 | To install Julia and Jupyter locally on your own machine, do the following.
10 |
11 | [Note that it is *not* necessary to install Anaconda separately; Julia will do this automatically for you.]
12 |
13 | 1. Download and install the stable version of Julia (0.6.3) from [here](http://www.julialang.org/downloads) for your operating system.
14 |
15 | 2. Run the copy of Julia that you just installed.
16 |
17 | Execute the following commands within the Julia terminal ("REPL") environment, where you will see a `julia> ` prompt.
18 |
19 | 3. If you use Linux, first type:
20 | ```jl
21 | julia> ENV["JUPYTER"] = ""
22 | ```
23 |
24 | 4. Now install the IJulia package, which will automatically install Jupyter (using `miniconda`):
25 | ```
26 | julia> Pkg.add("IJulia")
27 | ```
28 |
29 | 5. Open the notebook as follows.
30 | ```jl
31 | julia> using IJulia
32 | julia> notebook()
33 | ```
34 | By default, new notebooks will be created in your home directory. Navigate to a different directory to save them in your preferred location.
35 |
36 | 6. Install some of the packages that we will use during the course (you will need an internet connection):
37 | ```jl
38 | julia> packages = split(
39 | """Plots GR PlotlyJS Interact
40 | BenchmarkTools
41 | ForwardDiff
42 | TaylorSeries
43 | DynamicalSystems
44 | DifferentialEquations
45 | IntervalArithmetic
46 | IntervalRootFinding
47 | """)
48 |
49 | julia> for package in packages
50 | Pkg.add(package)
51 | end
52 | ```
53 | ## Get up to speed with basic Julia syntax
54 |
55 | If you have had little exposure to Julia, please work through [this video tutorial](https://youtu.be/4igzy3bGVkQ) to get up to speed with basic Julia syntax, in particular the notebooks 1 through 8 (up to and including "Plotting"). The notebooks are available directly in JuliaBox, or [here](https://github.com/JuliaComputing/JuliaBoxTutorials/tree/master/intro-to-julia).
56 |
57 | We suggest that you bookmark, download or even print out the following two "cheat sheets" with summaries of basic Julia syntax:
58 | - a [one-page summary by Steven Johnson](https://github.com/stevengj/1806/blob/master/julia/Julia-cheatsheet.pdf)
59 |
60 | - a [more extensive summary](https://juliadocs.github.io/Julia-Cheat-Sheet)
61 |
62 | There is an ever-growing list of resources for learning Julia available on the [learning page](http://www.julialang.org/learning) of the Julia homepage; in particular, check out the [QuantEcon lectures](https://lectures.quantecon.org/jl).
63 |
64 |
65 | ## Julia IDE: Juno
66 |
67 | There are two IDEs (Integrated Development Environments) available for Julia: Juno, based on the [Atom editor](https://atom.io/), and a Julia plug-in for the Visual Studio Code editor.
68 |
69 | Please download Atom and install the `uber-juno` package; this will give you a Julia development environment. More info is available at the [Juno IDE homepage](http://junolab.org/).
70 |
71 |
72 | ## Questions and comments
73 | Please contact [David](dpsanders@ciencias.unam.mx) if you have any further questions and comments
74 |
--------------------------------------------------------------------------------
/setup_es.md:
--------------------------------------------------------------------------------
1 | ## Correr Julia en linea: JuliaBox
2 | La forma más fácil de correr Julia es en línea usando el servicio [JuliaBox](http://www.juliabox.com).
3 | Este provee una versión en línea de una [Jupyter notebook](http://www.jupyter.org), que se usara durante el curso. Se usa `Shift-Enter` para ejecutar una celda.
4 |
5 | Una alternativa es [CoCalc](http://www.cocalc.com), que permite la edición simultanea de las notebooks por distintas personas.
6 |
7 | ## Instalar Julia y Jupyter localmente
8 | Para instalar Julia y Jupyter localmente en sus computadoras se siguen los siguientes pasos.
9 |
10 | [Nota que *no* es necesario instalar Anaconda de manera separada; Julia hará esto por ti.]
11 |
12 | 1. Descarga e instala la versión estable de Julia (0.6.3) de [aqui](http://www.julialang.org/downloads) para el sistema operativo que uses.
13 |
14 | 2. Corre la copia de Julia que instalaste.
15 |
16 | Ejecuta los siguientes comandos en la teminal del entorno de Julia ("REPL"), en donde veras un `julia> `.
17 |
18 | 3. Si usas Linux, primero teclea:
19 | ```jl
20 | julia> ENV["JUPYTER"] = ""
21 | ```
22 |
23 | 4. Ahora instala el paquete IJulia, que automáticamente instalará Jupyter (usando `miniconda`):
24 | ```
25 | julia> Pkg.add("IJulia")
26 | ```
27 |
28 | 5. Abre la libreta como sigue.
29 | ```jl
30 | julia> using IJulia
31 | julia> notebook()
32 | ```
33 | Por default, notebooks nuevas seran creadas en tu directorio principal. Abre o crea una carpeta diferente de tu preferencia para guardarlos en la locación de tu elección.
34 |
35 | 6. Instala algunos otros paquetes que usaremos durante el curso (Necesitaras una conexión a Internet):
36 | ```jl
37 | julia> packages = split(
38 | """Plots GR PlotlyJS Interact
39 | BenchmarkTools
40 | ForwardDiff
41 | TaylorSeries
42 | DynamicalSystems
43 | DifferentialEquations
44 | IntervalArithmetic
45 | IntervalRootFinding
46 | """)
47 |
48 | julia> for package in packages
49 | Pkg.add(package)
50 | end
51 | ```
52 | ## Poniendose al día con la sintaxis básica de Julia
53 |
54 | Si no has tenido un acercamiento a Julia, puedes usar [este video turorial](https://youtu.be/4igzy3bGVkQ) para ponerte al día con la sintaxis basica de Julia, en particular las notebooks del 1 al 8 (incluyendo "Plotting"). Las libretas estas disponibles directamente en JuliaBox o [aqui](https://github.com/JuliaComputing/JuliaBoxTutorials/tree/master/intro-to-julia).
55 |
56 | Sugerimos que añadas a favoritos, descargues o incluso imprimas los siguientes "acordeones" que resume la sintaxis basica de Julia:
57 | - A [one-page summary by Steven Johnson](https://github.com/stevengj/1806/blob/master/julia/Julia-cheatsheet.pdf)
58 |
59 | - A [more extensive summary](https://juliadocs.github.io/Julia-Cheat-Sheet)
60 |
61 | Existe una siempre creciente lista de recursos para aprender Julia disponibles en la [learning page](http://www.julialang.org/learning) de Julia; en particular revisa [QuantEcon lectures](https://lectures.quantecon.org/jl).
62 |
63 |
64 | ## Julia IDE: Juno
65 |
66 | Existen dos IDEs (Integrated Development Environments) disponibles para Julia: Juno, basada en el editor de texto [Atom](https://atom.io/), y una extensión de Julia para el editor Visual Studio Code.
67 |
68 | Descargue Atom e instale el paqeute `uber-juno`; Esto te dara un entorno de desarrollador de Julia. Más información disponible en [Juno IDE homepage](http://junolab.org/).
69 |
70 |
71 | ## Preguntas y Comentarios
72 | Por favor contactar a [David](dpsanders@ciencias.unam.mx) si tienes alguna duda o comentario.
73 |
--------------------------------------------------------------------------------
/notebooks/03. Caminatas aleatorias en 2D.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Caminatas aleatorias en más dimensiones"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Es interesante extender el modelo de caminatas aleatorias a 2 y 3 dimensiones, lo cual es físicamente más realista."
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "#### Ejercicio 1"
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "metadata": {},
27 | "source": [
28 | "(i) Define una caminata aleatoria en 2D, con coordenadas $x$ y $y$, que vive en $\\mathbb{Z}^2$.\n",
29 | "\n",
30 | "(ii) Escribe una función que hace un paso del caminante. Puede moverse sólo arriba, abajo, a la izquierda o a la derecha en cada paso, con probabilidades iguales.\n",
31 | "\n",
32 | "(iii) Escribe una simulación de $N$ caminantes en 2D, siguiendo las mismas ideas que en el notebook anterior."
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "#### Ejercicio 2\n",
40 | "\n",
41 | "(i) Haz una visualización de las posiciones de los caminantes en distintos momentos del tiempo en una sola gráfica, e.g. usando `scatter`.\n",
42 | "\n",
43 | "(ii) Utiliza `IJulia.clear_output()` para hacer una animación del proceso."
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "#### Ejercicio 3\n",
51 | "\n",
52 | "(i) Calcula el promedio y la varianza como función del tiempo y grafícalos."
53 | ]
54 | },
55 | {
56 | "cell_type": "markdown",
57 | "metadata": {},
58 | "source": [
59 | "#### Ejercicio 4\n",
60 | "\n",
61 | "(i) Ahora considera caminantes en 3D. Haz la simulación y la visualización de una nube de caminantes."
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "metadata": {},
67 | "source": [
68 | "## Caminatas en el espacio"
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {},
74 | "source": [
75 | "Hasta ahora, las caminatas han vivido sobre los enteros únicamente. Pero eso no es necesario; pueden vivir en el espacio real."
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {},
81 | "source": [
82 | "#### Ejercicio 5"
83 | ]
84 | },
85 | {
86 | "cell_type": "markdown",
87 | "metadata": {},
88 | "source": [
89 | "(i) Escribe una función `uniforme` que utilice `rand` para generar un número aleatorio distribuido simétricamente alrededor de cero.\n",
90 | "\n",
91 | "(ii) Verifica con un histograma que tu generador realmente cumpla con esta propiedad.\n",
92 | "\n",
93 | "(iii) Utiliza `uniforme` para hacer una simulación de un caminante aleatorio en el espacio 2D que cambia su posición tanto en $x$ como en $y$ en cada paso.\n",
94 | "\n",
95 | "(iv) Haz unas vizualizaciones y calcula dibuja el promedio y la varianza como función del tiempo."
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "#### Ejercicio 6"
103 | ]
104 | },
105 | {
106 | "cell_type": "markdown",
107 | "metadata": {},
108 | "source": [
109 | "(i) Repite lo mismo en 3D."
110 | ]
111 | }
112 | ],
113 | "metadata": {
114 | "kernelspec": {
115 | "display_name": "Julia 0.6.4",
116 | "language": "julia",
117 | "name": "julia-0.6"
118 | },
119 | "language_info": {
120 | "file_extension": ".jl",
121 | "mimetype": "application/julia",
122 | "name": "julia",
123 | "version": "0.6.4"
124 | }
125 | },
126 | "nbformat": 4,
127 | "nbformat_minor": 2
128 | }
129 |
--------------------------------------------------------------------------------
/notebooks/15. Ecuacion de calor en 2 dimensiones.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# La ecuación de calor en 2D"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Los sistemas físicos raremente viven en 1 sola dimensión. Es más usual que sean dos-dimensionales o tres-dimensionales. \n",
15 | "\n",
16 | "Dado que los sistemas 3D son computacionalmente demandantes, y las ideas a menudo son las mismas que en 2D, nos restringiremos al caso 2D."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "La ecuación de difusión en 2D es\n",
24 | "\n",
25 | "$$\\frac{\\partial u(x,y,t)}{\\partial t} = \\nabla^2 u(x,y,t),$$\n",
26 | "\n",
27 | "donde $\\nabla^2 u(x,y,t) = \\frac{\\partial^2 u(x,y,t)}{\\partial x^2} + \\frac{\\partial^2 u(x,y,t)}{\\partial y^2}$."
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {},
33 | "source": [
34 | "Para discretizar el sistema, extenderemos lo que ya habíamos hecho en 1D:\n",
35 | "utilizaremos una malla con nodos $(x_i, y_j; t_n)$, con paso $h$ en el tiempo, y tamaños de celda $k$ para $x$, y $l$ para $y$. Notaremos por $u_{i, j}^n$ la aproximación que calcularemos de $u(x_i, y_j; t_n)$."
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "#### Ejercicio 1\n",
43 | "\n",
44 | "(i) Encuentra una discretización de $\\nabla^2 u$ en el punto $(x_i, y_j; t_n)$.\n",
45 | "\n",
46 | "(ii) Así, escribe la ecuación discretizada en el punto $(x_i, y_j; t_n)$ la malla, y de ahí la regla para la evolución de Euler en el tiempo.\n",
47 | "\n",
48 | "(iii) ¿Cómo son las condiciones de frontera de Dirichlet ahora? ¿Qué esperas ver físicamente para este tipo de condiciones absorbentes?"
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": null,
54 | "metadata": {},
55 | "outputs": [],
56 | "source": []
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "#### Ejercicio 2\n",
63 | "\n",
64 | "(i) Implementa esto computacionalmente y haz una animación para una condición inicial tipo delta. \n",
65 | "Ahora en lugar de un vector para representar al estado actual del sistema, necesitarás una *matriz* para las $u^n_{i,j}$ en el tiempo actual $t_n$.\n",
66 | "\n",
67 | "(ii) ¿Qué ocurre para otras condiciones iniciales?\n",
68 | "\n",
69 | "(iii) Haz animaciones, por ejemplo utilizando `Interact.jl`."
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "metadata": {},
76 | "outputs": [],
77 | "source": []
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "#### Ejercicio 3 \n",
84 | "\n",
85 | "(i) Escribe las condiciones de frontera de Neumann para el sistema en un cuadrado.\n",
86 | "\n",
87 | "(ii) Discretízalas. \n",
88 | "\n",
89 | "(iii) Implementa la evolución con condiciones de Neumann. ¿Qué esperas ver físicamente?\n",
90 | "\n",
91 | "(iv) Haz animaciones.\n",
92 | "\n",
93 | "[Nota que se puede reutilizar el mismo código que ya hiciste para las condiciones de Dirichlet, si extraes la parte de implementar las condiciones de frontera a otra función, y mandas esta función como otro argumento a la función principal para escoger cuáles condiciones de frontera se ocuparán.]"
94 | ]
95 | },
96 | {
97 | "cell_type": "markdown",
98 | "metadata": {},
99 | "source": []
100 | },
101 | {
102 | "cell_type": "markdown",
103 | "metadata": {},
104 | "source": [
105 | "#### Ejercicio 4\n",
106 | "\n",
107 | "Ahora considera condiciones **periódicas** de frontera. Aquí, el vecino de una celda en la frontera que \"se sale del sistema\" se toma como la celda *del otro lado del sistema*. [Esto le da al sistema la topología de un toro; minimiza el efecto de las fronteras, para simular mejor un sistema de tamaño \"infinito\".]\n",
108 | "\n",
109 | "(i) Para todos los sitios de frontera, calcula cuáles son sus 4 vecinos. Esto se puede hacer utilizando una 4 funciones, una para cada dirección, escritas con `if` o con módulo (`%`).\n",
110 | "\n",
111 | "(ii) Implementa la ecuación de calor con fronteras periódicas. ¿Qué esperas observar?\n",
112 | "\n",
113 | "(iii) Haz animaciones.\n",
114 | "\n",
115 | "**Opcional: Otra manera de implementarlo es copiando las fronteras de un lado del sistema al otro en cada paso para extender las fronteras en una distancia de uno en cada dirección, con llamadas \"celdas fantasma\". Impleméntalo.\n"
116 | ]
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": null,
121 | "metadata": {},
122 | "outputs": [],
123 | "source": []
124 | }
125 | ],
126 | "metadata": {
127 | "kernelspec": {
128 | "display_name": "Julia 0.6.4",
129 | "language": "julia",
130 | "name": "julia-0.6"
131 | },
132 | "language_info": {
133 | "file_extension": ".jl",
134 | "mimetype": "application/julia",
135 | "name": "julia",
136 | "version": "0.6.4"
137 | }
138 | },
139 | "nbformat": 4,
140 | "nbformat_minor": 1
141 | }
142 |
--------------------------------------------------------------------------------
/notebooks/16. Problemas estacionarios con valores en la frontera.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Problemas estacionarios con valores en la frontera"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Hasta ahora, hemos estudiado únicamente las **ecuaciones de evolución**, o sea, problemas **con valores iniciales**, en los cuales se quiere determinar la evolución temporal de la solución, tanto para EDOs como para EDPs.\n",
15 | "\n",
16 | "Otra clase fundamental de problemas son los **problemas estacionarios** o **problemas estáticos**, también llamados **problemas con valores en la frontera**. En este tipo de problemas, se busca una solución estacionaria, es decir, una solución que *no* cambia en el tiempo, pero que sí depende del espacio.\n",
17 | "\n",
18 | "Este tipo de problemas surge en distintos contextos. Por ejemplo, si resolvemos la ecuación de difusión con condiciones de Dirichlet dadas que no sean cero, la solución temporal *converge* a una solución estacionaria. ¿Podemos calcular directamente esta solución estacionaria? Los problemas estacionarios también ocurren naturalmente al resolver, por ejemplo, las ecuaciones de Laplace y de Poisson para determinar el potencial (y de ahí el campo) eléctrico para una configuración dada de cargas y fronteras."
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "## Las ecuaciones de Poisson y de Laplace "
26 | ]
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "metadata": {},
31 | "source": [
32 | "Consideremos el problema de encontrar el campo de potencial debido a una distribución de carga eléctrica. El campo de potencial $V(\\mathbf{x})$ satisface la ecuación de Poisson,\n",
33 | "\n",
34 | "$$ \\nabla^2 V(\\mathbf{x}) = -\\rho(\\mathbf{x}), $$\n",
35 | "\n",
36 | "donde $\\rho(\\mathbf{x})$ es la densidad de carga en unidades adecuadas.\n",
37 | "Si hay, por ejemplo, dos placas con potenciales dados, entonces queremos resolver este problema con los valores en la frontera $V = V_1$ y $V = V_2$ en las dos placas.\n",
38 | "\n",
39 | "Para comenzar, reduzcamos el problema a una sola dimensión. Entonces la ecuación se vuelve\n",
40 | "\n",
41 | "$$ \\frac{d^2 V(x)}{dx^2} = -\\rho(x) \\quad (*) $$ \n",
42 | "\n",
43 | "para todas las $x$,\n",
44 | "con $V(a) = x_1$ y $V(b) = x_2$,\n",
45 | "es decir, una EDO con valores en la frontera.\n",
46 | "\n",
47 | "Este tipo de problema tiene una naturaleza *completamente diferente* de los que hemos visto anteriormente en EDOs, ya que *no hay evolución* en el tiempo. Y sin embargo..."
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "#### Ejercicio 1\n",
55 | "\n",
56 | "(i) Discretiza la ecuación con una malla en el espacio, tal como hicimos para la ecuación de difusión: ¿cuál ecuación discretizada se satisface en el sitio $x_i$? \n",
57 | "\n",
58 | "(ii) ¿Si hay una sola carga puntual, cuáles sitios son especiales?\n",
59 | "\n",
60 | "(iii) Dado que ya no hay evolución en el tiempo, todas las ecuaciones para todos los sitios $i$ **se deben cumplir simultáneamente**. \n",
61 | "\n",
62 | "¿Qué tipo de problema resulta entonces? Escribe el problema con una notación breve que ya conoces de otros cursos."
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "## Método iterativo de solución"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "Hay varios métodos posibles para resolver problemas de esta índole. Empezaremos con ocupar un método **iterativo** que recién vimos:"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "#### Ejercicio 2\n",
84 | "\n",
85 | "(i) Reescribe la ecuación en el sitio $x_i$ que encontraste en la pregunta **1** para despejar $V_i$, el valor aproximado de $V(x_i)$.\n",
86 | "\n",
87 | "Ahora **inventemos** una dinámica, de una manera parecida a la que utilizamos con los primeros métodos iterativos para resolver ecuaciones: pongamos esta $V_i$ como $V_i^{t+1}$, y los demás $V_i$ como $V_i^t$.\n",
88 | "\n",
89 | "(ii) Escribe la nueva ecuación. ¿Cómo se relaciona la solución de la ecuación (*) con esta dinámica?\n",
90 | "\n",
91 | "(iii) Implementa esta dinámica para el caso cuando $\\rho(x) \\equiv 0$, es decir, la **ecuación de Laplace** con condiciones en la frontera $V(x=0) = a$ y $V(x=1) = b$. Haz una animación con `Interact.jl`.\n",
92 | "\n",
93 | "(iv) Encuentra la solución analítica de la ecuación diferencial y compáralo con tu solución. [Nota que tendrás que esperar bastante tiempo para que la solución a la ecuación dinámica converja.]\n",
94 | "\n",
95 | "(v) ¿De qué es discretización la ecuación dinámica?, es decir, ¿cuál ecuación de evolución estamos resolviendo? ¿Por qué es tan lenta la convergencia?"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "#### Ejercicio 3\n",
103 | "\n",
104 | "(i) Utiliza la misma técnica para resolver la siguiente EDO con valores en la frontera para $y(x)$:\n",
105 | "\n",
106 | "\\begin{align}\n",
107 | "y'' + y &= 0 \\\\\n",
108 | "y(0) &= 0\\\\\n",
109 | "y \\left( \\frac{\\pi}{2} \\right) &= 2\n",
110 | "\\end{align}\n",
111 | "\n",
112 | "Compara tu solución con el resultado analítico.\n",
113 | "\n",
114 | "(ii) ¿Qué ocurre si cambias las condiciones en la frontera a $y(0) = 1$ y $y(\\frac{\\pi}{2}) = 2$?"
115 | ]
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "metadata": {},
120 | "source": [
121 | "#### Ejercicio 4\n",
122 | "\n",
123 | "Ahora pensemos en la ecuación de Poisson en 1D con una carga puntual en la posición $x_0$.\n",
124 | "\n",
125 | "(i) ¿Cómo puedes modelar matemáticamente la carga puntual? Para tratar esto numéricamente, utilizamos la misma técnica que anteriormente.\n",
126 | "\n",
127 | "(ii) Escribe la ecuación diferencial y discretízala, tomando cuidado con los puntos especiales.\n",
128 | "\n",
129 | "(iii) Impleméntalo y verifica que la solución sea correcta."
130 | ]
131 | },
132 | {
133 | "cell_type": "code",
134 | "execution_count": null,
135 | "metadata": {},
136 | "outputs": [],
137 | "source": []
138 | }
139 | ],
140 | "metadata": {
141 | "kernelspec": {
142 | "display_name": "Julia 1.0.2",
143 | "language": "julia",
144 | "name": "julia-1.0"
145 | },
146 | "language_info": {
147 | "file_extension": ".jl",
148 | "mimetype": "application/julia",
149 | "name": "julia",
150 | "version": "1.0.2"
151 | }
152 | },
153 | "nbformat": 4,
154 | "nbformat_minor": 1
155 | }
156 |
--------------------------------------------------------------------------------
/notebooks/12. Mas alla de Euler.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Euler puede fracasar: sistemas con leyes de conservación"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "El método de Euler es sencillo y útil, pero tiene un defecto importante: ¡puede fracasar!, o sea, no integra correctamente las EDOs. De hecho, resulta que *casi siempre fracasa*, no sólo cuantitativamente, sino también cualitativamente.\n",
15 | "\n",
16 | "Por ejemplo, consideremos la ecuación del péndulo para ángulos pequeños, o sea, un oscilador armónico simple, ahora *sin* amortiguamiento."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "#### Ejercicio 1\n",
24 | "\n",
25 | "(i) Escribe la ecuación de movimiento del oscilador armónico simple, en términos del ángulo $\\theta$ del péndulo desde el vertical, y la velocidad angular $\\omega$.\n",
26 | "\n",
27 | "(ii) Dibuja el campo vectorial.\n",
28 | "\n",
29 | "(ii) Integra la ecuación utilizando el método de Euler dibuja bastantes trayectorias en el espacio fase $(\\theta, \\omega)$, empezando desde distintas condiciones iniciales.\n",
30 | " ¿Tienen sentido físico? ¿Por qué?\n",
31 | "\n",
32 | "(iii) Recuerda que este sistema físico tiene una propiedad especial: existe una **ley de conservación**. ¿Cuál es la cantidad física que se conserva? Escríbela en términos de $\\theta$ y $\\omega$.\n",
33 | "\n",
34 | "(iv) Dado que esta cantidad se conserva, ¿qué debe satisfacer una trayectoria que sale de una condición inicial dada? [Pista: piensa en **curvas de nivel**.] ¿Por qué? ¿Puedes escribir una ecuación que describe cómo evoluciona la cantidad conservada a lo largo del tiempo?\n",
35 | "\n",
36 | "Utiliza `contour` para dibujar curvas de nivel, y compáralos gráficamente con las trayectorias que da Euler. ¿Qué observas?\n",
37 | "\n",
38 | "(v) Calcula numéricamente cómo varía la cantidad \"conservada\" a lo largo de una trayectoria calculada con Euler. ¿Qué ocurre?"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "metadata": {},
45 | "outputs": [],
46 | "source": []
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "# El método de Euler-Cromer"
53 | ]
54 | },
55 | {
56 | "cell_type": "markdown",
57 | "metadata": {},
58 | "source": [
59 | "Un cambio aparentemente insignificativo al método numérico puede dar resultados mucho mejores para ciertas clases de sistema.\n",
60 | "\n",
61 | "En el llamado método de Euler-Cromer, actualizamos\n",
62 | "*primero* la velocidad, y utilizamos esta *nueva* velocidad para actualizar la posición en las reglas usuales del método de Euler."
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "#### Ejercicio 2\n",
70 | "\n",
71 | "(i) Aplica el método de Euler-Cromer al oscilador armónico. [Haz una versión nueva de tu código de Euler para 2 variables.] Dibuja trayectorias desde varios puntos iniciales en un solo plano fase, junto con las curvas de nivel y campo vectorial correspondientes.\n",
72 | "\n",
73 | "(ii) Encuentra la tasa de convergencia de Euler-Cromer a la solución exacta cuando el tamaño $h$ de un paso converge a cero. ¿Cómo se compara con la tasa de convergencia del método de Euler?"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": null,
79 | "metadata": {},
80 | "outputs": [],
81 | "source": []
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "#### Ejercicio 3\n",
88 | "\n",
89 | "(i) Escribe la EDO que describe un péndulo simple. ¿Cuál cantidad se conserva?\n",
90 | "\n",
91 | "(ii) Aplica Euler-Cromer a este sistema y dibuja bastantes trayectorias en el espacio fase, junto con curvas de nivel y el campo vectorial correspondientes.\n",
92 | "\n",
93 | "(iii) Dibuja el comportamiento de las dos componentes en función del tiempo. \n",
94 | "\n",
95 | "(iv) Resume el comportamiento físico del sistema.\n",
96 | "\n",
97 | "(v) Hay regiones (puntos, curvas, etc.) especiales en el espacio fase? ¿Cuáles son, y a qué corresponden físicamente?\n"
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {},
104 | "outputs": [],
105 | "source": []
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "# El método de Euler para atrás"
112 | ]
113 | },
114 | {
115 | "cell_type": "markdown",
116 | "metadata": {},
117 | "source": [
118 | "Tomemos otro punto de vista de los métodos numéricos para las EDOs.\n",
119 | "\n",
120 | "Al integrar los dos lados de la EDO\n",
121 | "\n",
122 | "$$\\dot{x}(t) = f(x(t), t)$$\n",
123 | "\n",
124 | "con respecto al tiempo para $t$ entre $t_0$ y $t_0+h$, obtenemos\n",
125 | "\n",
126 | "$$x(t_0+h) - x(t_0) = \\int_{t_0}^{t_0+h} f(x(t'), t') \\, dt'.$$\n",
127 | "\n",
128 | "Por lo tanto, podemos intentar aplicar los métodos numéricos que ya vimos para calcular integrales definidas a este problema."
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "#### Ejercicio 4\n",
136 | "\n",
137 | "(i) ¿A cuál método de integración numérica corresponde el método de Euler? - es decir, ¿cómo se aproxima la función $f$ adentro de la integral?\n",
138 | "\n",
139 | "(ii) Supón (para simplicidad) que $f$ no depende explícitamente de $t$ y escribe una fórmula analítica de cómo sería un paso del método del trapecio a la integral para encontrar una ecuación para $x(t_0 + h)$. ¿Qué *tipo de* ecuación resulta?\n",
140 | "\n",
141 | "(iii) ¿Cuál método numérico podemos aplicar para resolver esta ecuación?\n",
142 | "\n",
143 | "(iv) Implementa esto y pruébalo. Compara los resultados con los del método de Euler. ¿Converge más rápido?\n",
144 | "\n",
145 | "(v) ¿Cómo se puede aplicar para sistemas con dos variables?"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {},
152 | "outputs": [],
153 | "source": []
154 | }
155 | ],
156 | "metadata": {
157 | "kernelspec": {
158 | "display_name": "Julia 1.0.0",
159 | "language": "julia",
160 | "name": "julia-1.0"
161 | },
162 | "language_info": {
163 | "file_extension": ".jl",
164 | "mimetype": "application/julia",
165 | "name": "julia",
166 | "version": "1.0.1"
167 | },
168 | "toc": {
169 | "colors": {
170 | "hover_highlight": "#DAA520",
171 | "running_highlight": "#FF0000",
172 | "selected_highlight": "#FFD700"
173 | },
174 | "moveMenuLeft": true,
175 | "nav_menu": {
176 | "height": "66px",
177 | "width": "252px"
178 | },
179 | "navigate_menu": true,
180 | "number_sections": true,
181 | "sideBar": true,
182 | "threshold": "2",
183 | "toc_cell": false,
184 | "toc_section_display": "block",
185 | "toc_window_display": false
186 | }
187 | },
188 | "nbformat": 4,
189 | "nbformat_minor": 1
190 | }
191 |
--------------------------------------------------------------------------------
/notebooks/04. Metodos de Monte Carlo.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Métodos de Monte Carlo"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "El término \"método de Monte Carlo\" se aplica en general a cualquier método numérico que emplea números aleatorios. Las caminatas aleatorias se pueden ver como un tipo de método de Monte Carlo.\n",
15 | "\n",
16 | "En este notebook, veremos dos tipos diferentes de métodos de Monte Carlo: uno para simulación estocástica de un problema físico que tiene la estocasticidad inherente; y otro para calcular una cantidad determinista (una integral).\n"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "## Decaimiento radioactivo "
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "En esta sección, haremos un modelo de decaimiento radioactivo, el cual es un proceso físico inherentemente estocástico. Este proceso se suele modelar con una ecuación diferencial ordinaria, la cual, en mi opinión, es muy poco motivada. El modelaje estocástico explica mucho mejor lo que está pasando.\n",
31 | "\n",
32 | "Supón que empecemos con $N$ núcleos radioactivos, y que en cada paso $\\delta t$ de tiempo, una proporción $p$ decaen en promedio. Podemos modelar eso como sigue."
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "#### Ejercicio 1 "
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "metadata": {},
45 | "source": [
46 | "(i) Toma $N = 100$ núcleos, y $p=0.01$. En cada paso, cada núcleo que siga sin decaerse decae con probabilidad $p$. Escribe una función para llevar a cabo la simulación por un cierto número de pasos; la función debe aceptar $N$ y $p$ como variables. \n",
47 | "\n",
48 | "En cada paso, calcula el número de núcleos que decaigan en ese paso.\n",
49 | "Devuelve el número de núcleos $N(t)$ en el tiempo $t$, para todos los $t$. \n",
50 | "\n",
51 | "(ii) Dibuja $N(t)$ en distintas corridas en una sola gráfica. ¿Qué observas? ¿Tiene sentido físico?\n",
52 | "\n",
53 | "(iii) Calcula el promedio $\\langle N \\rangle (t)$ sobre distintas corridas y dibújalo encima de tu gráfica. ¿Qué tipo de comportamiento esperas que tenga? Verifica esto al dibujar la gráfica con otro tipo de eje."
54 | ]
55 | },
56 | {
57 | "cell_type": "markdown",
58 | "metadata": {},
59 | "source": [
60 | "#### Ejercicio 2"
61 | ]
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "(i) ¿Qué es la vida media? ¿Cómo lo puedes calcular? Escribe una función para calcular la vida media para una corrida. Calcula el promedio sobre varias corridas distintas. \n",
68 | "\n",
69 | "(ii) ¿Cómo depende la vida media de $p$? Dibuja esta relación numéricamente. ¿Tiene sentido?"
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "#### Ejercicio 3\n",
77 | "\n",
78 | "(i) En promedio, para $N$ y $p$ dadas, ¿cuántos núcleos decaen en un paso?\n",
79 | "\n",
80 | "(ii) Utilizando esto, escribe una ecuación de evolución para $\\langle N \\rangle(t)$.\n",
81 | "\n",
82 | "(iii) ¿Cuál es la relación de esta ecuación con la ecuación diferencial ordinaria que se suele utilizar para modelar el decaimiento?\n",
83 | "\n",
84 | "(iv) Fija $N$ y $p$ y simula un paso de decaimiento muchas veces. Dibuja la distribución de probabilidad del número de núcleos que decae. Esta distribución se llama la **distribución binomial**. \n",
85 | "\n",
86 | "(v) Haz una visualización interactiva con `@manipulate` para poder variar $N$ y $p$."
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {},
92 | "source": [
93 | "## Calcular $\\pi$"
94 | ]
95 | },
96 | {
97 | "cell_type": "markdown",
98 | "metadata": {},
99 | "source": [
100 | "¿Cómo podemos calcular $\\pi$ numéricamente? Por supuesto Julia tiene eso integrado: al teclear `\\pi`, produce π."
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "execution_count": null,
106 | "metadata": {},
107 | "outputs": [],
108 | "source": [
109 | "π"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {},
115 | "source": [
116 | "#### Ejercicio 3"
117 | ]
118 | },
119 | {
120 | "cell_type": "markdown",
121 | "metadata": {},
122 | "source": [
123 | "(i) ¿De qué tipo es el objeto `π` en Julia? ¿Funciona correctamente en expresiones aritméticas?"
124 | ]
125 | },
126 | {
127 | "cell_type": "markdown",
128 | "metadata": {},
129 | "source": [
130 | "De no conocer el valor de $\\pi$ lo podemos calcular de diversas formas, como ya vimos.\n",
131 | "Una manera es con un método de Monte Carlo, como sigue."
132 | ]
133 | },
134 | {
135 | "cell_type": "markdown",
136 | "metadata": {},
137 | "source": [
138 | "(ii) Dibuja un círculo de radio $r=1$. Dibuja un cuadrado que lo contiene. Genera muchos puntos distribuidos uniformemente en el cuadrado y dibújalos. Dibuja los puntos que caigan adentro del círculo con otro color.\n",
139 | "\n",
140 | "(iii) Utiliza esto para determinar el área del círculo, y de ahí el valor de $\\pi$."
141 | ]
142 | },
143 | {
144 | "cell_type": "markdown",
145 | "metadata": {},
146 | "source": [
147 | "## Calcular integrales"
148 | ]
149 | },
150 | {
151 | "cell_type": "markdown",
152 | "metadata": {},
153 | "source": [
154 | "Este tipo de métodos se pueden ocupar para calcular otras integrales complicadas, las cuales serían difíciles o imposibles de evaluar con otros métodos. Por ejemplo:"
155 | ]
156 | },
157 | {
158 | "cell_type": "markdown",
159 | "metadata": {},
160 | "source": [
161 | "#### Ejercicio 4\n",
162 | "Considera la función complicada (patológica) $$f(x) = \\sin^2 (\\textstyle \\frac{1}{x}).$$\n",
163 | "\n",
164 | "(i) Dibuja la función para $x$ entre $-2$ y $2$.\n",
165 | "\n",
166 | "Sea $I(x) := \\int_0^x f(x') dx'$. Sabemos que $0 < I(x) < x$ para toda $x$ (¿por qué?), pero no está fácil calcular su valor, ni siquiera con los métodos numéricos estándares, debido a la naturaleza complicada de la función cerca de $x = 0$.\n",
167 | "\n",
168 | "(ii) Utiliza un método parecido al que usamos en la pregunta 2 para calcular $I(x)$ para un valor de $x$ dado. \n",
169 | "\n",
170 | "(iii) Dibuja la función $I(x)$."
171 | ]
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {},
176 | "source": [
177 | "Los métodos tipo Monte Carlo pueden ser mucho más complicados que esto, en particular para calcular integrales en dimensión alta que son simplemente imposibles de calcular de cualquier otra manera."
178 | ]
179 | }
180 | ],
181 | "metadata": {
182 | "kernelspec": {
183 | "display_name": "Julia 0.6.2",
184 | "language": "julia",
185 | "name": "julia-0.6"
186 | },
187 | "language_info": {
188 | "file_extension": ".jl",
189 | "mimetype": "application/julia",
190 | "name": "julia",
191 | "version": "0.6.2"
192 | }
193 | },
194 | "nbformat": 4,
195 | "nbformat_minor": 1
196 | }
197 |
--------------------------------------------------------------------------------
/notebooks/06. Raices de funciones uni-dimensionales.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Raíces de funciones uni-dimensionales"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "En este notebook, investigaremos algunos algoritmos para encontrar **raíces** de funciones uni-dimensionales, utilizando métodos iterativos. Esto es un problema que ocurre por todos lados en la física, por ejemplo para el pozo cuadrado en mecánica cuántica, o para encontrar el valor máximo de una función.\n",
15 | "\n",
16 | "Recuerda que $x^*$ es una raíz (o cero) de la función $f$ si $f(x^*) = 0$. Como sabemos, en general las raíces de una función no se pueden encontrar de manera analítica, excepto para funciones $f$ que sean polinomios de grado $\\le 4$.\n",
17 | "\n",
18 | "Por lo tanto, para encontrar raíces tendremos que utilizar algoritmos iterativos.\n",
19 | "Recuerda que un algoritmo iterativo tiene la forma general\n",
20 | "\n",
21 | "$$x_{n+1} := f(x_n),$$\n",
22 | "\n",
23 | "y consiste en comenzar en una *adivinianza* inicial $x_0$ y generar una secuencia $x_1 := f(x_0)$; $x_2 := f(x_1)$, etc.\n",
24 | "Si diseñamos correctamente el algoritmo, la esperanza es que la secuencia $(x_n)_{n=1}^\\infty$ converja a alguna raíz $x^*$ con $f(x^*) = 0$, es decir que $f(x_n) \\to 0$ cuando $n \\to \\infty$."
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {},
30 | "source": [
31 | "Dado que no podemos llevar a cabo la iteración un número infinito de veces, se corta la iteración después de un cierto número de pasos, para dar una solución *aproximada*, que se encuentra dentro de cierta *tolerancia* del resultado teórico exacto $x^*$. Por lo tanto, cualquier algoritmo iterativo requiere una condición de terminación."
32 | ]
33 | },
34 | {
35 | "cell_type": "markdown",
36 | "metadata": {},
37 | "source": [
38 | "# Raíces de funciones: Bisección"
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {},
44 | "source": [
45 | "Un primer método para encontrar una raíz es el **método de bisección**.\n",
46 | "Dada una función continua $f$, una condición suficiente (pero no necesaria) para que *exista* una raiz en un intervalo dado $[a, b]$ es que $F$ cambie de signo en el intervalo, es decir, que $f(a)$ y $f(b)$ tengan signos opuestos. Si ocurre esto, entonces el teorema del valor intermedio nos dice que se sigue que $f$ sí tiene al menos una raíz en $[a, b]$."
47 | ]
48 | },
49 | {
50 | "cell_type": "markdown",
51 | "metadata": {},
52 | "source": [
53 | "#### Ejercicio 1\n",
54 | "\n",
55 | "La idea del método de bisección es adivinar que el punto medio del intervalo $[a, b]$ sea una primera aproximación para la raíz. Escribamos una función `bisección` que implemente este método, que toma como argumento la función $f$ y los extremos `a` y `b`.\n",
56 | "\n",
57 | "(i) Define una función `punto_medio` que tome $a$ y $b$ y calcule el punto medio entre ellos. Verifica que tu definición sea correcto en algunos casos.\n",
58 | "\n",
59 | "(ii) Sea $c$ el punto medio de $[a, b]$. Esto divide el intervalo original en dos partes. Es posible (aunque improbable) que $c$ ya es la raíz, en cuyo caso ya podemos terminar la función y regresar la raíz que hemos encontrado. ¿Cómo se checa si ya es la raíz? Si no, ¿cómo podemos saber en cuál de los dos sub-intervalos cae la raíz? Impleméntalo. \n",
60 | "\n",
61 | "(iii) Define un algoritmo iterativo al repitir estos pasos hasta que encuentres la raíz con cierta tolerancia. [Pista: Para la siguiente vuelta del bucle, deberás tener un nuevo intervalo `[a, b]`.\n",
62 | "Puedes utilizar una expresión de la forma `(e, f) = (g, h)` para copiar el valor de `g` a la variable `e` y el valor de `h` a la variable `f`.]\n",
63 | "\n",
64 | "(iv) La función debe regresar la raíz que encontró, así como un vector de todos los iterados."
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": null,
70 | "metadata": {},
71 | "outputs": [],
72 | "source": []
73 | },
74 | {
75 | "cell_type": "markdown",
76 | "metadata": {},
77 | "source": [
78 | "#### Ejercicio 2\n",
79 | "\n",
80 | "(i) Aplica tu función `bisección` para encontrar la raíz cuadrada positiva de $2$. Para hacerlo, tendrás que escoger (a mano) intervalos iniciales que cumplan con la condición de cambio de signo. \n",
81 | "\n",
82 | "(ii) Define la distancia $d_n := x_n - x^*$, donde $x^*$ es la raíz. Dibuja $d_n$ como función del paso $n$. ¿Qué tan rápidamente converge $d_n$ a $0$? [Pista: Dibuja la gráfica con distintos tipos de escalas para entender la forma funcional de la convergencia.]\n",
83 | "\n",
84 | "(iii) Encuentra la solución de la ecuación $\\sin(x) = x$ utilizando bisección. ¿Qué tan rápidamente se acercan los iterados $x_n$ a la solución en este caso?"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": null,
90 | "metadata": {},
91 | "outputs": [],
92 | "source": []
93 | },
94 | {
95 | "cell_type": "markdown",
96 | "metadata": {},
97 | "source": [
98 | "# El algoritmo Babilónico"
99 | ]
100 | },
101 | {
102 | "cell_type": "markdown",
103 | "metadata": {},
104 | "source": [
105 | "Un ejemplo de un algoritmo sorprendente es el *algoritmo Babilónico* (o de Herón) para calcular la raiz cuadrada $\\sqrt{y}$ de un número real $y$. Una forma de este algoritmo se utiliza a menudo para calcular la raíz cuadrada en las computadoras.\n",
106 | "\n",
107 | "Para un algoritmo, siempre necesitamos una *idea*, que toma una adivinanza $x_n$ y produce una (probablemente) mejor, $x_{n+1}$. La idea del algoritmo Babilónico es la siguiente."
108 | ]
109 | },
110 | {
111 | "cell_type": "markdown",
112 | "metadata": {},
113 | "source": [
114 | "#### Ejercicio 3\n",
115 | "\n",
116 | "(i) ¿De cuál ecuación en $x$ es raíz el número $x^* = \\sqrt{y}$? ¿Cuál otra solución de esta ecuación hay?\n",
117 | "\n",
118 | "(ii) Dada una adivinanza $x_n$, es posible (pero improbable) que $x_n$ ya sea exactamente $\\sqrt{y}$. ¿Cómo lo puedes verificar, sin utilizar (por supuesto) alguna función en Julia que calcule la raíz cuadrada? Escribe el código correspondiente.\n",
119 | "\n",
120 | "(iii) Si $x_n$ no es raíz, demuestra con papel que $\\frac{y}{x_n}$ se encuentra *del lado opuesto de $\\sqrt{y}$ que $x_n$* sobre la recta real. [Pista: Hay dos casos que considerar.]\n",
121 | "\n",
122 | "(iv) Así, tenemos dos valores que se encuentran por dos lados diferentes de $\\sqrt{y}$. ¿Cuál sería una mejor adivinanza para $x_{n+1}$? Impleméntalo.\n",
123 | "\n",
124 | "(v) Utiliza esta idea para escribir una función que calcule $\\sqrt{y}$ para una $y$ dada.\n",
125 | "\n",
126 | "(vi) ¿Qué tan rápido converge a la raíz cuadrada? Grafícalo. ¿Cómo se compara con el método de bisección?"
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": null,
132 | "metadata": {},
133 | "outputs": [],
134 | "source": []
135 | }
136 | ],
137 | "metadata": {
138 | "kernelspec": {
139 | "display_name": "Julia 0.6.4",
140 | "language": "julia",
141 | "name": "julia-0.6"
142 | },
143 | "language_info": {
144 | "file_extension": ".jl",
145 | "mimetype": "application/julia",
146 | "name": "julia",
147 | "version": "0.6.4"
148 | }
149 | },
150 | "nbformat": 4,
151 | "nbformat_minor": 1
152 | }
153 |
--------------------------------------------------------------------------------
/notebooks/07. El metodo de Newton.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# El método de Newton"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "El método de Newton (también llamado algoritmo de Newton-Raphson) constituye otro método numérico iterativo para encontrar raíces de una función $f$. \n",
15 | "\n",
16 | "Requiere más información, a saber la **derivada** $f'$, pero a cambio suele funcionar mucho mejor. Derivaremos e implementaremos el método en este notebook. Por el momento, supondremos que el usuario provea también la derivada analítica de la función $f$, como otro argumento `df`; posteriormente en el curso, veremos cómo calcular derivadas numéricamente."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "#### Ejercicio 1 (Esta pregunta se lleva a cabo con papel y pluma)\n",
24 | "\n",
25 | "Considera una función $f: \\mathbb{R} \\to \\mathbb{R}$.\n",
26 | "Supón que $x_0$ es una adivinanza inicial de una raíz, y que $x^*$ es la raíz exacta pero \n",
27 | "desconocida. Sigue los siguientes pasos para derivar el método de Newton.\n",
28 | "\n",
29 | "(i) Supón que $x_0$ es suficientemente cercana a $x^*$. Define $\\delta$ como la distancia (con signo) de $x_0$ desde $x^*$. \n",
30 | "\n",
31 | "(ii) Escribe la ecuación que corresponde a que $x^*$ sea una raíz de la función, y exprésala en términos de $\\delta$. \n",
32 | "\n",
33 | "(iii) Desarrolla esta ecuación en una serie de Taylor a primer orden alrededor de $x_0$, para encontrar un valor aproximado de $\\delta$.\n",
34 | "\n",
35 | "(iv) Así encuentra una ecuación para la siguiente aproximación a la raíz, $x_1 = x_0 + \\delta$. \n",
36 | "\n",
37 | "(v) Por lo tanto, dada una adivinanza, podemos obtener otra que esperemos esté mejor (más cerca a la raíz). Escribe la misma ecuación que obtuviste en (iv), pero ahora para $x_{n+1}$ en términos de $x_n$. Esto es la regla general para el método de Newton."
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {},
44 | "outputs": [],
45 | "source": []
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "#### Ejercicio 2\n",
52 | "\n",
53 | "Demuestra que el método Babilónico es un caso especial del método de Newton. [Pista: ¿Para cuál función $f$?]"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": null,
59 | "metadata": {},
60 | "outputs": [],
61 | "source": []
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "#### Ejercicio 3"
68 | ]
69 | },
70 | {
71 | "cell_type": "markdown",
72 | "metadata": {},
73 | "source": [
74 | "(i) Escribe una función que implementa el método de Newton. Puedes suponer que el usuario provea tanto la función `f` como su derivada `df` como argumentos a la función `newton`, así como la condición inicial `x0`. [Posteriormente veremos cómo calcular derivadas con la computadora.] [NB: Si prefieres, puedes utilizar `f′` como nombre de la derivada, al teclear `f\\prime`. *No* se puede utilizar el apóstrofe aquí.]"
75 | ]
76 | },
77 | {
78 | "cell_type": "markdown",
79 | "metadata": {},
80 | "source": [
81 | "(ii) Para la función $x \\mapsto x^2$, dibuja la dinámica del método de Newton, dada una función $f$ y una condición inicial $x_0$. Para hacerlo, dibuja una recta entre cada $(x_n, 0)$ y $(x_n, f(x_n))$, así como entre $(x_n, f(x_n)$ y $(x_{n+1}, 0)$. Hazlo interactivo con `Interact.jl` (dibujando los primeros $n$ pasos y cambiando $n$). Viendo la figura, interpreta geométricamente lo que está haciendo el método de Newton."
82 | ]
83 | },
84 | {
85 | "cell_type": "markdown",
86 | "metadata": {},
87 | "source": [
88 | "(iii) Aplica el método de Newton para encontrar raíces de distintas funciones. ¿Qué ocurre si empiezas con distintas condiciones iniciales?"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": null,
94 | "metadata": {},
95 | "outputs": [],
96 | "source": []
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "#### Ejercicio 4"
103 | ]
104 | },
105 | {
106 | "cell_type": "markdown",
107 | "metadata": {},
108 | "source": [
109 | "¿Qué tan rápido converge el método cuando esté cerca de una raíz? Corre el algoritmo utilizando `BigFloat`s para averiguarlo y graficar la convergencia. ¿El método de Newton es mejor que bisección? ¿Por qué (no)?"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": null,
115 | "metadata": {},
116 | "outputs": [],
117 | "source": []
118 | },
119 | {
120 | "cell_type": "markdown",
121 | "metadata": {},
122 | "source": [
123 | "#### Ejercicio 5"
124 | ]
125 | },
126 | {
127 | "cell_type": "markdown",
128 | "metadata": {},
129 | "source": [
130 | "Sin embargo, es posible que el método de Newton *no converja*, como sigue."
131 | ]
132 | },
133 | {
134 | "cell_type": "markdown",
135 | "metadata": {},
136 | "source": [
137 | "(i) El mismo código del método de Newton debería funcionar con números complejos. Utilízalo para encontrar raíces de la función $f(z) = z^3 -1$ **en el plano complejo**.\n",
138 | "[Nota que la parte imaginaria $i = \\sqrt{-1}$ se escribe como `im` en Julia. Hay funciones `real` e `imag` para extraer las partes reales e imaginarias de un número complejo.]\n",
139 | "\n",
140 | "(ii) Escribe una función que verifica si convergió después de un número dado de iterados. Si sí, regresa la parte imaginaria de la raíz a la cual convergió.\n",
141 | "\n",
142 | "(iii) Haz el cálculo para una malla de condiciones iniciales en el plano complejo alrededor de $0$. Dibuja la matriz correspondiente. ¿Qué observas? [Pista: Puedes utilizar una comprehensión de arreglo 2-dimensional.]"
143 | ]
144 | },
145 | {
146 | "cell_type": "code",
147 | "execution_count": null,
148 | "metadata": {},
149 | "outputs": [],
150 | "source": []
151 | },
152 | {
153 | "cell_type": "markdown",
154 | "metadata": {},
155 | "source": [
156 | "#### Ejercicio 6\n",
157 | "\n",
158 | "Considera ahora cómo encontrar raíces de un sistema de ecuaciones, escrito en forma vectorial:\n",
159 | "\n",
160 | "$$\\mathbf{f}(\\mathbf{x}) = \\mathbf{0}.$$\n",
161 | "\n",
162 | "Repite un desarrollo siguiendo la pauta del ejercicio **1** en este contexto.\n",
163 | "¿Qué es lo que cambia? ¿Qué tipo de operación numérica necesitaríamos para llevar a cabo el método de Newton en este nuevo contexto? [No es necesario que lo implementes por el momento -- opcional.]"
164 | ]
165 | },
166 | {
167 | "cell_type": "code",
168 | "execution_count": null,
169 | "metadata": {},
170 | "outputs": [],
171 | "source": []
172 | }
173 | ],
174 | "metadata": {
175 | "kernelspec": {
176 | "display_name": "Julia 0.6.2",
177 | "language": "julia",
178 | "name": "julia-0.6"
179 | },
180 | "language_info": {
181 | "file_extension": ".jl",
182 | "mimetype": "application/julia",
183 | "name": "julia",
184 | "version": "0.6.2"
185 | },
186 | "toc": {
187 | "colors": {
188 | "hover_highlight": "#DAA520",
189 | "running_highlight": "#FF0000",
190 | "selected_highlight": "#FFD700"
191 | },
192 | "moveMenuLeft": true,
193 | "nav_menu": {
194 | "height": "29px",
195 | "width": "251px"
196 | },
197 | "navigate_menu": true,
198 | "number_sections": true,
199 | "sideBar": true,
200 | "threshold": "2",
201 | "toc_cell": false,
202 | "toc_section_display": "block",
203 | "toc_window_display": false
204 | }
205 | },
206 | "nbformat": 4,
207 | "nbformat_minor": 2
208 | }
209 |
--------------------------------------------------------------------------------
/notebooks/08. Diferencias finitas.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Diferencias finitas: cálculo numérico de derivadas"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "En el último notebook, vimos que el método de Newton requiere utilizar la derivada de una función.\n",
15 | "En este notebook, veremos una manera (no necesariamente la mejor) de calcular derivadas de funciones de forma numérica: las llamadas **diferencias finitas**."
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "## Derivadas de funciones uni-dimensionales"
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "#### Ejercicio 1\n",
30 | "\n",
31 | "Considera una función uni-dimensional $f: \\mathbb{R} \\to \\mathbb{R}$, y supón que es suficientemente diferenciable para que las derivadas que tomemos estén definidas [por ejemplo, si $f$ es de clase $C^2$].\n",
32 | "\n",
33 | "(i) Escribe, usando notación LaTeX, la definición de la derivada $f'(a)$ de $f$ en el punto $a$, como límite cuando la variable $h$ tiende a $0$.\n",
34 | "\n",
35 | "Desgraciadamente, **no podemos llevar a cabo el proceso de límite en la computadora**: un límite es algo **continuo**, mientras que la computadora maneja cantidades **discretas**.\n",
36 | "\n",
37 | "(ii) ¿Cuál solución se te ocurre para esto en términos de la variable $h$? \n",
38 | "\n",
39 | "La expresión $f(a+h) - f(a)$ se llama una **diferencia para adelante** (\"forward difference\"), y cuando lo dividimos por un valor fijo de $h$ se llama un **cociente de diferencias** (\"difference quotient\"). \n",
40 | "\n",
41 | "(iii) ¿Geométricamente, a qué corresponde una diferencia de este tipo? ¿Y un cociente de diferencias?"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": null,
47 | "metadata": {},
48 | "outputs": [],
49 | "source": []
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "#### Ejercicio 2\n",
56 | "\n",
57 | "(i) Escribe una función que implemente una diferencia para adelante para una función $f$, punto $a$ y paso $h$ dadas.\n",
58 | "\n",
59 | "(ii) Para distintas funciones $f$, grafica la función $f$, su derivada analítica $f'$, y la aproximación a $f'$ utilizando diferencias finitas con distintos pasos $h$.\n",
60 | "\n",
61 | "(iii) Calcula el error desde el valor analítico que se comete al utilizar la aproximación de la derivada al tomar una $f$ y $a$ dadas, y al variar $h$.\n",
62 | "Puedes utilizar la función `logspace` para que los valores de $h$ estén espaciados de forma logarítmica. Hazlo para diferentes funciones y para valores de $h$ tan chicos como $10^{-15}$. (¡Escribe una función que haga el cálculo!) ¿Qué podría causar este efecto?\n",
63 | "\n",
64 | "(iv) ¿Para qué clase de funciones será el resultado exacto? Demuéstralo gráficamente. Así, qué tipo de **aproximación local** de la función estamos usando? "
65 | ]
66 | },
67 | {
68 | "cell_type": "markdown",
69 | "metadata": {},
70 | "source": [
71 | "#### Ejercicio 3 \n",
72 | "\n",
73 | "(i) Desarrolla $f(a + h)$ en una serie de Taylor con término complementario de Lagrange. Así, rederiva la expresión aproximada que ya obtuviste para la derivada, pero ahora con información *analítica* sobre **el tamaño del error** que cometes cuando utilizas esta aproximación (asintóticamente cuando $h \\to 0$). Si el error va como $C.h^n$, con $C$ una constante, entonces escribimos $\\mathcal{O}(h^n)$. \n",
74 | "\n",
75 | "(ii) Verifica que coinicide con lo que encontraste numéricamente."
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "metadata": {},
82 | "outputs": [],
83 | "source": []
84 | },
85 | {
86 | "cell_type": "markdown",
87 | "metadata": {},
88 | "source": [
89 | "#### Ejercicio 4\n",
90 | "\n",
91 | "(i) Una mejor aproximación (¿a qué nos referimos con eso?) es la **diferencia centrada**: expande $f(a+h)$ y $f(a - h)$ en series de Taylor separadas. Así, deriva una mejor aproximación a la primera derivada. Calcula su error y chécalo numéricamente. ¿Para qué tipo de funciones es exacta? \n",
92 | "\n",
93 | "(ii) Encuentra una aproximación para la segunda derivada y encuentra su error; chécalo numéricamente. "
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": null,
99 | "metadata": {},
100 | "outputs": [],
101 | "source": []
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "## Funciones multi-dimensionales "
108 | ]
109 | },
110 | {
111 | "cell_type": "markdown",
112 | "metadata": {},
113 | "source": [
114 | "Ahora consideremos una función $f: \\mathbb{R}^2 \\to \\mathbb{R}$ y $g: \\mathbb{R}^2 \\to \\mathbb{R}^2$."
115 | ]
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "metadata": {},
120 | "source": [
121 | "#### Ejercicio 5\n",
122 | "\n",
123 | "(i) ¿Qué tipo de derivadas quisiéramos poder calcular para $f$ y $g$? ¿Cómo podemos utilizar lo que ya hicimos para funciones uni-dimensionales para aplicarlo directamente a $f$ y $g$?\n",
124 | "\n",
125 | "(ii) Impleméntalo y compara con funciones cuyas derivadas conoces analíticamente."
126 | ]
127 | },
128 | {
129 | "cell_type": "code",
130 | "execution_count": null,
131 | "metadata": {},
132 | "outputs": [],
133 | "source": []
134 | },
135 | {
136 | "cell_type": "markdown",
137 | "metadata": {},
138 | "source": [
139 | "## De regreso al método de Newton"
140 | ]
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "#### Ejercicio 6\n",
147 | "\n",
148 | "Utiliza una diferencia finita, con una $h$ pequeña, para aproximar la derivada en el método de Newton. ¿Cómo afecta el utilizar una aproximación de la derivada, en lugar del valor exacto, en la tasa de convergencia? Compara los resultados al utilizar los dos tipos de diferencias finitas (para adelante y centrada)."
149 | ]
150 | },
151 | {
152 | "cell_type": "code",
153 | "execution_count": null,
154 | "metadata": {},
155 | "outputs": [],
156 | "source": []
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "## Diferencias finitas con pasos complejos"
163 | ]
164 | },
165 | {
166 | "cell_type": "markdown",
167 | "metadata": {},
168 | "source": [
169 | "\n",
170 | "\n",
171 | "Una alternativa interesante es el utilizar la fórmula\n",
172 | "\n",
173 | "$$f'(a) \\simeq \\frac{\\mathrm{Im}[f(a + ih)]}{h},$$\n",
174 | "\n",
175 | "donde $i=\\sqrt{-1}$ y utilizamos evaluaciones complejas de la función real $f$; $\\mathrm{Im}$ denota la parte imaginaria."
176 | ]
177 | },
178 | {
179 | "cell_type": "markdown",
180 | "metadata": {},
181 | "source": [
182 | "#### Ejercicio 7\n",
183 | "\n",
184 | "(i) Implementa esto y verifica que puedes utilizar valores de $h$ ridículamente pequeñas.\n",
185 | "\n",
186 | "(ii) Encuentra el tamaño del error numérico en función de $h$.\n",
187 | "\n",
188 | "(iii) Utiliza un desarrollo de Taylor para encontrar el tamaño del error."
189 | ]
190 | },
191 | {
192 | "cell_type": "code",
193 | "execution_count": null,
194 | "metadata": {},
195 | "outputs": [],
196 | "source": []
197 | }
198 | ],
199 | "metadata": {
200 | "kernelspec": {
201 | "display_name": "Julia 0.6.4",
202 | "language": "julia",
203 | "name": "julia-0.6"
204 | },
205 | "language_info": {
206 | "file_extension": ".jl",
207 | "mimetype": "application/julia",
208 | "name": "julia",
209 | "version": "0.6.4"
210 | }
211 | },
212 | "nbformat": 4,
213 | "nbformat_minor": 2
214 | }
215 |
--------------------------------------------------------------------------------
/notebooks/10. Integracion numerica.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Integración numérica (\"cuadratura\")"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "A menudo en la física, es necesario evaluar integrales feas. [La verdad es que casi todas las integrales son feas...] Mientras que la diferenciación es un proceso que se puede llevar a cabo de manera algorítmica, siguiendo una receta, la integración no lo es. De hecho, se puede demostrar que hay integrales que no se pueden llevar a cabo de forma analítica en términos de las funciones elementales; un ejemplo famoso, y de suma importancia, es la llamada [función error](https://es.wikipedia.org/wiki/Funci%C3%B3n_error), dada por\n",
15 | "\n",
16 | "$$\\mathrm{erf}(x) = \\frac{2}{\\sqrt{\\pi}}\\int_{0}^x e^{-t^2} \\, dt,$$\n",
17 | "\n",
18 | "la cual está estrechamente relacionada con la probabilidad de eventos para una variable aleatoria distribuida de forma normal (gaussiana)."
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "Por lo tanto, necesitamos encontrar maneras de aproximar integrales definidas, de forma numérica.\n",
26 | "\n",
27 | "Recordemos que la integral \n",
28 | "\n",
29 | "$$I(f) = \\int_a^b f(x) \\, dx$$ \n",
30 | "\n",
31 | "representa el **área debajo de la curva $y=f(x)$ entre $x=a$ y $x=b$**. Por lo tanto, la integración numérica también se llama \"cuadratura numérica\". [Ver, por ejemplo, https://es.wikipedia.org/wiki/Cuadratura_del_c%C3%ADrculo.] Por lo tanto, da una manera de aproximar numéricamente una **integral de Riemann**.\n",
32 | "\n",
33 | "Nota que la integral $I(f)$ es una función [de hecho, un \"funcional\"] **lineal** de $f$. Por lo tanto, buscaremos métodos numéricos con la misma propiedad. Siguiendo la pista que vimos en el notebook sobre la interpolación, pensamos en **discretizar** (por supuesto). Una forma de hacerlo es evaluar la función $f$ en $N+1$ **nodos** $x_j$, y buscaremos **pesos** $\\alpha_i$ que den una aproximación a la integral de la forma\n",
34 | "\n",
35 | "$$Q(f) = \\sum_{i=0}^N \\alpha_j \\, f(x_j), \\qquad (*)$$\n",
36 | "\n",
37 | "es decir como una suma ponderada de los valores de la función en los nodos."
38 | ]
39 | },
40 | {
41 | "cell_type": "markdown",
42 | "metadata": {},
43 | "source": [
44 | "#### Ejercicio 1\n",
45 | "\n",
46 | "Un caso particular es una $f$ que sea **monótona**, por ejemplo el integrando $f$ que aparece en la función $\\mathrm{erf}$, dado por $f(x) = e^{-x^2/2}$. \n",
47 | "\n",
48 | "(i) La idea más natural [pero ¡no necesariamente mejor!] es dividir el intervalo $[0, x]$ en $N$ intervalos iguales de longitud $h=1/N$. Dada una $x$ y una $N$, dibuja la función, así como líneas verticales punteadas [dibujar con `linestyle=:dash`] en los nodos.\n",
49 | "Grafícalo.\n",
50 | "\n",
51 | "(ii) La idea más sencilla es aproximar la función $f$ en un intervalo dado con una recta horizontal. \n",
52 | "¿Cómo podríamos calcular tanto una cota inferior como una cota superior, suponiendo que $f$ es monótona? Exprésalos en la forma de la ecuación (*). Grafícalos.\n",
53 | "\n",
54 | "Escribe una función que calcule estas áreas dadas $f$ (monótona), $a$, $b$ y $N$.\n",
55 | "\n",
56 | "(iii) ¿Cuál es la tasa de convergencia hacia el resultado exacto cuando $N \\to \\infty$ para $f(x) = e^{-x^2/2}$? [Pista: La función $\\mathrm{erf}$ en Julia se llama... `erf`. Se encuentra en el paquete `SpecialFunctions.jl`.]"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": null,
62 | "metadata": {},
63 | "outputs": [],
64 | "source": []
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "metadata": {},
69 | "source": [
70 | "#### Ejercicio 2\n",
71 | "\n",
72 | "(i) Dibuja las cotas inferior y superior para $\\mathrm{erf}(x)$, como función de $x$.\n",
73 | "\n",
74 | "(ii) Encuentra una cota superior analítica para $\\int_{t=x}^\\infty e^{-t^2/2} dt$. [Pista: puedes utilizar, por ejemplo, $f(t) \\le e^{-t}$ para $t$ suficientemente grande. [¿Qué tan grande?].] \n",
75 | "\n",
76 | "(iii) Así, encuentra cotas para $\\lim_{x \\to \\infty} \\mathrm{erf}(x)$. ¿Cuál valor analítica tiene? Así, podemos encontrar cotas para integrales con rango infinito."
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {},
83 | "outputs": [],
84 | "source": []
85 | },
86 | {
87 | "cell_type": "markdown",
88 | "metadata": {},
89 | "source": [
90 | "#### Ejercicio 3\n",
91 | "\n",
92 | "(i) Para funciones $f$ que no sean monótonas, ¿qué necesitaríamos poder hacer para encontrar cotas inferiores y superiores para $\\int_a^b f$? [Esto es bastante más difícil. Se puede lograr utilizando la **aritmética de intervalos**, por ejemplo.]\n",
93 | "\n",
94 | "(i) Después de una recta horizontal, ¿cuál es la siguiente forma más natural de aproximar a la función $f$ adentro de un intervalo dado? ¿A qué aproximación de la integral lleva, expresada en la forma de la ecuación (*)? Grafícalo. Este método se llama el **método del trapecio**.\n",
95 | "\n",
96 | "(ii) Impleméntalo. Nota que este método funciona para *cualquier* función $f$, sin que tenga que ser monótona. \n",
97 | "(iii) Aplícalo a algunas funciones cuyas integrales conoces y encuentra la \n",
98 | "tasa de convergencia. ¿Cómo se compara con el método de la pregunta [1]?"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "metadata": {},
105 | "outputs": [],
106 | "source": []
107 | },
108 | {
109 | "cell_type": "markdown",
110 | "metadata": {},
111 | "source": [
112 | "#### Ejercicio 4\n",
113 | "\n",
114 | "Lo que estamos haciendo es aproximar la función $f$ en cada sub-intervalo. La siguiente aproximación es una cuadrática, la cual lleva a una regla llamada el **método de Simpson**.\n",
115 | "\n",
116 | "(i) Utiliza el método de interpolación de Lagrange para encontrar una expresión analítica para un polinomio que interpola la función $f$ en tres puntos: $x_i$, $x_{i+1}$, y el punto medio $m$ entre $x_i$ y $x_{i+1}$.\n",
117 | "\n",
118 | "(ii) Integra este polinomio para encontrar $\\int_{x_i}^{x_{i+1}} f(t) \\, dt$. \n",
119 | "\n",
120 | "(iii) Así, encuentra una aproximación para $\\int_{a}^{b} f(t) \\, dt$.\n",
121 | "\n",
122 | "(iv) Encuentra numéricamente la tasa de convergencia del método."
123 | ]
124 | },
125 | {
126 | "cell_type": "code",
127 | "execution_count": null,
128 | "metadata": {},
129 | "outputs": [],
130 | "source": []
131 | },
132 | {
133 | "cell_type": "markdown",
134 | "metadata": {},
135 | "source": [
136 | "## Métodos más avanzados "
137 | ]
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {},
142 | "source": [
143 | "Hay métodos muy precisos, por ejemplo la llamada **cuadratura de Gauss**, que funcionan si la función es suave. En estos métodos, se puede utilizar la interpolación de Lagrange para aproximar una función con un polinomio *globalmente* en todo el rango $[a,b]$, y luego ¡se integra el polinomio! La dificultad es en escoger dónde deberían ser los nodos $x_i$.\n",
144 | "\n",
145 | "[¡Esto podría ser un proyecto final interesante!]\n",
146 | "\n",
147 | "Estos métodos se pueden extender a integrales en más dimensiones."
148 | ]
149 | },
150 | {
151 | "cell_type": "code",
152 | "execution_count": null,
153 | "metadata": {},
154 | "outputs": [],
155 | "source": []
156 | }
157 | ],
158 | "metadata": {
159 | "kernelspec": {
160 | "display_name": "Julia 0.6.2",
161 | "language": "julia",
162 | "name": "julia-0.6"
163 | },
164 | "language_info": {
165 | "file_extension": ".jl",
166 | "mimetype": "application/julia",
167 | "name": "julia",
168 | "version": "0.6.2"
169 | }
170 | },
171 | "nbformat": 4,
172 | "nbformat_minor": 1
173 | }
174 |
--------------------------------------------------------------------------------
/notebooks/02. Caminatas aleatorias II.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Análisis de caminatas aleatorias"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Una tarea fundamental en la física es el análisis de datos. \n",
15 | "A menudo, un experimento produce una cierta cantidad de datos correspondientes a la medición de ciertas cantidades. Se repite una medición varias veces para asegurar que sea reproducible, y luego se llevan a cabo análisis de estos datos.\n",
16 | "\n",
17 | "Podemos llevar a cabo el mismo proceso con los datos provenientes de un **experimento numérico**, o sea, una simulación.\n",
18 | "\n",
19 | "Retomemos nuestra simulación de caminatas aleatorias del notebook 1 y recordemos algo de estadística para poder caracterizar a las caminatas (y para finalmente entender la estadística...)."
20 | ]
21 | },
22 | {
23 | "cell_type": "markdown",
24 | "metadata": {},
25 | "source": [
26 | "## Datos"
27 | ]
28 | },
29 | {
30 | "cell_type": "markdown",
31 | "metadata": {},
32 | "source": [
33 | "Pensemos en una caminata aleatoria como el experimento. Al repetir varias veces la caminata, saldrán datos diferentes. ¿Cómo podemos caracterizar estos datos?"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "#### Ejercicio 1"
41 | ]
42 | },
43 | {
44 | "cell_type": "markdown",
45 | "metadata": {},
46 | "source": [
47 | "(i) Escribe una función `caminatas` para simular la dinámica de $N$ caminatas aleatorias para un tiempo total $T$. Sigue los pasos siguientes.\n",
48 | "\n",
49 | "1. Crea un vector llamado `xs` de enteros ceros de longitud $N$ con la función `zeros`. [Pista: Utiliza `?zeros` para ver la documentación de la función.]\n",
50 | "\n",
51 | "\n",
52 | "2. Haz una función `paso!` que acepte como argumentos `xs` e `i` y lleva a cabo un paso del caminante número $i$. [Puedes acceder a la entrada número `i` del vector `xs` con `xs[i]`.]\n",
53 | "\n",
54 | "\n",
55 | "3. Haz una función `paso!` (mismo nombre) que acepte sólo el argumento `xs` y lleva a cabo un paso de todos los caminantes.\n",
56 | "[Pista: La función `length` nos dice cuántos elementos contiene un `Vector`.]\n",
57 | "\n",
58 | "\n",
59 | "4. Haz la función `caminatas`. Guarda el vector de `xs` en cada paso en un vector nuevo `posiciones`. Tendrás que utilizar la función `copy` para copiar `xs`. (¿Qué ocurre si no lo haces?)\n",
60 | "La función regresa todos los datos.\n",
61 | "\n",
62 | "\n",
63 | "(ii) Simula 1000 caminantes para un tiempo 100 y capta la salida de la función en una variable `posiciones`."
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "metadata": {},
69 | "source": [
70 | "## Promedios"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "La primera cosa que se nos debe ocurrir es sacar el **promedio** de los datos. Podemos pensar en calcular el promedio en cada tiempo."
78 | ]
79 | },
80 | {
81 | "cell_type": "markdown",
82 | "metadata": {},
83 | "source": [
84 | "#### Ejercicio 2"
85 | ]
86 | },
87 | {
88 | "cell_type": "markdown",
89 | "metadata": {},
90 | "source": [
91 | "(i) Si simulas $N$ caminatas aleatorias $x_i(t)$, con $i=1, \\ldots, N$, para un tiempo total (número de pasos) $T$, ¿cómo esperas salga el promedio de todos los $x_i(t)$ con un tiempo $t$ fijo?\n",
92 | "\n",
93 | "(ii) Escribe una función `promedio` que calcule el promedio de un vector. Acepta el vector `v` como argumento y regresa el promedio.\n",
94 | "\n",
95 | "(iii) Escribe una función `promedios` que calcula los promedios de $x_i(t)$ para cada $t$. \n",
96 | "\n",
97 | "(iv) Calcula los promedios de 1000 caminantes por un tiempo 100. \n",
98 | "\n",
99 | "(v) Dibuja el promedio como función del tiempo. ¿Es lo que esperabas?"
100 | ]
101 | },
102 | {
103 | "cell_type": "markdown",
104 | "metadata": {},
105 | "source": [
106 | "## Estadística "
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "metadata": {},
112 | "source": [
113 | "Ya hemos recordado la primera cantidad estadística fundamental, el promedio, y vimos que no nos dio información tan valiosa. ¿Cuál es la siguiente cantidad importante?"
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "metadata": {},
119 | "source": [
120 | "#### Ejercicio 3\n",
121 | "\n",
122 | "(i) Escribe una función `varianza` que calcule la varianza de un vector `v`.\n",
123 | "\n",
124 | "(ii) Escribe una función que calcule las varianzas de las $x_i(t)$ para una $t$ dada.\n",
125 | "\n",
126 | "(iii) Dibuja la varianza como función del tiempo. Repite el cálculo varias veces y dibuja las distintas curvas en una sola gráfica. ¿Qué observas? ¿Cómo crece la varianza?\n",
127 | "\n",
128 | "(iv) Haz lo mismo para la desviación estándar."
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "### Densidad de probabilidad"
136 | ]
137 | },
138 | {
139 | "cell_type": "markdown",
140 | "metadata": {},
141 | "source": [
142 | "El promedio y la varianza son medidas burdas que caracterizan a una colección de datos. Una medida más refinada es la **distribución de probabilidad**. Una forma de caracterizarla es a través de un **histograma**, que nos proporciona la **densidad de probabilidad** o densidad de masa."
143 | ]
144 | },
145 | {
146 | "cell_type": "markdown",
147 | "metadata": {},
148 | "source": [
149 | "#### Ejercicio 4"
150 | ]
151 | },
152 | {
153 | "cell_type": "markdown",
154 | "metadata": {},
155 | "source": [
156 | "(i) ¿Qué es lo que mide un histograma?\n",
157 | "\n",
158 | "(ii) `Plots.jl` contiene una función `histograma`. Busca documentación y/o ejemplos del uso de esta función para dibujar, en una sola gráfica, algunos histogramas normalizados correspondientes a algunos tiempos $t$."
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {},
164 | "source": [
165 | "## Caminatas con sesgo"
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "metadata": {},
171 | "source": [
172 | "Las caminatas hasta ahora han brincado con la misma probabilidad a la izquierda y a la derecha. Ahora vamos a relajar esta restricción."
173 | ]
174 | },
175 | {
176 | "cell_type": "markdown",
177 | "metadata": {},
178 | "source": [
179 | "#### Ejercicio 5\n",
180 | "\n",
181 | "(i) Simula $N = 1000$ números aleatorios entre $0$ y $1$ con la función `rand`.\n",
182 | "\n",
183 | "(ii) Calcula la fracción de los números que salgan menores que 0.1, menores que 0.2, menores que 0.3, etc, es decir, la **probabilidad** de que salgan menores que 0.1 etc. ¿Qué observas?\n",
184 | "\n",
185 | "(iii) Así, escribe una función `mi_rand` que acepte un valor $0 \\le p \\le 1$ y genere `true` con probabilidad $p$, y `false` con probabilidad $1-p$. Para hacerlo, podrás hacer uso de un **condicional**, con la sintaxis esquemática\n",
186 | "\n",
187 | " if *condición*\n",
188 | " *haz algo*\n",
189 | " else\n",
190 | " *haz otra cosa*\n",
191 | " end\n",
192 | " "
193 | ]
194 | },
195 | {
196 | "cell_type": "markdown",
197 | "metadata": {},
198 | "source": [
199 | "#### Ejercicio 6"
200 | ]
201 | },
202 | {
203 | "cell_type": "markdown",
204 | "metadata": {},
205 | "source": [
206 | "(i) Dibuja una nube de trayectorias para distintos valores de $p$. Cada nube debe ir en una sola gráfica; las nubes con distintos valores de $p$ van en gráficas por separado.\n",
207 | "\n",
208 | "Para hacerlo, haz un bucle sobre valores de $p$.\n",
209 | "\n",
210 | "¿Qué observas?\n",
211 | "\n",
212 | "(ii) Repite las preguntas 2, 3 y 4 para caminantes que brincan con probabilidad $p$ a la izquierda y $q = 1-p$ a la derecha. ¿Qué observas?"
213 | ]
214 | }
215 | ],
216 | "metadata": {
217 | "kernelspec": {
218 | "display_name": "Julia 0.6.2",
219 | "language": "julia",
220 | "name": "julia-0.6"
221 | },
222 | "language_info": {
223 | "file_extension": ".jl",
224 | "mimetype": "application/julia",
225 | "name": "julia",
226 | "version": "0.6.2"
227 | }
228 | },
229 | "nbformat": 4,
230 | "nbformat_minor": 2
231 | }
232 |
--------------------------------------------------------------------------------
/notebooks/17. Sistemas de ecuaciones lineales.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Sistemas de ecuaciones lineales"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "En el notebook anterior, vimos que un problema de valores en la frontera, por ejemplo, el problema de Poisson, se puede expresar como un sistema de ecuaciones lineales, y, por lo tanto, se puede escribir en forma matricial como\n",
15 | "\n",
16 | "$$ \\mathsf{A} \\cdot \\mathbf{V} = \\mathbf{b},$$\n",
17 | "\n",
18 | "donde $\\mathbf{V} = (V_0, \\ldots, V_L)$ son los valores desconocidos del potencial, $\\mathsf{A}$ es una matriz proveniente de la discretización del Laplaciano usando diferencias finitas, y $\\mathbf{b}$ es un vector que combina el potencial y las condiciones en la frontera."
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "En el notebook anterior, utilizamos un método **iterativo** para resolver este sistema, pero vimos que converge lentamente a la solución. \n",
26 | "\n",
27 | "En este notebook, veremos un método **directo** (es decir, no iterativo, y que requiere un número de pasos finito para terminar el cálculo) para resolver sistemas de ecuaciones lineales, el método de **eliminación gaussiana**, que seguramente ya vieron en Álgebra Lineal."
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {},
33 | "source": [
34 | "## Eliminación gaussiana"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "Considera el sistema de ecuaciones lineales\n",
42 | "\n",
43 | "$$ \\mathsf{A} \\cdot \\mathbf{x} = \\mathbf{b}. \\qquad (1)$$\n",
44 | "\n",
45 | "Aquí, $\\mathsf{A}$ es una matriz cuadrada dada, de tamaño $n \\times n$, y $\\mathbf{b}$ es un vector dado en $\\mathbb{R}^n$. Queremos resolver esta ecuación para encontrar el vector desconocido $\\mathbf{x} \\in \\mathbb{R}^n$.\n",
46 | "\n",
47 | "Recuerda que podemos resolver este sistema utilizando el método de eliminación gaussiana, que consiste en llevar a cabo **operaciones de renglón**, tanto para la matriz $\\mathsf{A}$ como el vector $\\mathbf{b}$, para reducir $\\mathsf{A}$ a una forma triangular.\n",
48 | "\n",
49 | "[En este notebook, debes implementar los métodos numéricos \"a mano\" en la computadora, sin utilizar ningún método ni paquete de Julia ya implementado.]"
50 | ]
51 | },
52 | {
53 | "cell_type": "markdown",
54 | "metadata": {},
55 | "source": [
56 | "#### Ejercicio 1\n",
57 | "\n",
58 | "Re-escribe la ecuación (1) utilizando índices y sumas."
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {},
65 | "outputs": [],
66 | "source": []
67 | },
68 | {
69 | "cell_type": "markdown",
70 | "metadata": {},
71 | "source": [
72 | "#### Ejercicio 2\n",
73 | "\n",
74 | "Considera la ecuación $\\mathsf{U} \\cdot \\mathbf{x} = \\mathbf{c}$, en la cual $\\mathsf{U}$ es una matriz triangular superior (\"*U*pper triangular\").\n",
75 | "\n",
76 | "(i) ¿Cuál es la condición para que una matriz $\\mathsf{A}$ sea triangular superior, en términos de sus entradas $A_{ij}$? \n",
77 | "\n",
78 | "\n",
79 | "(ii) ¿Cómo se puede resolver esta ecuación? Piensa primero en un caso chiquito, e.g. $3 \\times 3$ con entradas $U_{11}$ etc., para que puedas hacer todo explícitamente.\n",
80 | "\n",
81 | "(iii) Implementa este método para una matriz triangular superior arbitraria. (Supón que la matriz ya tenga esta forma.)\n",
82 | "\n",
83 | "(iv) Verifica que tu método numérico funciona, es decir ¡que el resultado sí sea solución de la ecuación original!"
84 | ]
85 | },
86 | {
87 | "cell_type": "markdown",
88 | "metadata": {},
89 | "source": []
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "metadata": {},
94 | "source": [
95 | "#### Ejercicio 3\n",
96 | "\n",
97 | "(i) Escribe, a mano, el método de eliminación gaussiana para reducir una matriz de $2 \\times 2$ a una matriz triangular superior, en términos de operaciones de renglón. ¿Qué se debe hacer al lado derecho de la ecuación? Supón (por el momento) que no hay problemas con dividir por cero. \n",
98 | "\n",
99 | "(ii) Impleméntalo numéricamente. Utiliza tu código para resolver el sistema de ecuaciones lineales\n",
100 | "\n",
101 | "\\begin{align} \n",
102 | " 3x + 7y &= 1; \\\\\n",
103 | " 2x + 4y &= 1.\n",
104 | "\\end{align}\n",
105 | "\n",
106 | "Por supuesto, ¡debes verificar que la solución que encuentres realmente sí sea solución de la ecuación!"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": null,
112 | "metadata": {},
113 | "outputs": [],
114 | "source": []
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "metadata": {},
119 | "source": [
120 | "#### Ejercicio 4\n",
121 | "\n",
122 | "(i) Implementa el método de eliminación gaussiana para reducir una matriz arbitraria a una matriz triangular superior, suponiendo que no ocurra ningún caso problemático (0 en el lugar del pivot).\n",
123 | "\n",
124 | "(ii) Utiliza lo que ya has hecho para resolver un sistema lineal general [pero todavía suponiendo que no haya divisiones entre 0].\n",
125 | "\n",
126 | "(iii) Utiliza tu código para resolver el sistema\n",
127 | "\n",
128 | "\\begin{align}\n",
129 | " 2x + y - z &= 8; \\\\\n",
130 | " -3x - y + 2z &= -11; \\\\\n",
131 | " -2x + y + 2x &= -3.\n",
132 | "\\end{align}"
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {},
139 | "outputs": [],
140 | "source": []
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "#### Ejercicio 5\n",
147 | "\n",
148 | "(i) El acto de llevar a cabo una operación de renglón (como las que se utilizan en la eliminación gaussiana) sobre una matriz $\\mathsf{A}$ se puede escribir como una multiplicación de $\\mathsf{A}$ con otra matriz $\\mathsf{L}$. ¿Cuál matriz $\\mathsf{L}$? ¿Qué propiedad tiene $\\mathsf{L}$?\n",
149 | "\n",
150 | "\n",
151 | "(ii) Considerando que el método de eliminación gaussiana consiste en una secuencia de operaciones de renglón, que son multiplicaciones por matrices $L_j$, y que produce una matriz triangular superior $U$, ¿cómo se puede escribir $U$ en términos de las $L_j$?\n",
152 | "\n",
153 | "(iii) Por lo tanto, ¿de qué forma se puede escribir $\\mathsf{A}$? \n",
154 | "\n",
155 | "(iv) ¿Qué implica esto si un problema consiste en resolver muchas ecuaciones de la forma $\\mathsf{A} \\cdot \\mathbf{x}^{(i)} = \\mathbf{b}^{(i)}$, para distintos lados derechos $\\mathbf{b}^{(i)}$?"
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": null,
161 | "metadata": {},
162 | "outputs": [],
163 | "source": []
164 | },
165 | {
166 | "cell_type": "markdown",
167 | "metadata": {},
168 | "source": [
169 | "#### Ejercicio 6 \n",
170 | "\n",
171 | "Utiliza tu función que resuelve sistemas de ecuaciones lineales para implementar el método de Newton en varias dimensiones.\n",
172 | "\n",
173 | "Como ejemplo, resuelve el siguiente sistema de ecuaciones no-lineales:\n",
174 | "\n",
175 | "$$x^2 + y^2 = 1$$\n",
176 | "$$x + y = 1.$$\n",
177 | "\n",
178 | "¿Cuántas soluciones tiene? Compara con la solución analítica."
179 | ]
180 | },
181 | {
182 | "cell_type": "code",
183 | "execution_count": null,
184 | "metadata": {},
185 | "outputs": [],
186 | "source": []
187 | }
188 | ],
189 | "metadata": {
190 | "kernelspec": {
191 | "display_name": "Julia 1.0.0",
192 | "language": "julia",
193 | "name": "julia-1.0"
194 | },
195 | "language_info": {
196 | "file_extension": ".jl",
197 | "mimetype": "application/julia",
198 | "name": "julia",
199 | "version": "1.0.0"
200 | },
201 | "toc": {
202 | "colors": {
203 | "hover_highlight": "#DAA520",
204 | "running_highlight": "#FF0000",
205 | "selected_highlight": "#FFD700"
206 | },
207 | "moveMenuLeft": true,
208 | "nav_menu": {
209 | "height": "49px",
210 | "width": "252px"
211 | },
212 | "navigate_menu": true,
213 | "number_sections": true,
214 | "sideBar": true,
215 | "threshold": "2",
216 | "toc_cell": false,
217 | "toc_section_display": "block",
218 | "toc_window_display": false
219 | }
220 | },
221 | "nbformat": 4,
222 | "nbformat_minor": 1
223 | }
224 |
--------------------------------------------------------------------------------
/notebooks/09. Interpolacion.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Interpolación"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "En el notebook anterior, vimos cómo se puede discretizar una función continua para calcular numéricamente una derivada.\n",
15 | "\n",
16 | "Un problema muy común en el cómputo científico es el problema opuesto: tenemos datos discretos, y queremos encontrar una función continua que los aproxime. Una manera de hacer esto es la **interpolación**: \n",
17 | "\n",
18 | "> Dados datos $(x_i, y_i)$ para $i=1,\\ldots,N$, encontrar una función $f(x)$ que pase exactamente por los puntos, es decir, tal que $f(x_i) = y_i$ para cada $i$.\n",
19 | "\n",
20 | "La interpolación provee, entre otras cosas, una manera de formalizar la derivación de diferencias finitas para calcular derivadas, y para llevar a cabo integrales de manera numérica. Mucho más allá, provee también una manera para manipular funciones de forma numérica.\n",
21 | "\n",
22 | "Podríamos escoger distintas clases de función $f$ con las cuales interpolar. Aquí, trabajaremos con los **polinomios** y la llamada **interpolación de Lagrange**."
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "#### Ejercicio 1\n",
30 | "\n",
31 | "El primer caso que tratar es con $N=2$, es decir encontrar una función que interpole entre los puntos $(x_1, y_1)$ y $(x_2, y_2)$. Es claro que basta utilizar una recta para hacerlo. Para encontrar cuál recta es, hacemos lo siguiente.\n",
32 | "\n",
33 | "(i) Define una función $L_1(x)$ que es lineal en $x$, tal que $L_1(x)$ tome el valor $0$ en $x = x_2$, es decir, $L_1(x_2) = 0$. Ahora haz que también tome el valor $1$ en $x = x_1$, es decir, que $L_1(x_1) = 1$.\n",
34 | "\n",
35 | "(ii) Por simetría, encuentra la función $L_2(x)$ tal que $L_2(x_1) = 0$ y $L_2(x_2) = 1$.\n",
36 | "\n",
37 | "(iii) Utiliza $L_1$ y $L_2$ para encontrar un polinomio lineal que interpola los datos.\n",
38 | "\n",
39 | "(iv) Impleméntalo.\n",
40 | "\n",
41 | "(v) Toma dos puntos. Dibújalos y el polinomio lineal que los interpola."
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": null,
47 | "metadata": {},
48 | "outputs": [],
49 | "source": []
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "#### Ejercicio 2\n",
56 | "\n",
57 | "Hagamos lo mismo con tres puntos:\n",
58 | "\n",
59 | "(i) Encuentra un polinomio $L_1(x)$ sencillo, tal que $L(x)$ sea igual a $0$ para $x=x_2$ y $x=x_3$. Ahora normalízalo para que $L_1(x_1) = 1$. ¿De qué grado es el polinomio?\n",
60 | "\n",
61 | "(ii) De manera similar, encuentra $L_i(x)$ que sea igual a $1$ en $x_i$, y que se anule en $x_j$ para $j \\neq i$, para $i=2, 3$.\n",
62 | "\n",
63 | "(iii) Implementa estas funciones como una función `L(i, x)` que toma $i$ y $x$ como argumentos y calcule la función $L_i$ evaluada en el punto $x$. \n",
64 | "\n",
65 | "(iv) Calcula la función $L(x)$ que interpola los tres puntos simultáneamente, basado en las funciones $L_i$ que acabas de encontrar. ¿Qué tipo de polinomio es?\n",
66 | "\n",
67 | "(v) Escoge 3 puntos $(x_i, y_i)$. Dibújalos y dibuja la función $L$ que los interpola.\n"
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": null,
73 | "metadata": {},
74 | "outputs": [],
75 | "source": []
76 | },
77 | {
78 | "cell_type": "markdown",
79 | "metadata": {},
80 | "source": [
81 | "#### Ejercicio 3\n",
82 | "\n",
83 | "Ahora generalicemos esto a $N$ puntos:\n",
84 | "\n",
85 | "(i) Encuentra un polinomio $L_1(x)$ sencillo, tal que $L(x)$ sea igual a $0$ para $x=x_2$, $x=x_3$, \\ldots, $x=x_N$. Ahora normalízalo para que $L_1(x_1) = 1$. ¿De qué grado es el polinomio?\n",
86 | "\n",
87 | "(ii) De manera similar, encuentra $L_i(x)$ que sea igual a $1$ en $x_i$, y que se anule en $x_j$ para $j \\neq i$.\n",
88 | "\n",
89 | "(iii) Implementa estas funciones como una función `L(i, x)` que toma $i$ y $x$ como argumentos y calcule la función $L_i$ evaluada en el punto $x$. \n",
90 | "\n",
91 | "(iv) Dibuja algunas $L_i$ como función de $x$ para $N$ chiquitas. Asegúrate de que sí se comporten correctamente, es decir que sí tomen los valores $1$ y $0$ en donde deben."
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": null,
97 | "metadata": {},
98 | "outputs": [],
99 | "source": []
100 | },
101 | {
102 | "cell_type": "markdown",
103 | "metadata": {},
104 | "source": [
105 | "#### Ejercicio 4\n",
106 | "\n",
107 | "(i) Utiliza las $L_i$ que encontraste en el ejercicio 2 para interpolar los datos $(x_i, y_i)_{i=1}^N$ con un polinomio $p$. ¿De qué orden es el polinomio resultante? Nota que $p$ es *único* en el conjunto de polinomios con grado $\\le$ el grado de $p$.\n",
108 | "\n",
109 | "(ii) Escribe una función `interpolar` que acepta un vector `x` de las $x_i$ y otro vector `y` de las $y_i$, y regresa *una función* que las interpole. [Pista: Puedes definir la función adentro de la función `interpolar` y regresar esta misma función.]\n",
110 | "\n",
111 | "(iii) Toma funciones polinomiales de orden $n$ diferentes, y genera $n+1$ datos al *muestrear* (es decir, evaluar) la función en distintos puntos $x_i$, espaciados de forma uniforme. Dibuja la función original y la función interpolada en estos puntos.\n",
112 | "\n",
113 | "(iv) Intenta interpolar la función $\\sin(x)$. ¿Funciona bien?"
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": null,
119 | "metadata": {},
120 | "outputs": [],
121 | "source": []
122 | },
123 | {
124 | "cell_type": "markdown",
125 | "metadata": {},
126 | "source": [
127 | "#### Ejercicio 5\n",
128 | "\n",
129 | "Considera la función de Runge, $f(x) = \\frac{1}{1+25x^2}$, en la región $x \\in [-1, 1]$. Interpólala con tu función `interpolar` para distintos números $N$ de puntos. ¿Qué observas? Utiliza `@manipulate` para variar el número de puntos muestreados / grado del polinomio interpolador."
130 | ]
131 | },
132 | {
133 | "cell_type": "code",
134 | "execution_count": null,
135 | "metadata": {},
136 | "outputs": [],
137 | "source": []
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {},
142 | "source": [
143 | "## Interpolación en puntos espaciados no-uniformemente"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {},
149 | "source": [
150 | "Le que acabas de observar se llama el **fenómeno de Runge**. Esto demuestra que en general *es una mala idea* interpolar en puntos uniformemente espaciados. Sin embargo, resulta que el problema no es la interpolación en sí, sino la elección de puntos en donde interpolar: una solución es el tomar puntos en el intervalo $[-1,1]$, espaciados tales que se amontonen cerca de los puntos extremos del intervalo. [La razón por esto se puede entender con la teoría de potenciales (\"potential theory\"); ver e.g. Trefethen, *Approximation Theory and Approximation Practice*.] \n",
151 | "\n",
152 | "Lo más común es utilizar los llamados **puntos de Chebyshev** con parámetro $n$, definidos como \n",
153 | "\n",
154 | "$$x_j := \\cos \\left( \\frac{j \\pi}{n} \\right) \\quad \\text{con } 0 \\le j \\le n.$$"
155 | ]
156 | },
157 | {
158 | "cell_type": "markdown",
159 | "metadata": {},
160 | "source": [
161 | "#### Ejercicio 6\n",
162 | "\n",
163 | "(i) Escribe una función que calcula los puntos de Chebyshev para un valor de $n$ dado.\n",
164 | "\n",
165 | "(ii) Escribe una función que interpola una función dada en los puntos de Chebyshev. Grafica los resultados.\n",
166 | "\n",
167 | "(iii) Interpola la función de Runge con puntos de Chebyshev. ¿Qué observas?"
168 | ]
169 | },
170 | {
171 | "cell_type": "code",
172 | "execution_count": null,
173 | "metadata": {},
174 | "outputs": [],
175 | "source": []
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {},
180 | "source": [
181 | "#### Ejercicio 7\n",
182 | "\n",
183 | "(i) Dada una función $f$, calcula numéricamente el error al utilizar la interpolación de Chebyshev $p$ con respecto a la función original $f$, dado por la norma\n",
184 | "\n",
185 | "$$\\|f - p\\|_{\\infty} := \\sup_x |f(x) - p(x)|,$$\n",
186 | "\n",
187 | "para distintos números de puntos de Chebyshev.\n",
188 | "\n",
189 | "(ii) Conforme se aumenta el número de puntos, ¿cómo es la convergencia a $0$ del error? "
190 | ]
191 | },
192 | {
193 | "cell_type": "code",
194 | "execution_count": null,
195 | "metadata": {},
196 | "outputs": [],
197 | "source": []
198 | },
199 | {
200 | "cell_type": "markdown",
201 | "metadata": {},
202 | "source": [
203 | "#### Ejercicio 8\n",
204 | "\n",
205 | "Resulta que la tasa de convergencia depende de qué tan suave sea la función.\n",
206 | "Por ejemplo, inténtalo con la función `abs` y con la función `floor`."
207 | ]
208 | },
209 | {
210 | "cell_type": "code",
211 | "execution_count": null,
212 | "metadata": {},
213 | "outputs": [],
214 | "source": []
215 | },
216 | {
217 | "cell_type": "markdown",
218 | "metadata": {},
219 | "source": [
220 | "## Hacia el futuro"
221 | ]
222 | },
223 | {
224 | "cell_type": "markdown",
225 | "metadata": {},
226 | "source": [
227 | "Lo que hemos logrado es reemplazar (aproximar) una función continua $f$ por un conjunto discreto de sus valores $f(x_i)$ en la **malla** $(x_i)_{i=1}^N$. Ahora podremos manipular la función ¡al manipular sólo estos valores discretos!"
228 | ]
229 | },
230 | {
231 | "cell_type": "markdown",
232 | "metadata": {},
233 | "source": [
234 | "Resulta que es más útil cambiar de punto de vista, y utilizar la llamada [**interpolación baricéntrica**](https://people.maths.ox.ac.uk/trefethen/barycentric.pdf).\n",
235 | "\n",
236 | "Luego llevamos a cabo un **cambio de base** en el espacio de polinomios, y utilizamos los **polinomios de Chebyshev** en lugar de los polinomios basados en $x^i$.\n",
237 | "\n",
238 | "La idea es escribir el polinomio interpolante como una suma de polinomios de Chebyshev y examinar los coeficientes de estos polinomios, que tienen propiedades muy útiles. Esto lo podremos ver hasta después de ver álgebra lineal numérica. ¡Podría formar un proyecto final interesante! "
239 | ]
240 | },
241 | {
242 | "cell_type": "code",
243 | "execution_count": null,
244 | "metadata": {},
245 | "outputs": [],
246 | "source": []
247 | }
248 | ],
249 | "metadata": {
250 | "kernelspec": {
251 | "display_name": "Julia 0.5.2",
252 | "language": "julia",
253 | "name": "julia-0.5"
254 | },
255 | "language_info": {
256 | "file_extension": ".jl",
257 | "mimetype": "application/julia",
258 | "name": "julia",
259 | "version": "0.5.2"
260 | }
261 | },
262 | "nbformat": 4,
263 | "nbformat_minor": 2
264 | }
265 |
--------------------------------------------------------------------------------
/notebooks/13. Metodos tipo Runge-Kutta.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Métodos tipo Runge-Kutta para EDOs"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Consideremos la EDO\n",
15 | "\n",
16 | "$$\\dot{x}(t) = f(x(t), t) \\qquad (1).$$\n",
17 | "\n",
18 | "Queremos desarrollor métodos numéricos que aproximen mejor la solución exacta que el método de Euler, es decir, para los cuales el tamaño del error sea menor, de orden $h^n$ con $n$ más grande."
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "#### Ejercicio 1\n",
26 | "\n",
27 | "Como hemos visto con el método de Euler, dada una aproximación para la solución $x(t_0)$ en el tiempo $t_0$, queremos encontrar una aproximación para la solución $x(t_0 + h)$ en el siguiente paso.\n",
28 | "\n",
29 | "(i) Desarrolla $x(t_0 + h)$ en una serie de Taylor, incluyendo explícitamente los términos hasta segundo orden. Para calcular $\\ddot{x}$, deriva la ecuación (1) con respecto a $t$. Nota que $f$ es una **función de dos variables**.\n",
30 | "\n",
31 | "(ii) ¿A qué corresponde el método de Euler?"
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": null,
37 | "metadata": {},
38 | "outputs": [],
39 | "source": []
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {},
44 | "source": [
45 | "Es posible derivar métodos (llamados **métodos de Taylor**) que calculen explícitamente las derivadas de $f$, utilizando técnicas de **diferenciación algorítmica** (también llamado \"diferenciación automática).\n",
46 | "\n",
47 | "En lugar de esto, estudiaremos los llamados **métodos de Runge-Kutta** (RK), los cuales utilizan una idea diferente: \n",
48 | "\n",
49 | "evalúan $f$ varias veces, posiblemente en distintos lugares, y toman una combinación lineal de estas evaluaciones para reproducir la expansión de Taylor a diferentes órdenes.\n",
50 | "\n",
51 | "Veremos un par de métodos de Runge-Kutta **explícitos**, es decir, en los cuales no es necesario de resolver una ecuación no-lineal, lo cual corresponde a un método **implícito** (por ejemplo, el método de Euler hacia atrás)."
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "#### Ejercicio 2\n",
59 | "\n",
60 | "Para entender la idea de los métodos RK, regresemos al método de Euler hacia atrás. Si $t_n$ son los nodos en donde aproximamos la solución, y $x_n$ los valores aproximados, entonces tenemos lo siguiente (que obtenemos al aproximar la integral):\n",
61 | "\n",
62 | "$$x_{n+1} = x_n + \\frac{h}{2} \\left[ f(x_n, t_n) + f(x_{n+1}, t_{n+1}) \\right] \\qquad (2).$$\n",
63 | "\n",
64 | "Para convertir esta ecuación implícita en un método Runge-Kutta, tomemos una *aproximación* de $f(x_{n+1})$, al utilizar... ¡un *paso de Euler*! En general, los métodos de Runge-Kutta incorporan varios pasos de Euler, que pueden ser de distintos tamaños.\n",
65 | "\n",
66 | "(i) Escribe la ecuación de un paso de Euler para $x_{n+1}$ en términos de $x_n$.\n",
67 | "\n",
68 | "(ii) Inserte ese paso de Euler en la ecuación (2). Expande en potencias de $h$ hasta segundo orden. Demuestra que recupera la expansión de Taylor de $x(t_n+h)$ a segundo orden. Este método se llama el **método de Euler modificado**.\n",
69 | "\n",
70 | "(iii) Una alternativa es el tomar un paso de Euler en todo el intervalo de tamaño $h$, pero utilizando una mejor aproximación de la derivada en el intervalo. Para hacerlo, se toma un primer paso de Euler hasta la *mitad* del camino entre $t_n$ y $t_{n+1}$, es decir una \"distancia\" $h/2$ en el tiempo, y se evalúa ahí $f(x(t+h/2), t+h/2)$. Este valor luego se utiliza como la aproximación de $\\dot{x}$ sobre el intervalo en otro paso de Euler. Este método se llama el **método del punto medio**.\n",
71 | "\n",
72 | "Demuestra que también recupera la expansión de Taylor de $x(t_n+h)$ a segundo orden.\n",
73 | "\n",
74 | "(iv) Implementa funciones para pasos individuales de estos dos métodos, para una EDO escalar (es decir, para una sola variable dependiente).\n",
75 | "\n",
76 | "(v) Implementa funciones para pasos individuales de estos dos métodos, de forma vectorial."
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {},
83 | "outputs": [],
84 | "source": []
85 | },
86 | {
87 | "cell_type": "markdown",
88 | "metadata": {},
89 | "source": [
90 | "#### Ejercicio 3\n",
91 | "\n",
92 | "Para poder comparar distintos métodos, es útil contar con un integrador de EDOs general, con el cual podemos escoger cuál método utilizar en cada paso.\n",
93 | "\n",
94 | "(i) Escribe una función `integrar` que integra una EDO con un método dado. Como primer argumento, debe aceptar un argumento `método`, el cual indica la función que llamar en cada paso de la integración.\n",
95 | "\n",
96 | "(ii) Utiliza la función `integrar` para integrar una EDO sencilla escalar con el método de Euler, el método de Euler modificado, y el método del punto medio. Compara las tasas de convergencia de los métodos."
97 | ]
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": null,
102 | "metadata": {},
103 | "outputs": [],
104 | "source": []
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "## Runga-Kutta de más alto orden"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "Se pueden derivar métodos de Runge-Kutta de más alto orden, es decir, siempre con la meta de reproducir la expansión de Taylor de $x(t+h)$ a cada vez más alto orden. Sin embargo, los cálculos se vuelven bastante complicados."
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {},
123 | "source": [
124 | "#### Ejercicio 4\n",
125 | "\n",
126 | "(i) Uno de los métodos de Runge-Kutta más utilizados es el llamado **RK4**, que es de cuarto orden. Encuentra las ecuaciones para este método e impleméntalo para el caso de una ecuación EDO escalar.\n",
127 | "\n",
128 | "(ii) Implementa un paso de RK4 para una ecuación EDO vectorial.\n",
129 | "\n",
130 | "(iii) Utiliza `integrar` para comparar su tasa de convergencia y compáralo visualmente con los demás métodos."
131 | ]
132 | },
133 | {
134 | "cell_type": "code",
135 | "execution_count": null,
136 | "metadata": {},
137 | "outputs": [],
138 | "source": []
139 | },
140 | {
141 | "cell_type": "markdown",
142 | "metadata": {},
143 | "source": [
144 | "## Paso adaptativo"
145 | ]
146 | },
147 | {
148 | "cell_type": "markdown",
149 | "metadata": {},
150 | "source": [
151 | "Hasta ahora, en todas las integraciones de EDOs que hemos hecho, ha habido un tamaño de paso fijo, que es un parámetro que pasamos a la función `RK4` etc.\n",
152 | "\n",
153 | "Pero surge una pregunta: ¿cómo se debe escoger el tamaño del paso? (Seguro ¡has pasado por esta pregunta!) La respuesta dependerá de la función $\\mathbf{f}$ que estemos integrando: si $\\mathbf{f}$ cambia rápido, debemos usar un paso más chiquito para resolver los cambios; si cambia más lentamente, podemos utilizar un paso más grande. \n",
154 | "\n",
155 | "El problema es que ¡sólo podemos saber qué tan rápido varía la función en medio de la integración misma!\n",
156 | "La solución es utilizar un método *adaptativo*: el método mismo tiene (cierto) control del tamaño de paso, el cual *se irá cambiando de manera automática* para tomar en cuenta la propia tasa de cambio de la función.\n",
157 | "\n",
158 | "Por esta razón, (casi) *nunca* se deberían utilizar los métodos simples y no-adaptativos como Euler y RK4 en la práctica."
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {},
164 | "source": [
165 | "## Euler adaptativo "
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "metadata": {},
171 | "source": [
172 | "Dado que este tema se puede volver complicado, consideremos el método de Euler por simplicidad. Queremos resolver \n",
173 | "\n",
174 | "$$\\dot{x} = f(x),$$\n",
175 | "\n",
176 | "y tenemos\n",
177 | "\n",
178 | "$$x_{n+1} = x_n + h \\, f(x_n) + \\epsilon_1(h), \\qquad (3)$$\n",
179 | "\n",
180 | "donde $\\epsilon_1(h) = C \\, h^2$ es el error de un paso.\n",
181 | "Aquí, hemos supuesto que $C$ no depende de $h$. Esto no es realmente cierto (¿por qué?), pero facilita el cálculo.\n",
182 | "\n",
183 | "Para ciertos tipos de función $f$ (¿cuáles? -- ¿qué otra forma podríamos utilizar para el término del error?), el término del error será grande.\n",
184 | "¿Cómo podemos *estimar* el tamaño de este término?\n",
185 | "\n",
186 | "Una idea es el de tomar *dos* pasos, de tamaño $h/2$."
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "#### Ejercicio 5\n",
194 | "\n",
195 | "(i) Encuentra la expresión para $x_n$ si se toman dos pasos de tamaño $h/2$, \n",
196 | "donde $x_{n+\\frac{1}{2}}$ es el lugar intermedio.\n",
197 | "Substrae los dos resultados del método de Euler para encontrar el tamaño del error $\\epsilon$."
198 | ]
199 | },
200 | {
201 | "cell_type": "markdown",
202 | "metadata": {},
203 | "source": [
204 | "Si $\\epsilon < \\mathrm{tol}$, una cierta tolerancia que imponemos, entonces el paso es exitoso, y actualizamos las variables. En este caso, la función está variando lentamente, así que podemos *incrementar* el tamaño del paso. \n",
205 | "Si no es exitoso, reducimos la tolerancia. En los dos casos, podemos actualizar según una regla de la forma\n",
206 | "\n",
207 | "$$ h' = 0.9 h \\, \\frac{\\mathrm{tol}}{|\\epsilon|}.$$"
208 | ]
209 | },
210 | {
211 | "cell_type": "markdown",
212 | "metadata": {},
213 | "source": [
214 | "(ii) ¿Por qué funciona esta fórmula tanto cuando el paso tuvo éxito, como cuando no fue así?\n",
215 | "\n",
216 | "(iii) Implementa un método adaptativo de Euler. Nota que será necesario escribir una nueva función `integrar_adaptivo` que maneje los cambios del tamaño del paso.\n",
217 | "\n",
218 | "(iv) Prúebalo para un sistema que hemos estudiado en el cual fracasa Euler. ¿Ayuda?"
219 | ]
220 | },
221 | {
222 | "cell_type": "markdown",
223 | "metadata": {},
224 | "source": []
225 | },
226 | {
227 | "cell_type": "markdown",
228 | "metadata": {},
229 | "source": [
230 | "## Métodos de Runge-Kutta adaptativos "
231 | ]
232 | },
233 | {
234 | "cell_type": "markdown",
235 | "metadata": {},
236 | "source": [
237 | "Supongamos que hiciéramos la misma idea para Runge-Kutta 4."
238 | ]
239 | },
240 | {
241 | "cell_type": "markdown",
242 | "metadata": {},
243 | "source": [
244 | "#### Ejercicio 6\n",
245 | "\n",
246 | "¿Cuántas evaluaciones de la función $f$ se requieren para llevar a cabo un paso de tamaño $h$?"
247 | ]
248 | },
249 | {
250 | "cell_type": "code",
251 | "execution_count": null,
252 | "metadata": {},
253 | "outputs": [],
254 | "source": []
255 | },
256 | {
257 | "cell_type": "markdown",
258 | "metadata": {},
259 | "source": [
260 | "Dado que esto puede ser caro, hay una mejor solución. Resulta que hay métodos de Runge-Kutta llamados \"embedded\" (\"embebido\") tales que podemos utilizar las *mismas* evaluaciones de la función $f$ (en los mismos lugares del intervalo $[t, t+h]$), y nos proporciona ¡*dos* estimados diferentes de $x(t+h)$, con dos órdenes de error distintos! Esto se puede aplicar de la misma forma para controlar el tamaño de paso, pero con menos evaluaciones de $f$ en cada paso que tomar dos pasos de tamaño $h/2$.\n",
261 | "\n",
262 | "Este método, y otros parecidos, es uno de los que se suele utilizar para cálculos serios."
263 | ]
264 | },
265 | {
266 | "cell_type": "markdown",
267 | "metadata": {},
268 | "source": [
269 | "#### Ejercicio 7 (opcional) \n",
270 | "\n",
271 | "Implementa el método \"RK45\" (Runge-Kutta-Fehlberg), que mezcla un método de 4o. y de 5o. orden. Verifica su orden de convergencia."
272 | ]
273 | },
274 | {
275 | "cell_type": "code",
276 | "execution_count": null,
277 | "metadata": {},
278 | "outputs": [],
279 | "source": []
280 | }
281 | ],
282 | "metadata": {
283 | "kernelspec": {
284 | "display_name": "Julia 1.0.0",
285 | "language": "julia",
286 | "name": "julia-1.0"
287 | },
288 | "language_info": {
289 | "file_extension": ".jl",
290 | "mimetype": "application/julia",
291 | "name": "julia",
292 | "version": "1.0.1"
293 | }
294 | },
295 | "nbformat": 4,
296 | "nbformat_minor": 1
297 | }
298 |
--------------------------------------------------------------------------------
/notebooks/14. Ecuacion de calor.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Ecuaciones parciales diferenciales de evolución"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Las ecuaciones diferenciales parciales (EDPs) constituyen un área de suma importancia en la física, ya que modelan sistemas que varían con respecto a varias variables *in*dependientes, por ejemplo, tanto el tiempo como el espacio.\n",
15 | "\n",
16 | "Del punto de vista numérico, se puede decir que el tipo de EDPs que es más sencillo conceptualmente son las llamadas **parabólicas**, es decir, **ecuaciones de evolución**, de las cuales la más conocida es la **ecuación de calor** o **ecuación de difusión**."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "# La ecuación de calor"
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {},
29 | "source": [
30 | "La ecuación de calor modela el esparcimiento en el tiempo y en el espacio de un \"paquete\" de calor (perturbación local de temperatura en una región), o de concentración de una sustancia física o química, en cuyo caso se llama la **ecuación de difusión**. \n",
31 | "\n",
32 | "Llamemos $u(t, \\mathbf{x})$ la perturbación de la temperatura o la concentración de la sustancia en la posición $\\mathbf{x}$ al tiempo $t$. La ecuación de calor es\n",
33 | "\n",
34 | "$$\\frac{\\partial u(t, \\mathbf{x})}{\\partial t} = D \\, \\nabla^2 u(t, \\mathbf{x}).$$\n",
35 | "\n",
36 | "[Recordemos que $\\nabla^2 := \\frac{\\partial^2}{\\partial x^2} + \\frac{\\partial^2}{\\partial y^2} + \\frac{\\partial^2}{\\partial z^2}$ en tres dimensiones.]\n",
37 | "\n",
38 | "Esta ecuación nos dice cómo varía la concentración en el tiempo, dadas las condiciones locales en el espacio. Se deriva a partir una ley de conservación que dice que la concentración de sustancia no se destruye, ni se construye, sino sólo fluye en el espacio. Al imponer esto en una caja chiquita y tomar el límite cuando el tamaño de la caja tiende a cero, obtenemos que\n",
39 | "\n",
40 | "$$\\frac{\\partial u}{\\partial t} + \\nabla \\cdot \\mathbf{J} = 0.$$\n",
41 | "\n",
42 | "Además, podemos suponer (al menos, en una primera aproximación) que el flujo de calor o de concentración $\\mathbf{J}$ es proporcional a la gradiente local:\n",
43 | "\n",
44 | "$$\\mathbf{J} = -D \\, \\nabla u.$$\n",
45 | "\n",
46 | "Sustituyendo esta relación en la anterior, obtenemos la ecuación de calor.\n",
47 | "\n",
48 | "La ecuación de calor es una **ecuación de evolución**; es decir, describe cómo evoluciona el sistema en el tiempo (y en el espacio). Por lo tanto, su tratamiento se sigue de forma bastante directa de lo que hemos visto para EDOs."
49 | ]
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "## Una dimensión\n",
56 | "\n",
57 | "Empecemos con el caso más sencillo, con sólo una dimensión espacial. En este caso, la ecuación de calor se reduce a\n",
58 | "\n",
59 | "\n",
60 | "$$\\frac{\\partial u}{\\partial t} = D \\frac{\\partial^2 u}{\\partial x^2}.$$\n",
61 | "\n",
62 | "Nota que aquí, las derivadas $\\frac{\\partial u}{\\partial t}$ son ellas mismas *funciones del tiempo y de la posición*. De forma análoga a las EDOs, esta ecuación quiere decir que \n",
63 | "\n",
64 | "$$\\frac{\\partial u}{\\partial t}(t, x) = D \\frac{\\partial^2 u}{\\partial x^2}(t, x),$$\n",
65 | "\n",
66 | "para todas las $t \\in [t_0, t_f]$ y todas las $x$ en un rango dado (que puede ser infinito).\n",
67 | "\n",
68 | "Para resolver esta EDP, necesitaremos una condición inicial funcional, $u(t=0, x) = f(x)$ (una función del espacio), así como condiciones en la frontera $u(t, x)$ para todos los valores de $x$ que se encuentren en la frontera del dominio espacial, y para todo $t$."
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {},
74 | "source": [
75 | "# Métodos numéricos para la ecuación de calor"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {},
81 | "source": [
82 | "Dado que, como siempre, no podemos resolver problemas de naturaleza continua en la computadora, debemos *aproximar* la solución $u(t, x)$ de alguna forma a través de una **discretización**. Hay distintas formas de llevar a cabo la discretización; aquí, escogeremos el más sencillo."
83 | ]
84 | },
85 | {
86 | "cell_type": "markdown",
87 | "metadata": {},
88 | "source": [
89 | "#### Ejercicio 1\n",
90 | "\n",
91 | "(i) Pensando en tu experiencia con las ecuaciones diferenciales ordinarias, ¿cómo se puede discretizar $u(t, x)$, utilizando un tamaño de paso $h$ en el tiempo y $k$ en el espacio? Toma el intervalo $[-L, L]$ como los valores posibles de $x$, así como tiempos en el rango $[t_0, t_f]$.\n",
92 | "\n",
93 | "Denotemos con $t_n$ el tiempo al paso número $n$, y con $u^n_i$ la aproximación de la solución en el nodo número $i$ en el espacio al tiempo $n$.\n",
94 | "\n",
95 | "(ii) ¿Cómo se puede discretizar la ecuación de calor unidimensional? \n",
96 | "\n",
97 | "(iii) Reescribe la discretización para dar $u^{n+1}_i$ en términos de distintos $u^n_j$s al tiempo anterior."
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {},
104 | "outputs": [],
105 | "source": []
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "#### Ejercicio 2\n",
112 | "\n",
113 | "Considera la ecuación de calor en una dimensión sobre el intervalo de $x=-L$ a $x=L$, con condición inicial $u(t=0, x) = \\delta(x)$, donde $\\delta$ es la delta de Dirac, y condiciones de frontera absorbentes (de Dirichlet), es decir, $u(t, x=-L) = u(t, x=L) = 0$ para $t > 0$.\n",
114 | "\n",
115 | "(i) ¿Qué esperas intuitivamente que pase durante la evolución? ¿Qué pasará para tiempos largos?\n",
116 | "\n",
117 | "(ii) Escribe la solución analítica exacta para $u(x, t)$ en el caso cuando $L = \\infty$ (es decir, cuando \"no hay fronteras\" y la difusión ocurre en toda la recta real). [No es necesario que *derives* la solución, sólo que la anotes.]\n",
118 | "\n",
119 | "(iii) Dibuja la solución analítica como función del tiempo."
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "execution_count": null,
125 | "metadata": {},
126 | "outputs": [],
127 | "source": []
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "#### Ejercicio 3\n",
134 | "\n",
135 | "(i) Para resolver la ecuación de calor en la computadora, debemos saber cómo discretizar la $\\delta$ de Dirac; recuerda que es es un bicho raro, ya que *no es una función*. [De hecho, la delta de Dirac es un ejemplo de lo que se llama una **distribución** o [**función generalizada**](https://en.wikipedia.org/wiki/Generalized_function).]\n",
136 | "\n",
137 | "Pensando que (la parte no-cero de) la delta de Dirac se localiza en una celda de la discretización con ancho $h$, ¿cómo podemos representar la condición inicial para que *tenga la misma área* que $\\delta(x)$? [Pista: ¿Cuál es el \"área\" debajo de la delta de Dirac? ¿Cómo podemos darle la misma área a nuestra condición inicial si consideramos que aproximamos la delta con una función constante en una caja?]\n",
138 | "\n",
139 | "(ii) Implementa el sistema, tomando cuidado en lo que ocurre en las fronteras. Para hacerlo, puedes utilizar un vector para representar el estado actual del sistema, y otro vector para el estado al tiempo siguiente. [Nota que deberás tomar en cuenta el punto tocado en el Ejercicio 4: puede que tu método numérico explota; en ese caso; reduce la $h$ hasta que ya no explote.]\n",
140 | "\n",
141 | "(iii) Dibuja la evolución en el tiempo, por ejemplo usando `Interact`. ¿Ocurre lo que esperabas? Dibuja en la misma gráfica la solución analítica exacta para $L = \\infty$. ¿Qué observas?\n",
142 | "\n",
143 | "(iv) También dibuja la evolución como un \"heat map\" (mapa de calor), es decir, dibuja la matriz dos-dimensional $u^n_i$ con colores que representan los valores de cada elemento de la matriz. [Pista: Utiliza la función `heatmap` de `Plots.jl`.]\n",
144 | "\n",
145 | "(v) ¿Qué ocurre si tomas otra condición inicial, por ejemplo una suma de dos deltas? Compáralo con el caso anterior.\n",
146 | "\n",
147 | "(vi) Pensando en la ecuación como la ecuación de difusión, ¿cuál cantidad relacionada con $u$ representa la cantidad total de masa? ¿Qué debería satisfacer esta cantidad durante la evolución para un sistema infinito? ¿Qué ocurre con esta cantidad cuando hay condiciones de frontera de Dirichlet? Demuéstralo numéricamente."
148 | ]
149 | },
150 | {
151 | "cell_type": "code",
152 | "execution_count": null,
153 | "metadata": {},
154 | "outputs": [],
155 | "source": []
156 | },
157 | {
158 | "cell_type": "markdown",
159 | "metadata": {},
160 | "source": [
161 | "#### Ejercicio 4\n",
162 | "\n",
163 | "(i) Los parámetros $h$ y $k$ de la discretización en el tiempo y en el espacio, respectivamente, ocurren en una cierta combinación adimensional en la ecuación discretizada que obtuviste. ¿Cuál es? \n",
164 | "\n",
165 | "(ii) Resulta que el método numérico es estable para ciertos valores de este parámetro adimensional, e inestable para otros. Encuentra numéricamente el valor crítico de este parámetro, debajo del cual el método es estable y arriba del cual es inestable."
166 | ]
167 | },
168 | {
169 | "cell_type": "code",
170 | "execution_count": null,
171 | "metadata": {},
172 | "outputs": [],
173 | "source": []
174 | },
175 | {
176 | "cell_type": "markdown",
177 | "metadata": {},
178 | "source": [
179 | "#### Ejercicio 5\n",
180 | "\n",
181 | "Considera la ecuación de difusión unidimensional, pero ahora con condiciones de frontera **reflejantes** (de Neumann).\n",
182 | "\n",
183 | "(i) Escribe la ecuación correspondiente a las condiciones de frontera en $x=\\pm L$.\n",
184 | "\n",
185 | "(ii) ¿Cómo se puede discretizar en términos de la misma discretización que antes?\n",
186 | "\n",
187 | "(iii) ¿Qué esperas intuitivamente que ocurre con este tipo de ecuaciones de frontera?\n",
188 | "\n",
189 | "(iv) Impleméntalo y grafica la evolución temporal.\n",
190 | "\n",
191 | "(v) Confirma la ley de conservación en este caso."
192 | ]
193 | },
194 | {
195 | "cell_type": "code",
196 | "execution_count": null,
197 | "metadata": {},
198 | "outputs": [],
199 | "source": []
200 | },
201 | {
202 | "cell_type": "markdown",
203 | "metadata": {},
204 | "source": [
205 | "#### Ejercicio 6\n",
206 | "\n",
207 | "Considera un sistema con condiciones **periódicas**, es decir, \n",
208 | "sobre un círculo, en el cual $u(x=0) = u(x=L)$ para toda $t$. \n",
209 | "\n",
210 | "Numéricamente, esto quiere decir que la vecina izquierda de la celda número 1 es la celda número $L$, y vice versa.\n",
211 | "Esto se puede implementar con un `if` o un `%`, o bien haciendo \"celdas fantasmas\" adicionales, a las cuales se copia la información correspondiente en cada paso.\n",
212 | "\n",
213 | "(i) ¿Qué esperas intuitivamente ver con estas condiciones de frontera?\n",
214 | "\n",
215 | "(ii) Impleméntalo, tal que puedas escoger qué tipo de condiciones de frontera quieras según un argumento a la función.\n",
216 | "\n",
217 | "(iii) ¿Se tiene una ley de conservación en este caso? Demúestralo numéricamente."
218 | ]
219 | },
220 | {
221 | "cell_type": "code",
222 | "execution_count": null,
223 | "metadata": {},
224 | "outputs": [],
225 | "source": []
226 | },
227 | {
228 | "cell_type": "markdown",
229 | "metadata": {},
230 | "source": [
231 | "#### Ejercicio 7\n",
232 | "\n",
233 | "Regresemos a la ecuación de calor original y pensemos *únicamente* en la parte de la evolución temporal.\n",
234 | "\n",
235 | "(i) ¿A qué método numérico para EDOs corresponde lo que ya implementaste?\n",
236 | "\n",
237 | "(ii) Ahora, discretiza *sólo* la derivada espacial de la ecuación de calor, dejando *sin* discretizarse la derivada temporal. El resultado se llama una **semi-discretización** de la ecuación. ¿Qué forma tienen las ecuaciones resultantes?\n",
238 | "\n",
239 | "(iii) Así, especifica cuáles otros métodos numéricos podrías aplicar.\n",
240 | "\n",
241 | "(iv) Impleméntalo."
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": null,
247 | "metadata": {},
248 | "outputs": [],
249 | "source": []
250 | }
251 | ],
252 | "metadata": {
253 | "kernelspec": {
254 | "display_name": "Julia 1.0.0",
255 | "language": "julia",
256 | "name": "julia-1.0"
257 | },
258 | "language_info": {
259 | "file_extension": ".jl",
260 | "mimetype": "application/julia",
261 | "name": "julia",
262 | "version": "1.0.1"
263 | }
264 | },
265 | "nbformat": 4,
266 | "nbformat_minor": 1
267 | }
268 |
--------------------------------------------------------------------------------
/notebooks/11. Ecuaciones diferenciales ordinarias - metodo de Euler.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Ecuaciones diferenciales ordinarias: el método de Euler"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Recordemos que una **ecuación diferencial ordinaria (EDO)** es (aproximadamente) una ecuación en la cual aparece una (o más) derivada(s) de una función, y para la cual queremos buscar la función que satisface esta relación.\n",
15 | "\n",
16 | "La EDO más simple no-trivial y físicamente relevante en una variable es \n",
17 | "\n",
18 | "$$\\dot{x} = -\\alpha \\, x. \\qquad (*)$$\n",
19 | "\n",
20 | "[Recordemos la notación $\\dot{x} := \\textstyle \\frac{dx}{dt}$, donde $t$ es el tiempo; es muy común en la física que las EDOs involucren derivadas con respecto al tiempo.]"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {},
26 | "source": [
27 | "Una solución a esta ecuación es un objeto $x$, tal que cuando la derivamos con respecto al tiempo, nos arroja $-\\alpha$ (una constante) multiplicada por el mismo objeto. Implícitamente está claro que $x$ depende de $t$, por lo que realmente $x$ se refiere a una función de $t$, es decir $x: \\mathbb{R} \\to \\mathbb{R}$ es la función $t \\mapsto x(t)$. \n",
28 | "\n",
29 | "Por lo tanto, la ecuación $\\dot{x} = -\\alpha x$ se puede considerar como una ecuación *funcional*, es decir, una igualdad entre funciones. \n",
30 | "\n",
31 | "Para entenderla, se reescribe de forma más explícita como sigue:\n",
32 | "\n",
33 | "$$\\dot{x}(t) = -\\alpha x(t) \\qquad \\text{para cada } t \\in \\mathbb{R}.$$\n",
34 | "\n",
35 | "Ahora es una igualdad de números, que dice que la \"velocidad\" en el tiempo $t$ es un cierto múltiplo de la posición en ese momento. De esta forma queda más claro (en mi opinión).\n",
36 | "\n",
37 | "Esto quiere decir que si *de alguna manera* hayamos logrado saber que la solución en el tiempo $t$ está en la posición $x(t)$, entonces nos indica cuál será la *velocidad* $\\dot{x}(t)$ en este momento. Esta es la información que necesitaremos para actualizar la solución al \"siguiente momento en el tiempo\" de forma numérica."
38 | ]
39 | },
40 | {
41 | "cell_type": "markdown",
42 | "metadata": {},
43 | "source": [
44 | "La forma general de una EDO en una variable es\n",
45 | "\n",
46 | "$$\\dot{x} = f(x, t),$$\n",
47 | "\n",
48 | "o sea\n",
49 | "\n",
50 | "$$\\dot{x}(t) = f(x(t), t) \\qquad \\text{para cada } t \\in \\mathbb{R}.$$\n",
51 | "\n",
52 | "Recordemos que debe ir acompañada por una condición inicial $x(t=t_0) = x_0$ para que constituya un problema bien posado (*problema de valores iniciales*, o *problema de Cauchy*).\n",
53 | "La solución de una ecuación de este tipo será una *función* $x(t)$ que satisface al mismo tiempo que $\\dot{x}(t) = f(x(t), t)$ para cada $t$, y que $x(t=t_0) = x_0$. \n",
54 | "\n",
55 | "En el caso particular de la ecuación $\\dot{x} = -\\alpha x$, conocemos analíticamente la solución, y nos servirá para comprobar nuestros métodos. Pero para las ecuaciones de interés para la física, esto *casi nunca ocurre*, una situación que ¡suele pasar desapercibida durante la carrera! En estos casos, debemos aplicar distintas técnicas de *aproximación* de la solución, entre las cuales se destacan los *métodos numéricos*."
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "# Método de Euler"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "Para resolver una EDO numéricamente en la computadora, tendremos que *aproximar* la solución continua $x: t \\mapsto x(t)$ con una versión con una cantidad finita de información, es decir, *discretizarla* de alguna forma.\n",
70 | "\n",
71 | "La manera más sencilla de hacerla es utilizando *diferencias finitas*. Empezaremos con el caso más sencillo, el llamado *método de Euler*."
72 | ]
73 | },
74 | {
75 | "cell_type": "markdown",
76 | "metadata": {},
77 | "source": [
78 | "#### Ejercicio 1\n",
79 | "\n",
80 | "(i) ¿Cuál es la aproximación más sencilla de la derivada $\\dot{x}(t)$, en términos de un tamaño de paso pequeño $h$?\n",
81 | "\n",
82 | "(ii) Aplica esta aproximación con la ecuación $\\dot{x} = f(x, t)$ para obtener una expresión para $x(t+h)$, es decir el valor *predicho* en el siguiente *paso* de tiempo, en términos del valor ya conocido $x(t)$.\n",
83 | "\n",
84 | "(iii) Implementa un paso de este *método de Euler* en una función `paso_euler` para una función `f` cualquiera. ¿Cuáles argumentos debe tomar?\n",
85 | "\n",
86 | "(iv) Ahora implementa el método de Euler completo en una función `euler`.\n",
87 | "Para hacerlo, crea un arreglo `ts` de los tiempos en los cuales se evaluará la función. Luego crea otro arreglo de ceros, con la función `zeros`. [Si pasas el arreglo `t` como argumento a esta función, creará un arreglo del mismo tamaño al poner `zeros(size(t))`.] Ahora implementa el paso (ii) en un algoritmo iterativo para actualizar los valores en el nuevo arreglo para cada tiempo sucesivamente.\n",
88 | "\n",
89 | "(v) Verifica que funcione tu método al aplicarlo a una función $f(t)$ sencilla que dependa *únicamente del tiempo*. [Recuerda que debes imponer una condición inicial.] ¿Cuál operación matemática acabas de llevar a cabo? Compara con la solución analítica."
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": null,
95 | "metadata": {},
96 | "outputs": [],
97 | "source": []
98 | },
99 | {
100 | "cell_type": "markdown",
101 | "metadata": {},
102 | "source": [
103 | "#### Ejercicio 2\n",
104 | "\n",
105 | "(i) Utiliza tu función `euler` para resolver la ecuación $\\dot{x} = -\\alpha x$, y compara tu solución numérica gráficamente con la solución analítica de la ecuación. ¿Qué pasa al variar el paso de tiempo? Hazlo interactivo.\n",
106 | "\n",
107 | "(ii) Dado que el método de Euler utiliza una aproximación, el resultado no es exacto. Fija una $t$ final y calcula el error (desde la solución analítica) en función del tamaño de paso $h$. ¿Cómo es la convergencia en función de $h$?"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": null,
113 | "metadata": {},
114 | "outputs": [],
115 | "source": []
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "metadata": {},
120 | "source": [
121 | "#### Ejercicio 3\n",
122 | "\n",
123 | "Considera la ecuación diferencial nolineal $\\dot{x} = x \\, (1-x)$, la cual modela la dinámica de una población; $x$ representa de alguna forma la densidad de población. \n",
124 | "\n",
125 | "(i) Dibuja el \"campo vectorial\" en el espacio $t$--$x$, es decir flechitas que indican en cuál dirección se camina en cada paso. \n",
126 | "\n",
127 | "[Pista: Utiliza la función `quiver`, con la sintaxis \n",
128 | "\n",
129 | " quiver(xs, ys, vectorfield=(vxs, vys))\n",
130 | " \n",
131 | "donde `xs` y `ys` son las coordenadas de las posiciones de las flechas, y `vxs` y `vys` las componentes de los vectores que dibujar.\n",
132 | "]\n",
133 | "\n",
134 | "(ii) Resúelvela numéricamente desde distintas condiciones iniciales (incluso las no-físicas) y dibuja las soluciones correspondientes. Interpreta el resultado de manera física (o biológica). "
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": null,
140 | "metadata": {},
141 | "outputs": [],
142 | "source": []
143 | },
144 | {
145 | "cell_type": "markdown",
146 | "metadata": {},
147 | "source": [
148 | "## Varias variables"
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "metadata": {},
154 | "source": [
155 | "El método de Euler se extiende directamente a EDOs con más de una variable."
156 | ]
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "#### Ejercicio 4\n",
163 | "\n",
164 | "(i) Escribe la ecuación diferencial que describe un oscilador armónico amortiguado.\n",
165 | "\n",
166 | "(ii) Recuerda que hay un \"truco\" para reducir una ecuación diferencial de segundo orden a dos ecuaciones de primer orden; ¿cuál es? ¿Qué resulta en el caso del oscilador armónico amortiguado?\n",
167 | "\n",
168 | "(iii) Deriva un método de Euler para las ecuaciones acopladas\n",
169 | "\n",
170 | "$$\\dot{x} = f(x, y);$$\n",
171 | "$$\\dot{y} = g(x, y).$$\n",
172 | "\n",
173 | "Para hacerlo, aplica la definición de la derivada de nuevo.\n",
174 | "\n",
175 | "(iv) Implementa el método.\n",
176 | "\n",
177 | "(v) Aplícalo al oscilador armónico amortiguado.\n",
178 | "Calcula trayectorias desde distintas condiciones iniciales y dibújalas, y ¡hazlo interactivo!\n",
179 | "Debes dibujar tanto $x(t)$ y $y(t)$ como funciones del tiempo, como el **espacio fase**. Dibuja también el campo vectorial en el espacio fase."
180 | ]
181 | },
182 | {
183 | "cell_type": "code",
184 | "execution_count": null,
185 | "metadata": {},
186 | "outputs": [],
187 | "source": []
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "metadata": {},
192 | "source": [
193 | "## El enfoque vectorial"
194 | ]
195 | },
196 | {
197 | "cell_type": "markdown",
198 | "metadata": {},
199 | "source": [
200 | "Recordemos que *cualquier* EDO, *incluídas las de orden superior* (es decir, con derivadas más altas que la primera de alguna función) se puede escribir de la siguiente manera, conteniendo únicamente primeras derivadas en el tiempo:\n",
201 | "\n",
202 | "$$\\dot{\\mathbf{x}} = \\mathbf{f}(\\mathbf{x}, t),$$\n",
203 | "\n",
204 | "es decir\n",
205 | "\n",
206 | "$$\\dot{\\mathbf{x}}(t) = \\mathbf{f}(\\mathbf{x}(t), t),$$\n",
207 | "\n",
208 | "donde ahora $\\mathbf{x} = (x_1, \\ldots, x_n) \\in \\mathbb{R}^n$ es un vector y $\\mathbf{f}: \\mathbb{R}^n \\to \\mathbb{R}^n$ es una función vectorial, que nos da un **campo vectorial** que indica en cuál dirección moverse desde cada punto del espacio."
209 | ]
210 | },
211 | {
212 | "cell_type": "markdown",
213 | "metadata": {},
214 | "source": [
215 | "#### Ejercicio 5\n",
216 | "\n",
217 | "(i) Escribe una función para hacer un paso del método de Euler para las ecuaciones acopladas\n",
218 | "\n",
219 | "$$\\dot{\\mathbf{x}} = \\mathbf{f}(\\mathbf{x}, t).$$\n",
220 | "\n",
221 | "El código ahora deberá ser *genérico*, es decir, debe funcionar para cualquier función $\\mathbf{f}$ y vector $\\mathbf{x}$.\n",
222 | "\n",
223 | "(ii) Escribe el método de Euler completo. \n",
224 | "\n",
225 | "(iii) Úsalo para resolver la caída libre y una caída con fricción lineal en la velocidad. Compara con el resultado exacto cuando puedes. Dibuja las resultados con distintos tamaños de fricción.\n",
226 | "\n",
227 | "(iv) Resuelve la caída libre con fricción cuadrática en la velocidad."
228 | ]
229 | },
230 | {
231 | "cell_type": "code",
232 | "execution_count": null,
233 | "metadata": {},
234 | "outputs": [],
235 | "source": []
236 | },
237 | {
238 | "cell_type": "markdown",
239 | "metadata": {},
240 | "source": [
241 | "#### Ejercicio 6\n",
242 | "\n",
243 | "(i) Resuelve numéricamente el problema del tiro parabólico con Euler para un proyectil que empieza en una altura $h>0$ con rapidez $1$ y ángulo inicial $\\alpha$, *hasta que* caiga al suelo. [Pista: ¿Cómo puedes implementar esta condición en tu código? Haz una nueva función si sea necesario.]\n",
244 | "\n",
245 | "(ii) Encuentra la distancia horizontal donde cae al suelo (el *rango*). Dibuja el resultado tal que puedas manipular interactivamente las condiciones iniciales. Encuentra numéricamente el ángulo que maximiza el rango. ¿Es correcto?\n",
246 | "\n",
247 | "(iii) Agrega fricción del aire al problema y agrégalo como otro parámetro que puedas manipular. ¿Cómo cambia el resultado de la pregunta (ii)?"
248 | ]
249 | },
250 | {
251 | "cell_type": "code",
252 | "execution_count": null,
253 | "metadata": {},
254 | "outputs": [],
255 | "source": []
256 | },
257 | {
258 | "cell_type": "markdown",
259 | "metadata": {},
260 | "source": [
261 | "#### Ejercicio 7"
262 | ]
263 | },
264 | {
265 | "cell_type": "markdown",
266 | "metadata": {},
267 | "source": [
268 | "En el caso del oscilador armónico, podemos hacer mucho de forma analítica. Pero no siempre es el caso:\n",
269 | "\n",
270 | "(i) Escribe la ecuación diferencial ordinaria que modela un péndulo simple amortiguado.\n",
271 | "\n",
272 | "(ii) Dibuja el campo vectorial y encuentra distintas trayectorias.\n",
273 | "\n",
274 | "(iii) ¿Los resultados coinciden con la intuición física?"
275 | ]
276 | },
277 | {
278 | "cell_type": "code",
279 | "execution_count": null,
280 | "metadata": {},
281 | "outputs": [],
282 | "source": []
283 | }
284 | ],
285 | "metadata": {
286 | "kernelspec": {
287 | "display_name": "Julia 1.0.0",
288 | "language": "julia",
289 | "name": "julia-1.0"
290 | },
291 | "language_info": {
292 | "file_extension": ".jl",
293 | "mimetype": "application/julia",
294 | "name": "julia",
295 | "version": "1.0.0"
296 | }
297 | },
298 | "nbformat": 4,
299 | "nbformat_minor": 1
300 | }
301 |
--------------------------------------------------------------------------------
/notebooks/05. Iteracion de punto fijo y bucles while.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# ¿Qué es un algoritmo?"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "En este notebook, empezaremos en serio nuestro estudio de algoritmos computacionales."
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "Un **algoritmo** es una \"receta\" computacional, que consiste en una serie de instrucciones para que la computadora lleve a cabo un cálculo dado. Gran parte del curso consistirá en desarrollar algoritmos para calcular, de forma numérica, distintas cantidades en la física, a partir de algún modelo matemático. El campo que se ocupa de diseñar y estudiar estos algoritmos es el **análisis numérico**. Su aplicación a problemas de física se puede decir que constituye la **física computacional**.\n",
22 | "\n",
23 | "Algunos algoritmos (por ejemplo, la eliminación gaussiana que veremos más adelante) proveen una manera de llevar a cabo un cálculo de manera \"exacta\" (dentro de las restricciones impuestas por el uso de números con precisión finita) en un número finito de pasos.\n",
24 | "\n",
25 | "Sin embargo, en general, no podemos esperar que haya una fórmula analítica cerrada para calcular las cantidades de interés de manera exacta. En este caso, será necesario emplear un algoritmo **iterativo**, que en principio podría correr ¡por un tiempo infinito! Lo pararemos cuando pensemos que el problema ya se resolvió de forma \"suficientemente buena\"."
26 | ]
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "metadata": {},
31 | "source": [
32 | "## Algoritmos iterativos"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "Un **algoritmo iterativo** repite un mismo cálculo un gran número de veces, modificando un valor (o varios valores) en el proceso, hasta que (en el mejor de los casos) converja a una solución.\n",
40 | "\n",
41 | "Un algorithmo iterativo empieza desde una adivinanza inicial $x_0$, y aplica un procedimiento / receta matemática, o sea alguna función $f$ (que puede ser complicada), para producir una siguiente adivinanza $x_1 := f(x_0)$. Esto se repite para producir una secuencia $x_0, x_1, \\ldots, x_n, \\ldots$, tales que\n",
42 | "\n",
43 | "$$x_1 = f(x_0)$$\n",
44 | "$$x_2 = f(x_1)$$\n",
45 | "$$x_3 = f(x_2)$$\n",
46 | "\n",
47 | "etc. En general, escribimos una iteración como \n",
48 | "\n",
49 | "$$x_{n+1} := f(x_n).$$\n",
50 | "\n",
51 | "Nota que entonces tenemos $x_2 = f(f(x_0))$, luego $x_3 = f(f(f(x_0)))$, etc., así que la iteración consiste en aplicar de forma iterada la función $f$."
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "La idea es que diseñemos el método para que la secuencia $x_n$ que se produce *converja* hacia un valor límite $x^*$ cuando $n \\to \\infty$, y que el $x^*$ resultante *¡sea solución del problema original*!\n",
59 | "\n",
60 | "Dado que no podemos llevar a cabo la iteración un número infinito de veces, se corta la iteración después de un cierto número de pasos, para dar una solución *aproximada*, que se acerca dentro de cierta *tolerancia* al resultado teórico exacto $x^*$. Por lo tanto, cualquier algoritmo iterativo requiere una condición de terminación. En muchos casos, podemos lograr que la tolerancia sea del orden de magnitud del llamado **épsilon de la máquina**, que es el número $\\epsilon$ más pequeño tal que la computadora distinga $1$ de $1 + \\epsilon$. Nota que esto depende de la **precisión** de los números flotantes; esto, a su vez, es consecuencia de la representación interna de los mismos, lo cual veremos más adelante en el curso."
61 | ]
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "#### Ejercicio 1 \n",
68 | "\n",
69 | "(i) Utiliza la función `nextfloat` para encontrar el épsilon de la máquina.\n",
70 | "\n",
71 | "(ii) Verifica lo mismo utilizando la función `eps`.\n",
72 | "\n",
73 | "(iii) Este valor es igual a $2^{-n}$. Encuentra el valor de $n$.\n",
74 | "\n",
75 | "(iv) Haz lo mismo para `Float32`. [Pista: Para convertir un número `x` a `Float32`, se pone `Float32(x)`.]"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "metadata": {
82 | "collapsed": true
83 | },
84 | "outputs": [],
85 | "source": []
86 | },
87 | {
88 | "cell_type": "markdown",
89 | "metadata": {},
90 | "source": [
91 | "# Iteraciones de punto fijo"
92 | ]
93 | },
94 | {
95 | "cell_type": "markdown",
96 | "metadata": {},
97 | "source": [
98 | "En la computadora, podríamos empezar con un arreglo vacío con cierto número de elementos, de saber cuánto durará la iteración.\n",
99 | "\n",
100 | "Pero, en general, no sabemos cuánto durará. Por lo tanto, es más usual pensar en el **valor actual** de $x$, y el **valor siguiente** de $x$. Dentro del cuerpo del bucle, usamos el valor actual de $x$ para calcular el valor nuevo. Al final del cuerpo del bucle, debemos actualizar el \"valor actual\"."
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "#### Ejercicio 2\n",
108 | "\n",
109 | "(i) Define la función $f_1(x) = \\frac{x}{2} - 1$.\n",
110 | "\n",
111 | "(ii) Toma una condición inicial $x_0$ y lleva a cabo la iteración a mano. ¿Qué observas?\n",
112 | "\n",
113 | "(iii) Utiliza un bucle `for` para ver cómo son los primeros $N$ iterados $x_n$. Haz una función que tome como argumento $x_0$ y $N$.\n",
114 | "\n",
115 | "(iv) Repite la iteración para varios valores de $x_0$ y dibuja los iterados enen una sola gráfica. ¿Cuál tipo de gráfica es la más apropiada? ¿Qué observas?\n",
116 | "\n",
117 | "(v) Si $x_{n+1} = f(x_n)$ y $x_n \\to x^*$ cuando $n \\to \\infty$, ¿cuál ecuación satisface $x^*$? ¿Cómo podemos llamar entonces a $x^*$? Resuelva esta ecuación para $f_1$. ¿Concuerda con lo que hayas visto?"
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": null,
123 | "metadata": {
124 | "collapsed": true
125 | },
126 | "outputs": [],
127 | "source": []
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "#### Ejercicio 3\n",
134 | "\n",
135 | "(i) Define una función `iterar` que lleva a cabo lo que hiciste en la pregunta 1. Debe aceptar como su primer argumento (el nombre de) la función `f` que iterar, así como el número de veces que se iterará, y la condición inicial. Regresa un arreglo de los iterados.\n",
136 | "\n",
137 | "(ii) Utiliza la función para iterar la función $f_2(x) = \\cos(x)$, y dibuja el resultado para distintas condiciones iniciales.\n",
138 | "\n",
139 | "(iii) ¿Adónde converge la iteración? ¿Cuál ecuación hemos resuelto?\n",
140 | "\n",
141 | "(iv) Utiliza `@manipulate` para tener una versión dinámica de la visualización, en la cual puedes cambiar tanto la condición inicial, como el número de iterados."
142 | ]
143 | },
144 | {
145 | "cell_type": "code",
146 | "execution_count": null,
147 | "metadata": {
148 | "collapsed": true
149 | },
150 | "outputs": [],
151 | "source": []
152 | },
153 | {
154 | "cell_type": "markdown",
155 | "metadata": {},
156 | "source": [
157 | "#### Ejercicio 4 \n",
158 | "\n",
159 | "(i) ¿Qué ocurre si iteras la función $f_3(x) = 2x + 1$?\n",
160 | "\n",
161 | "(ii) ¿Puedes adivinar cuál es una condición para que una iteración converja?"
162 | ]
163 | },
164 | {
165 | "cell_type": "code",
166 | "execution_count": null,
167 | "metadata": {
168 | "collapsed": true
169 | },
170 | "outputs": [],
171 | "source": []
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {},
176 | "source": [
177 | "#### Ejercicio 5\n",
178 | "\n",
179 | "A menudo, se utiliza una iteración de este tipo para resolver ecuaciones. \n",
180 | "\n",
181 | "(i) Inventa una iteración de la forma $x_{n+1} = f(x_n)$ para resolver la ecuación $x^2 + x - 1 = 0$. ¿Para cuáles $x_0$ funciona? ¿A cuál solución converge?\n",
182 | "\n",
183 | "(ii) Inventa otra. ¿Funciona para $x_0$ diferentes?\n",
184 | "\n",
185 | "(iii) Nota que hay algunas iteraciones que **no converjan**. Por ejemplo, ¿qué ocurre con la iteración $x_{n+1} = 1 - x_n^2$?"
186 | ]
187 | },
188 | {
189 | "cell_type": "markdown",
190 | "metadata": {},
191 | "source": [
192 | "## Bucles `while`"
193 | ]
194 | },
195 | {
196 | "cell_type": "markdown",
197 | "metadata": {},
198 | "source": [
199 | "En lo anterior, usamos un bucle `for`, que requiere que sepamos de antemano el número de iteraciones que queramos.\n",
200 | "Sin embargo, en este tipo de problemas, es más natural esperar **hasta que** converja, sin saber cuánto tiempo tomará.\n",
201 | "\n",
202 | "Para esto, podemos ocupar otro tipo de bucle, un bucle `while` (\"mientras\", en español). Un bucle de este tipo repite los comandos en el cuerpo del bucle **mientras** una condición siga cierta. Su sintaxis es como sigue:"
203 | ]
204 | },
205 | {
206 | "cell_type": "markdown",
207 | "metadata": {},
208 | "source": [
209 | "```\n",
210 | "while \n",
211 | " [haz esto]\n",
212 | " [y esto]\n",
213 | "end\n",
214 | "```\n",
215 | "\n",
216 | "Sin embargo, para evitar bucles infinitos, a menudo es sensato incluir un contador para que no pueda haber demasiadas (posiblemente infinitas) iteraciones."
217 | ]
218 | },
219 | {
220 | "cell_type": "markdown",
221 | "metadata": {},
222 | "source": [
223 | "Mientras que en un bucle `for` hay un contador que se actualiza automáticamente, en un bucle `while` **nosotros somos los responsables** de tener una variable que actúe como contador."
224 | ]
225 | },
226 | {
227 | "cell_type": "markdown",
228 | "metadata": {},
229 | "source": [
230 | "#### Ejercicio 5\n",
231 | "\n",
232 | "(i) Utilice un bucle `while` para contar de 1 a 10.\n",
233 | "\n",
234 | "(ii) Utilice un bucle `while` para encontrar la potencia de 2 más grande debajo de un número dado.\n",
235 | "\n",
236 | "(iii) Repite lo mismo con un bucle `for`, usando la palabra clave `break` para salir del bucle cuando una cierta condición se satisfaga."
237 | ]
238 | },
239 | {
240 | "cell_type": "markdown",
241 | "metadata": {},
242 | "source": [
243 | "## Bucles while e iteraciones de punto fijo"
244 | ]
245 | },
246 | {
247 | "cell_type": "markdown",
248 | "metadata": {},
249 | "source": [
250 | "#### Ejercicio 6\n",
251 | "\n",
252 | "(i) Modifica tu función `iterar` para que utilice un bucle `while` para la iteración de una función. Agrega un argumento opcional que da una **tolerancia** razonable, y repite la iteración **hasta que** la distancia entre un iterado y el siguiente sea menor a la tolerancia. [Pista: ¿Cuál función matemática da la distancia entre dos números en una dimensión. Encuentra la función de Julia que lo hace.] \n",
253 | "\n",
254 | "(ii) Utiliza una iteración para resolver la ecuación $\\tan(x) = x$. Dibuja la solución. ¿En qué rama de la física surge esta ecuación?"
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": null,
260 | "metadata": {
261 | "collapsed": true
262 | },
263 | "outputs": [],
264 | "source": []
265 | },
266 | {
267 | "cell_type": "markdown",
268 | "metadata": {},
269 | "source": [
270 | "## Haz tu propia biblioteca "
271 | ]
272 | },
273 | {
274 | "cell_type": "markdown",
275 | "metadata": {},
276 | "source": [
277 | "#### Ejercicio 7"
278 | ]
279 | },
280 | {
281 | "cell_type": "markdown",
282 | "metadata": {},
283 | "source": [
284 | "Puedes ¡hacer tu propia biblioteca de Julia!, con funciones útiles que vayas haciendo, para que ya no tengas que reescribir las mismas funciones una y otra vez.\n",
285 | "\n",
286 | "(i) Guarda la función `iterar` en un archivo que se llama `herramientas.jl`. Iremos agregando más métodos a este archivo.\n",
287 | "\n",
288 | "(ii) Verifica en un nuevo notebook que al poner `include(\"herramientas.jl\")`, tienes acceso a la función `iterar`. [Nota que el notebook debe estar en el mismo directorio, o bien hay que poner la dirección competa de `herramientas.jl`.]"
289 | ]
290 | },
291 | {
292 | "cell_type": "code",
293 | "execution_count": null,
294 | "metadata": {
295 | "collapsed": true
296 | },
297 | "outputs": [],
298 | "source": []
299 | }
300 | ],
301 | "metadata": {
302 | "kernelspec": {
303 | "display_name": "Julia 0.6.2",
304 | "language": "julia",
305 | "name": "julia-0.6"
306 | },
307 | "language_info": {
308 | "file_extension": ".jl",
309 | "mimetype": "application/julia",
310 | "name": "julia",
311 | "version": "0.6.2"
312 | },
313 | "toc": {
314 | "colors": {
315 | "hover_highlight": "#DAA520",
316 | "running_highlight": "#FF0000",
317 | "selected_highlight": "#FFD700"
318 | },
319 | "moveMenuLeft": true,
320 | "nav_menu": {
321 | "height": "48px",
322 | "width": "252px"
323 | },
324 | "navigate_menu": true,
325 | "number_sections": true,
326 | "sideBar": true,
327 | "threshold": "1",
328 | "toc_cell": false,
329 | "toc_section_display": "block",
330 | "toc_window_display": false
331 | }
332 | },
333 | "nbformat": 4,
334 | "nbformat_minor": 1
335 | }
336 |
--------------------------------------------------------------------------------
/en_clase/10 oct - Funciones vectoriales en Julia.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Funciones vectoriales en Julia"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "¿Cómo puedo escribir una función `f` que coma un vector y regrese un vector?"
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "Como ejemplo: $f(\\mathbf{x}) = (x + y, y^2 - x)$"
22 | ]
23 | },
24 | {
25 | "cell_type": "code",
26 | "execution_count": 3,
27 | "metadata": {},
28 | "outputs": [
29 | {
30 | "data": {
31 | "text/plain": [
32 | "f (generic function with 1 method)"
33 | ]
34 | },
35 | "execution_count": 3,
36 | "metadata": {},
37 | "output_type": "execute_result"
38 | }
39 | ],
40 | "source": [
41 | "function f(x, t)\n",
42 | " \n",
43 | " return [x[1] + x[2], x[2]^2 - x[1] ] \n",
44 | "end"
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "execution_count": 4,
50 | "metadata": {},
51 | "outputs": [
52 | {
53 | "data": {
54 | "text/plain": [
55 | "2-element Array{Int64,1}:\n",
56 | " 5\n",
57 | " 1"
58 | ]
59 | },
60 | "execution_count": 4,
61 | "metadata": {},
62 | "output_type": "execute_result"
63 | }
64 | ],
65 | "source": [
66 | "f([3, 2], 0)"
67 | ]
68 | },
69 | {
70 | "cell_type": "code",
71 | "execution_count": 5,
72 | "metadata": {},
73 | "outputs": [
74 | {
75 | "data": {
76 | "text/plain": [
77 | "g (generic function with 1 method)"
78 | ]
79 | },
80 | "execution_count": 5,
81 | "metadata": {},
82 | "output_type": "execute_result"
83 | }
84 | ],
85 | "source": [
86 | "function g(xx, t)\n",
87 | " \n",
88 | " x = xx[1]\n",
89 | " y = xx[2]\n",
90 | " \n",
91 | " return [x + y, y^2 - x]\n",
92 | "end"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": 6,
98 | "metadata": {},
99 | "outputs": [
100 | {
101 | "data": {
102 | "text/plain": [
103 | "2-element Array{Int64,1}:\n",
104 | " 5\n",
105 | " 1"
106 | ]
107 | },
108 | "execution_count": 6,
109 | "metadata": {},
110 | "output_type": "execute_result"
111 | }
112 | ],
113 | "source": [
114 | "g([3, 2], 0)"
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "execution_count": 7,
120 | "metadata": {},
121 | "outputs": [
122 | {
123 | "data": {
124 | "text/plain": [
125 | "h (generic function with 1 method)"
126 | ]
127 | },
128 | "execution_count": 7,
129 | "metadata": {},
130 | "output_type": "execute_result"
131 | }
132 | ],
133 | "source": [
134 | "function h(xx, t)\n",
135 | " \n",
136 | " (x, y) = xx\n",
137 | " \n",
138 | " return [x + y, y^2 - x]\n",
139 | "end"
140 | ]
141 | },
142 | {
143 | "cell_type": "code",
144 | "execution_count": 8,
145 | "metadata": {},
146 | "outputs": [
147 | {
148 | "data": {
149 | "text/plain": [
150 | "2-element Array{Int64,1}:\n",
151 | " 5\n",
152 | " 1"
153 | ]
154 | },
155 | "execution_count": 8,
156 | "metadata": {},
157 | "output_type": "execute_result"
158 | }
159 | ],
160 | "source": [
161 | "h([3, 2], 0)"
162 | ]
163 | },
164 | {
165 | "cell_type": "code",
166 | "execution_count": 9,
167 | "metadata": {},
168 | "outputs": [
169 | {
170 | "data": {
171 | "text/plain": [
172 | "h2 (generic function with 1 method)"
173 | ]
174 | },
175 | "execution_count": 9,
176 | "metadata": {},
177 | "output_type": "execute_result"
178 | }
179 | ],
180 | "source": [
181 | "function h2(xx, t)\n",
182 | " \n",
183 | " (x, y, z) = xx\n",
184 | " \n",
185 | " return [x + y, y^2 - x]\n",
186 | "end"
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": 10,
192 | "metadata": {},
193 | "outputs": [
194 | {
195 | "ename": "BoundsError",
196 | "evalue": "BoundsError: attempt to access 2-element Array{Int64,1} at index [3]",
197 | "output_type": "error",
198 | "traceback": [
199 | "BoundsError: attempt to access 2-element Array{Int64,1} at index [3]",
200 | "",
201 | "Stacktrace:",
202 | " [1] getindex at ./array.jl:731 [inlined]",
203 | " [2] indexed_iterate at ./tuple.jl:61 [inlined]",
204 | " [3] h2(::Array{Int64,1}, ::Int64) at ./In[9]:3",
205 | " [4] top-level scope at In[10]:1"
206 | ]
207 | }
208 | ],
209 | "source": [
210 | "h2([3, 2], 0)"
211 | ]
212 | },
213 | {
214 | "cell_type": "code",
215 | "execution_count": 11,
216 | "metadata": {},
217 | "outputs": [
218 | {
219 | "ename": "BoundsError",
220 | "evalue": "BoundsError: attempt to access 1\n at index [2]",
221 | "output_type": "error",
222 | "traceback": [
223 | "BoundsError: attempt to access 1\n at index [2]",
224 | "",
225 | "Stacktrace:",
226 | " [1] indexed_iterate(::Int64, ::Int64, ::Nothing) at ./tuple.jl:69",
227 | " [2] h2(::Int64, ::Int64) at ./In[9]:3",
228 | " [3] top-level scope at In[11]:1"
229 | ]
230 | }
231 | ],
232 | "source": [
233 | "h2(1, 3)"
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "execution_count": 12,
239 | "metadata": {},
240 | "outputs": [
241 | {
242 | "data": {
243 | "text/plain": [
244 | "h3 (generic function with 1 method)"
245 | ]
246 | },
247 | "execution_count": 12,
248 | "metadata": {},
249 | "output_type": "execute_result"
250 | }
251 | ],
252 | "source": [
253 | "function h3(xx::Vector, t)\n",
254 | " \n",
255 | " (x, y) = xx\n",
256 | " \n",
257 | " return [x + y, y^2 - x]\n",
258 | "end"
259 | ]
260 | },
261 | {
262 | "cell_type": "code",
263 | "execution_count": 13,
264 | "metadata": {},
265 | "outputs": [
266 | {
267 | "data": {
268 | "text/plain": [
269 | "2-element Array{Int64,1}:\n",
270 | " 5\n",
271 | " 1"
272 | ]
273 | },
274 | "execution_count": 13,
275 | "metadata": {},
276 | "output_type": "execute_result"
277 | }
278 | ],
279 | "source": [
280 | "h3([3, 2], 0)"
281 | ]
282 | },
283 | {
284 | "cell_type": "code",
285 | "execution_count": 14,
286 | "metadata": {},
287 | "outputs": [
288 | {
289 | "ename": "MethodError",
290 | "evalue": "MethodError: no method matching h3(::Int64, ::Int64)\nClosest candidates are:\n h3(!Matched::Array{T,1} where T, ::Any) at In[12]:3",
291 | "output_type": "error",
292 | "traceback": [
293 | "MethodError: no method matching h3(::Int64, ::Int64)\nClosest candidates are:\n h3(!Matched::Array{T,1} where T, ::Any) at In[12]:3",
294 | "",
295 | "Stacktrace:",
296 | " [1] top-level scope at In[14]:1"
297 | ]
298 | }
299 | ],
300 | "source": [
301 | "h3(3, 0)"
302 | ]
303 | },
304 | {
305 | "cell_type": "code",
306 | "execution_count": 15,
307 | "metadata": {},
308 | "outputs": [
309 | {
310 | "ename": "MethodError",
311 | "evalue": "MethodError: no method matching h3(::Tuple{Int64,Int64}, ::Int64)\nClosest candidates are:\n h3(!Matched::Array{T,1} where T, ::Any) at In[12]:3",
312 | "output_type": "error",
313 | "traceback": [
314 | "MethodError: no method matching h3(::Tuple{Int64,Int64}, ::Int64)\nClosest candidates are:\n h3(!Matched::Array{T,1} where T, ::Any) at In[12]:3",
315 | "",
316 | "Stacktrace:",
317 | " [1] top-level scope at In[15]:1"
318 | ]
319 | }
320 | ],
321 | "source": [
322 | "h3( (3, 2), 0)"
323 | ]
324 | },
325 | {
326 | "cell_type": "code",
327 | "execution_count": 16,
328 | "metadata": {},
329 | "outputs": [
330 | {
331 | "data": {
332 | "text/plain": [
333 | "2-element Array{Int64,1}:\n",
334 | " 5\n",
335 | " 1"
336 | ]
337 | },
338 | "execution_count": 16,
339 | "metadata": {},
340 | "output_type": "execute_result"
341 | }
342 | ],
343 | "source": [
344 | "h( (3, 2), 0)"
345 | ]
346 | },
347 | {
348 | "cell_type": "code",
349 | "execution_count": 17,
350 | "metadata": {},
351 | "outputs": [
352 | {
353 | "name": "stdout",
354 | "output_type": "stream",
355 | "text": [
356 | "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n",
357 | "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n",
358 | "\u001b[2K\u001b[?25h[1mFetching:\u001b[22m\u001b[39m [========================================>] 100.0 %.0 %14.6 %> ] 29.2 %\u001b[36m\u001b[1mFetching:\u001b[22m\u001b[39m [=============> ] 31.1 %> ] 45.5 %\u001b[36m\u001b[1mFetching:\u001b[22m\u001b[39m [=======================> ] 55.9 % ] 70.4 %\u001b[36m\u001b[1mFetching:\u001b[22m\u001b[39m [==============================> ] 74.9 %> ] 89.4 %\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n",
359 | "\u001b[32m\u001b[1m Installed\u001b[22m\u001b[39m IJulia ─────── v1.13.0\n",
360 | "\u001b[32m\u001b[1m Installed\u001b[22m\u001b[39m Plots ──────── v0.20.5\n",
361 | "\u001b[32m\u001b[1m Installed\u001b[22m\u001b[39m UnicodePlots ─ v0.3.1\n",
362 | "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m `~/.julia/environments/v1.0/Project.toml`\n",
363 | " \u001b[90m [7073ff75]\u001b[39m\u001b[93m ↑ IJulia v1.12.0 ⇒ v1.13.0\u001b[39m\n",
364 | " \u001b[90m [138f1668]\u001b[39m\u001b[31m ? IntervalConstraintProgramming v0.8.0+ [`~/.julia/environments/v1.0/../../dev/IntervalConstraintProgramming`] ⇒ v0.9.0+ [`~/.julia/environments/v1.0/../../dev/IntervalConstraintProgramming`]\u001b[39m\n",
365 | " \u001b[90m [c7c68f13]\u001b[39m\u001b[93m ~ IntervalOptimisation v0.2.0+ #dps/v0.7 (https://github.com/JuliaIntervals/IntervalOptimisation.jl.git) ⇒ v0.3.0+ #dps/v0.7 (https://github.com/JuliaIntervals/IntervalOptimisation.jl.git)\u001b[39m\n",
366 | " \u001b[90m [91a5bcdd]\u001b[39m\u001b[93m ↑ Plots v0.20.4 ⇒ v0.20.5\u001b[39m\n",
367 | " \u001b[90m [b8865327]\u001b[39m\u001b[92m + UnicodePlots v0.3.1\u001b[39m\n",
368 | "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m `~/.julia/environments/v1.0/Manifest.toml`\n",
369 | " \u001b[90m [7073ff75]\u001b[39m\u001b[93m ↑ IJulia v1.12.0 ⇒ v1.13.0\u001b[39m\n",
370 | " \u001b[90m [138f1668]\u001b[39m\u001b[31m ? IntervalConstraintProgramming v0.8.0+ [`~/.julia/environments/v1.0/../../dev/IntervalConstraintProgramming`] ⇒ v0.9.0+ [`~/.julia/environments/v1.0/../../dev/IntervalConstraintProgramming`]\u001b[39m\n",
371 | " \u001b[90m [c7c68f13]\u001b[39m\u001b[93m ~ IntervalOptimisation v0.2.0+ #dps/v0.7 (https://github.com/JuliaIntervals/IntervalOptimisation.jl.git) ⇒ v0.3.0+ #dps/v0.7 (https://github.com/JuliaIntervals/IntervalOptimisation.jl.git)\u001b[39m\n",
372 | " \u001b[90m [91a5bcdd]\u001b[39m\u001b[93m ↑ Plots v0.20.4 ⇒ v0.20.5\u001b[39m\n",
373 | " \u001b[90m [b8865327]\u001b[39m\u001b[92m + UnicodePlots v0.3.1\u001b[39m\n",
374 | "\u001b[32m\u001b[1m Building\u001b[22m\u001b[39m IJulia → `~/.julia/packages/IJulia/0cLgR/deps/build.log`\n",
375 | "\u001b[32m\u001b[1m Building\u001b[22m\u001b[39m Plots ─→ `~/.julia/packages/Plots/7o1Vu/deps/build.log`\n"
376 | ]
377 | }
378 | ],
379 | "source": [
380 | "]add UnicodePlots\n"
381 | ]
382 | },
383 | {
384 | "cell_type": "code",
385 | "execution_count": 18,
386 | "metadata": {},
387 | "outputs": [
388 | {
389 | "name": "stderr",
390 | "output_type": "stream",
391 | "text": [
392 | "┌ Info: Recompiling stale cache file /Users/dpsanders/.julia/compiled/v1.0/Plots/ld3vC.ji for Plots [91a5bcdd-55d7-5caf-9e0b-520d859cae80]\n",
393 | "└ @ Base loading.jl:1184\n"
394 | ]
395 | }
396 | ],
397 | "source": [
398 | " using Plots"
399 | ]
400 | },
401 | {
402 | "cell_type": "code",
403 | "execution_count": 19,
404 | "metadata": {},
405 | "outputs": [
406 | {
407 | "name": "stderr",
408 | "output_type": "stream",
409 | "text": [
410 | "┌ Info: Precompiling UnicodePlots [b8865327-cd53-5732-bb35-84acbb429228]\n",
411 | "└ @ Base loading.jl:1186\n"
412 | ]
413 | },
414 | {
415 | "data": {
416 | "text/plain": [
417 | "Plots.UnicodePlotsBackend()"
418 | ]
419 | },
420 | "execution_count": 19,
421 | "metadata": {},
422 | "output_type": "execute_result"
423 | }
424 | ],
425 | "source": [
426 | "unicodeplots()"
427 | ]
428 | },
429 | {
430 | "cell_type": "code",
431 | "execution_count": 23,
432 | "metadata": {},
433 | "outputs": [
434 | {
435 | "data": {
436 | "text/plain": [
437 | " +------------------------------------------------------------+ \n",
438 | " 2 | , | y1\n",
439 | " | | | \n",
440 | " | | | \n",
441 | " | | | \n",
442 | " | | | \n",
443 | " | /\"\". | ./\"\\, ./\"\\. | \n",
444 | " | / . | / \", / \\. | \n",
445 | " |, ,` \", |/ \\. / \\ | \n",
446 | " |\\. .` l |` \\ . \\ | \n",
447 | " | \\ / \". | \", .` |. | \n",
448 | " |\"\\7\"\"\"\"\"\"\")\"\"\"\"\"\"\"\"\"\\7\"\"\"\"\"\"\")F\"\"\"\"\"\"\"\"]\"\"\"\"\"\"\"\"7\"\"\"\"\"\"\"\"\"l`| \n",
449 | " | l ./ l ./| . ,` .| \n",
450 | " | . / \". / | \", / '| \n",
451 | " | |. .` \\. . | l. / | \n",
452 | " | \\._,` \\u_/` | \\u_/ | \n",
453 | " | | | \n",
454 | " | | | \n",
455 | " | | | \n",
456 | " | | | \n",
457 | " -2 | | | \n",
458 | " +------------------------------------------------------------+ \n",
459 | " -10 10\n"
460 | ]
461 | },
462 | "execution_count": 23,
463 | "metadata": {},
464 | "output_type": "execute_result"
465 | }
466 | ],
467 | "source": [
468 | "plot(sin, -10, 10)\n",
469 | "xlims!(-10, 10)"
470 | ]
471 | },
472 | {
473 | "cell_type": "code",
474 | "execution_count": null,
475 | "metadata": {},
476 | "outputs": [],
477 | "source": []
478 | }
479 | ],
480 | "metadata": {
481 | "kernelspec": {
482 | "display_name": "Julia 1.0.0",
483 | "language": "julia",
484 | "name": "julia-1.0"
485 | },
486 | "language_info": {
487 | "file_extension": ".jl",
488 | "mimetype": "application/julia",
489 | "name": "julia",
490 | "version": "1.0.0"
491 | }
492 | },
493 | "nbformat": 4,
494 | "nbformat_minor": 2
495 | }
496 |
--------------------------------------------------------------------------------
/en_clase/8 octubre Euler.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# El método de Euler"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Queremos resolver\n",
15 | "\n",
16 | "$$\\dot{x} = f(x, t)$$"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "Idea: Aproximar la solución $x(t)$ al discretizarla:\n",
24 | "\n",
25 | "- Avanzar de pasito en pasito: de $t_0$, avanzamos a $t_1 = t_0 + h$, con $h \\ll t_f - t_0$.\n",
26 | "\n",
27 | "Por lo tanto, queremos calcular\n",
28 | "\n",
29 | "$x(t_0+h) \\simeq x(t_0) + h \\cdot \\dot{x}(t_0) + \\mathcal{O}(h^2) = x(t_0) + h \\cdot f(x_0, t_0) + \\mathcal{O}(h^2)$\n",
30 | "\n",
31 | "Si llamamos $x_n$ la aproximación en el $n$-ésimo paso, o sea al tiempo $t_n$, tenemos un **paso del método de Euler**:\n",
32 | "\n",
33 | "$$\\boxed{x_{n+1} = x_n + h \\cdot f(x_n, t_n)}$$\n",
34 | "\n",
35 | "\n",
36 | "\n"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "metadata": {},
42 | "source": [
43 | "## Implementación de Euler "
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": 2,
49 | "metadata": {},
50 | "outputs": [
51 | {
52 | "data": {
53 | "text/plain": [
54 | "paso_euler (generic function with 1 method)"
55 | ]
56 | },
57 | "execution_count": 2,
58 | "metadata": {},
59 | "output_type": "execute_result"
60 | }
61 | ],
62 | "source": [
63 | "function paso_euler(f, x, t, h)\n",
64 | " \n",
65 | " x_siguiente = x + h * f(x, t)\n",
66 | "\n",
67 | " return x_siguiente\n",
68 | "end"
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "execution_count": 3,
74 | "metadata": {},
75 | "outputs": [
76 | {
77 | "data": {
78 | "text/plain": [
79 | "g (generic function with 1 method)"
80 | ]
81 | },
82 | "execution_count": 3,
83 | "metadata": {},
84 | "output_type": "execute_result"
85 | }
86 | ],
87 | "source": [
88 | "g(x) = x"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": 4,
94 | "metadata": {},
95 | "outputs": [
96 | {
97 | "ename": "MethodError",
98 | "evalue": "MethodError: no method matching g(::Float64, ::Float64)\nClosest candidates are:\n g(::Any) at In[3]:1",
99 | "output_type": "error",
100 | "traceback": [
101 | "MethodError: no method matching g(::Float64, ::Float64)\nClosest candidates are:\n g(::Any) at In[3]:1",
102 | "",
103 | "Stacktrace:",
104 | " [1] paso_euler(::typeof(g), ::Float64, ::Float64, ::Float64) at ./In[2]:3",
105 | " [2] top-level scope at In[4]:1"
106 | ]
107 | }
108 | ],
109 | "source": [
110 | "paso_euler(g, 1.0, 3.0, 0.1)"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": 5,
116 | "metadata": {},
117 | "outputs": [
118 | {
119 | "data": {
120 | "text/plain": [
121 | "g (generic function with 2 methods)"
122 | ]
123 | },
124 | "execution_count": 5,
125 | "metadata": {},
126 | "output_type": "execute_result"
127 | }
128 | ],
129 | "source": [
130 | "g(x, t) = x"
131 | ]
132 | },
133 | {
134 | "cell_type": "code",
135 | "execution_count": 7,
136 | "metadata": {},
137 | "outputs": [
138 | {
139 | "data": {
140 | "text/plain": [
141 | "\u001b[32m\u001b[1mTest Passed\u001b[22m\u001b[39m"
142 | ]
143 | },
144 | "execution_count": 7,
145 | "metadata": {},
146 | "output_type": "execute_result"
147 | }
148 | ],
149 | "source": [
150 | "using Test # using Base.Test en Julia 0.6\n",
151 | "\n",
152 | "@test paso_euler(g, 1.0, 3.0, 0.1) == 1.1"
153 | ]
154 | },
155 | {
156 | "cell_type": "code",
157 | "execution_count": 8,
158 | "metadata": {},
159 | "outputs": [
160 | {
161 | "name": "stdout",
162 | "output_type": "stream",
163 | "text": [
164 | "\u001b[91m\u001b[1mTest Failed\u001b[22m\u001b[39m at \u001b[39m\u001b[1mIn[8]:1\u001b[22m\n",
165 | " Expression: paso_euler(g, 1.0, 3.0, 0.1) == 1.0\n",
166 | " Evaluated: 1.1 == 1.0\n"
167 | ]
168 | },
169 | {
170 | "ename": "Test.FallbackTestSetException",
171 | "evalue": "There was an error during testing",
172 | "output_type": "error",
173 | "traceback": [
174 | "There was an error during testing",
175 | "",
176 | "Stacktrace:",
177 | " [1] record(::Test.FallbackTestSet, ::Test.Fail) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/Test/src/Test.jl:707",
178 | " [2] do_test(::Test.Returned, ::Expr) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/Test/src/Test.jl:496",
179 | " [3] top-level scope at In[8]:1"
180 | ]
181 | }
182 | ],
183 | "source": [
184 | "@test paso_euler(g, 1.0, 3.0, 0.1) == 1.0"
185 | ]
186 | },
187 | {
188 | "cell_type": "code",
189 | "execution_count": 11,
190 | "metadata": {},
191 | "outputs": [
192 | {
193 | "name": "stdout",
194 | "output_type": "stream",
195 | "text": [
196 | "\u001b[37m\u001b[1mTest Summary: | \u001b[22m\u001b[39m\u001b[32m\u001b[1mPass \u001b[22m\u001b[39m\u001b[36m\u001b[1mTotal\u001b[22m\u001b[39m\n",
197 | "Tests para paso_euler | \u001b[32m 2 \u001b[39m\u001b[36m 2\u001b[39m\n"
198 | ]
199 | },
200 | {
201 | "data": {
202 | "text/plain": [
203 | "Test.DefaultTestSet(\"Tests para paso_euler\", Any[], 2, false)"
204 | ]
205 | },
206 | "execution_count": 11,
207 | "metadata": {},
208 | "output_type": "execute_result"
209 | }
210 | ],
211 | "source": [
212 | "@testset \"Tests para paso_euler\" begin\n",
213 | " g(x, t) = x\n",
214 | " \n",
215 | " @test paso_euler(g, 1.0, 3.0, 0.1) == 1.1\n",
216 | " @test paso_euler(g, 1.0, 3.0, 0.2) == 1.2\n",
217 | "end"
218 | ]
219 | },
220 | {
221 | "cell_type": "markdown",
222 | "metadata": {},
223 | "source": [
224 | "Se puede hacer \"Test-driven development\"\n",
225 | "(Desarrollo dirigido por las pruebas): escribes *primero* los tests, y luego las funciones"
226 | ]
227 | },
228 | {
229 | "cell_type": "markdown",
230 | "metadata": {},
231 | "source": [
232 | "### Euler\n",
233 | "\n",
234 | "La función `euler` integrará la EDO $\\dot{x} = f$ de $(x_0, t_0)$ hasta $t_f$ con pasos $h$"
235 | ]
236 | },
237 | {
238 | "cell_type": "code",
239 | "execution_count": 16,
240 | "metadata": {},
241 | "outputs": [
242 | {
243 | "data": {
244 | "text/plain": [
245 | "euler (generic function with 1 method)"
246 | ]
247 | },
248 | "execution_count": 16,
249 | "metadata": {},
250 | "output_type": "execute_result"
251 | }
252 | ],
253 | "source": [
254 | "function euler(f, x0; t0=0.0, tf, h)\n",
255 | " \n",
256 | " @show t0, tf, h\n",
257 | " \n",
258 | "end"
259 | ]
260 | },
261 | {
262 | "cell_type": "code",
263 | "execution_count": 17,
264 | "metadata": {},
265 | "outputs": [
266 | {
267 | "ename": "UndefKeywordError",
268 | "evalue": "UndefKeywordError: keyword argument tf not assigned",
269 | "output_type": "error",
270 | "traceback": [
271 | "UndefKeywordError: keyword argument tf not assigned",
272 | "",
273 | "Stacktrace:",
274 | " [1] euler(::Function, ::Float64) at ./In[16]:3",
275 | " [2] top-level scope at In[17]:1"
276 | ]
277 | }
278 | ],
279 | "source": [
280 | "euler(g, 1.0)"
281 | ]
282 | },
283 | {
284 | "cell_type": "code",
285 | "execution_count": 18,
286 | "metadata": {},
287 | "outputs": [
288 | {
289 | "name": "stdout",
290 | "output_type": "stream",
291 | "text": [
292 | "(t0, tf, h) = (0.0, 10.0, 0.1)\n"
293 | ]
294 | },
295 | {
296 | "data": {
297 | "text/plain": [
298 | "(0.0, 10.0, 0.1)"
299 | ]
300 | },
301 | "execution_count": 18,
302 | "metadata": {},
303 | "output_type": "execute_result"
304 | }
305 | ],
306 | "source": [
307 | "euler(g, 1.0, tf=10.0, h=0.1)"
308 | ]
309 | },
310 | {
311 | "cell_type": "code",
312 | "execution_count": 22,
313 | "metadata": {},
314 | "outputs": [
315 | {
316 | "data": {
317 | "text/plain": [
318 | "euler (generic function with 2 methods)"
319 | ]
320 | },
321 | "execution_count": 22,
322 | "metadata": {},
323 | "output_type": "execute_result"
324 | }
325 | ],
326 | "source": [
327 | "function euler(f; x0, t0, tf, h) # argumentos de palabra clave\n",
328 | " # \"keyword arguments\"\n",
329 | " \n",
330 | " @show x0, t0, tf, h\n",
331 | " \n",
332 | "end"
333 | ]
334 | },
335 | {
336 | "cell_type": "code",
337 | "execution_count": 23,
338 | "metadata": {},
339 | "outputs": [
340 | {
341 | "name": "stdout",
342 | "output_type": "stream",
343 | "text": [
344 | "(x0, t0, tf, h) = (1.0, 0.0, 10.0, 0.1)\n"
345 | ]
346 | },
347 | {
348 | "data": {
349 | "text/plain": [
350 | "(1.0, 0.0, 10.0, 0.1)"
351 | ]
352 | },
353 | "execution_count": 23,
354 | "metadata": {},
355 | "output_type": "execute_result"
356 | }
357 | ],
358 | "source": [
359 | "euler(g, t0=0.0, x0=1.0, h=0.1, tf=10.0)"
360 | ]
361 | },
362 | {
363 | "cell_type": "code",
364 | "execution_count": 37,
365 | "metadata": {},
366 | "outputs": [
367 | {
368 | "data": {
369 | "text/plain": [
370 | "1-element Array{Float64,1}:\n",
371 | " 1.1"
372 | ]
373 | },
374 | "execution_count": 37,
375 | "metadata": {},
376 | "output_type": "execute_result"
377 | }
378 | ],
379 | "source": [
380 | "t = 1.1\n",
381 | "v = [t]"
382 | ]
383 | },
384 | {
385 | "cell_type": "code",
386 | "execution_count": 38,
387 | "metadata": {},
388 | "outputs": [
389 | {
390 | "data": {
391 | "text/plain": [
392 | "0-element Array{Float64,1}"
393 | ]
394 | },
395 | "execution_count": 38,
396 | "metadata": {},
397 | "output_type": "execute_result"
398 | }
399 | ],
400 | "source": [
401 | "v = Float64[]"
402 | ]
403 | },
404 | {
405 | "cell_type": "code",
406 | "execution_count": 29,
407 | "metadata": {},
408 | "outputs": [
409 | {
410 | "data": {
411 | "text/plain": [
412 | "euler (generic function with 2 methods)"
413 | ]
414 | },
415 | "execution_count": 29,
416 | "metadata": {},
417 | "output_type": "execute_result"
418 | }
419 | ],
420 | "source": [
421 | "function euler(f; x0, t0, tf, h)\n",
422 | " # en Julia 0.6: tienes que dar valores por defecto \n",
423 | " # para los argumentos de palabra clave\n",
424 | " \n",
425 | " ts = [t0]\n",
426 | " xs = [x0]\n",
427 | " \n",
428 | " t = t0\n",
429 | " x = x0\n",
430 | " \n",
431 | " while t < tf\n",
432 | " x_siguiente = paso_euler(f, x, t, h)\n",
433 | " t += h\n",
434 | " \n",
435 | " # final de la vuelta de un bucle:\n",
436 | " x = x_siguiente\n",
437 | " \n",
438 | " push!(xs, x)\n",
439 | " push!(ts, t)\n",
440 | " end\n",
441 | " \n",
442 | " return xs, ts\n",
443 | " \n",
444 | "end"
445 | ]
446 | },
447 | {
448 | "cell_type": "code",
449 | "execution_count": 30,
450 | "metadata": {},
451 | "outputs": [
452 | {
453 | "data": {
454 | "text/plain": [
455 | "([1.0, 1.1, 1.21, 1.331, 1.4641, 1.61051, 1.77156, 1.94872, 2.14359, 2.35795 … 2.85312, 3.13843, 3.45227, 3.7975, 4.17725, 4.59497, 5.05447, 5.55992, 6.11591, 6.7275], [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 … 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0])"
456 | ]
457 | },
458 | "execution_count": 30,
459 | "metadata": {},
460 | "output_type": "execute_result"
461 | }
462 | ],
463 | "source": [
464 | "g(x, t) = x # ẋ = x\n",
465 | "\n",
466 | "xs, ts = euler( (x,t) -> x, \n",
467 | " t0=0.0, tf=2.0, x0=1.0, h=0.1)"
468 | ]
469 | },
470 | {
471 | "cell_type": "code",
472 | "execution_count": 35,
473 | "metadata": {},
474 | "outputs": [
475 | {
476 | "ename": "InexactError",
477 | "evalue": "InexactError: Int64(Int64, 0.1)",
478 | "output_type": "error",
479 | "traceback": [
480 | "InexactError: Int64(Int64, 0.1)",
481 | "",
482 | "Stacktrace:",
483 | " [1] Type at ./float.jl:700 [inlined]",
484 | " [2] convert at ./number.jl:7 [inlined]",
485 | " [3] push! at ./array.jl:855 [inlined]",
486 | " [4] #euler#14(::Float64, ::Int64, ::Float64, ::Float64, ::Function, ::Function) at ./In[29]:17",
487 | " [5] (::getfield(Main, Symbol(\"#kw##euler\")))(::NamedTuple{(:t0, :tf, :x0, :h),Tuple{Int64,Float64,Float64,Float64}}, ::typeof(euler), ::Function) at ./none:0",
488 | " [6] top-level scope at In[35]:1"
489 | ]
490 | }
491 | ],
492 | "source": [
493 | "xs, ts = euler( (x,t) -> x, \n",
494 | " t0=0, tf=2.0, x0=1.0, h=0.1)"
495 | ]
496 | },
497 | {
498 | "cell_type": "code",
499 | "execution_count": 31,
500 | "metadata": {},
501 | "outputs": [
502 | {
503 | "data": {
504 | "text/plain": [
505 | "21-element Array{Float64,1}:\n",
506 | " 1.0 \n",
507 | " 1.1 \n",
508 | " 1.2100000000000002\n",
509 | " 1.3310000000000002\n",
510 | " 1.4641000000000002\n",
511 | " 1.61051 \n",
512 | " 1.7715610000000002\n",
513 | " 1.9487171 \n",
514 | " 2.1435888100000002\n",
515 | " 2.357947691 \n",
516 | " 2.5937424601 \n",
517 | " 2.8531167061100002\n",
518 | " 3.1384283767210004\n",
519 | " 3.4522712143931003\n",
520 | " 3.7974983358324104\n",
521 | " 4.177248169415652 \n",
522 | " 4.594972986357217 \n",
523 | " 5.054470284992938 \n",
524 | " 5.559917313492232 \n",
525 | " 6.115909044841455 \n",
526 | " 6.727499949325601 "
527 | ]
528 | },
529 | "execution_count": 31,
530 | "metadata": {},
531 | "output_type": "execute_result"
532 | }
533 | ],
534 | "source": [
535 | "xs"
536 | ]
537 | },
538 | {
539 | "cell_type": "markdown",
540 | "metadata": {},
541 | "source": [
542 | "## InexactError"
543 | ]
544 | },
545 | {
546 | "cell_type": "code",
547 | "execution_count": 32,
548 | "metadata": {},
549 | "outputs": [
550 | {
551 | "data": {
552 | "text/plain": [
553 | "3-element Array{Int64,1}:\n",
554 | " 1\n",
555 | " 2\n",
556 | " 3"
557 | ]
558 | },
559 | "execution_count": 32,
560 | "metadata": {},
561 | "output_type": "execute_result"
562 | }
563 | ],
564 | "source": [
565 | "v = [1, 2, 3]"
566 | ]
567 | },
568 | {
569 | "cell_type": "code",
570 | "execution_count": 33,
571 | "metadata": {},
572 | "outputs": [
573 | {
574 | "data": {
575 | "text/plain": [
576 | "4-element Array{Int64,1}:\n",
577 | " 1\n",
578 | " 2\n",
579 | " 3\n",
580 | " 4"
581 | ]
582 | },
583 | "execution_count": 33,
584 | "metadata": {},
585 | "output_type": "execute_result"
586 | }
587 | ],
588 | "source": [
589 | "push!(v, 4.0)"
590 | ]
591 | },
592 | {
593 | "cell_type": "code",
594 | "execution_count": 34,
595 | "metadata": {},
596 | "outputs": [
597 | {
598 | "ename": "InexactError",
599 | "evalue": "InexactError: Int64(Int64, 4.1)",
600 | "output_type": "error",
601 | "traceback": [
602 | "InexactError: Int64(Int64, 4.1)",
603 | "",
604 | "Stacktrace:",
605 | " [1] Type at ./float.jl:700 [inlined]",
606 | " [2] convert at ./number.jl:7 [inlined]",
607 | " [3] push!(::Array{Int64,1}, ::Float64) at ./array.jl:855",
608 | " [4] top-level scope at In[34]:1"
609 | ]
610 | }
611 | ],
612 | "source": [
613 | "push!(v, 4.1)"
614 | ]
615 | },
616 | {
617 | "cell_type": "code",
618 | "execution_count": null,
619 | "metadata": {},
620 | "outputs": [],
621 | "source": []
622 | }
623 | ],
624 | "metadata": {
625 | "kernelspec": {
626 | "display_name": "Julia 1.0.0",
627 | "language": "julia",
628 | "name": "julia-1.0"
629 | },
630 | "language_info": {
631 | "file_extension": ".jl",
632 | "mimetype": "application/julia",
633 | "name": "julia",
634 | "version": "1.0.0"
635 | }
636 | },
637 | "nbformat": 4,
638 | "nbformat_minor": 2
639 | }
640 |
--------------------------------------------------------------------------------
/notebooks/01. Caminatas aleatorias.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Caminatas aleatorias"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "En este notebook, empezaremos a explorar Julia, al aplicarlo para modelar una **caminata aleatoria**, que es básicamente un **movimiento Browniano** -- un movimiento aleatorio de una partícula moviéndose en un fluido.\n",
15 | "\n",
16 | "Llevaremos a cabo una primera simulación computacional de este sistema. Para hacerlo, veremos por encima algunos conceptos de programación en Julia. Luego profundizaremos en esos conceptos, pero el punto de este notebook es llegar lo más rápido posible a poder hacer algo interesante, y así mostrar el poder del lenguaje."
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "## Modelaje\n",
24 | "\n",
25 | "Para hacer un modelo matemático / computacional de un sistema físico, siempre es necesario hacer unas simplificaciones.\n",
26 | "Para empezar a modelar una partícula en un fluido, haremos unas simplificaciones bastante drásticas:\n",
27 | "\n",
28 | "- En lugar de modelar el fluido, modelaremos el fluido a través de impactos **aleatorios** sobre la partícula. \n",
29 | "\n",
30 | "\n",
31 | "- Supondremos (aunque no es nada realista) que los impactos causen que la partícula dé brincos en el espacio.\n",
32 | "\n",
33 | "\n",
34 | "- Supondremos que los impactos occurran en tiempos espaciados de forma regular, así que podemos hablar de pasitos de tiempo.\n",
35 | "\n",
36 | "\n",
37 | "- Supondremos que la partícula brinque la misma distancia en cada pasito, y que vive en una red.\n",
38 | "\n",
39 | "Por supuesto, todas estas restricciones se pueden quitar después."
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "metadata": {},
45 | "source": [
46 | "## Caminata aleatoria"
47 | ]
48 | },
49 | {
50 | "cell_type": "markdown",
51 | "metadata": {},
52 | "source": [
53 | "Pensemos, entonces, en una partícula con posición $x \\in \\mathbb{Z}$. En el tiempo $0$, empieza en la posición $x = 0$."
54 | ]
55 | },
56 | {
57 | "cell_type": "markdown",
58 | "metadata": {},
59 | "source": [
60 | "#### Ejercicio 1\n",
61 | "\n",
62 | "(i) Define una variable `x` que valga 0. \n",
63 | "\n",
64 | "(ii) Checa que `x` realmente valga, al poner `x` únicamente. Nota que Julia siempre devuelve el valor de la última expresión que se calculó.\n",
65 | "\n",
66 | "(iii) Utiliza la función `typeof` para ver el tipo de `x`. [Pista: Utiliza paréntesis, `(` y `)`, para llamar a la función.]"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": []
73 | },
74 | {
75 | "cell_type": "markdown",
76 | "metadata": {},
77 | "source": [
78 | "### Números aleatorios"
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "metadata": {},
84 | "source": [
85 | "Julia tiene una función `rand` para generar cosas aleatorias (\"*rand*om\", en inglés).\n",
86 | "Esta función tiene distintas variantes para generar distintos tipos de objetos aleatorios."
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {},
92 | "source": [
93 | "#### Ejercicio 2\n",
94 | "(i) ¿Qué pasa si simplemente pones la función `rand`, sin paréntesis?\n",
95 | "\n",
96 | "(ii) Ahora utiliza paréntesis para ejecutar la función. Hazlo varias veces para adivinar qué es lo que está produciendo.\n",
97 | "\n",
98 | "(iii) Ahora pon `rand(Bool)` varias veces. ¿Qué es lo que genera? Nota que `Bool` quiere decir una variable *Bool*eana."
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "metadata": {},
105 | "outputs": [],
106 | "source": []
107 | },
108 | {
109 | "cell_type": "markdown",
110 | "metadata": {},
111 | "source": [
112 | "## Programando una caminata aleatoria"
113 | ]
114 | },
115 | {
116 | "cell_type": "markdown",
117 | "metadata": {},
118 | "source": [
119 | "¿Qué necesitaremos para *programar* una caminata aleatoria en la computadora?\n",
120 | "\n",
121 | "Ya hemos visto como generar un `Bool` aleatorio. Pero necesitamos más bien un *brinco* aleatorio:"
122 | ]
123 | },
124 | {
125 | "cell_type": "markdown",
126 | "metadata": {},
127 | "source": [
128 | "### Ejercicio 3\n",
129 | "\n",
130 | "(i) Define una variable `r` que es igual al resultado de `rand(Bool)`. Conviértelo a un número entero `s`, usando la función `Int`. (Entero en inglés es \"*int*eger\".) [Nota que en Julia, sí importa si los nombres se escriben con mayúsculas o minúsculas.]\n",
131 | "\n",
132 | "(ii) Para una caminata aleatoria, necesitamos brincos de tamaño $1$ o $-1$. Cómo puedes utilizar aritmética para generar un brinco $\\Delta$ a partir de `s`? [Nota que en Julia, puedes escribir $\\Delta$ como `\\Delta`, donde `` indica la tecla \"tabulador\".]"
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {},
139 | "outputs": [],
140 | "source": []
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "### Iteración (repetición)"
147 | ]
148 | },
149 | {
150 | "cell_type": "markdown",
151 | "metadata": {},
152 | "source": [
153 | "Ahora sabemos cómo generar un brinco. Pero necesitaremos varios brincos, uno tras otro; es decir, necesitamos una manera de *repetir* un comando una y otra vez, es decir, necesitamos saber cómo utilizar la **iteración**, a través de un **bucle** (o ciclo, loop).\n",
154 | "\n",
155 | "Una manera de hacer esto es con un bucle `for`, el cual se utiliza para iterar sobre un conjunto conocido de valores. La sintaxis se ve así:"
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": null,
161 | "metadata": {},
162 | "outputs": [],
163 | "source": [
164 | "for i in 1:10\n",
165 | " @show i\n",
166 | " @show i^2\n",
167 | "end"
168 | ]
169 | },
170 | {
171 | "cell_type": "markdown",
172 | "metadata": {},
173 | "source": [
174 | "#### Ejercicio 4\n",
175 | "\n",
176 | "(i) Ejecuta este código. ¿Qué hace? \n",
177 | "\n",
178 | "(ii) Existe la variable `i` afuera del bucle?\n",
179 | "\n",
180 | "(iii) Modifica el código para que defina una variable `a` que es dos veces `i`, e imprime sólo el valor de `a` en cada vuelta. Hazlo para valores de `i` que son los números pares de 2 hasta 20. [Pista: Agrega otro número al rango `1:10` con otro `:`.]"
181 | ]
182 | },
183 | {
184 | "cell_type": "code",
185 | "execution_count": null,
186 | "metadata": {},
187 | "outputs": [],
188 | "source": []
189 | },
190 | {
191 | "cell_type": "markdown",
192 | "metadata": {},
193 | "source": [
194 | "#### Ejercicio 5"
195 | ]
196 | },
197 | {
198 | "cell_type": "markdown",
199 | "metadata": {},
200 | "source": [
201 | "Supón que ahora querramos calcular la suma de los números de 1 a 10. Tendremos que tener un lugar, digamos una variable llamada `suma`, en donde guardar el resultado. \n",
202 | "\n",
203 | "(i) ¿Cuál es el valor inicial de `suma`? ¿Dónde hay que colocar esta inicialización?\n",
204 | "\n",
205 | "(ii) ¿Cómo se actualiza `suma` en cada vuelta del bucle?\n",
206 | "\n",
207 | "(iii) Muestra el valor final de `suma` y compáralo con el valor analítico exacto de la suma."
208 | ]
209 | },
210 | {
211 | "cell_type": "code",
212 | "execution_count": null,
213 | "metadata": {},
214 | "outputs": [],
215 | "source": []
216 | },
217 | {
218 | "cell_type": "markdown",
219 | "metadata": {},
220 | "source": [
221 | "### Funciones"
222 | ]
223 | },
224 | {
225 | "cell_type": "markdown",
226 | "metadata": {},
227 | "source": [
228 | "Supón que querramos repetir el cálculo anterior para sumar los enteros de 1 a $n$, para varios valores distintos de $n$. Tendríamos que copiar y pegar el código. Esto lleva a la posibilidad de errores que introduzcamos. Además, si modificamos el código en un lugar, tendríamos que modificarlo en todas las copias. Esto nos lleva a la regla\n",
229 | "\n",
230 | "> *Nunca* copies y pegues para repetir código.\n",
231 | "\n",
232 | "¿Qué hacemos entonces? Escribimos una **`función`**, es decir, un subprograma que ejecuta una tarea dada. Una función puede tomar argumentos, por ejemplo `n`, y regresar resultados.\n",
233 | "\n",
234 | "La sintaxis extendida para escribir una función en Julia es"
235 | ]
236 | },
237 | {
238 | "cell_type": "code",
239 | "execution_count": null,
240 | "metadata": {},
241 | "outputs": [],
242 | "source": [
243 | "function f(xx)\n",
244 | " xx = xx + 1 # Pon operaciones aquí\n",
245 | " return xx \n",
246 | "end"
247 | ]
248 | },
249 | {
250 | "cell_type": "markdown",
251 | "metadata": {},
252 | "source": [
253 | "Aquí:\n",
254 | "- `xx` es el argumento que la función acepta. \n",
255 | "- `#` denota que el resto de la línea es un comentario, el cual no se procesará por Julia. \n",
256 | "- La palabra clave `return` indica qué información se regresa desde la función."
257 | ]
258 | },
259 | {
260 | "cell_type": "markdown",
261 | "metadata": {},
262 | "source": [
263 | "#### Ejercicio 6\n",
264 | "\n",
265 | "(i) ¿Qué ocurre cuando corres el código? ¿Se ejecutó la función?\n",
266 | "\n",
267 | "(ii) Ejecuta la función, pasándole el valor 10. ¿Qué dice Julia?\n",
268 | "\n",
269 | "(iii) ¿Existe la variable `xx` afuera de la función?\n",
270 | "\n",
271 | "(iii) Capta lo que regresa en la variable `yy`."
272 | ]
273 | },
274 | {
275 | "cell_type": "code",
276 | "execution_count": null,
277 | "metadata": {},
278 | "outputs": [],
279 | "source": []
280 | },
281 | {
282 | "cell_type": "markdown",
283 | "metadata": {},
284 | "source": [
285 | "#### Ejercicio 7\n",
286 | "\n",
287 | "(i) Escribe una función `sumar` que toma la variable `n` y suma los números de 1 a $n$.\n",
288 | "Checa que funcione correctamente, al comparar la suma de los números de 1 a 1000 con el resultado exacto.\n",
289 | "\n",
290 | "(ii) Escribe una función `fact` que calcule el factorial del número $n$.\n",
291 | "Checa que funcione correctamente, al comparar algunos resultados con algo escrito a mano.\n",
292 | "\n",
293 | "(iii) ¿Hasta cuál valor de $n$ funciona la función `fact` correctamente? ¿Qué crees que esté pasando más allá de ese valor? ¿Cómo se podría arreglar el problema?"
294 | ]
295 | },
296 | {
297 | "cell_type": "code",
298 | "execution_count": null,
299 | "metadata": {},
300 | "outputs": [],
301 | "source": []
302 | },
303 | {
304 | "cell_type": "markdown",
305 | "metadata": {},
306 | "source": [
307 | "#### Ejercicio 8\n",
308 | "\n",
309 | "Ya podemos poner todo esto junto para hacer nuestra primera simulación: ¡simulemos una caminata aleatoria!\n",
310 | "\n",
311 | "(i) Define una función `caminata` que tome un argumento `n` y simule una caminata aleatoria de `n` pasos. Escribe la posición en cada paso en la pantalla."
312 | ]
313 | },
314 | {
315 | "cell_type": "code",
316 | "execution_count": null,
317 | "metadata": {},
318 | "outputs": [],
319 | "source": []
320 | },
321 | {
322 | "cell_type": "markdown",
323 | "metadata": {},
324 | "source": [
325 | "### Vectores"
326 | ]
327 | },
328 | {
329 | "cell_type": "markdown",
330 | "metadata": {},
331 | "source": [
332 | "¡Acabamos de llevar a cabo una simulación en la computadora! Podemos ver los datos que se generaron, es decir, las posiciones de la caminata después de cada paso. Pero ahora supón que querramos visualizar estos datos, o guardarlos en un archivo. ¿Dónde están?\n",
333 | "\n",
334 | "Resulta que sólo están en la pantalla. No están guardados en ningún lado, ya que ¡no le dijimos a la computadora que guardara los datos!\n",
335 | "\n",
336 | "Ya hemos visto que podemos guardar datos en una variable. Pero ahora podríamos tener muchas variables, es decir, la posición en cada uno de $n$ pasos. No queremos crear de forma individual tantas variables, ni encontrar nombres para ellas.\n",
337 | "\n",
338 | "La solución es crear un bloque de variables con un solo nombre y un índice, es decir un **vector** (o arreglo uni-dimensional)."
339 | ]
340 | },
341 | {
342 | "cell_type": "markdown",
343 | "metadata": {},
344 | "source": [
345 | "#### Ejercicio 9\n",
346 | "\n",
347 | "(i) Crea una variable `x` con el valor `0`.\n",
348 | "\n",
349 | "(ii) Crea un arreglo `posiciones` con la sintaxis `posiciones = [x]`. Los corchetes (`[`, `]`) indican que el arreglo contendrá el valor de `x`.\n",
350 | "\n",
351 | "(iii) Checa de qué tipo es `posiciones` con la función `typeof`. ¿Qué observas?\n",
352 | "\n",
353 | "(iv) Agrega un valor al arreglo con la función `push!`. Verifica que se agregó correctamente.\n",
354 | "\n",
355 | "(v) Escribe un bucle para agregar todos los números de 1 a 10, uno por uno, a `posiciones`."
356 | ]
357 | },
358 | {
359 | "cell_type": "code",
360 | "execution_count": null,
361 | "metadata": {},
362 | "outputs": [],
363 | "source": []
364 | },
365 | {
366 | "cell_type": "markdown",
367 | "metadata": {},
368 | "source": [
369 | "#### Ejercicio 10\n",
370 | "\n",
371 | "(i) Modifica tu función `caminata` para guardar todas las posiciones a un vector. Regresa este vector de la función.\n",
372 | "\n",
373 | "(ii) Llama a la función para crear una caminata con 10 pasos en la variable `camino1`.\n",
374 | "\n",
375 | "(iii) Crea una variable `camino2` con una caminata de 100 pasos. Para averiguar cuánto tiempo se tardó en hacerlo, pon `@time` justo antes de la llamada a la función."
376 | ]
377 | },
378 | {
379 | "cell_type": "code",
380 | "execution_count": null,
381 | "metadata": {},
382 | "outputs": [],
383 | "source": []
384 | },
385 | {
386 | "cell_type": "markdown",
387 | "metadata": {},
388 | "source": [
389 | "### Guardar los datos"
390 | ]
391 | },
392 | {
393 | "cell_type": "markdown",
394 | "metadata": {},
395 | "source": [
396 | "#### Ejercicio 11\n",
397 | "\n",
398 | "(i) Guarda los datos que se generaron con `writedlm(\"archivo.dat\", v)`, donde el primer argumento es el archivo nuevo que escribir, y `v` es la variable que escribir. [En Julia 0.7 y 1.0, hay que poner `using DelimitedFiles` primero.]\n",
399 | "\n",
400 | "(ii) Verifica (no con Julia) que se generó correctamente el archivo en tu sistema operativo.\n",
401 | "\n",
402 | "(iii) Utiliza `readdlm` para leer el archivo y guardar el resultado en una variable llamada `nuevo`."
403 | ]
404 | },
405 | {
406 | "cell_type": "code",
407 | "execution_count": null,
408 | "metadata": {},
409 | "outputs": [],
410 | "source": []
411 | },
412 | {
413 | "cell_type": "markdown",
414 | "metadata": {},
415 | "source": [
416 | "### Visualización"
417 | ]
418 | },
419 | {
420 | "cell_type": "markdown",
421 | "metadata": {},
422 | "source": [
423 | "Los humanos somos seres visuales, por lo cual la mejor manera de entender un conjunto de datos es la visualización. \n",
424 | "\n",
425 | "Julia tiene unas buenas herramientas para la visualización. Ocuparemos el paquete `Plots.jl`. Primero hay que cargar el paquete:"
426 | ]
427 | },
428 | {
429 | "cell_type": "code",
430 | "execution_count": 6,
431 | "metadata": {},
432 | "outputs": [],
433 | "source": [
434 | "using Plots"
435 | ]
436 | },
437 | {
438 | "cell_type": "markdown",
439 | "metadata": {},
440 | "source": [
441 | "Si no está instalado, Julia reportará ese hecho, y entonces se tiene que instalar (una sola vez) con"
442 | ]
443 | },
444 | {
445 | "cell_type": "code",
446 | "execution_count": null,
447 | "metadata": {},
448 | "outputs": [],
449 | "source": [
450 | "Pkg.add(\"Plots\") "
451 | ]
452 | },
453 | {
454 | "cell_type": "markdown",
455 | "metadata": {},
456 | "source": [
457 | "#### Ejercicio 12\n",
458 | "\n",
459 | "(i) Crea un camino `camino1` con 10 pasos. \n",
460 | "\n",
461 | "(ii) Dibújalo con la función `plot`. ¿Qué utilizó para \n",
462 | "\n",
463 | "(iii) Pon también puntos utilizando el \"argumento de palabra clave\" `m='o'` adentro del comando de `plot`.\n",
464 | "\n",
465 | "(iv) Dibujar únicamente los puntos al utilizar `scatter` en lugar de `plot`.\n",
466 | "\n",
467 | "(v) Crea y dibuja 5 caminos en la misma gráfica, utilizando `plot!` (con `!` al final) para agregar elementos a un dibujo pre-existente."
468 | ]
469 | },
470 | {
471 | "cell_type": "code",
472 | "execution_count": null,
473 | "metadata": {},
474 | "outputs": [],
475 | "source": []
476 | },
477 | {
478 | "cell_type": "markdown",
479 | "metadata": {},
480 | "source": [
481 | "#### Ejercicio 13\n",
482 | "\n",
483 | "Ahora podemos empezar a ver cosas interesantes.\n",
484 | "\n",
485 | "(i) Utiliza un bucle `for` para dibujar 100 caminos con 100 pasos cada uno. Para hacerlo, primero crea un `plot` vacío con el nombre `p` y sin leyenda (`leg=false`). Luego dibuja los caminantes. Al final, muestra el objeto `p`.\n",
486 | "\n",
487 | "(ii) ¿Qué observas? ¿Cómo parece crecer la nube de caminantes en el tiempo? ¿Cómo podrías pensar en averiguar eso numéricamente? **Opcional: ¡Hazlo!\n",
488 | "\n",
489 | "(iii) En la gráfica, los caminos se sobreponen, así que no se puede ver cuántos caminantes pasaron por un punto dado en cada paso. En un paso dado, ¿qué harías para ver esto? **Opcional: ¡Hazlo!"
490 | ]
491 | },
492 | {
493 | "cell_type": "code",
494 | "execution_count": null,
495 | "metadata": {},
496 | "outputs": [],
497 | "source": []
498 | }
499 | ],
500 | "metadata": {
501 | "kernelspec": {
502 | "display_name": "Julia 0.6.4",
503 | "language": "julia",
504 | "name": "julia-0.6"
505 | },
506 | "language_info": {
507 | "file_extension": ".jl",
508 | "mimetype": "application/julia",
509 | "name": "julia",
510 | "version": "0.6.4"
511 | }
512 | },
513 | "nbformat": 4,
514 | "nbformat_minor": 1
515 | }
516 |
--------------------------------------------------------------------------------