├── Pics ├── Pics.md └── tensor.png ├── requirements.txt ├── Data └── Data.txt ├── Modulos ├── Modulos.txt ├── NumDer.py ├── Solver_EDOC.py ├── Solver_EDOS_P2.py ├── Solver_EDO.py ├── Solver_EDOS.py └── Solver_EDOS_P3.py ├── Cuadernos ├── Alternativas_Online.ipynb ├── Bungee_2D_Cord.ipynb ├── Tipos_Datos.ipynb ├── Instalando_Kernels.ipynb ├── Ambientes.ipynb ├── Intro_Graphics.ipynb ├── Ejemplos_Model.ipynb ├── Intro_Python.ipynb ├── MN_RK.ipynb ├── Paquetes.ipynb └── MN_Butcher.ipynb └── README.md /Pics/Pics.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | pandas 3 | matplotlib 4 | -------------------------------------------------------------------------------- /Data/Data.txt: -------------------------------------------------------------------------------- 1 | Aquí irán algunos datos de prueba para las clases, ejercicios y parciales. 2 | -------------------------------------------------------------------------------- /Modulos/Modulos.txt: -------------------------------------------------------------------------------- 1 | Aquí los módulos necesarios para solucionar ecuaciones diferenciales. 2 | -------------------------------------------------------------------------------- /Pics/tensor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AprendizajeProfundo/Modelamiento-Metodos-Numericos/master/Pics/tensor.png -------------------------------------------------------------------------------- /Modulos/NumDer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pyxhon 2 | # coding: utf-8 3 | 4 | # importing necessary modules 5 | import numpy as np 6 | 7 | # Forward Derivative (FD==BD, just changes in time plot) 8 | def FD(x,y): 9 | #Convert Types if you need to 10 | x=np.array(x) 11 | y=np.array(y) 12 | # Derivative has one point less than total data 13 | n=len(x)-1 14 | # Allocate Memory 15 | ΔyΔx=np.empty(n) 16 | 17 | 18 | for i in range(n): 19 | # Change in x 20 | Δx=x[i+1]-x[i] 21 | # Change in y 22 | Δy=y[i+1]-y[i] 23 | # Quotient's difference (Derivative) 24 | ΔyΔx[i]=Δy/Δx 25 | 26 | return ΔyΔx 27 | 28 | ## Central Derivative (CD) 29 | def CD(x,y): 30 | x=np.array(x) 31 | y=np.array(y) 32 | n=len(x)-2 33 | ΔyΔx=np.empty(n) 34 | 35 | for i in range(n): 36 | Δx=x[i+2]-x[i] 37 | Δy=y[i+2]-y[i] 38 | ΔyΔx[i]=Δy/Δx 39 | 40 | return ΔyΔx 41 | 42 | ## Second Derivative 43 | def CD2(daxosx,y): 44 | x=np.array(x) 45 | y=np.array(y) 46 | n=len(x)-1 47 | ΔfΔx=np.empty(n) 48 | 49 | for i in range(n): 50 | Δx=x[i+1]-x[i] 51 | Δy=y[i+2]-2*y[i+1]+y[i] 52 | ΔyΔx[i]=Δy/(Δx**2) 53 | 54 | return ΔyΔx 55 | 56 | -------------------------------------------------------------------------------- /Modulos/Solver_EDOC.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | import numpy as np 5 | 6 | #### dx/dt=f(t,x), x(t0)=x0 7 | 8 | ##################### Método de Euler ################################################### 9 | 10 | def Euler(f,x,t,h): 11 | x+=h*f(t,x) 12 | t+=h 13 | return t,x 14 | 15 | ################## Método del Punto Medio ################################################# 16 | 17 | def MidPt(f,x,t,h): 18 | x+=h*f(t+h/2,x+h*f(t,x)/2) 19 | t+=h 20 | return t,x 21 | 22 | ################################# Método de Heun ############################################ 23 | 24 | def Heun(f,x,t,h): 25 | k1=f(t,x) 26 | x+=h*(k1/2+f(t+h,x+h*k1)/2) 27 | t+=h 28 | return t,x 29 | 30 | ###################### Método de Ralson ###################################################### 31 | 32 | def Ralson(f,x,t,h): 33 | k1=f(t,x) 34 | x+=h*(1/4*k1+3/4*f(t+2/3*h,x+h*2/3*k1)) 35 | t+=h 36 | return t,x 37 | 38 | ########################################## Método de Runge-Kutta (RK4) ######################################## 39 | 40 | def RK4(f,x,t,h): 41 | k1=f(t,x) 42 | k2=f(t+h/2,x+h*k1/2) 43 | k3=f(t+h/2,x+h*k2/2) 44 | k4=f(t+h ,x+h*k3) 45 | x+=h*(1/6*k1+1/3*k2+1/3*k3+1/6*k4) 46 | t+=h 47 | return t,x 48 | 49 | ########################################## Método de Runge-Kutta, Regla 3/8 #################################### 50 | 51 | def RK38(f,x,t,h): 52 | k1=f(t,x) 53 | k2=f(t+1/3*h,x+h*k1/3) 54 | k3=f(t+2/3*h,x+h*(-1/3*k1+k2)) 55 | k4=f(t+h ,x+h*(k1-k2+k3)) 56 | x+=h*(1/8*k1+3/8*k2+3/8*k3+1/8*k4) 57 | t+=h 58 | return t,x 59 | 60 | ################################################# Funciones de Error##################################################### 61 | 62 | def Error(aprox,real): 63 | err=abs(aprox-real) 64 | return err 65 | 66 | def Error_Rela(aprox,real): 67 | err=abs(aprox-real)/abs(real) 68 | return err 69 | 70 | def MSE(err,approx,real,n): 71 | err=(err**2+abs(aprox-real)**2)/n -------------------------------------------------------------------------------- /Cuadernos/Alternativas_Online.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Alternativas Online\n", 8 | "**Universidad Central**\n", 9 | "\n", 10 | "*Carlos Isaac Zainea, Daniel Montenegro y Luis Campos*" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": {}, 16 | "source": [ 17 | "## Ejecución en la nube\n", 18 | "\n", 19 | "Una de las prácticas más comunes en esta época es tratar de tener la menor cantidad de datos en nuestros discos físicos, de hecho, la filosofia de alojar todo en la nube ha tomado bastante fuerza en los ultimos años. El *Cloud Computing* quizás se reconoce como uno de los paradigmas actuales de computación. Acorde a esa filosofía tenemos varias herramientas en la nube que nos permiten ejecutar código en Python y R usando cuadernos e Ides como la de R Studio. aquí mencionamos las tres alternativas Online para ejecutar código de R y Python en la nube.\n", 20 | "\n", 21 | "## [Google Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb)\n", 22 | "\n", 23 | "Colaboratory es un entorno de notebook de Jupyter gratuito que no requiere configuración y se ejecuta completamente en la nube. Permite ejecutar código, guardar y compartir análisis, y acceder a recursos informáticos potentes, desde el navegador. Adicionalmente, cuenta con un IDE amable y algunas extensiones que facilitan el ejercicio de programación, entre ellos completación inteligente de texto código, una vista simultanea para celdas Markdown, gran parte de los paquetes usados instalados, sincronizado sobre la nube, entre otros. \n", 24 | "\n", 25 | "\n", 26 | "\n", 27 | "## [RStudio Cloud](https://rstudio.cloud/)\n", 28 | "\n", 29 | "Una plataforma web con la que aloja todas las funcionalidades de R Studio. Mantiene la filosofia de crear proyectos y es fiel a la versión de R Studio del ordenador. Quizás una de las versiones interesantes en el momento de aprender R, con una guía de tutoriales para los primerizos: (https://rstudio.cloud/learn/primers).\n", 30 | "\n", 31 | "\n", 32 | "\n", 33 | "## [Azure Notebooks](https://notebooks.azure.com/)\n", 34 | "\n", 35 | "De las tres alternativas esta permite crear cuadernos en Python y R. Igual que las anteriores es un servicio gratuito y su interfaz es muy fiel a Jupyter, si bien tiene algunas dificultades con la instalación de extensiones, los paquetes más usados ya vienen preinstalados. Es la alternativa online más completa para el analista de datos por tener acceso a núcleo de Python y R. Se accede con una cuenta de Microsoft.\n", 36 | "\n", 37 | "" 38 | ] 39 | } 40 | ], 41 | "metadata": { 42 | "kernelspec": { 43 | "display_name": "Python 3", 44 | "language": "python", 45 | "name": "python3" 46 | }, 47 | "language_info": { 48 | "codemirror_mode": { 49 | "name": "ipython", 50 | "version": 3 51 | }, 52 | "file_extension": ".py", 53 | "mimetype": "text/x-python", 54 | "name": "python", 55 | "nbconvert_exporter": "python", 56 | "pygments_lexer": "ipython3", 57 | "version": "3.7.4" 58 | } 59 | }, 60 | "nbformat": 4, 61 | "nbformat_minor": 4 62 | } 63 | -------------------------------------------------------------------------------- /Cuadernos/Bungee_2D_Cord.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "from Solver_EDOS import RK38,np # Solver de EDOS\n", 10 | "import matplotlib.pyplot as plt # graficar\n", 11 | "\n", 12 | "###\n", 13 | "g=9.8\n", 14 | "c_d=0.25\n", 15 | "m=68.1\n", 16 | "L=30\n", 17 | "k=40\n", 18 | "γ=8\n", 19 | "θ=np.pi/4\n", 20 | "\n", 21 | "## Modelo\n", 22 | "\n", 23 | "F= lambda t,X:np.array([X[1],\n", 24 | " -,\n", 25 | " -X[3],\n", 26 | " g-c_d/m*X[3]**2-(np.sqrt(X[0]**2+X[2]**2)<-L)*(k/m*(-X[0]-L)+γ/m*X[1])])\n", 27 | " \n", 28 | "#F1=lambda t,X:np.array([X[1],0,-X[3],g-c_d/m*abs(X[3])*X[3]])\n", 29 | "\n", 30 | "### Con in\n", 31 | "X0=[0,2*np.cos(θ),200,-40*np.sin(θ)]\n", 32 | "\n", 33 | "#tiempo\n", 34 | "T=[0,12]\n", 35 | "#par num\n", 36 | "n=50\n", 37 | "\n", 38 | "t,X=RK38(F,X0,T,n)\n", 39 | "#t,X1=RK38(F1,X0,T,n)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "plt.figure(figsize=(22,18))\n", 49 | "\n", 50 | "plt.subplot(221)\n", 51 | "plt.plot(t,X[:,0],'r',label=\"Posición x, Incorrect Drag\")\n", 52 | "plt.plot(t,X1[:,0],'g.',label=\"Posición x, Correct Drag\")\n", 53 | "plt.legend()\n", 54 | "plt.grid()\n", 55 | "\n", 56 | "plt.subplot(222)\n", 57 | "plt.plot(t,X[:,2],'r',label=\"Posición y, Incorrect Drag\")\n", 58 | "plt.plot(t,X1[:,2],'g',label=\"Posición y, Correct Drag\")\n", 59 | "plt.grid()\n", 60 | "plt.legend()\n", 61 | "\n", 62 | "plt.subplot(223)\n", 63 | "plt.plot(X[:,0],X[:,1],'r',label=\"$x$ Vs $v_x$, Incorrect Drag\")\n", 64 | "plt.plot(X1[:,0],X1[:,1],'g.',label=\"$x$ Vs $v_x$, Correct Drag\")\n", 65 | "plt.legend()\n", 66 | "plt.grid()\n", 67 | "\n", 68 | "plt.subplot(224)\n", 69 | "plt.plot(X[:,2],X[:,3],'r',label=\"$y$ Vs $v_y$, Incorrect Drag\")\n", 70 | "plt.plot(X1[:,2],X1[:,3],'g',label=\"$y$ Vs $v_y$, Correct Drag\")\n", 71 | "plt.legend()\n", 72 | "plt.grid()\n", 73 | "\n", 74 | "plt.figure(figsize=(9,8))\n", 75 | "plt.subplot(111)\n", 76 | "plt.plot(X[:,0],X[:,2],'r--',label=\"Trayectoria, Incorrect Drag\")\n", 77 | "plt.plot(X1[:,0],X1[:,2],'g--',label=\"Trayectoria, Correct Drag\")\n", 78 | "#plt.xlim([0,3])\n", 79 | "plt.legend()\n", 80 | "plt.grid()\n", 81 | "\n", 82 | "#plt.subplot(122)\n", 83 | "#plt.plot(t,X[:,1],'r',label=\"Velocidad, Incorrect Drag\")\n", 84 | "#plt.plot(t,X1[:,1],'g',label=\"Velocidad, Correct Drag\")\n", 85 | "#plt.legend()\n", 86 | "#plt.grid()\n", 87 | "plt.show()" 88 | ] 89 | } 90 | ], 91 | "metadata": { 92 | "kernelspec": { 93 | "display_name": "Python 3", 94 | "language": "python", 95 | "name": "python3" 96 | }, 97 | "language_info": { 98 | "codemirror_mode": { 99 | "name": "ipython", 100 | "version": 3 101 | }, 102 | "file_extension": ".py", 103 | "mimetype": "text/x-python", 104 | "name": "python", 105 | "nbconvert_exporter": "python", 106 | "pygments_lexer": "ipython3", 107 | "version": "3.7.7" 108 | } 109 | }, 110 | "nbformat": 4, 111 | "nbformat_minor": 4 112 | } 113 | -------------------------------------------------------------------------------- /Cuadernos/Tipos_Datos.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "-MlSHN16Bg8-" 8 | }, 9 | "source": [ 10 | "# Tipos de Datos\n", 11 | "\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "colab_type": "text", 18 | "id": "Qwzm74tvByHP" 19 | }, 20 | "source": [ 21 | "En programación, los **tipos de datos** son un concepto muy importante.\n", 22 | "\n", 23 | "Las variables pueden contener distintos tipos de datos, y estos tipos pueden hacer distintas cosas.\n", 24 | "\n", 25 | "En Python, existen diferentes tipos de datos por defecto:\n", 26 | "\n", 27 | "* **Texto:** *str.*\n", 28 | "* **Numérico:** *int, float, complex.*\n", 29 | "* **Sequencial:** *list, tuple, range.*\n", 30 | "* **Mapping:** *dict.*\n", 31 | "* **Conjunto:** *set, frozenset.*\n", 32 | "* **Booleano:** *bool*\n", 33 | "* **Binario:** *bytes, bytearray, memoryview.*\n" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": { 39 | "colab_type": "text", 40 | "id": "G0azTyRzledS" 41 | }, 42 | "source": [ 43 | "## Obtener el tipo de Dato de Una Variable\n", 44 | "\n", 45 | "Para esto, se usa el comando **type**:" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 1, 51 | "metadata": { 52 | "colab": { 53 | "base_uri": "https://localhost:8080/", 54 | "height": 238 55 | }, 56 | "colab_type": "code", 57 | "executionInfo": { 58 | "elapsed": 11, 59 | "status": "ok", 60 | "timestamp": 1567723950352, 61 | "user": { 62 | "displayName": "Daniel Montenegro", 63 | "photoUrl": "", 64 | "userId": "07275166318289302366" 65 | }, 66 | "user_tz": 300 67 | }, 68 | "id": "pWF-PQsLlZm2", 69 | "outputId": "96ec6334-2e86-4c74-949f-90ebdecd7287" 70 | }, 71 | "outputs": [ 72 | { 73 | "name": "stdout", 74 | "output_type": "stream", 75 | "text": [ 76 | "\n", 77 | "\n", 78 | "\n", 79 | "\n", 80 | "\n", 81 | "\n", 82 | "\n", 83 | "\n", 84 | "\n", 85 | "\n", 86 | "\n", 87 | "\n", 88 | "\n" 89 | ] 90 | } 91 | ], 92 | "source": [ 93 | "x = 5;\n", 94 | "print(type(x));\n", 95 | "\n", 96 | "x = 5.9\n", 97 | "print(type(x));\n", 98 | "\n", 99 | "x = 5j\n", 100 | "print(type(x));\n", 101 | "\n", 102 | "x = [\"Hey\", \"Let's go\"]\n", 103 | "print(type(x));\n", 104 | "\n", 105 | "x = (\"Hey\", \"Let's go\")\n", 106 | "print(type(x));\n", 107 | "\n", 108 | "x = range(5)\n", 109 | "print(type(x));\n", 110 | "\n", 111 | "x = {\"name\" : \"Daniel\", \"age\" : 28}\n", 112 | "print(type(x));\n", 113 | "\n", 114 | "x = {\"Daniel\",28, 45.6}\n", 115 | "print(type(x));\n", 116 | "\n", 117 | "x = frozenset({\"Daniel\",28, 45.6})\n", 118 | "print(type(x));\n", 119 | "\n", 120 | "x = True\n", 121 | "print(type(x));\n", 122 | "\n", 123 | "x = b\"Matrix\"\n", 124 | "print(type(x));\n", 125 | "\n", 126 | "x = bytearray(5)\n", 127 | "print(type(x));\n", 128 | "\n", 129 | "x = memoryview(bytes(5))\n", 130 | "print(type(x));" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": { 136 | "colab_type": "text", 137 | "id": "dUOgiGiyoPyy" 138 | }, 139 | "source": [ 140 | "Es decir, Python asume el tipo de variable sin tener que definirla explícitamente." 141 | ] 142 | } 143 | ], 144 | "metadata": { 145 | "colab": { 146 | "collapsed_sections": [ 147 | "scclT03UHVrm", 148 | "qAqnr4i70sLy", 149 | "OqFH478Xza5l" 150 | ], 151 | "name": "1.1 Introducción a Python.ipynb", 152 | "provenance": [], 153 | "version": "0.3.2" 154 | }, 155 | "kernelspec": { 156 | "display_name": "Python 3", 157 | "language": "python", 158 | "name": "python3" 159 | }, 160 | "language_info": { 161 | "codemirror_mode": { 162 | "name": "ipython", 163 | "version": 3 164 | }, 165 | "file_extension": ".py", 166 | "mimetype": "text/x-python", 167 | "name": "python", 168 | "nbconvert_exporter": "python", 169 | "pygments_lexer": "ipython3", 170 | "version": "3.7.6" 171 | } 172 | }, 173 | "nbformat": 4, 174 | "nbformat_minor": 4 175 | } 176 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Modelamiento Matemático y Métodos Numéricos 2 | 3 | **Colaboradores Actuales:** 4 | 5 | *Carlos Isaac Zainea, Daniel Montenegro y Luis Campos* 6 | 7 | Este es un espacio para crear, contribuir y aprender sobre Modelamiento y Métodos Numéricos. 8 | 9 | ## Contenido 10 | 11 | 1. **Preliminares** 12 | 1. [Instalación Anaconda](https://github.com/AprendizajeProfundo/2020/blob/master/Cuadernos/Instalaci%C3%B3n%20de%20Anaconda.ipynb) 13 | 2. [Alternativas Online](./Cuadernos/Alternativas_Online.ipynb) 14 | 3. [Lenguaje Markdown](https://guides.github.com/features/mastering-markdown/) 15 | 4. [Imágenes en Jupyterlab](./Cuadernos/Imagenes_Jupyter.ipynb) 16 | 6. [Ambientes de Trabajo](./Cuadernos/Ambientes.ipynb) 17 | 7. [Instalación de Kernels](./Cuadernos/Instalando_Kernels.ipynb) 18 | 19 | 2. **Introducción a Python** 20 | 1. [¿Qué es Python? Primeros Pasos](./Cuadernos/Intro_Python.ipynb) [[NbView](https://nbviewer.jupyter.org/github/AprendizajeProfundo/Modelamiento-Metodos-Numericos/blob/master/Cuadernos/Intro_Python.ipynb)] [[Binder](https://mybinder.org/v2/gh/AprendizajeProfundo/Modelamiento-Metodos-Numericos/3d47764fafd73fcde3977b351101515fade1058b?urlpath=lab%2Ftree%2FCuadernos%2FIntro_Python.ipynb)] 21 | 2. [Tipos de Datos](./Cuadernos/Tipos_Datos.ipynb) 22 | 3. [Módulos de Python (Paquetes, Métodos, Funciones)](./Cuadernos/Paquetes.ipynb) 23 | 4. [Introducción a Tensores](./Cuadernos/Intro_Tensors.ipynb) 24 | 5. [Cálculos Simples usando Numpy](./Cuadernos/Intro_Numpy.ipynb) 25 | 6. [Visualización de Datos (Matplotlib)](./Cuadernos/Intro_Graphics.ipynb) 26 | 7. [Manejo de Datos (Pandas)](./Cuadernos/Intro_Pandas.ipynb) 27 | 28 | 3. **Introducción a Métodos Numéricos** 29 | 1. ¿Qué es un método numérico? 30 | 2. [Modelamiento Matemático](./Cuadernos/Intro_Model.ipynb) 31 | 3. [Ejemplos de Modelos](./Cuadernos/Ejemplos_Model.ipynb) 32 | 4. Derivadas (Crash Course) 33 | 1. Derivadas Matemáticas 34 | 2. Derivadas Numéricas 35 | 36 | 4. **Ecuaciones Diferenciales** 37 | 1. **Primer Orden** 38 | 1. **Una Dimensión** 39 | 1. [Método de Euler](./Cuadernos/MN_Euler.ipynb) 40 | 2. [Tipos de Error](https://nbviewer.jupyter.org/github/AprendizajeProfundo/Modelamiento-Metodos-Numericos/blob/master/Cuadernos/Tipos_de_Error.ipynb) 41 | 3. [Desventajas del Método de Euler](./Cuadernos/MN_EulerFalla.ipynb) 42 | 4. [Método de Runge-Kutta](./Cuadernos/MN_RK.ipynb) 43 | 5. [Tabla de Butcher](./Cuadernos/MN_Butcher.ipynb) 44 | 6. [Campo de Pendientes](./Cuadernos/Slope_Field.ipynb) 45 | 2. **Dos Dimensiones** 46 | 1. Depredador-Presa 47 | 2. Espacio Fase 48 | 2. Modelos Competitivos 49 | 3. [Campo de Direcciones](./Cuadernos/Dir_Field.ipynb) 50 | 3. **Tres Dimensiones** 51 | 1. [Modelos Epidemiológicos: COVID-19](./Cuadernos/COVID-19-Point.ipynb) 52 | 2. [Ecuaciones de Lorenz](./Cuadernos/Lorenz-Point.ipynb) 53 | 3. [Atractor de Lu-Chen](./Cuadernos/Multiscroll-Point.ipynb) 54 | 4. [Atractor de Rabinovich-Fabrikant](./Cuadernos/Rabinovich-Fabrikant-Point.ipynb) 55 | 4. **N Dimensiones** 56 | 1. [Modelos Competitivos](./Cuadernos/Modelos-Competitivos.ipynb) 57 | 2. Métodos Numéricos Vectoriales 58 | 3. [Atractor de Rössler](./Cuadernos/Rösler.ipynb) 59 | 5. **Modelamiento Matemático** 60 | 1. [Datos Reales](./Cuadernos/Datos_Reales.ipynb) 61 | 2. Regresión Lineal 62 | 3. Re-ajuste de Modelos 63 | 2. **Segundo Orden** 64 | 1. **Una Dimensión** 65 | 1. Segunda Ley de Newton. Reducción a Primer Orden. 66 | 2. [Salto con Bungee](./Cuadernos/Bungee_1D.ipynb) 67 | 3. [Bungee con Cuerda](./Cuadernos/Bungee_1D_Cord.ipynb) 68 | 4. Masa-Resorte 69 | 5. Funciones Especiales (Bessel, Airy, Péndulo) 70 | 6. Ley de Gravitación Universal 71 | 2. **Dos Dimensiones** 72 | 1. [Bungee 2D](./Cuadernos/Bungee_2D_Cord.ipynb) 73 | 2. Más ejemplos 74 | 3. **Tres dimensiones** 75 | 1. [Bungee 3D](./Cuadernos/Bungee_3D.ipynb) 76 | 2. Más ejemplos 77 | 3. Introducción a Processing 78 | 3. **Tercer Orden y más allá** 79 | 1. Reducción a sistemas de Primer Orden 80 | 2. Interpretación. Estudio de caso 81 | 82 | 4. **Animación en Programación** 83 | 1. Bases de Processing 84 | 2. Animaciones básicas 85 | 3. Simulación de sistemas físicos 86 | 4. Péndulo Doble 87 | 5. Arte y Ciencia 88 | 6. Sensores. Generacion de Datos. 89 | 90 | 5. **Introducción a Machine Learning** 91 | 92 | -------------------------------------------------------------------------------- /Modulos/Solver_EDOS_P2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf( 3 | 4 | import numpy as np 5 | 6 | #### dx/dt=f1(t,x,y), x(t0)=x0 7 | #### dy/dt=f2(t,x,y), y(t0)=y0 8 | 9 | ##################### Método de Euler ################################################### 10 | 11 | def EulerM(f1,f2,x0,y0,T,n): 12 | t=np.linspace(T[0],T[1],n) 13 | h=abs(t[1]-t[0]) 14 | x=np.empty(n) 15 | x[0]=x0 16 | y=np.empty(n) 17 | y[0]=y0 18 | 19 | for i in range(n-1): 20 | x[i+1]=x[i]+h*f1(t[i],x[i],y[i]) 21 | y[i+1]=y[i]+h*f2(t[i],x[i],y[i]) 22 | return t,x,y 23 | 24 | ################## Método del Punto Medio ############################################# 25 | 26 | def MidPt(f1,f2,x0,y0,T,n): 27 | t=np.linspace(T[0],T[1],n) 28 | h=abs(t[1]-t[0]) 29 | x=np.empty(n) 30 | x[0]=x0 31 | y=np.empty(n) 32 | y[0]=y0 33 | 34 | for i in range(n-1): 35 | 36 | k1=f1(t[i],x[i],y[i]) 37 | k2=f1(t[i]+h/2,x[i]+h*1/2*k1,y[i]+h*1/2*k1) 38 | x[i+1]=x[i]+h*k2 39 | 40 | k1=f2(t[i],x[i],y[i]) 41 | k2=f2(t[i]+h/2,x[i]+h*1/2*k1,y[i]+h*1/2*k1) 42 | y[i+1]=y[i]+h*k2 43 | 44 | return t,x,y 45 | 46 | ################################# Método de Heun ############################################# 47 | 48 | def Heun(f1,f2,x0,y0,T,n): 49 | t=np.linspace(T[0],T[1],n) 50 | h=abs(t[1]-t[0]) 51 | x=np.empty(n) 52 | x[0]=x0 53 | y=np.empty(n) 54 | y[0]=y0 55 | 56 | for i in range(n-1): 57 | 58 | k1=f1(t[i],x[i],y[i]) 59 | k2=f1(t[i+1],x[i]+h*k1,y[i]+h*k1) 60 | x[i+1]=x[i]+h*(1/2*k1+1/2*k2) 61 | 62 | k1=f2(t[i],x[i],y[i]) 63 | k2=f2(t[i+1],x[i]+h*k1,y[i]+h*k1) 64 | y[i+1]=y[i]+h*(1/2*k1+1/2*k2) 65 | 66 | return t,x,y 67 | 68 | ########################### Método de Ralson ############################################################### 69 | 70 | def Ralson(f1,f2,x0,y0,T,n): 71 | t=np.linspace(T[0],T[1],n) 72 | h=abs(t[1]-t[0]) 73 | x=np.empty(n) 74 | x[0]=x0 75 | y=np.empty(n) 76 | y[0]=y0 77 | 78 | for i in range(n-1): 79 | 80 | k1=f1(t[i],x[i],y[i]) 81 | k2=f1(t[i]+2/3*h,x[i]+h*2/3*k1,y[i]+h*2/3*k1) 82 | x[i+1]=x[i]+h*(1/4*k1+3/4*k2) 83 | 84 | k1=f2(t[i],x[i],y[i]) 85 | k2=f2(t[i]+2/3*h,x[i]+h*2/3*k1,y[i]+h*2/3*k1) 86 | y[i+1]=y[i]+h*(1/4*k1+3/4*k2) 87 | 88 | return t,x,y 89 | 90 | ########################################## Método de Runge-Kutta (RK4) ######################################## 91 | 92 | def RK4(f1,f2,x0,y0,T,n): 93 | t=np.linspace(T[0],T[1],n) 94 | h=abs(t[1]-t[0]) 95 | x=np.zeros(n) 96 | x[0]=x0 97 | y=np.zeros(n) 98 | y[0]=y0 99 | 100 | for i in range(n-1): 101 | 102 | k1=f1(t[i],x[i],y[i]) 103 | k2=f1(t[i]+1/2*h,x[i]+h*1/2*k1,y[i]+h*1/2*k1) 104 | k3=f1(t[i]+1/2*h,x[i]+h*1/2*k2,y[i]+h*1/2*k2) 105 | k4=f1(t[i+1] ,x[i]+h*k3 ,y[i]+h*k3) 106 | 107 | x[i+1]=x[i]+h*(1/6*k1+1/3*k2+1/3*k3+1/6*k4) 108 | 109 | k1=f2(t[i],x[i],y[i]) 110 | k2=f2(t[i]+1/2*h,x[i]+h*1/2*k1,y[i]+h*1/2*k1) 111 | k3=f2(t[i]+1/2*h,x[i]+h*1/2*k2,y[i]+h*1/2*k2) 112 | k4=f2(t[i+1] ,x[i]+h*k3 ,y[i]+h*k3) 113 | 114 | y[i+1]=y[i]+h*(1/6*k1+1/3*k2+1/3*k3+1/6*k4) 115 | 116 | return t,x,y 117 | 118 | ########################################## Método de Runge-Kutta, Regla 3/8 #################################### 119 | 120 | def RK38(f1,f2,x0,y0,T,n): 121 | t=np.linspace(T[0],T[1],n) 122 | h=abs(t[1]-t[0]) 123 | x=np.empty(n) 124 | x[0]=x0 125 | y=np.empty(n) 126 | y[0]=y0 127 | 128 | for i in range(n-1): 129 | 130 | k1=f1(t[i],x[i],y[i]) 131 | k2=f1(t[i]+1/3*h,x[i]+h*k1/3 ,y[i]+h*k1/3) 132 | k3=f1(t[i]+2/3*h,x[i]+h*(-1/3*k1+k2),y[i]+h*(-1/3*k1+k2)) 133 | k4=f1(t[i+1] ,x[i]+h*(k1-k2+k3) ,y[i]+h*(k1-k2+k3)) 134 | 135 | x[i+1]=x[i]+h*(1/8*k1+3/8*k2+3/8*k3+1/8*k4) 136 | 137 | k1=f2(t[i],x[i],y[i]) 138 | k2=f2(t[i]+1/3*h,x[i]+h*k1/3 ,y[i]+h*k1/3) 139 | k3=f2(t[i]+2/3*h,x[i]+h*(-1/3*k1+k2),y[i]+h*(-1/3*k1+k2)) 140 | k4=f2(t[i+1] ,x[i]+h*(k1-k2+k3) ,y[i]+h*(k1-k2+k3)) 141 | 142 | y[i+1]=y[i]+h*(1/8*k1+3/8*k2+3/8*k3+1/8*k4) 143 | 144 | 145 | return t,x,y 146 | 147 | ################################################# Funciones de Error##################################################### 148 | 149 | def Error_Abs(aprox,real): 150 | err=abs(aprox-real) 151 | return err 152 | 153 | def Error_Rela(aprox,real): 154 | err=abs(aprox-real)/abs(real) 155 | return err 156 | 157 | 158 | def MSE(aprox,real): 159 | mse=np.square(aprox-real).mean() 160 | return mse 161 | 162 | ######################################################################################################################### -------------------------------------------------------------------------------- /Modulos/Solver_EDO.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | import numpy as np 5 | 6 | #### dx/dt=f(t,x), x(t0)=x0 7 | 8 | ##################### Método de Euler ################################################### 9 | 10 | def EulerM(f,x0,T,n): 11 | t=np.linspace(T[0],T[1],n) 12 | h=abs(t[1]-t[0]) 13 | x=np.empty(n) 14 | x[0]=x0 15 | 16 | for i in range(n-1): 17 | x[i+1]=x[i]+h*f(t[i],x[i]) 18 | return t,x 19 | 20 | ################## Método del Punto Medio ###################################################### 21 | 22 | def MidPt(f,x0,T,n): 23 | t=np.linspace(T[0],T[1],n) 24 | h=abs(t[1]-t[0]) 25 | x=np.empty(n) 26 | x[0]=x0 27 | 28 | for i in range(n-1): 29 | 30 | k1=f(t[i],x[i]) 31 | k2=f(t[i]+h/2,x[i]+h*1/2*k1) 32 | x[i+1]=x[i]+h*k2 33 | 34 | return t,x 35 | 36 | ################################# Método de Heun ############################################# 37 | 38 | def Heun(f,x0,T,n): 39 | t=np.linspace(T[0],T[1],n) 40 | h=abs(t[1]-t[0]) 41 | x=np.empty(n) 42 | x[0]=x0 43 | 44 | for i in range(n-1): 45 | k1=f(t[i],x[i]) 46 | k2=f(t[i+1],x[i]+h*k1) 47 | x[i+1]=x[i]+h*(1/2*k1+1/2*k2) 48 | 49 | return t,x 50 | 51 | ###################### Método de Ralson ############################################################### 52 | 53 | def Ralson(f,x0,T,n): 54 | t=np.linspace(T[0],T[1],n) 55 | h=abs(t[1]-t[0]) 56 | x=np.empty(n) 57 | x[0]=x0 58 | 59 | for i in range(n-1): 60 | k1=f(t[i],x[i]) 61 | k2=f(t[i]+2/3*h,x[i]+h*2/3*k1) 62 | x[i+1]=x[i]+h*(1/4*k1+3/4*k2) 63 | 64 | return t,x 65 | 66 | ########################################## Método de Runge-Kutta (RK4) ######################################## 67 | 68 | ## f es la funcion 69 | ## x0 es la condicion incial 70 | ## T es el tiempo en el cual se va a solucionar el modelo 71 | ## n es el numero de puntos del metodo numerico 72 | 73 | def RK4(f,x0,T,n): 74 | t=np.linspace(T[0],T[1],n) 75 | h=abs(t[1]-t[0]) 76 | x=np.empty(n) 77 | x[0]=x0 78 | 79 | for i in range(n-1): 80 | 81 | k1=f(t[i],x[i]) 82 | k2=f(t[i]+1/2*h,x[i]+h*1/2*k1) 83 | k3=f(t[i]+1/2*h,x[i]+h*1/2*k2) 84 | k4=f(t[i+1] ,x[i]+h*k3) 85 | 86 | x[i+1]=x[i]+h*(1/6*k1+1/3*k2+1/3*k3+1/6*k4) 87 | 88 | return t,x 89 | 90 | ########################################## Método de Runge-Kutta, Regla 3/8 #################################### 91 | 92 | def RK38(f,x0,T,n): 93 | t=np.linspace(T[0],T[1],n) 94 | h=abs(t[1]-t[0]) 95 | x=np.empty(n) 96 | x[0]=x0 97 | 98 | for i in range(n-1): 99 | k1=f(t[i],x[i]) 100 | k2=f(t[i]+1/3*h,x[i]+h*k1/3) 101 | k3=f(t[i]+2/3*h,x[i]+h*(-1/3*k1+k2)) 102 | k4=f(t[i+1] ,x[i]+h*(k1-k2+k3)) 103 | 104 | x[i+1]=x[i]+h*(1/8*k1+3/8*k2+3/8*k3+1/8*k4) 105 | return t,x 106 | 107 | ########################################## Método de Runge-Kutta-Fehlberg #################################### 108 | 109 | def RKF(f,x0,T,n,order=5): 110 | t=np.linspace(T[0],T[1],n) 111 | h=abs(t[1]-t[0]) 112 | x=np.empty(n) 113 | x[0]=x0 114 | 115 | for i in range(n-1): 116 | k1=f(t[i],x[i]) 117 | k2=f(t[i]+1/4*h ,x[i]+h*k1/4) 118 | k3=f(t[i]+3/8*h ,x[i]+h*(3/32*k1+9/32*k2)) 119 | k4=f(t[i]+12/13*h,x[i]+h*(1932/2197*k1-7200/2197*k2+7296/2197*k3)) 120 | k5=f(t[i]+h ,x[i]+h*(439/216*k1-8*k2+3680/513*k3-845/4104*k4)) 121 | k6=f(t[i]+h/2 ,x[i]+h*(-8/27*k1+2*k2-3544/2565*k3+1859/4104*k4-11/40*k5)) 122 | 123 | if order==5: 124 | x[i+1]=x[i]+h*(16/135*k1+6656/12825*k3+28561/56430*k4-9/50*k5+2/55*k6) 125 | else: 126 | x[i+1]=x[i]+h*(25/216*k1+1408/2565*k3+2197/4104*k4-1/5*k5) 127 | return t,x 128 | 129 | ########################################## Método de Dormand-Prince #################################### 130 | 131 | def DP(f,x0,T,n,order=5): 132 | t=np.linspace(T[0],T[1],n) 133 | h=abs(t[1]-t[0]) 134 | x=np.empty(n) 135 | x[0]=x0 136 | 137 | for i in range(n-1): 138 | k1=f(t[i] ,x[i]) 139 | k2=f(t[i]+1/5*h ,x[i]+h*k1/5) 140 | k3=f(t[i]+3/10*h,x[i]+h*(3/40*k1+9/40*k2)) 141 | k4=f(t[i]+4/5*h ,x[i]+h*(44/45*k1-56/15*k2+32/9*k3)) 142 | k5=f(t[i]+8/9*h ,x[i]+h*(19372/6561*k1-25360/2187*k2+64448/6561*k3-212/729*k4)) 143 | k6=f(t[i]+h ,x[i]+h*(9017/3168*k1-355/33*k2+46732/5247*k3+49/176*k4-5103/18656*k5)) 144 | k7=f(t[i]+h ,x[i]+h*(35/384*k1+500/1113*k3+125/192*k4-2187/6784*k5+11/84*k6)) 145 | if order==5: 146 | x[i+1]=x[i]+h*(35/384*k1+500/1113*k3+125/192*k4-2187/6784*k5+11/84*k6) 147 | else: 148 | x[i+1]=x[i]+h*(5179/57600*k1+7571/16695*k3+393/640*k4-92097/339200*k5+187/2100*k6+1/40*k7) 149 | return t,x 150 | 151 | ################################################# Funciones de Error##################################################### 152 | 153 | def Error_Abs(aprox,real): 154 | err=abs(aprox-real) 155 | return err 156 | 157 | def Error_Rela(aprox,real): 158 | err=abs(aprox-real)/abs(real) 159 | return err 160 | 161 | 162 | def MSE(aprox,real): 163 | mse=np.square(aprox-real).mean() 164 | return mse 165 | 166 | ################################################################################################################## -------------------------------------------------------------------------------- /Cuadernos/Instalando_Kernels.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "FnbvkSDCE8CZ" 8 | }, 9 | "source": [ 10 | "# Utilizando Kernels en JupyterLab\n", 11 | "\n", 12 | "¿Alguna vez te has preguntado si sería posible usar las posibilidades de Julia, Python y R en un sólo entorno gráfico estilo Notebook?\n", 13 | "\n", 14 | "\n", 15 | "**
¡Es posible!
**\n", 16 | "\n", 17 | "Para esto es necesario el concepto de Kernel e implementarlo en JupyterLab a través de Anaconda.\n", 18 | "\n", 19 | "El Objetivo de este cuaderno será lograr lo que se muestra a continuación cuando se inicialize JupyterLab:\n", 20 | "\n", 21 | "" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": { 27 | "colab_type": "text", 28 | "id": "5vVk_9W0E8Ci" 29 | }, 30 | "source": [ 31 | "# Requisitos:\n", 32 | "\n", 33 | "- Descargar e instalar una versión de **R** (Descarga [aquí](https://cran.r-project.org/bin/windows/base/R-3.6.2-win.exe), versión actual: 3.6.2).\n", 34 | "\n", 35 | "- Descargar e instalar una versión de **Julia** (Descarga [aquí](https://julialang-s3.julialang.org/bin/winnt/x64/1.3/julia-1.3.1-win64.exe), versión actual: 1.3.1).\n" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": { 41 | "colab_type": "text", 42 | "id": "Om9KzFLzE8Cp" 43 | }, 44 | "source": [ 45 | "# Instalación de IR\n", 46 | "\n", 47 | "- Para comenzar, iniciamos el **Prompt** de Anaconda como **Administrador**.\n", 48 | "\n", 49 | "Ir a la ruta donde se encuentra instalado R.\n", 50 | "\n", 51 | "**Ejemplo (Para cada computador, es diferente la ruta):**\n", 52 | "\n", 53 | "- Ejecutar el comando ```\"C:\\Program Files\\R\\R-3.6.2\\bin\\R.exe\"``` en la consola de Anaconda (**note las comillas dobles**)\n", 54 | "\n", 55 | "Esto iniciará el motor de R dentro de Anaconda.\n", 56 | "\n", 57 | "Ahora vamos a instalar unos paquetes necesarios:\n", 58 | "\n", 59 | "- ```install.packages('IRkernel')```\n", 60 | "\n", 61 | "Elegir un mirror (0-Cloud es recomendado).\n", 62 | "\n", 63 | "Esto tomará algo de tiempo\n", 64 | "\n", 65 | "- ```update.packages(ask=FALSE)```\n", 66 | "\n", 67 | "Esto tomará algo de tiempo.\n", 68 | "\n", 69 | "Finalmente, \n", 70 | "\n", 71 | "- ```IRkernel::installspec()```\n", 72 | "\n", 73 | "Si todo marcha bien, no aparecerá ningún error.\n", 74 | "\n", 75 | "- Lanzar Jupyterlab para verificar la instalación." 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": { 81 | "colab_type": "text", 82 | "id": "DCnkhVKiE8Ct" 83 | }, 84 | "source": [ 85 | "# Instalación de IJulia\n", 86 | "\n", 87 | "En este caso, debemos ejecutar Julia, ubicado en la carpeta:\n", 88 | "\n", 89 | "```C:\\Users\\Nombre_Usuario\\AppData\\Local\\Julia-1.3.1\\bin\\julia.exe```" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": { 95 | "colab_type": "text", 96 | "id": "DCnkhVKiE8Ct" 97 | }, 98 | "source": [ 99 | "Dentro de la consola, se ejecutara:\n", 100 | "\n", 101 | "- ```using Pkg```\n", 102 | "- ```Pkg.add(\"IJulia\")```\n", 103 | "- ```Pkg.build(\"IJulia\")``` (Si el resultado final es false, indica que todo marchó bien)\n", 104 | "\n", 105 | "Si todo finaliza bien, no deberá aparecer ningún error." 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": { 111 | "colab_type": "text", 112 | "id": "VVGSYrApE8Cy" 113 | }, 114 | "source": [ 115 | "# Lista de kernels instalados\n", 116 | "\n", 117 | "La instalación de los kernels de Jupyter atraviesa todos los ambientes de trabajo, así que no hay que instalarlos para cada uno de ellos.\n", 118 | "\n", 119 | "Para ver la lsita de Kernels instalados, se ejecuta en el Prompt de Anaconda:\n", 120 | "\n", 121 | "```jupyter kernelspec list```\n", 122 | "\n", 123 | "\n", 124 | "\n", 125 | "Hemos terminado, ahora sólo falta arrancar Jupyter e iniciar en nuestro kernel favorito!\n", 126 | "\n", 127 | "**Notas:** \n", 128 | "\n", 129 | "1. De aquí el nombre **Jupyter**: \n", 130 | "\n", 131 | "- **Ju**(Julia)\n", 132 | "- **Pyt**(Python)\n", 133 | "- **e**(et)\n", 134 | "- **r**(R)\n", 135 | "\n", 136 | "2. Por supuesto, se úeden instalar muchos otros kernels, por ejemplo GNU Octave (Versión libre de MATLAB), lo único que hay que hacer es seguir las guías online con mucha paciencia.\n", 137 | "\n", 138 | "![kernels](http://datahonor-1252464519.costj.myqcloud.com/201803/Screenshot%20from%202018-03-21%2011-22-42.png)\n", 139 | "![kernels2](https://miro.medium.com/max/3560/1*ENGFiVsAWmc_0NCGAjpzSg.png)\n" 140 | ] 141 | } 142 | ], 143 | "metadata": { 144 | "colab": { 145 | "collapsed_sections": [], 146 | "name": "Instalando_Kernels.ipynb", 147 | "provenance": [] 148 | }, 149 | "kernelspec": { 150 | "display_name": "Python 3", 151 | "language": "python", 152 | "name": "python3" 153 | }, 154 | "language_info": { 155 | "codemirror_mode": { 156 | "name": "ipython", 157 | "version": 3 158 | }, 159 | "file_extension": ".py", 160 | "mimetype": "text/x-python", 161 | "name": "python", 162 | "nbconvert_exporter": "python", 163 | "pygments_lexer": "ipython3", 164 | "version": "3.7.1" 165 | } 166 | }, 167 | "nbformat": 4, 168 | "nbformat_minor": 4 169 | } 170 | -------------------------------------------------------------------------------- /Modulos/Solver_EDOS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | import numpy as np 5 | 6 | #----------------------------Vector System-------------------------# 7 | 8 | # dX/dt=F(t,X), X(t0)=X0 9 | # X=(x1,x2,...xn) 10 | # F=(f1,f2,...,fn) 11 | 12 | # Pythonic 13 | 14 | # X=(X[0],X[1],...,X[n-1]) 15 | # F=(f[0],f[1],...,f[n-1]) 16 | 17 | 18 | #------------------------------ Método de Euler -----------------------# 19 | 20 | def Euler(F,X0,T,n): 21 | t=np.linspace(T[0],T[1],n) 22 | h=abs(t[1]-t[0]) 23 | col=len(X0) 24 | X=np.empty(shape=(n,col)) 25 | X[0,:]=X0 26 | 27 | for i in range(n-1): 28 | 29 | X[i+1,:]=X[i,:]+h*F(t[i],X[i,:]) 30 | 31 | return t,X 32 | 33 | ################## Método del Punto Medio ###################################################### 34 | 35 | def MidPt(F,X0,T,n): 36 | t=np.linspace(T[0],T[1],n) 37 | h=abs(t[1]-t[0]) 38 | col=len(X0) 39 | X=np.empty(shape=(n,col)) 40 | X[0,:]=X0 41 | 42 | for i in range(n-1): 43 | k1=F(t[i],X[i,:]) 44 | k2=F(t[i]+h/2,X[i,:]+h*1/2*k1) 45 | X[i+1,:]=X[i,:]+h*k2 46 | 47 | return t,X 48 | 49 | ################################# Método de Heun ############################################# 50 | 51 | def Heun(F,X0,T,n): 52 | t=np.linspace(T[0],T[1],n) 53 | h=abs(t[1]-t[0]) 54 | col=len(X0) 55 | X=np.empty(shape=(n,col)) 56 | X[0,:]=X0 57 | 58 | for i in range(n-1): 59 | 60 | k1=F(t[i],X[i,:]) 61 | k2=F(t[i+1],X[i,:]+h*k1) 62 | 63 | X[i+1,:]=X[i,:]+h*(1/2*k1+1/2*k2) 64 | 65 | return t,X 66 | 67 | ###################### Método de Ralson ############################################################### 68 | 69 | def Ralson(F,X0,T,n): 70 | t=np.linspace(T[0],T[1],n) 71 | h=abs(t[1]-t[0]) 72 | col=len(X0) 73 | X=np.empty(shape=(n,col)) 74 | X[0,:]=X0 75 | 76 | for i in range(n-1): 77 | k1=F(t[i],X[i,:]) 78 | k2=F(t[i]+2/3*h,X[i,:]+h*2/3*k1) 79 | 80 | X[i+1,:]=X[i,:]+h*(1/4*k1+3/4*k2) 81 | 82 | return t,X 83 | 84 | ########################################## Método de Runge-Kutta (RK4) ######################################## 85 | 86 | def RK4(F,X0,T,n): 87 | t=np.linspace(T[0],T[1],n) 88 | h=abs(t[1]-t[0]) 89 | col=len(X0) 90 | X=np.empty(shape=(n,col)) 91 | X[0,:]=X0 92 | 93 | for i in range(n-1): 94 | 95 | k1=F(t[i],X[i,:]) 96 | k2=F(t[i]+1/2*h,X[i,:]+h*1/2*k1) 97 | k3=F(t[i]+1/2*h,X[i,:]+h*1/2*k2) 98 | k4=F(t[i]+h,X[i,:]+h*+k3) 99 | 100 | X[i+1,:]=X[i,:]+h*(1/6*k1+1/3*k2+1/3*k3+1/6*k4) 101 | 102 | return t,X 103 | 104 | ########################################## Método de Runge-Kutta, Regla 3/8 #################################### 105 | 106 | def RK38(F,X0,T,n): 107 | t=np.linspace(T[0],T[1],n) 108 | h=abs(t[1]-t[0]) 109 | N=len(X0) 110 | X=np.empty(shape=(n,N)) 111 | X[0,:]=X0 112 | 113 | for i in range(n-1): 114 | 115 | k1=F(t[i],X[i,:]) 116 | k2=F(t[i]+1/3*h,X[i,:]+h*k1/3) 117 | k3=F(t[i]+2/3*h,X[i,:]+h*(-1/3*k1+k2)) 118 | k4=F(t[i+1] ,X[i,:]+h*(k1-k2+k3)) 119 | 120 | X[i+1,:]=X[i,:]+h*(1/8*k1+3/8*k2+3/8*k3+1/8*k4) 121 | 122 | return t,X 123 | 124 | ########################################## Método de Runge-Kutta-Fehlberg #################################### 125 | 126 | def RKF(f,X0,T,n,order=5): 127 | t=np.linspace(T[0],T[1],n) 128 | h=abs(t[1]-t[0]) 129 | N=len(X0) 130 | X=np.empty(shape=(n,N)) 131 | X[0,:]=X0 132 | 133 | for i in range(n-1): 134 | k1=f(t[i],X[i,:]) 135 | k2=f(t[i]+1/4*h ,X[i,:]+h*k1/4) 136 | k3=f(t[i]+3/8*h ,X[i,:]+h*(3/32*k1+9/32*k2)) 137 | k4=f(t[i]+12/13*h,X[i,:]+h*(1932/2197*k1-7200/2197*k2+7296/2197*k3)) 138 | k5=f(t[i]+h ,X[i,:]+h*(439/216*k1-8*k2+3680/513*k3-845/4104*k4)) 139 | k6=f(t[i]+h/2 ,X[i,:]+h*(-8/27*k1+2*k2-3544/2565*k3+1859/4104*k4-11/40*k5)) 140 | 141 | if order==5: 142 | X[i+1,:]=X[i,:]+h*(16/135*k1+6656/12825*k3+28561/56430*k4-9/50*k5+2/55*k6) 143 | else: 144 | X[i+1,:]=X[i,:]+h*(25/216*k1+1408/2565*k3+2197/4104*k4-1/5*k5) 145 | return t,X 146 | 147 | ########################################## Método de Dormand-Prince ########################### 148 | 149 | def DP(f,X0,T,n,order=5): 150 | t=np.linspace(T[0],T[1],n) 151 | h=abs(t[1]-t[0]) 152 | N=len(X0) 153 | X=np.empty(shape=(n,N)) 154 | X[0,:]=X0 155 | 156 | for i in range(n-1): 157 | k1=f(t[i] ,X[i,:]) 158 | k2=f(t[i]+1/5*h ,X[i,:]+h*k1/5) 159 | k3=f(t[i]+3/10*h,X[i,:]+h*(3/40*k1+9/40*k2)) 160 | k4=f(t[i]+4/5*h ,X[i,:]+h*(44/45*k1-56/15*k2+32/9*k3)) 161 | k5=f(t[i]+8/9*h ,X[i,:]+h*(19372/6561*k1-25360/2187*k2+64448/6561*k3-212/729*k4)) 162 | k6=f(t[i]+h ,X[i,:]+h*(9017/3168*k1-355/33*k2+46732/5247*k3+49/176*k4-5103/18656*k5)) 163 | k7=f(t[i]+h ,X[i,:]+h*(35/384*k1+500/1113*k3+125/192*k4-2187/6784*k5+11/84*k6)) 164 | if order==5: 165 | X[i+1,:]=X[i,:]+h*(35/384*k1+500/1113*k3+125/192*k4-2187/6784*k5+11/84*k6) 166 | else: 167 | X[i+1,:]=X[i,:]+h*(5179/57600*k1+7571/16695*k3+393/640*k4-92097/339200*k5+187/2100*k6+1/40*k7) 168 | return t,X 169 | 170 | ################################################# Funciones de Error ######################### 171 | 172 | def Error(aprox,real): 173 | err=real-aprox 174 | return err 175 | 176 | def Error_Abs(aprox,real): 177 | err=abs(real-aprox) 178 | return err 179 | 180 | def Error_Rela(aprox,real): 181 | err=abs(real-aprox)/abs(real) 182 | return err 183 | 184 | def MSE(aprox,real): 185 | mse=np.square(aprox-real).mean() 186 | return mse 187 | 188 | ############################################################################################## -------------------------------------------------------------------------------- /Modulos/Solver_EDOS_P3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | 5 | import numpy as np 6 | 7 | #### dx/dt=f1(t,x,y,z), x(t0)=x0 8 | #### dy/dt=f2(t,x,y,z), y(t0)=y0 9 | #### dz/dt=f3(t,x,y,z), z(t0)=z0 10 | 11 | ##################### Método de Euler ################################################### 12 | 13 | def EulerM(f1,f2,f3,x0,y0,z0,T,n): 14 | t=np.linspace(T[0],T[1],n) 15 | h=abs(t[1]-t[0]) 16 | x=np.empty(n) 17 | x[0]=x0 18 | y=np.empty(n) 19 | y[0]=y0 20 | z=np.empty(n) 21 | z[0]=z0 22 | 23 | for i in range(n-1): 24 | x[i+1]=x[i]+h*f1(t[i],x[i],y[i],z[i]) 25 | y[i+1]=y[i]+h*f2(t[i],x[i],y[i],z[i]) 26 | z[i+1]=z[i]+h*f3(t[i],x[i],y[i],z[i]) 27 | 28 | return t,x,y,z 29 | 30 | ################## Método del Punto Medio ############################################# 31 | 32 | def MidPt(f1,f2,f3,x0,y0,z0,T,n): 33 | t=np.linspace(T[0],T[1],n) 34 | h=abs(t[1]-t[0]) 35 | x=np.empty(n) 36 | x[0]=x0 37 | y=np.empty(n) 38 | y[0]=y0 39 | z=np.empty(n) 40 | z[0]=z0 41 | 42 | for i in range(n-1): 43 | 44 | k1=f1(t[i],x[i],y[i],z[i]) 45 | k2=f1(t[i]+h/2,x[i]+h*1/2*k1,y[i]+h*1/2*k1,z[i]+h*1/2*k1) 46 | x[i+1]=x[i]+h*k2 47 | 48 | k1=f2(t[i],x[i],y[i],z[i]) 49 | k2=f2(t[i]+h/2,x[i]+h*1/2*k1,y[i]+h*1/2*k1,z[i]+h*1/2*k1) 50 | y[i+1]=y[i]+h*k2 51 | 52 | k1=f3(t[i],x[i],y[i],z[i]) 53 | k2=f3(t[i]+h/2,x[i]+h*1/2*k1,y[i]+h*1/2*k1,z[i]+h*1/2*k1) 54 | z[i+1]=z[i]+h*k2 55 | 56 | return t,x,y,z 57 | 58 | ################################# Método de Heun ############################################# 59 | 60 | def Heun(f1,f2,f3,x0,y0,z0,T,n): 61 | t=np.linspace(T[0],T[1],n) 62 | h=abs(t[1]-t[0]) 63 | x=np.empty(n) 64 | x[0]=x0 65 | y=np.empty(n) 66 | y[0]=y0 67 | z=np.empty(n) 68 | z[0]=z0 69 | 70 | for i in range(n-1): 71 | 72 | k1=f1(t[i],x[i],y[i],z[i]) 73 | k2=f1(t[i+1],x[i]+h*k1,y[i]+h*k1,z[i]+h*k1) 74 | x[i+1]=x[i]+h*(1/2*k1+1/2*k2) 75 | 76 | k1=f2(t[i],x[i],y[i],z[i]) 77 | k2=f2(t[i+1],x[i]+h*k1,y[i]+h*k1,z[i]+h*k1) 78 | y[i+1]=y[i]+h*(1/2*k1+1/2*k2) 79 | 80 | k1=f3(t[i],x[i],y[i],z[i]) 81 | k2=f3(t[i+1],x[i]+h*k1,y[i]+h*k1,z[i]+h*k1) 82 | z[i+1]=z[i]+h*(1/2*k1+1/2*k2) 83 | 84 | return t,x,y,z 85 | 86 | ########################### Método de Ralson ############################################################### 87 | 88 | def Ralson(f1,f2,f3,x0,y0,z0,T,n): 89 | t=np.linspace(T[0],T[1],n) 90 | h=abs(t[1]-t[0]) 91 | x=np.empty(n) 92 | x[0]=x0 93 | y=np.empty(n) 94 | y[0]=y0 95 | z=np.empty(n) 96 | z[0]=z0 97 | 98 | for i in range(n-1): 99 | 100 | k1=f1(t[i],x[i],y[i],z[i]) 101 | k2=f1(t[i]+2/3*h,x[i]+h*2/3*k1,y[i]+h*2/3*k1,z[i]+h*2/3*k1) 102 | x[i+1]=x[i]+h*(1/4*k1+3/4*k2) 103 | 104 | k1=f2(t[i],x[i],y[i]) 105 | k2=f2(t[i]+2/3*h,x[i]+h*2/3*k1,y[i]+h*2/3*k1,z[i]+h*2/3*k1) 106 | y[i+1]=y[i]+h*(1/4*k1+3/4*k2) 107 | 108 | k1=f3(t[i],x[i],y[i],z[i]) 109 | k2=f3(t[i]+2/3*h,x[i]+h*2/3*k1,y[i]+h*2/3*k1,z[i]+h*2/3*k1) 110 | z[i+1]=z[i]+h*(1/4*k1+3/4*k2) 111 | 112 | return t,x,y,z 113 | 114 | ########################################## Método de Runge-Kutta (RK4) ######################################## 115 | 116 | def RK4(f1,f2,f3,x0,y0,z0,T,n): 117 | t=np.linspace(T[0],T[1],n) 118 | h=abs(t[1]-t[0]) 119 | x=np.empty(n) 120 | x[0]=x0 121 | y=np.empty(n) 122 | y[0]=y0 123 | z=np.empty(n) 124 | z[0]=z0 125 | 126 | for i in range(n-1): 127 | 128 | k1=f1(t[i],x[i],y[i],z[i]) 129 | k2=f1(t[i]+1/2*h,x[i]+h*1/2*k1,y[i]+h*1/2*k1,z[i]+h*1/2*k1) 130 | k3=f1(t[i]+1/2*h,x[i]+h*1/2*k2,y[i]+h*1/2*k2,z[i]+h*1/2*k2) 131 | k4=f1(t[i+1] ,x[i]+h*k3 ,y[i]+h*k3, z[i]+h*k3) 132 | 133 | x[i+1]=x[i]+h*(1/6*k1+1/3*k2+1/3*k3+1/6*k4) 134 | 135 | k1=f2(t[i],x[i],y[i],z[i]) 136 | k2=f2(t[i]+1/2*h,x[i]+h*1/2*k1,y[i]+h*1/2*k1,z[i]+h*1/2*k1) 137 | k3=f2(t[i]+1/2*h,x[i]+h*1/2*k2,y[i]+h*1/2*k2,z[i]+h*1/2*k2) 138 | k4=f2(t[i+1] ,x[i]+h*k3 ,y[i]+h*k3, z[i]+h*k3) 139 | 140 | y[i+1]=y[i]+h*(1/6*k1+1/3*k2+1/3*k3+1/6*k4) 141 | 142 | k1=f3(t[i],x[i],y[i],z[i]) 143 | k2=f3(t[i]+1/2*h,x[i]+h*1/2*k1,y[i]+h*1/2*k1,z[i]+h*1/2*k1) 144 | k3=f3(t[i]+1/2*h,x[i]+h*1/2*k2,y[i]+h*1/2*k2,z[i]+h*1/2*k2) 145 | k4=f3(t[i+1] ,x[i]+h*k3 ,y[i]+h*k3, z[i]+h*k3) 146 | 147 | z[i+1]=z[i]+h*(1/6*k1+1/3*k2+1/3*k3+1/6*k4) 148 | 149 | return t,x,y,z 150 | 151 | ########################################## Método de Runge-Kutta, Regla 3/8 #################################### 152 | 153 | def RK38(f1,f2,f3,x0,y0,z0,T,n): 154 | t=np.linspace(T[0],T[1],n) 155 | h=abs(t[1]-t[0]) 156 | x=np.empty(n) 157 | x[0]=x0 158 | y=np.empty(n) 159 | y[0]=y0 160 | z=np.empty(n) 161 | z[0]=z0 162 | 163 | for i in range(n-1): 164 | 165 | k1=f1(t[i],x[i],y[i],z[i]) 166 | k2=f1(t[i]+1/3*h,x[i]+h*k1/3 ,y[i]+h*k1/3 ,z[i]+h*k1/3) 167 | k3=f1(t[i]+2/3*h,x[i]+h*(-1/3*k1+k2),y[i]+h*(-1/3*k1+k2),z[i]+h*(-1/3*k1+k2)) 168 | k4=f1(t[i+1] ,x[i]+h*(k1-k2+k3) ,y[i]+h*(k1-k2+k3) ,z[i]+h*(k1-k2+k3)) 169 | 170 | x[i+1]=x[i]+h*(1/8*k1+3/8*k2+3/8*k3+1/8*k4) 171 | 172 | k1=f2(t[i],x[i],y[i],z[i]) 173 | k2=f2(t[i]+1/3*h,x[i]+h*k1/3 ,y[i]+h*k1/3 ,z[i]+h*k1/3) 174 | k3=f2(t[i]+2/3*h,x[i]+h*(-1/3*k1+k2),y[i]+h*(-1/3*k1+k2),z[i]+h*(-1/3*k1+k2)) 175 | k4=f2(t[i+1] ,x[i]+h*(k1-k2+k3) ,y[i]+h*(k1-k2+k3) ,z[i]+h*(k1-k2+k3)) 176 | 177 | y[i+1]=y[i]+h*(1/8*k1+3/8*k2+3/8*k3+1/8*k4) 178 | 179 | k1=f3(t[i],x[i],y[i],z[i]) 180 | k2=f3(t[i]+1/3*h,x[i]+h*k1/3 ,y[i]+h*k1/3 ,z[i]+h*k1/3) 181 | k3=f3(t[i]+2/3*h,x[i]+h*(-1/3*k1+k2),y[i]+h*(-1/3*k1+k2),z[i]+h*(-1/3*k1+k2)) 182 | k4=f3(t[i+1] ,x[i]+h*(k1-k2+k3) ,y[i]+h*(k1-k2+k3) ,z[i]+h*(k1-k2+k3)) 183 | 184 | z[i+1]=z[i]+h*(1/8*k1+3/8*k2+3/8*k3+1/8*k4) 185 | 186 | 187 | return t,x,y,z 188 | 189 | ################################################# Funciones de Error##################################################### 190 | 191 | def Error_Abs(aprox,real): 192 | err=abs(aprox-real) 193 | return err 194 | 195 | def Error_Rela(aprox,real): 196 | err=abs(aprox-real)/abs(real) 197 | return err 198 | 199 | 200 | def MSE(aprox,real): 201 | mse=np.square(aprox-real).mean() 202 | return mse 203 | 204 | ######################################################################################################################### -------------------------------------------------------------------------------- /Cuadernos/Ambientes.ipynb: -------------------------------------------------------------------------------- 1 | {"nbformat":4,"nbformat_minor":0,"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.6"},"colab":{"name":"Ambientes.ipynb","provenance":[],"collapsed_sections":[]}},"cells":[{"cell_type":"markdown","metadata":{"id":"YpCjMi-eESDM","colab_type":"text"},"source":["# Creando Ambientes de Trabajo con Anaconda\n","\n","## Motivación:\n","\n","Ha llegado el momento de utilizar los lenguajes de programación **inteligentemente**.\n","\n","Imaginemos que por alguna razón, algún genio informático ha diseñado un código para **predecir la bolsa de valores**.\n","\n","Como el genio informático no tiene mucha idea de lo que ha hecho es algo grande, ha decidido publicarlo en alguna parte (Drive, GitHub, etc).\n","\n","Nosotros, **curiosos como siempre**, hemos decidido darle un vistazo a su código y por qué no, ejecutarlo.\n","\n","Sin embargo, existe un gran problema:\n","\n","**La sintáxis del código está escrita en versiones anteriores de Python (3.5 por ejemplo) y nosotros poseemos la version 3.7.6 en nuestro ambiente de Jupyter!**\n","\n","El secreto detrás de la **creación de ambientes de trabajo** es poder ejecutar ese trabajo que otras personas han hecho en el pasado y poder obtener sus resultados!\n","\n","**Good News!**\n","\n"]},{"cell_type":"markdown","metadata":{"id":"yAQ45Kp0ESDV","colab_type":"text"},"source":["# Anaconda Prompt\n","\n","Para comenzar a programar en serio, es necesario usar la consola que viene con Anaconda.\n","\n","Es **fundamental** para instalar paquetes y crear ambientes, iniciar como Administrador\n","\n","\n","\n",""]},{"cell_type":"markdown","metadata":{"id":"LxIrPJdtESDb","colab_type":"text"},"source":["Notemos el **(base)** antes de la ruta **(path)** en el computador.\n","\n","Este **(base)** representa nuestro ambiente base instalado en el PC por defecto que hace Anaconda.\n","\n","Al ejecutar el comando \n","\n","```conda list```\n","\n","Podremos observar todos los paquetes instalados por defecto (150+), útiles para hacer cálculos científicos y muchos otros fines.\n","\n","**conda** es el manejador de paquetes de Anaconda (Siendo Anaconda el Software)\n","\n","Usaremos con mucha frecuencia el comando **```conda```** de aquí en adelante."]},{"cell_type":"markdown","metadata":{"id":"_s8ODm60ESDi","colab_type":"text"},"source":["# Mantener Actualizados los Paquetes de Anaconda\n","\n","Ejecutamos los siguientes comandos:\n","\n","```conda update conda```\n","\n","```conda update anaconda```\n","\n","para ver qué paquetes con mejoras están disponibles a tiempo real.\n","\n","No es necesario hacer este paso, pero es una buena práctica de programación.\n"]},{"cell_type":"markdown","metadata":{"id":"xfVeIPOVESDm","colab_type":"text"},"source":["# Creando Nuevos Ambientes de Trabajo\n","\n","Crear un nuevo ambiente de trabajo es tan fácil como ejecutar\n","\n","```conda create -n myenv```\n","\n","donde **myenv** es el nombre que uno quiere darle a dicho ambiente.\n","\n","**-n** es un shortcut para decir **name** (también se puede usar **--name**)\n","\n","**Ejemplo:**\n","\n","```conda create -n clase```\n","\n","Pedirá confirmación del usuario para crear el ambiente.\n","\n","Para visualizar los ambientes disponibles, se debe ejecutar\n","\n","```conda env list``` \n","\n","(env = environment = ambiente)\n","\n","\n","\n","En este caso, podemos ver que están disponibles tres ambientes de trabajo:\n","\n","* base ( * significa que es el ambiente que por defecto se inicializa al iniciar Anaconda)\n","* clase\n","* tf2"]},{"cell_type":"markdown","metadata":{"id":"KdoqEbi5ESDu","colab_type":"text"},"source":["# Activando Ambientes\n","\n","Para **activar** un ambiente de trabajo, se ejecuta\n","\n","```conda activate myenv```\n","\n","Para **desactivar** el ambiente se ejecuta\n","\n","```conda deactivate```\n","\n","**Ejemplo:**\n","\n","\n","\n","Podemos ver como se cambia de **(base)** a **(clase)** y luego se desactiva y se vuelve a **(base)**\n","\n","Veamos que hay dentro del ambiente **(clase)**:\n","\n","\n","\n","Como no hemos pedido que instale ningún paquete, éste ambiente está **vacío**.\n","\n","Vamos entonces a agregar unas cuantas cosas."]},{"cell_type":"markdown","metadata":{"id":"qiNU7evtESDz","colab_type":"text"},"source":["# Instalando Paquetes en Ambientes Diferentes del (base)\n","\n","Es importante hacer esto, sobre todo cuando se hacen proyectos profesionales.\n","\n","Queremos administrar versiones compatibles de paquetes, ya sean anteriores o nuevas, para poder ejecutar cualquier tipo de código existente en la Web.\n","\n","Para **instalar un paquete** en un ambiente de trabajo, debemos activarlo y usar el comando ```conda install pkgname``` (pkgname = nombre del paquete):\n","\n","**Ejemplo**\n","\n","```conda activate clase```\n","\n","```conda install python=3.5 -y```\n","\n","**-y** es un shortcut para no pedir confirmación del usuario (algo parecido a \"*yes, you will!*\" )\n","\n","\n","\n","Ahora podemos ver los **nuevos paquetes** instalados en el nuevo ambiente de trabajo:\n","\n",""]},{"cell_type":"markdown","metadata":{"id":"R_Feki0-ESD4","colab_type":"text"},"source":["# ¿Cómo Eliminar Ambientes y Por Qué es Importante Todo Esto?\n","\n","La idea detrás de los ambientes de trabajo es poder tener una alternativa a la configuración por default que tiene Anaconda.\n","\n","Si algo llegase a fallar en el (base) por algún paquete que instalemos mal, es muy posible que toque **reinstalar** todo el software de Anaconda desde cero, lo cual es bastante largo en Windows.\n","\n","En cambio, si tenemos un ambiente separado del (base) y lo dañamos, podremos eliminarlo facilmente sin afectar al (base), ejecutando \n","\n","```conda env remove --name myenv -y```\n","\n","Esto es una manera bastante inteligente de trabajar con software.\n","\n","Muchos lenguajes cerrados de programación no tienen estas opciones, por lo que si falla algo interno, es necesario llamar a soporte y esperar un buen tiempo a que se solucione el problema. \n","\n","En algunas ocasiones, se tendrá que esperar a que se realice una nueva versión del programa.\n","\n"]},{"cell_type":"markdown","metadata":{"id":"zpVD6VkHESD7","colab_type":"text"},"source":["# Tareas:\n","\n","- Crear un ambiente llamado tf2 que contenga jupyter, jupyterlab y tensorflow.\n","\n","- ¿Qué versión de Python es implicada por la instalación?, ¿Es la más actual?\n","\n","- Crear un ambiente llamado clase que contenga jupyter, jupyterlab, numpy y pandas.\n","\n","- ¿Qué versión de Numpy es implicada por la instalación?, ¿Es la más actual?\n","\n","- Halle en la Web algún código que ejecute en versiones viejas de Python no compatibles con las actuales."]}]} -------------------------------------------------------------------------------- /Cuadernos/Intro_Graphics.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "

Visualización de Gráficos en Python

\n", 8 | "\n", 9 | "Ahora que hemos jugado un poco con la libreria **numpy** para hacer cálculos númericos pertenecientes al Álgebra Lineal, tratemos de visualizar algunos datos.\n", 10 | "\n", 11 | "El módulo que contiene las herramientas adecuadas para gráficar datos se llama **matplotlib**.\n", 12 | "\n", 13 | "Esta librería fue heredada de **MATLAB** y ahora es sposible usarla de forma gratuita.\n", 14 | "\n", 15 | "Es por eso, que para llamar los módulos que funcionan con **Python**, es necesario llamar a la librería interna llamada **pyplot**.\n", 16 | "\n", 17 | "Entonces, lo que se hace normalmente es importar la libreŕia como:" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "import matplotlib.pyplot as plt" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "Para luego poder gráficar todo lo necesario bajo el Kernel de Python.\n", 34 | "\n", 35 | "**Ejemplo:**" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "# Create Data for Testing\n", 45 | "# Data for the x-axis\n", 46 | "x=[0,1,2,3,4,5,6]\n", 47 | "# Data for the y-axis\n", 48 | "y=[0,1,4,9,16,25,36]\n", 49 | "# Call plot function for plotting. Note the '.' inside plot!!!\n", 50 | "plt.plot(x,y,'.')\n", 51 | "# Show the graphics for x,y data\n", 52 | "plt.show()" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "Bastante simple, ¿verdad?\n", 60 | "\n", 61 | "Este el principio de graficación. Lo demás es maquillar la ventana del plot para dar más información al respecto:" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": null, 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [ 70 | "plt.plot(x,y)\n", 71 | "plt.xlabel(\"Puntos en el eje x\")\n", 72 | "plt.ylabel(\"Puntos en el eje y\")\n", 73 | "plt.show()" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "**Ejercicio 1:**\n", 81 | "\n", 82 | "- Explique las siguientes líneas de código, colocando comentarios adecuados a cada línea\n", 83 | "- ¿Por qué el rango de valores en x van de cero a cuatro?\n", 84 | "- ¿Para qué sirve el método axis?" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [ 93 | "import matplotlib.pyplot as plt\n", 94 | "x=[1,2,3,4,5]\n", 95 | "plt.plot(x,'o')\n", 96 | "plt.axis([-2, 6, 0, 7])\n", 97 | "plt.xlabel(\"Some Numbers\")\n", 98 | "plt.ylabel(\"Some Other Numbers\")\n", 99 | "plt.show()" 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "metadata": {}, 105 | "source": [ 106 | "## Múltiples Gráficos en una misma Ventana \n", 107 | "\n", 108 | "Es posible gráficar varias funciones dentro de un sólo gráfico.\n", 109 | "\n", 110 | "Para esto basta definir las funciones y graficarlas dentro del atributo plot:" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "import numpy as np\n", 120 | "\n", 121 | "# evenly sampled time at 200ms intervals\n", 122 | "t = np.arange(0., 5., 0.2)\n", 123 | "\n", 124 | "# first function: straight line\n", 125 | "f1=t\n", 126 | "# second function: Parabola\n", 127 | "f2=t**2\n", 128 | "# third function: polynomial of third degree\n", 129 | "f3=t**3\n", 130 | "\n", 131 | "print(\"t =\",t,\"\\n\")\n", 132 | "print(\"f1 =\",f1,\"\\n\")\n", 133 | "print(\"f2 =\",f2,\"\\n\")\n", 134 | "print(\"f3 =\",f3,\"\\n\")\n", 135 | "\n", 136 | "# red dashes, blue squares and green triangles\n", 137 | "plt.plot(t, f1, 'r--', t, f2, 'bs', t, f3, 'g^')\n", 138 | "plt.show()" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "## Otros Tipos de Plots\n", 146 | "\n", 147 | "Es posible graficar datos que estén en otro formato distinto del habitual.\n", 148 | "\n", 149 | "Por ejemplo, podemos hacer un diccionario, refiriéndonos a cada parte de los datos con una letra (variable) y graficando cada parte de esa información como si de objetos individuales se tratara:" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": null, 155 | "metadata": {}, 156 | "outputs": [], 157 | "source": [ 158 | "data = {'a': np.arange(50),\n", 159 | " 'c': np.random.randint(0, 50, 50),\n", 160 | " 'd': np.random.randn(50)}\n", 161 | "\n", 162 | "\n", 163 | "data['b'] = data['a'] + 10 * np.random.randn(50)\n", 164 | "data['d'] = np.abs(data['d']) * 100\n", 165 | "\n", 166 | "print('a:', data['a'][0:5])\n", 167 | "print('b:',data['b'][0:5])\n", 168 | "print('c:',data['c'][0:5])\n", 169 | "print('d:',data['d'][0:5])" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "metadata": {}, 176 | "outputs": [], 177 | "source": [ 178 | "plt.scatter('a', 'b', c='c', s='d', data=data)\n", 179 | "plt.xlabel('entry a')\n", 180 | "plt.ylabel('entry b')\n", 181 | "plt.show()" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "**Ejercicio 2:**\n", 189 | "\n", 190 | "- ¿Es posible hacer varias ventanas de plot en una sola ventana de plot? En caso afirmativo, hacer tres en una sola fila\n", 191 | "- Graficar un ejemplo de datos categóricos\n", 192 | "\n", 193 | "**Pista:** Puede guiarse del siguiente código, pero no copiarlo en sus respuestas." 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": null, 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "def f(t):\n", 203 | " return np.exp(-t) * np.cos(2*np.pi*t)\n", 204 | "\n", 205 | "t1 = np.arange(0.0, 5.0, 0.1)\n", 206 | "t2 = np.arange(0.0, 5.0, 0.02)\n", 207 | "\n", 208 | "plt.figure(figsize=(9,6))\n", 209 | "plt.subplot(211)\n", 210 | "plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')\n", 211 | "\n", 212 | "plt.subplot(212)\n", 213 | "plt.plot(t2, np.cos(2*np.pi*t2), 'r--')\n", 214 | "plt.show()" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": {}, 220 | "source": [ 221 | "**Ejercicio 3:**\n", 222 | "\n", 223 | "- Explique el siguiente código detalladamente y haga sus propias modificaciones\n", 224 | "- Vaya a la documentación oficial de matplotlib [aquí](https://matplotlib.org/tutorials/introductory/pyplot.html) en la sección **Working With Text**, entiendalo y cree su propia versión." 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": null, 230 | "metadata": {}, 231 | "outputs": [], 232 | "source": [ 233 | "import matplotlib.pyplot as plt\n", 234 | "plt.figure(1) # the first figure\n", 235 | "plt.subplot(211) # the first subplot in the first figure\n", 236 | "plt.plot([1, 2, 3])\n", 237 | "plt.subplot(212) # the second subplot in the first figure\n", 238 | "plt.plot([4, 5, 6])\n", 239 | "\n", 240 | "\n", 241 | "plt.figure(2) # a second figure\n", 242 | "plt.plot([4, 5, 6]) # creates a subplot(111) by default\n", 243 | "\n", 244 | "plt.figure(1) # figure 1 current; subplot(212) still current\n", 245 | "plt.subplot(211) # make subplot(211) in figure1 current\n", 246 | "plt.title('Easy as 1, 2, 3') # subplot 211 title\n", 247 | "plt.show()" 248 | ] 249 | }, 250 | { 251 | "cell_type": "markdown", 252 | "metadata": {}, 253 | "source": [ 254 | "**Ejercicio 4:**\n", 255 | "\n", 256 | "Haga una fila 1x3 de imágenes con lo siguiente:\n", 257 | "\n", 258 | "1. Datos científicos\n", 259 | "2. Una imagen de internet\n", 260 | "3. Una imagen en 3D" 261 | ] 262 | } 263 | ], 264 | "metadata": { 265 | "kernelspec": { 266 | "display_name": "Python 3", 267 | "language": "python", 268 | "name": "python3" 269 | }, 270 | "language_info": { 271 | "codemirror_mode": { 272 | "name": "ipython", 273 | "version": 3 274 | }, 275 | "file_extension": ".py", 276 | "mimetype": "text/x-python", 277 | "name": "python", 278 | "nbconvert_exporter": "python", 279 | "pygments_lexer": "ipython3", 280 | "version": "3.7.6" 281 | } 282 | }, 283 | "nbformat": 4, 284 | "nbformat_minor": 4 285 | } 286 | -------------------------------------------------------------------------------- /Cuadernos/Ejemplos_Model.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "NhtFTuoxBgbW" 8 | }, 9 | "source": [ 10 | "# Ejemplos de Modelos\n", 11 | "\n", 12 | "Ahora que hemos visto el gran potencial de lo que significa modelar, ejemplifiquemos diferentes modelos que han aparecido a lo largo de la historia." 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": { 18 | "colab_type": "text", 19 | "id": "h68KR1LqB8Xw" 20 | }, 21 | "source": [ 22 | "# 1. Modelos Mentales" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": { 28 | "colab_type": "text", 29 | "id": "H9T_ItC9AjlJ" 30 | }, 31 | "source": [ 32 | "El primer modelo matemático existente podría considerarse como la abstracción de los números para aprender a contar:\n", 33 | "\n", 34 | "\n", 35 | "\n", 36 | "\n", 37 | "\n", 38 | "

\n", 39 | "\n", 40 | "En este modelo, la idea era poder representar los objetos de la vida cotidiana como símbolos (en lo posible fáciles de manipular) para poder aumentar nuestra capacidad de cálculo y por lo tanto el **poder de predecir**.\n", 41 | "\n", 42 | "Muchos siglos después, se desarrollaría un modelo basado en modelos matemáticos: **Física**.\n", 43 | "\n", 44 | "El objetivo de la física sería usar estos modelos matemáticos ya desarrollados para poder predecir cosas útiles sobre el mundo real.\n", 45 | "\n", 46 | "Por ejemplo, anteriormente, cuando ocurrían eclipses solares, lunares o pasaba algún cometa cerca de la tierra, muchas culturas lo consideraban como un **castigo de los dioses**, pues no tenían un entendimiento suficiente sobre lo que estaba ocurriendo; en otras palabras era un acontecimiento **sobrenatural**.\n", 47 | "\n" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": { 53 | "colab_type": "text", 54 | "id": "v2GqFHLvCEVK" 55 | }, 56 | "source": [ 57 | "# 2. Modelos Determinísticos" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": { 63 | "colab_type": "text", 64 | "id": "zi6-Bz_pC29B" 65 | }, 66 | "source": [ 67 | "## Historia" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": { 73 | "colab_type": "text", 74 | "id": "j_1L6ai0Bud3" 75 | }, 76 | "source": [ 77 | "La primera persona en tratar de romper estos mitos (uno de ellos, muy aclamado en el momento, era que todo el cosmos giraba alrededor de la tierra) fue el personaje a continuación:\n", 78 | "\n", 79 | "" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": { 85 | "colab_type": "text", 86 | "id": "sIwuYWU9Cltc" 87 | }, 88 | "source": [ 89 | "## Ecuaciones de Movimiento (Cinemática)" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": { 95 | "colab_type": "text", 96 | "id": "Axs3Hdb5AjlS" 97 | }, 98 | "source": [ 99 | "Comencemos a pensar sobre el mundo real.\n", 100 | "\n", 101 | "¿Qué podemos decir sobre los objetos que caen?\n", 102 | "\n", 103 | "¿Existe alguna fuerza invisible que los atrae contra el suelo cómo si de hilos mágicos se tratase?\n", 104 | "\n", 105 | "**Pregunta: ¿Qué cae más rápido al suelo?**\n", 106 | "\n", 107 | "![Plumita](https://steemitimages.com/DQmTwoKJXYSzr9wHSRx5sdNwiPbH5YrB2amBR2CPadVzV2i/p051dk5h.jpg)\n" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": { 113 | "colab_type": "text", 114 | "id": "yQSebzW7G2cy" 115 | }, 116 | "source": [ 117 | "## Respuesta:\n", 118 | "[![Nasa](http://img.youtube.com/vi/KDp1tiUsZw8/0.jpg)](http://www.youtube.com/watch?v=KDp1tiUsZw8 \"Feather-Hammer\")" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": { 124 | "colab_type": "text", 125 | "id": "wuxTA9QEAjlu" 126 | }, 127 | "source": [ 128 | "**Asumamos** entonces que aquella fuerza invisible que atrae los objetos al suelo es una constante y llamémosla $g$.\n", 129 | "\n", 130 | "Ahora, analicemos lo siguiente de la naturaleza:\n", 131 | "\n", 132 | "- **Percibimos** el **movimiento** de los objetos.\n", 133 | "- Sabemos medir **distancias** (Gracias a los números).\n", 134 | "- Percibimos el **tiempo**.\n", 135 | "- Podemos **percibir y medir** el cambio de la distancia a través del tiempo (Velocidad).\n", 136 | "- Podemos percibir y medir el **cambio de la velocidad** en el tiempo (Aceleración).\n", 137 | "\n", 138 | "De Cálculo básico sabemos que:\n", 139 | "\n", 140 | "$$a=-g$$\n", 141 | "\n", 142 | "Recordemos que $a=\\frac{dv}{dt}$. Entonces, integrando obtenemos:\n", 143 | "\n", 144 | "$$v(t)=-gt+C$$\n", 145 | "\n", 146 | "**Consejo para la vida:** La cosas **siempre** tienen una condición inicial. Por ejemplo,\n", 147 | "\n", 148 | "$$v(0)=v_o$$\n", 149 | "\n", 150 | "Por lo tanto,\n", 151 | "\n", 152 | "$$v(t)= v_{o}-gt$$\n", 153 | "\n", 154 | "Usando un proceso similar (**Tarea**), llegamos a que\n", 155 | "\n", 156 | "$$x(t) = x_o+v_o t -\\frac{1}{2}gt^2 $$\n", 157 | "\n", 158 | "Combinando las anteriores ecuaciones tenemos el siguiente conjunto total (**Tarea**):\n", 159 | "\n", 160 | "1. $v(t)=v_o-gt$\n", 161 | "2. $x(t) = x_o+v_o t -\\frac{1}{2}gt^2 $\n", 162 | "3. $v^2(t) = v_{o}^2 -2g(x(t)-x_o)$\n", 163 | "\n", 164 | "Estas ecuaciones fueron las primeras ecuaciones que pretendían predecir los movimientos de los objetos, y fueron aquellas usadas por Galileo Galilei para pensar sobre la trayectoria de los objetos.\n", 165 | "\n", 166 | "Gracias a este pensamiento, fue posible salir de la oscuridad y concluir que **sólo somos un pálido punto girando alrededor de otro pequeño punto dentro de un vasto cosmos.**" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": { 172 | "colab_type": "text", 173 | "id": "oaDasEgzCuRb" 174 | }, 175 | "source": [ 176 | "## Leyes de Newton" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": { 182 | "colab_type": "text", 183 | "id": "x_OY2ghFAjly" 184 | }, 185 | "source": [ 186 | "Otro caso de éxito, fueron las famosas ecuaciones de Isaac Newton. Tan poderosas que con ellas fuimos capaces de ir a la Luna y volver con vida.\n", 187 | "\n", 188 | "Tal vez, la más importante es la segunda:\n", 189 | "\n", 190 | "$$F=ma$$\n", 191 | "\n", 192 | "Volviendo a escribir dicha ecuación en términos de ecuaciones diferenciales, tenemos:\n", 193 | "\n", 194 | "$$F=m\\frac{d^2 x}{dt}$$\n", 195 | "\n", 196 | "O sea, despejando, tenemos:\n", 197 | "\n", 198 | "$$\\frac{d^2 x}{dt}=\\frac{F}{m}$$\n", 199 | "\n", 200 | "En los cursos de física básica, muchas veces las fuerzas son constantes, pero en general, las fuerzas pueden cambiar en el tiempo. \n", 201 | "\n", 202 | "En otras palabras, tenemos la siguiente ecuación diferencial:\n", 203 | "\n", 204 | "$$\\begin{equation}\n", 205 | "\\frac{d^2 x}{dt}=\\frac{F(t,x,v)}{m}\n", 206 | "\\end{equation}$$\n", 207 | "\n", 208 | "Que quiere decir que la **Fuerza ejercida en un objeto puede depender tanto del tiempo como de la posición y de la velocidad**.\n", 209 | "\n", 210 | "El objetivo general de modelamiento es poder escribir dicha ecuación (es decir, describir la forma que tiene la fuerza) y resolver la ecuación resultante." 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": { 216 | "colab_type": "text", 217 | "id": "P0Nk3KCZDDQe" 218 | }, 219 | "source": [ 220 | "## Modelos Lineales" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": { 226 | "colab_type": "text", 227 | "id": "w17gpcJrAjl3" 228 | }, 229 | "source": [ 230 | "No todos los modelos son ecuaciones diferenciales. A veces, es posible modelar problemas que no cambian en el tiempo cuando las condiciones de un problema no cambian en el tiempo.\n", 231 | "\n", 232 | "Todos estos problemas **se pueden modelar** como\n", 233 | "\n", 234 | "$$A\\vec{x}=\\vec{b}$$\n", 235 | "\n", 236 | "es decir, como un sistema de ecuaciones lineales.\n", 237 | "\n", 238 | "Estamos entonces en el ámbito del **Álgebra Lineal**.\n", 239 | "\n", 240 | "**Ejemplo:**\n", 241 | "\n", 242 | "Supongamos que en una empresa se fabrican **100 productos** y trabajan **100 empleados** diferentes. \n", 243 | "\n", 244 | "Si pudieramos registrar cúantas horas se demora cada uno de los empleados en fabricar cada uno de los productos, podríamos, fijando ciertas horas de trabajo laboral en un contrato, podemos resumir la información en la siguiente tabla:\n", 245 | "\n", 246 | "|Emp\\Prod|$x_1$|$x_2$|$\\dots$|$x_{100}$|\n", 247 | "|---|---|---|---|---|\n", 248 | "|$$E_1$$|3|4|$\\dots$|7|\n", 249 | "|$$E_2$$|2|5|$\\dots$|8|\n", 250 | "|$$\\vdots$$|$\\vdots$|$\\vdots$|$\\dots$|$\\vdots$|\n", 251 | "|$$E_{100}$$|1|8|$\\dots$|2|\n", 252 | "\n", 253 | "O sea, podemos generar la siguiente matriz:\n", 254 | "\n", 255 | "$$E = \\begin{bmatrix}\n", 256 | "3 & 4 & \\dots & 7\\\\\n", 257 | "2 & 5 & \\dots & 8\\\\\n", 258 | "\\vdots & \\vdots & \\dots & \\vdots\\\\\n", 259 | "1 & 8 & \\dots & 2\n", 260 | "\\end{bmatrix}_{100x100}$$\n", 261 | "\n", 262 | "Si fijamos las horas totales de trabajo por empleado y llamamos a dichas horas el vector $\\vec{b}$, podemos construir el siguiente **modelo**:\n", 263 | "\n", 264 | "$$E\\vec{x}=\\vec{b}$$\n", 265 | "\n", 266 | "Entonces, si **queremos saber cuántos productos son capaces de producir los empleados de cada producto, debemos solucionar dicho sistema de ecuaciones**.\n", 267 | "

\n", 268 | "\n", 269 | "**Recuerde:**\n", 270 | "\n", 271 | "Un sistema tiene sólo tres opciones:\n", 272 | "\n", 273 | "- Tiene solución:\n", 274 | " - Solución Única.\n", 275 | " - Infinitas Soluciones.\n", 276 | "- No tiene solución (**inconsistente**).\n", 277 | "\n", 278 | "**Supongamos** que tiene solución única. La solución se escribe como\n", 279 | "\n", 280 | "$$\\vec{x}=E^{-1} \\text{ }\\vec{b}$$" 281 | ] 282 | }, 283 | { 284 | "cell_type": "markdown", 285 | "metadata": { 286 | "colab_type": "text", 287 | "id": "lzVViBxlDV0c" 288 | }, 289 | "source": [ 290 | "## Ejercicio 1" 291 | ] 292 | }, 293 | { 294 | "cell_type": "markdown", 295 | "metadata": { 296 | "colab_type": "text", 297 | "id": "QcJbTbBLAjl7" 298 | }, 299 | "source": [ 300 | "Realice un código que haga lo siguiente:\n", 301 | "\n", 302 | "- Genere una matriz de números aleatorios enteros $100\\textbf{x}100$ y un vector de números aleatorios para solucionar el problema anterior.\n", 303 | "- Interprete las soluciones.\n", 304 | "- Generalice el problema a matrices rectangulares.\n", 305 | "- ¿Qué ocurre si un sistema no tiene solución?\n", 306 | "- ¿Y si tiene infinitas soluciones?" 307 | ] 308 | }, 309 | { 310 | "cell_type": "markdown", 311 | "metadata": { 312 | "colab_type": "text", 313 | "id": "pFWHX_XwAjl_" 314 | }, 315 | "source": [ 316 | "## Ecuaciones Diferenciales Parciales" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": { 322 | "colab_type": "text", 323 | "id": "4ea4hIPADd6C" 324 | }, 325 | "source": [ 326 | "Contenido EDP" 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "metadata": { 332 | "colab_type": "text", 333 | "id": "ZkUDj_k2AjmD" 334 | }, 335 | "source": [ 336 | "# 3. Modelos Estocásticos" 337 | ] 338 | }, 339 | { 340 | "cell_type": "markdown", 341 | "metadata": { 342 | "colab_type": "text", 343 | "id": "X2YWc4SmAjmG" 344 | }, 345 | "source": [ 346 | "## Modelos Estadísticos:" 347 | ] 348 | }, 349 | { 350 | "cell_type": "markdown", 351 | "metadata": { 352 | "colab_type": "text", 353 | "id": "rZpu8SCUD-jL" 354 | }, 355 | "source": [ 356 | "Contenido Modelos Estocáásticos" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "metadata": { 362 | "colab_type": "text", 363 | "id": "1G-6AEo2AjmK" 364 | }, 365 | "source": [ 366 | "## Ejercicio 2" 367 | ] 368 | } 369 | ], 370 | "metadata": { 371 | "colab": { 372 | "collapsed_sections": [ 373 | "h68KR1LqB8Xw", 374 | "zi6-Bz_pC29B", 375 | "oaDasEgzCuRb", 376 | "P0Nk3KCZDDQe", 377 | "lzVViBxlDV0c", 378 | "ZkUDj_k2AjmD" 379 | ], 380 | "name": "Ejemplos_Model.ipynb", 381 | "provenance": [] 382 | }, 383 | "kernelspec": { 384 | "display_name": "Python 3", 385 | "language": "python", 386 | "name": "python3" 387 | }, 388 | "language_info": { 389 | "codemirror_mode": { 390 | "name": "ipython", 391 | "version": 3 392 | }, 393 | "file_extension": ".py", 394 | "mimetype": "text/x-python", 395 | "name": "python", 396 | "nbconvert_exporter": "python", 397 | "pygments_lexer": "ipython3", 398 | "version": "3.7.6" 399 | } 400 | }, 401 | "nbformat": 4, 402 | "nbformat_minor": 4 403 | } 404 | -------------------------------------------------------------------------------- /Cuadernos/Intro_Python.ipynb: -------------------------------------------------------------------------------- 1 | {"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"name":"Intro_Python.ipynb","provenance":[],"collapsed_sections":["-MlSHN16Bg8-","scclT03UHVrm","qAqnr4i70sLy","IUFSujLR2-Rl","ivDxEY5J3EXW","6YvlIG-G6o2Z","Tjq46qsVQ1F9","GPiu4RLJUzVj","dTnOKPXFUzVs","P8eMjQnDI1Eg","i9HdDU49UzWK","y012FyjJPR1O","iDjs_eszUzW0","IpXs0nQNOWpv","2xb_O2GUUzXF"]},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.4"},"toc":{"base_numbering":1,"nav_menu":{},"number_sections":false,"sideBar":true,"skip_h1_title":false,"title_cell":"Table of Contents","title_sidebar":"Contents","toc_cell":false,"toc_position":{},"toc_section_display":true,"toc_window_display":false}},"cells":[{"cell_type":"markdown","metadata":{"colab_type":"text","id":"-MlSHN16Bg8-"},"source":["# Introducción al lenguaje Python\n","\n"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"Qwzm74tvByHP"},"source":["Este es un cuaderno introductorio a Python diseñado en Jupyter, exploraremos las funciones básicas disponibles de **Python** y la programación básica para su posterior uso en el análisis de datos.\n","\n","Comencemos con un ambiente de **Python 3**.\n","\n","Para una introducción más extensa, ir [aquí](https://www.w3schools.com/python/)."]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"kzyZQ2syLu9O"},"source":["## ¿Qué es Python? \n","\n","![Logo Python](https://www.python.org/static/community_logos/python-logo-master-v3-TM.png)\n","\n","\n","Python es un lenguaje de programación (¿Qué es un programa?) popular que se usa normalmente para:\n","\n","* Desarrollo web en servidores,\n","* Desarrollo de Software,\n","* Cálculos Matemáticos,\n","* Desarrollo de Scripts.\n","\n","## ¿Qué puede hacer Python? \n","\n","* Puede ser usado en un servidor para crear **aplicaciones web**,\n","* Puede conectarse a sistemas de **bases de datos**. Puede leer y modificar archivos.\n","* Puede ser usado para manejar **Big Data** y hacer cálculos matemáticos de alta complejidad.\n","* **Prototipo rápido** para producción de Software.\n","\n","## ¿Por qué Python? \n","\n","* Funciona en diferentes **plataformas** (Windows, Mac, Linux, etc).\n","* Tiene una **sintaxis** (forma de escribir) simple, similar al idioma inglés.\n","* Tiene una sintáxis que permite escribir programas en **muy pocas líneas**, comparado con otros lenguajes de programación.\n","* Pyhton se ejecuta en un **sistema interpretado**. Es decir, que los códigos se pueden correr **justo después de ser escritos**; en otras palabras, no necesitan compilación previa.\n","* Se puede usar como un lenguaje **clásico**, como un lenguaje **orientado a objetos**, o como un lenguaje **funcional**.\n","* Es el principal lenguaje de la **Ciencia de Datos**.\n"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"scclT03UHVrm"},"source":["## Hello World!"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"c3ntgbdgHbS-"},"source":["El primer ejemplo clásico de programación es saludar, o sea, decirle al computador que muestre un saludo.\n","\n","Para esto, se usa la función de Python llamada **print**.\n","\n","Para colocar un saludo (o un **texto cualquiera**), se debe colocar entre **comillas dobles** dentro del comando print.\n","\n","Entonces, para que el computador muestre un saludo, por ejemplo **Hello, World!**, debemos escribir en ambiente de código\n","\n","*print(\"Hello World!\");*"]},{"cell_type":"code","metadata":{"colab_type":"code","id":"8i6cS6oYA-Lv","colab":{}},"source":["print(\"Hello friend. Hello friend?\")"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"aM1gxggOCDGO"},"source":["Note que el resultado se muestra sin las comillas dobles. Estas comillas dobles se usan para decirle al computador que vamos a ingresar texto.\n","\n","Si quisieramos escribir con un salto de linea escribimos \"\\n\" así al escribir `print(\"hola\\nmundo\")` tenemos:\n","\n","`hola\n","mundo`"]},{"cell_type":"code","metadata":{"id":"C5IwYTeHUzUT","colab_type":"code","colab":{}},"source":["print(\"hola\\nmundo\")"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"gGbUqKOAJc_C"},"source":["### Ejercicio 1\n","\n","Hacer un código que le diga al computador que devuelva el texto:\n","*****\n",">*Sólo sé ...* \n","*... que nada sé.*\n"," ***"]},{"cell_type":"code","metadata":{"colab_type":"code","id":"CVnwiYj8JZY-","colab":{}},"source":["# usando print para imprimir un coment\n","\n","print(\"Sólo sé...\\n...que nada sé.\")"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"qAqnr4i70sLy"},"source":["## Indentación en Python"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"oMyFFHSjlj9J"},"source":["Indentar significa **mover un bloque de texto hacia la derecha**, dejando una serie de espacios o un tabulador para distinguirlo del texto alineado a la izquierda. **Indentar** es un anglicismo, realmente se debería decir **sangrado** o aplicar **sangría**.\n","\n","Por ejemplo:\n","\n","> Este texto está indentado (sangrado).\n","\n","En **Python**, la identación es muy importante, pues indica un **Bloque de código** bajo un operador lógico."]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"OqFH478Xza5l"},"source":["### Ejemplo: Identación en Python"]},{"cell_type":"code","metadata":{"colab_type":"code","id":"ie3nUgSszhve","colab":{}},"source":["if 5>3:\n"," print(\"Five is greater than Three\");"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"Xvt2xJKPzudT"},"source":["**Sin la indentación**, el código produce un **error**:"]},{"cell_type":"code","metadata":{"colab_type":"code","id":"Q6UM2ujoztla","colab":{}},"source":["if 5>3:\n","print(\"Five is greater than Three\");"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"h_FUae2V1Dfu"},"source":["No importa cuántos espacios en blanco se dejen, siempre y cuando sea **al menos uno**:"]},{"cell_type":"code","metadata":{"colab_type":"code","id":"8shIg71S1KOI","colab":{}},"source":["if 5 > 3:\n"," print(\"Five is greater than Three\") \n","if 5 > 3:\n"," print(\"Five is greater than Three\")"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"NTTmenRR162S"},"source":["### Ejercicio 2\n","\n","Hacer un código que le diga al computador que devuelva los textos **I'm ready to code!** si su nombre tiene más de diez caracteres o **Hello, World!** si pasa lo contrario, para medir la longitud de su nombre utilice la función `len(\"Tu_nombre\")`."]},{"cell_type":"code","metadata":{"id":"h-aRHdmHUzUx","colab_type":"code","colab":{}},"source":["len(\"Tu_nombre\") #pruebe la funcion len. Cambia Tu_nombre por su nombre real."],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"colab_type":"code","id":"aljlfPUW2SRr","colab":{}},"source":["# Ingrese aquí el condicional \n","\n"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"IUFSujLR2-Rl"},"source":["# Variables en Python"]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"ivDxEY5J3EXW"},"source":["## Variables Locales:\n","\n","Una variable sirve para **guardar un valor específico**, ya sea **numérico**, **texto** u otro **Tipo de Dato** con el nombre con la que se nombre dicha variable:"]},{"cell_type":"code","metadata":{"colab_type":"code","id":"XlBRuUAD3ud4","colab":{}},"source":["# Asignamos 1 a la variable x\n","\n","x=1\n","\n","print(\"El valor de la variable x es \",x)\n","\n","# Asignamos \"I'm ready to code!\" a la variable y\n","\n","y=\"I'm ready to code!\"\n","\n","print(\"El valor de la variable y es\"+y)\n"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"6YvlIG-G6o2Z"},"source":["## Reglas de Creación de Variables:\n","\n","* El nombre de una variable **debe comenzar** con una letra ó con _ .\n","\n","* El nombre de una variable **no puede comenzar** con un número.\n","\n","* El nombre de una variable **sólo puede contener** carácteres alfa-numéricos.\n","\n","* El nombre de una variable tiene **sensibilidad** a **mayúsculas** y **minúsculas** (x es diferente de X)."]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"g0XQW90S5bCj"},"source":["### Ejercicio 3\n","\n","Hacer un código que le diga al computador que devuelva los textos **Tengo** *my_age* **años**, donde *my_age* es una variable que tenga asignada su edad.\n","\n"]},{"cell_type":"code","metadata":{"colab_type":"code","id":"yFtzd3Ok57ul","colab":{}},"source":["# Escribe aquí"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"qA6o2ObtUzVC","colab_type":"text"},"source":["### Ejercicio 4\n","\n","El siguiente código calcula la longitud del nombre y escribe una frase acorde a la longitud. Observe que en el comando `print()` , `sep=` es un parámetro que separa los valores ingresados dentro de la función print. Como vemos, escribimos `N='Tu_nombre'` eso asigna a la letra N el texto *Tu_nombre*. "]},{"cell_type":"code","metadata":{"id":"otVV2npDUzVD","colab_type":"code","colab":{}},"source":["N='Tu_nombre'# cambiar 'Tu_nombre' por su verdadero nombre\n","if len(N)>10:\n"," A=\"es un nombre muy largo\"\n","else:\n"," A=\"es un nombre muy corto\"\n","\n","print(N,A,sep=\" \")\n"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"2s1YfC-BUzVG","colab_type":"code","colab":{}},"source":["N='Tu_nombre_completo' #cambiar 'Tu_nombre_completo' por su verdadero nombre completo\n","if len(N)>10:\n"," A=\"es un nombre muy largo\"\n","else:\n"," A=\"es un nombre muy corto\"\n","\n","print(N,A,sep=\"/\")"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"P41c3wWHUzVI","colab_type":"code","colab":{}},"source":["N='El nombre'\n","if len(N)>10:\n"," A=\"es un nombre muy largo\"\n","else:\n"," A=\"es un nombre muy corto\"\n","\n","print(N,A,sep=\" \")"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"wspqLphleQ07"},"source":["## Variables Globales:\n","\n","Es posible usar variables **globales** que funcionarán a nivel general, traspasando funciones, múltiples espacios de trabajo y tiene prioridad sobre las variables locales."]},{"cell_type":"code","metadata":{"colab_type":"code","id":"Nl9DGNFmeQ1B","colab":{}},"source":["# Definiendo una variable local\n","\n","x = \"Local Variable\"\n","\n","print(\"x is a\",x,\"in this moment\");\n","\n","# Creando una variable global\n","def myfunc():\n"," global x\n"," \n"," x = \"Global Variable\"\n","\n","myfunc()\n","\n","# Impresión de la variable usando print()\n","\n","print(\"x is finally a \" + x)"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"jsYP__7Q7y6j"},"source":["## Múltiples Asignaciones:\n","\n","Es posible asignar valores a diferentes variables en una línea de código:"]},{"cell_type":"code","metadata":{"colab_type":"code","id":"dgS8D9paFG3g","colab":{}},"source":["# Asignación múltiple\n","\n","w, x, y, z = \"Apple\", \"Watermelon\", \"Grape\", 28;\n","\n","print(w);\n","print(x);\n","print(y);\n","print(z);\n","print(w,x,y,z,sep=\", \");"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"pgpUA2p5GXf2"},"source":["También es posible asignar un **mismo valor** a diferentes variables:"]},{"cell_type":"code","metadata":{"colab_type":"code","id":"uLVD53UgGXEr","colab":{}},"source":["# Asignación múltiple del mismo valor\n","\n","x1 = x2 = x3 = 0.5;\n","print('x1 =',x1);\n","print('x2 =',x2);\n","print('x3 =',x3);"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"gLXedYpJUzVb","colab_type":"text"},"source":["**Cuidado con las variables no asignadas**. Generan error:"]},{"cell_type":"code","metadata":{"id":"7rHYbSZZUzVc","colab_type":"code","colab":{}},"source":["n # Variable sin asignar"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"colab_type":"text","id":"4y3X0kbfHXzW"},"source":["## Suma de Variables\n","\n","Python es tan sencillo e intutivo, que es posible sumar diferentes variables y sumarlas con el símbolo **+**. Cuando las variables son numéricas, se **suman matemáticamente** y cuando es texto se **concatenan**."]},{"cell_type":"code","metadata":{"colab_type":"code","id":"nMPQKB2jHxuk","colab":{}},"source":["# Sumar dos textos\n","\n","x = \"Python is \";\n","y = \"awesome\";\n","z = x + y;\n","print(z);\n","\n","# Sumar dos números\n","\n","n1 = 1;\n","n2 = 5;\n","suma = n1 +n2;\n","print(suma);\n","\n","# Escribir texto y números\n","print(x+\"the number\",n1);"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"Yv9WSG97QyQX","colab_type":"text"},"source":["En el apartado anterior es claro que usamos dos tipos de variables unas textuales y otras numéricas, profundicemos en estos temas."]},{"cell_type":"markdown","metadata":{"id":"Tjq46qsVQ1F9","colab_type":"text"},"source":["# Números"]},{"cell_type":"markdown","metadata":{"id":"GPiu4RLJUzVj","colab_type":"text"},"source":["Respecto a los números en Python tenemos dos tipos de datos: los enteros (*int*) y los números con parte fraccionaria (*float*). La fortuna de que Python reconozca variables numéricas nos permite usarla como una calculadora simple, podemos ejecutar operaciones muy sencillas teniendo en cuenta la siguiente tabla:\n","\n","| **Operador** | **Descripción** |\n","| :---: | :---: |\n","|`+`|Suma|\n","|`-`|Resta|\n","|`*`|Multiplicación|\n","|`/`|División|\n","|`**`|Potencia|\n"]},{"cell_type":"markdown","metadata":{"id":"mWcTFd6gUzVk","colab_type":"text"},"source":["### Ejemplo 2\n"," Si queremos operar:\n"," \n"," $$ 5\\times(3-5)^2-\\cfrac{6}{(9)^{1/2}}$$\n"," \n"," tenemos que escribir:"]},{"cell_type":"code","metadata":{"id":"V285pz1XUzVl","colab_type":"code","colab":{}},"source":["5*(3-5)**2-(6)/(9**(1/2))"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"jDUMOPivUzVo","colab_type":"text"},"source":["*Recuerde oprimir [Shift]+[Enter]* "]},{"cell_type":"markdown","metadata":{"id":"dTnOKPXFUzVs","colab_type":"text"},"source":["### Ejercicio 5\n","Es muy importante usar bien los paréntesis, el uso o desuso puede generar problemas graves en las cuentas, encuentre el error y describa lo que hizo la máquina en los siguientes casos respecto a la operación anterior:"]},{"cell_type":"code","metadata":{"id":"fUepsH4JUzVt","colab_type":"code","colab":{}},"source":["5*3-5**2-(6)/(9**(1/2))"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"v3JKucM0UzVv","colab_type":"code","colab":{}},"source":["5*(3-5)**2-6/(9**1/2)"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"WSKpxgUPUzVy","colab_type":"code","colab":{}},"source":["5*(3-5)**2-6/9**1/2"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"GST4zCDtUzV1","colab_type":"code","colab":{}},"source":["5*3-5**2-6/9**1/2"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"TIkHNbN5UzV4","colab_type":"text"},"source":["La división es una operación bien especial pues la mayoría de ocasiones produce un número con parte fraccionaria. Sin embargo, cuando estabamos pequeños nos enseñaron a dividir enteros dando como respuesta un entero llamado cociente y lo que hacia falta para completar la división, un número llamado residuo. En Python podemos calcular esos valores con `\\\\` para el cociente y `%`para el residuo. Por ejemplo, sabemos que:\n","\n","$$ 20 \\div 3 = 6 \\ \\ \\ \\text{ con residuo } 2$$\n","tenemos:"]},{"cell_type":"code","metadata":{"id":"VYj4u-axUzV5","colab_type":"code","colab":{}},"source":["20//3"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"Rg9EebXCUzV7","colab_type":"code","colab":{}},"source":["20%3"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"GNZo18TJUzV-","colab_type":"text"},"source":["Python Tambien reconoce los números complejos. El valor imaginario se lo asigna a la letra `j`"]},{"cell_type":"code","metadata":{"id":"TkOeHTlXUzV-","colab_type":"code","colab":{}},"source":["3+(-4)**(1/2) # Recordemos un poquito de nuestras matemáticas"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"2TGfXoLdUzWB","colab_type":"text"},"source":["Finalmente, una función elemental y util para el tratamiento de números decimales es `round`. Lo usamos para redodendear los valores a uno con el decimal que escojamos. Tenemos:"]},{"cell_type":"code","metadata":{"id":"F1JNJ-WPUzWC","colab_type":"code","colab":{}},"source":["n1=47/3\n","n1"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"MRXeLGffUzWE","colab_type":"code","colab":{}},"source":["n2=round(n1)\n","n2"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"buhEFfx7UzWH","colab_type":"code","colab":{}},"source":["n3=round(n1,3)\n","n3"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"P8eMjQnDI1Eg","colab_type":"text"},"source":["## Ejercicio 6\n","\n","Use la función ```round()``` para redondear el número $\\pi$ hasta 5 cifras decimales.\n","\n","**Pista:** Para poder usar el número $\\pi$, use el siguiente código:"]},{"cell_type":"code","metadata":{"id":"UJQCI5k-I0qk","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":34},"outputId":"e07ea843-98d0-40d0-9f94-8f0e313be3d6","executionInfo":{"status":"ok","timestamp":1581607521193,"user_tz":300,"elapsed":1053,"user":{"displayName":"Daniel Montenegro","photoUrl":"","userId":"07275166318289302366"}}},"source":["# importando el número pi\n","\n","from math import *\n","\n","# visualizar pi\n","print(pi)\n","\n","# Your code here"],"execution_count":11,"outputs":[{"output_type":"stream","text":["3.141592653589793\n"],"name":"stdout"}]},{"cell_type":"markdown","metadata":{"id":"i9HdDU49UzWK","colab_type":"text"},"source":["# Textos"]},{"cell_type":"markdown","metadata":{"id":"Nhv2kU50RGVu","colab_type":"text"},"source":["\n","Los textos son expresiones que representan una cadena de caracteres, utiles para escribir mensajes y combinarlos con valores que generemos en nuestros procesamientos. Para escribi un texto en Python usamos comillas simples: `'...'` o comillas dobles: `\"...\"`. Combinamos comillas para poner comillas adentro:"]},{"cell_type":"code","metadata":{"id":"-29-9hgEUzWL","colab_type":"code","colab":{}},"source":["a='Texto simple escrito entre comillas simples'\n","print(a)\n","a"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"Ue2quTbyUzWN","colab_type":"code","colab":{}},"source":["b='Texto simple escrito entre comillas dobles'\n","print(b)\n","b"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"TzXiafxUUzWR","colab_type":"code","colab":{}},"source":["c='Texto simple escrito entre comillas simples que necesita \"adentrico\" comillas dobles'\n","print(c)"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"Mqibs8ieUzWW","colab_type":"code","colab":{}},"source":["d=\"Texto simple escrito entre comillas dobles que necesita 'adentrico' comillas simples\"\n","print(d)\n"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"Z-RNqrFEUzWa","colab_type":"text"},"source":["Como vimos, la función print es la que nos permite imprimir estos mensajes. El texto \\n indica una nueva linea en el texto:"]},{"cell_type":"code","metadata":{"id":"bkQZpWAbUzWa","colab_type":"code","colab":{}},"source":["print(\"Una línea\\notra línea\")"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"MCQfYItSUzWc","colab_type":"text"},"source":["No obstante, a veces necesitamos escribir \\n en un mensaje:"]},{"cell_type":"code","metadata":{"id":"-tCoup6-UzWd","colab_type":"code","colab":{}},"source":["print('La ruta del archivo es C:\\nombres\\archivo.ipynb')"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"WzED52iWUzWg","colab_type":"text"},"source":["En este caso la aparición de \\ daño el mensaje, para resolver el problema escribimos r antes:"]},{"cell_type":"code","metadata":{"id":"K2GM2rSDUzWg","colab_type":"code","outputId":"83a9f240-03b4-462f-92c3-130881d0d66e","executionInfo":{"status":"ok","timestamp":1581607552733,"user_tz":300,"elapsed":528,"user":{"displayName":"Daniel Montenegro","photoUrl":"","userId":"07275166318289302366"}},"colab":{"base_uri":"https://localhost:8080/","height":34}},"source":["# Qué significa la r???\n","print(r'La ruta del archivo es C:\\nombres\\archivo.ipynb')"],"execution_count":12,"outputs":[{"output_type":"stream","text":["La ruta del archivo es C:\\nombres\\archivo.ipynb\n"],"name":"stdout"}]},{"cell_type":"markdown","metadata":{"id":"DvFxzQq4UzWi","colab_type":"text"},"source":["Finalmente, podemos recorrer los valores de la cadena de texto de la siguiente forma:"]},{"cell_type":"code","metadata":{"id":"VfvvR1MaUzWj","colab_type":"code","colab":{}},"source":["texto=\"cuidado_con_el_orden\""],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"LGbUClMKKCLW","colab_type":"text"},"source":["Extrayendo el elemento cero del texto (**primer caracter**):"]},{"cell_type":"code","metadata":{"id":"bENx-JazUzWm","colab_type":"code","colab":{}},"source":["texto[0]"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"j0L1L6d5Khbk","colab_type":"text"},"source":["Extrayendo el elemento uno del texto (**segundo caracter**):"]},{"cell_type":"code","metadata":{"id":"fWH_t7h8UzWp","colab_type":"code","colab":{}},"source":["texto[1]"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"SrY2k2XSKyfD","colab_type":"text"},"source":["Extrayendo el elemento cinco hasta el elemento 9 del texto (**sin incluir el 9**):"]},{"cell_type":"code","metadata":{"id":"R9Py_A_IUzWw","colab_type":"code","colab":{}},"source":["texto[5:9]"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"VQMd1XUpLAAv","colab_type":"text"},"source":["**También se pueden usar índices negativos** (Python exclusive):"]},{"cell_type":"code","metadata":{"id":"AIcmHaNdUzWq","colab_type":"code","colab":{}},"source":["texto[3:-5]"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"y012FyjJPR1O","colab_type":"text"},"source":["# Listas y Arreglos"]},{"cell_type":"markdown","metadata":{"id":"iDjs_eszUzW0","colab_type":"text"},"source":["## Listas:\n","\n","Tambien podemos crear listas y arreglos en Python usando `[ ... ]`, los elementos de la lista **se separan por comas**. "]},{"cell_type":"code","metadata":{"id":"_1AWouoeUzW1","colab_type":"code","colab":{}},"source":["primos=[2,3,5,7,11,13,17,19]\n","print(primos)"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"CPQLz76GUzW5","colab_type":"text"},"source":["Igual que las cadenas de texto se pueden explorar los elementos usando `nombredelalista[pos] `, donde pos es la posición del elemento. "]},{"cell_type":"code","metadata":{"id":"DawjX3HaUzW5","colab_type":"code","colab":{}},"source":["primos[0] #0 siempre denota al primer elemento\n","primos[11] # elemento 11 de la lista"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"nnwLgimTUzW9","colab_type":"text"},"source":["se pueden adicionar elementos a la lista con la función `nombredelalista.append() `"]},{"cell_type":"code","metadata":{"id":"tWg3fgUwUzW9","colab_type":"code","colab":{}},"source":["print(\"Antes: \", primos)\n","primos.append(23)\n","print(\"Después: \", primos)"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"-lP12FBlUzW_","colab_type":"text"},"source":["Así mismo, los elemento se pueden modificar:\n"]},{"cell_type":"code","metadata":{"id":"wHQ767toUzW_","colab_type":"code","colab":{}},"source":["print(\"Antes: \",primos)\n","primos[0]=1\n","print(\"Después: \",primos)"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"xSSSmh2RUzXB","colab_type":"text"},"source":["o eliminar:"]},{"cell_type":"code","metadata":{"id":"i8ZjN7rZUzXB","colab_type":"code","colab":{}},"source":["print(\"Antes: \",primos)\n","primos[0:1]=[]\n","print(\"Después: \",primos)"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"IpXs0nQNOWpv","colab_type":"text"},"source":["## Ejercicio 7\n","\n","Trate de crear una lista que no contenga sóólo números.\n","\n","¿Es posible crear una **lista que contenga por dentro listas**? Justifique y en caso afirmativo, cree una."]},{"cell_type":"code","metadata":{"id":"E7CeY_MaOhSu","colab_type":"code","colab":{}},"source":["#You Code Here"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"2xb_O2GUUzXF","colab_type":"text"},"source":["## Arreglos:\n","\n","También se hacen listas de listas, se conocen como arreglos y si todas las listas tienen la misma cantidad de elementos las llamamos matrices:"]},{"cell_type":"code","metadata":{"id":"YetA7kmZUzXH","colab_type":"code","colab":{}},"source":["# Array example\n","Cel=[[7,8,9],[4,5,6],[1,2,3]]"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"0d-NZ_E1UzXJ","colab_type":"code","colab":{}},"source":["print(Cel)"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"peKcCkTNPwOF","colab_type":"text"},"source":["Se pueden acceder a las filas:"]},{"cell_type":"code","metadata":{"id":"Ie48hfAEUzXL","colab_type":"code","colab":{}},"source":["# First Row\n","Cel[0]"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"gfe5sz1fPzpG","colab_type":"text"},"source":["Y también a elementos específicos de las filas:"]},{"cell_type":"code","metadata":{"id":"IV6xqrdaUzXN","colab_type":"code","colab":{}},"source":["# First element on the first row\n","Cel[0][0]"],"execution_count":0,"outputs":[]},{"cell_type":"markdown","metadata":{"id":"REZ0OebXP5nF","colab_type":"text"},"source":["## Ejercicio 8\n","\n","Cree un arreglo de 8 filas y 8 columnas que contenga números enteros, complejos, decimales, y textos."]},{"cell_type":"code","metadata":{"id":"QhEndvGSQfUg","colab_type":"code","colab":{}},"source":["# Your Code Here"],"execution_count":0,"outputs":[]}]} -------------------------------------------------------------------------------- /Cuadernos/MN_RK.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# El Método de Runge-Kutta" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Introducción" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Nos hemos dado cuenta que **es posible que el método de Euler falle**.\n", 22 | "\n", 23 | "Por esto, nos disponemos a crear otro método numérico que sea más apropiado en una amplia gama de problemas.\n", 24 | "\n", 25 | "Para visualizar a lo que se comenta, observe la siguiente imagen (tomada de [Wikipedia](https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Runge-kutta.svg/1024px-Runge-kutta.svg.png)):\n", 26 | "\n", 27 | "![Metodos](https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Runge-kutta.svg/1024px-Runge-kutta.svg.png)\n", 28 | "\n", 29 | "De esta imagen podemos observar que, entre todos los métodos numéricos mostrados, Euler es el que tiene la aproximación más pobre (suponiendo que tenemos nuestra solución exacta, claro).\n", 30 | "\n", 31 | "En este sección veremos el famoso método numérico conocido como **Runge-Kutta**." 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "Recordemos, nuestro problema principal es\n", 39 | "\n", 40 | "$$\\frac{dx}{dt}=f(t,x),\\text{ }x(t_{0})=x_{0}$$\n", 41 | "\n", 42 | "esto es, la tasa de cambio instantáneo de la cantidad dependiente $x$, se puede modelar mediante la función $f(t,x)$. Además el experimento comienza en el momento $t_0$ con una cantidad inicial $x_0$ de la cantidad $x$." 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "## Procedimiento" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "### Algoritmo" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "Tomado de [wiki](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods), podemos resumir el método numérico como:\n", 64 | "\n", 65 | "$$\n", 66 | "\\begin{split}\n", 67 | "k_1 &=f(t_i,x_i) \\\\\n", 68 | "k_2 &=f\\biggl(t_i+\\frac{h}{2},x_i+h\\frac{k_1}{2}\\biggr) \\\\\n", 69 | "k_3 &=f\\biggl(t_i+\\frac{h}{2},x_i+h\\frac{k_1}{2}\\biggr) \\\\\n", 70 | "k_4 &=f\\bigl(t_i+h,x_i+hk_3\\bigr) \\\\\n", 71 | "x_{i+1} &= x_i+\\frac{1}{6}h\\bigl(k_1+2k_2+2k_3+k_4\\bigr) \\\\\n", 72 | "\\end{split}\n", 73 | "$$" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "### Implementación" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "**Por favor, documentar adecuadamente el siguiente código:**" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 2, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "def RK4(f,x0,t0,tf,n):\n", 97 | " t=np.linspace(t0,tf,n)\n", 98 | " h=abs(t[1]-t[0])\n", 99 | " x=np.empty(n)\n", 100 | " x[0]=x0\n", 101 | " \n", 102 | " for i in range(n-1):\n", 103 | " k1=f(t[i],x[i])\n", 104 | " k2=f(t[i]+1/2*h,x[i]+h*1/2*k1)\n", 105 | " k3=f(t[i]+1/2*h,x[i]+h*1/2*k2)\n", 106 | " k4=f(t[i+1] ,x[i]+h*k3)\n", 107 | " \n", 108 | " x[i+1]=x[i]+1/6*h*(k1+2*k2+2*k3+k4)\n", 109 | " return t,x" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "Es claro que esta debe ser la función de un módulo, junto con ```EulerM```.\n", 117 | "\n", 118 | "Resolvamos la siguiente ecuación:\n", 119 | "\n", 120 | "$$\\frac{dx}{dt}=\\sin(t²),\\text{ }x(0)=0$$\n", 121 | "\n", 122 | "Recordemos que \n", 123 | "\n", 124 | "$$\\int \\sin(t²)dt$$\n", 125 | "\n", 126 | "**No es posible resolverla** por métodos de Mate II y de hecho, es imposible escribirla como una función de las elementales que conocemos (Fuente).\n", 127 | "\n", 128 | "Esta integral se conoce como la **integral de Fresnel**, que son de gran uso en el campo de la óptica. \n", 129 | "\n", 130 | "**Por favor, documente el siguiente código adecuadamente.**" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": 86, 136 | "metadata": {}, 137 | "outputs": [ 138 | { 139 | "name": "stdout", 140 | "output_type": "stream", 141 | "text": [ 142 | "54.122667399443024\n" 143 | ] 144 | }, 145 | { 146 | "data": { 147 | "image/png": "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f/75vPrqqwC8/vrrnHfeeZx00knExcUxbtw43n33XdLT06tVV0REGr5n5qznjInz6D/uI7rdN5O+D/6PYRPmFpU/Nms15z09nwue+ZyRzy7gF88t4OZXlxSVPzFrNVdOXshVLy7kmimLuGbKIu555+f/mx+duYrRUxaVeDz0wcqi8rHvr+TalxaXeDz235/Xc1j4Q/38NrTxdNdV4LJ/fHHYttN7JHPTKUdwMCefa19adFj5xQPac8nADuzNzOFXr311WPlVx6dy3tFt2Z52kLaJ0X7F0aNHD0JDQxk9ejSXX345xx9/PElJSUXlU6dOZerUqcyZM6comb799tuLkhl/bd68mbPOOovnn3+eiy++mAMHDhQlisV98skn/PGPf+R///sfvXv35u677+byyy/n008/Ldpn+vTpLF68mAMHDjBgwADOO+88zjzzzDKPa2aMGzeOO++8kyuvvLJKUxPOmjWLr776ii1bttC/f38WLFjA66+/TvPmzRk8eDDTpk1j9OjRfP3111x//fV88MEHDBw4kNdee43zzz+fNWvWFPX0T5s2jRkzZtCiRYvDeqYnTpzItGnTmDlzJj169GD58uXExMQAMGjQIMaOHUtCQgJPPfUUl1xyCRs3biQqyr9Pw2+99RazZs0iKiqKIUOGMHXqVH75y18ett/8+fM599xzy21n+vTpJT5s+GPt2rWEhobSo0ePom1HH310Ue/9ypUrOeGEE4rKunbtSkREBGvXriUkJKTKdQcMGBBQnCIiEnzZufm8+t0hBhyfS3xUOPFRYXRpGctxXZJJjo2kWVQYMRE///95y0ldGNmvHSEh3v/5IWZEhv3cL3vPWUfyy5O7EhJiGGAGkWE/f1M97oI+ZBwq2fMcE/Fz+YRLjuZgbskF9+Ijfz7+id1a1NSp16gmkUzXF82aNWP+/Pk8/vjj3HTTTezYsYOzzz6bF154gZSUFF5//XXuuusuunTpAsCf/vQn+vTpw0svvRTQcV5//XVOP/10rrjiCgCaN29O8+bNy9zv+uuvp3///kXHS0pKYuPGjXTq1AmAP/zhDyQmJpKYmMgpp5zC0qVLy02mAc4//3weeeQRJk+ezE033RRQ3AD33HMPzZo1o3fv3vTp04fhw4cXvR9nnXUW33zzDaNHj+aFF17glltu4bjjjgNg9OjRPProo3z55ZecfPLJ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\n", 148 | "text/plain": [ 149 | "
" 150 | ] 151 | }, 152 | "metadata": { 153 | "needs_background": "light" 154 | }, 155 | "output_type": "display_data" 156 | } 157 | ], 158 | "source": [ 159 | "import numpy as np\n", 160 | "import matplotlib.pyplot as plt\n", 161 | "f = lambda t,x: 1.581*x-0.8*x*np.log(x)*np.cos(x)*np.sin(x)\n", 162 | "x0=1\n", 163 | "t0=0.1\n", 164 | "tf=4.3\n", 165 | "n=10000\n", 166 | "t,x=RK4(f,x0,t0,tf,n)\n", 167 | "plt.figure(figsize=(12,6))\n", 168 | "plt.plot(t,x,'--',label=\"Solución Numérica, n = \"+str(n))\n", 169 | "plt.plot(t[0],x[0],'ro', label=\"Condición Inicial\")\n", 170 | "plt.xlabel(\"Tiempo (t)\",fontsize=15)\n", 171 | "plt.ylabel(\"Solución Numérica de x(t)\",fontsize=15)\n", 172 | "plt.title(\"Método de Runge-Kutta (RK4)\",fontsize=15)\n", 173 | "print(x[-1])\n", 174 | "plt.legend(fontsize=12)\n", 175 | "plt.grid()\n", 176 | "plt.show()" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "Si aumentamos el parámetro $n$, o sea si dividimos en intervalo en más partes, deberiamos esperar una mejor aproximación, pues esto implicaría aproximarnos más y más a la derivada teórica. Miremos:" 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "### Tarea" 191 | ] 192 | }, 193 | { 194 | "cell_type": "markdown", 195 | "metadata": {}, 196 | "source": [ 197 | "Resuelva las siguientes ecuaciones usando el método de Runge-Kutta, compare los resultados con los obtenidos del método de Euler y muestre para cuál $n$ la solución se vuelve estable:\n", 198 | "\n", 199 | "1.\n", 200 | "$$\\frac{dP}{dt}=kP,\\text{ }P(0)=2,\\text{ en }T=[0,100]$$\n", 201 | "2.\n", 202 | "$$\\frac{dP}{dt}=kP\\biggl(1-\\frac{P}{S}\\biggr),\\text{ }P(0)=2,\\text{ en }T=[0,100],\\text{ }S=100000$$\n", 203 | "3.\n", 204 | "$$\\frac{dv}{dt}=g-\\frac{c_d}{m}v^{2},\\text{ }v(0)=-3,\\text{ en }T=[0,30]$$\n", 205 | "4.\n", 206 | "$$\\frac{dx}{dt}=e^{-t^2}\\sinh(x), \\text{ }x(-5)=0$$\n", 207 | "5.\n", 208 | "$$\\frac{dx}{dt}=\\tanh(xt)+\\ln(t^2)e^{-x^2}, \\text{ }x(-1)=2$$" 209 | ] 210 | } 211 | ], 212 | "metadata": { 213 | "kernelspec": { 214 | "display_name": "Python 3", 215 | "language": "python", 216 | "name": "python3" 217 | }, 218 | "language_info": { 219 | "codemirror_mode": { 220 | "name": "ipython", 221 | "version": 3 222 | }, 223 | "file_extension": ".py", 224 | "mimetype": "text/x-python", 225 | "name": "python", 226 | "nbconvert_exporter": "python", 227 | "pygments_lexer": "ipython3", 228 | "version": "3.7.7" 229 | } 230 | }, 231 | "nbformat": 4, 232 | "nbformat_minor": 4 233 | } 234 | -------------------------------------------------------------------------------- /Cuadernos/Paquetes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "NHyvNhPs-NDW" 8 | }, 9 | "source": [ 10 | "# Inspección, Instalación y Carga de Módulos y Paquetes\n", 11 | "\n", 12 | "Dependiendo del ambiente de trabajo usado, tenemos diferente cantidad de **paquetes** instalados.\n", 13 | "\n", 14 | "Hay una **forma** de ver qué paquetes existen en el ambiente actual sin salir del Notebook.\n", 15 | "\n", 16 | "Basta con colocar ```!``` en una celda de código.\n", 17 | "\n", 18 | "Dicho esto, ¿Qué es mejor, hacer todo desde el Prompt o el Notebook?\n", 19 | "\n", 20 | "*La elección si depende del gusto :)*\n", 21 | "\n", 22 | "**Ejemplo:**\n", 23 | "\n", 24 | "Verifiquemos que versión de Python estamos usando, qupe ambientes disponibles existen, cuál es el activo y qué paquetes están instalados, todo esto **sin salir del Notebook**." 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 1, 30 | "metadata": { 31 | "colab": { 32 | "base_uri": "https://localhost:8080/", 33 | "height": 68 34 | }, 35 | "colab_type": "code", 36 | "executionInfo": { 37 | "elapsed": 7228, 38 | "status": "ok", 39 | "timestamp": 1579910176981, 40 | "user": { 41 | "displayName": "daniel mauricio montenegro reyes", 42 | "photoUrl": "", 43 | "userId": "12701434767844263388" 44 | }, 45 | "user_tz": 300 46 | }, 47 | "id": "eLM-O1Ys-NDY", 48 | "outputId": "f2afbfa9-c30a-4b11-a2d6-e50ade489314" 49 | }, 50 | "outputs": [ 51 | { 52 | "name": "stdout", 53 | "output_type": "stream", 54 | "text": [ 55 | "Python 3.7.6\n", 56 | " \n" 57 | ] 58 | } 59 | ], 60 | "source": [ 61 | "# Recuerda que # es para usar comentarios\n", 62 | "!python --version # Versión Actual de Python siendo usada\n", 63 | "print(\" \") # Función print para dar un salto de línea\n", 64 | "#!conda env list # Lista de Ambientes Disponibles y Activo en el Notebook Linux" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 2, 70 | "metadata": { 71 | "colab": {}, 72 | "colab_type": "code", 73 | "id": "ZgrVqMBM-NDc" 74 | }, 75 | "outputs": [ 76 | { 77 | "name": "stdout", 78 | "output_type": "stream", 79 | "text": [ 80 | "# packages in environment at /home/moury/anaconda3/envs/tf2:\n", 81 | "#\n", 82 | "# Name Version Build Channel\n", 83 | "_libgcc_mutex 0.1 main \n", 84 | "_tflow_select 2.3.0 mkl \n", 85 | "absl-py 0.9.0 py37_0 conda-forge\n", 86 | "astor 0.7.1 py_0 conda-forge\n", 87 | "attrs 19.3.0 py_0 \n", 88 | "backcall 0.1.0 py37_0 \n", 89 | "blas 1.0 mkl \n", 90 | "bleach 3.1.0 py37_0 \n", 91 | "c-ares 1.15.0 h516909a_1001 conda-forge\n", 92 | "ca-certificates 2019.11.28 hecc5488_0 conda-forge\n", 93 | "cachetools 4.0.0 pypi_0 pypi\n", 94 | "certifi 2019.11.28 py37_0 conda-forge\n", 95 | "chardet 3.0.4 pypi_0 pypi\n", 96 | "cycler 0.10.0 py37_0 \n", 97 | "dbus 1.13.12 h746ee38_0 \n", 98 | "decorator 4.4.1 py_0 \n", 99 | "defusedxml 0.6.0 py_0 \n", 100 | "entrypoints 0.3 py37_0 \n", 101 | "expat 2.2.6 he6710b0_0 \n", 102 | "fontconfig 2.13.0 h9420a91_0 \n", 103 | "freetype 2.9.1 h8a8886c_1 \n", 104 | "gast 0.2.2 py_0 conda-forge\n", 105 | "glib 2.63.1 h5a9c865_0 \n", 106 | "gmp 6.1.2 h6c8ec71_1 \n", 107 | "google-auth 1.11.0 pypi_0 pypi\n", 108 | "google-auth-oauthlib 0.4.1 pypi_0 pypi\n", 109 | "google-pasta 0.1.8 py_0 conda-forge\n", 110 | "grpcio 1.23.0 py37he9ae1f9_0 conda-forge\n", 111 | "gst-plugins-base 1.14.0 hbbd80ab_1 \n", 112 | "gstreamer 1.14.0 hb453b48_1 \n", 113 | "h5py 2.10.0 nompi_py37h513d04c_102 conda-forge\n", 114 | "hdf5 1.10.5 nompi_h3c11f04_1104 conda-forge\n", 115 | "icu 58.2 h9c2bf20_1 \n", 116 | "idna 2.8 pypi_0 pypi\n", 117 | "importlib_metadata 1.5.0 py37_0 \n", 118 | "inflect 4.1.0 py37_0 \n", 119 | "intel-openmp 2020.0 166 \n", 120 | "ipykernel 5.1.4 py37h39e3cac_0 \n", 121 | "ipython 7.12.0 py37h5ca1d4c_0 \n", 122 | "ipython_genutils 0.2.0 py37_0 \n", 123 | "ipywidgets 7.5.1 py_0 \n", 124 | "jaraco.itertools 5.0.0 py_0 \n", 125 | "jedi 0.16.0 py37_0 \n", 126 | "jinja2 2.11.1 py_0 \n", 127 | "jpeg 9b h024ee3a_2 \n", 128 | "json5 0.9.0 py_0 \n", 129 | "jsonschema 3.2.0 py37_0 \n", 130 | "jupyter_client 5.3.4 py37_0 \n", 131 | "jupyter_core 4.6.1 py37_0 \n", 132 | "jupyterlab 1.2.4 py_0 conda-forge\n", 133 | "jupyterlab_server 1.0.6 py_0 \n", 134 | "keras-applications 1.0.8 py_1 conda-forge\n", 135 | "keras-preprocessing 1.1.0 py_0 conda-forge\n", 136 | "kiwisolver 1.1.0 py37he6710b0_0 \n", 137 | "ld_impl_linux-64 2.33.1 h53a641e_7 \n", 138 | "libedit 3.1.20181209 hc058e9b_0 \n", 139 | "libffi 3.2.1 hd88cf55_4 \n", 140 | "libgcc-ng 9.1.0 hdf63c60_0 \n", 141 | "libgfortran-ng 7.3.0 hdf63c60_0 \n", 142 | "libpng 1.6.37 hbc83047_0 \n", 143 | "libprotobuf 3.11.3 h8b12597_0 conda-forge\n", 144 | "libsodium 1.0.16 h1bed415_0 \n", 145 | "libstdcxx-ng 9.1.0 hdf63c60_0 \n", 146 | "libuuid 1.0.3 h1bed415_2 \n", 147 | "libxcb 1.13 h1bed415_1 \n", 148 | "libxml2 2.9.9 hea5a465_1 \n", 149 | "markdown 3.1.1 py_0 conda-forge\n", 150 | "markupsafe 1.1.1 py37h7b6447c_0 \n", 151 | "matplotlib 3.1.1 py37h5429711_0 \n", 152 | "mistune 0.8.4 py37h7b6447c_0 \n", 153 | "mkl 2020.0 166 \n", 154 | "mkl-service 2.3.0 py37he904b0f_0 \n", 155 | "mkl_fft 1.0.15 py37ha843d7b_0 \n", 156 | "mkl_random 1.1.0 py37hd6b4f25_0 \n", 157 | "more-itertools 8.2.0 py_0 \n", 158 | "nbconvert 5.6.1 py37_0 \n", 159 | "nbformat 5.0.4 py_0 \n", 160 | "ncurses 6.1 he6710b0_1 \n", 161 | "nodejs 11.14.0 he1b5a44_1 conda-forge\n", 162 | "notebook 6.0.3 py37_0 \n", 163 | "numpy 1.18.1 py37h4f9e942_0 \n", 164 | "numpy-base 1.18.1 py37hde5b4d6_1 \n", 165 | "oauthlib 3.1.0 pypi_0 pypi\n", 166 | "openssl 1.1.1d h516909a_0 conda-forge\n", 167 | "opt-einsum 3.1.0 pypi_0 pypi\n", 168 | "pandas 1.0.0 py37h0573a6f_0 \n", 169 | "pandoc 2.2.3.2 0 \n", 170 | "pandocfilters 1.4.2 py37_1 \n", 171 | "parso 0.6.0 py_0 \n", 172 | "pcre 8.43 he6710b0_0 \n", 173 | "pexpect 4.8.0 py37_0 \n", 174 | "pickleshare 0.7.5 py37_0 \n", 175 | "pip 20.0.2 py37_1 \n", 176 | "prometheus_client 0.7.1 py_0 \n", 177 | "prompt_toolkit 3.0.3 py_0 \n", 178 | "protobuf 3.11.3 py37he1b5a44_0 conda-forge\n", 179 | "ptyprocess 0.6.0 py37_0 \n", 180 | "pyasn1 0.4.8 pypi_0 pypi\n", 181 | "pyasn1-modules 0.2.8 pypi_0 pypi\n", 182 | "pygments 2.5.2 py_0 \n", 183 | "pyparsing 2.4.6 py_0 \n", 184 | "pyqt 5.9.2 py37h05f1152_2 \n", 185 | "pyrsistent 0.15.7 py37h7b6447c_0 \n", 186 | "python 3.7.6 h0371630_2 \n", 187 | "python-dateutil 2.8.1 py_0 \n", 188 | "pytz 2019.3 py_0 \n", 189 | "pyzmq 18.1.1 py37he6710b0_0 \n", 190 | "qt 5.9.7 h5867ecd_1 \n", 191 | "readline 7.0 h7b6447c_5 \n", 192 | "requests 2.22.0 pypi_0 pypi\n", 193 | "requests-oauthlib 1.3.0 pypi_0 pypi\n", 194 | "rsa 4.0 pypi_0 pypi\n", 195 | "scipy 1.4.1 py37h0b6359f_0 \n", 196 | "send2trash 1.5.0 py37_0 \n", 197 | "setuptools 45.1.0 py37_0 \n", 198 | "sip 4.19.8 py37hf484d3e_0 \n", 199 | "six 1.14.0 py37_0 \n", 200 | "sqlite 3.31.1 h7b6447c_0 \n", 201 | "tensorboard 2.1.0 pypi_0 pypi\n", 202 | "tensorflow 2.1.0 pypi_0 pypi\n", 203 | "tensorflow-estimator 2.1.0 pypi_0 pypi\n", 204 | "termcolor 1.1.0 py_2 conda-forge\n", 205 | "terminado 0.8.3 py37_0 \n", 206 | "testpath 0.4.4 py_0 \n", 207 | "tk 8.6.8 hbc83047_0 \n", 208 | "tornado 6.0.3 py37h7b6447c_1 \n", 209 | "traitlets 4.3.3 py37_0 \n", 210 | "urllib3 1.25.8 pypi_0 pypi\n", 211 | "wcwidth 0.1.8 py_0 \n", 212 | "webencodings 0.5.1 py37_1 \n", 213 | "werkzeug 0.16.1 py_0 conda-forge\n", 214 | "wheel 0.34.2 py37_0 \n", 215 | "widgetsnbextension 3.5.1 py37_0 \n", 216 | "wrapt 1.11.2 py37h516909a_0 conda-forge\n", 217 | "xz 5.2.4 h14c3975_4 \n", 218 | "zeromq 4.3.1 he6710b0_3 \n", 219 | "zipp 2.1.0 py_0 \n", 220 | "zlib 1.2.11 h7b6447c_3 \n" 221 | ] 222 | } 223 | ], 224 | "source": [ 225 | "!conda list" 226 | ] 227 | }, 228 | { 229 | "cell_type": "markdown", 230 | "metadata": { 231 | "colab_type": "text", 232 | "id": "Ysmfper4-NDe" 233 | }, 234 | "source": [ 235 | "Dentro de cada uno de estos paquetes se encuentran **modulos**, que juntos forman la librería de módulos disponibles en el ambiente de trabajo.\n", 236 | "\n", 237 | "**¿Qué es un módulo?**\n", 238 | "\n", 239 | "Un módulo es un archivo que tiene extensión *.py*, es decir, es un archivo de texto que tiene adentro código de python que se puede ejecutar. Un módulo puede definir funciones, clases y variables.\n", 240 | "\n", 241 | "Cabe resaltar lo siguiente: **Python es un lenguaje de programación orientado a objetos**.\n", 242 | "\n", 243 | "Para términos de visualización, imagínese una caja que tiene muchas cajas por dentro y dentro de cada caja existen herramientas de trabajo distintas.\n", 244 | "\n", 245 | "**Ejemplo:**\n", 246 | "\n", 247 | "Mi maleta. Mi maleta tiene dentro lo siguiente:\n", 248 | "\n", 249 | "- Una cartuchera.\n", 250 | "- Un computador.\n", 251 | "- Un cuaderno.\n", 252 | "\n", 253 | "Los roles serían los siguientes:\n", 254 | "\n", 255 | "- Maleta $\\rightarrow$ Paquete\n", 256 | "- Cartuchera $\\rightarrow$ Módulo\n", 257 | "- Cuaderno $\\rightarrow$ Módulo\n", 258 | "\n", 259 | "Entonces, si queremos usar la cartuchera, debemos primero abrir la maleta y tomarla.\n", 260 | "\n", 261 | "**O sea, del paquete, vamos a usar un módulo**.\n", 262 | "\n", 263 | "Dentro de la cartuchera tengo marcadores, lápices, y borrador.\n", 264 | "\n", 265 | "Estos toman el rol de **atributos**, objetos que hacen tareas específicas.\n", 266 | "\n", 267 | "Por tanto, si quiero usar un borrador, debería hacer lo siguiente\n", 268 | "\n", 269 | "Abrir maleta $\\rightarrow$ Tomar cartuchera $\\rightarrow$ Abrir Cartuchera $\\rightarrow$ Tomar Borrador\n", 270 | "\n", 271 | "En Python, estas acciones se pueden **traducir** a lo siguiente:\n", 272 | "\n", 273 | "```import Maleta```\n", 274 | "\n", 275 | "```Maleta.Cartuchera.Borrador()```\n", 276 | "\n", 277 | "Para saber qué módulos están disponibles en el ambiente de trabajo, basta con usar el siguiente comando:" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 3, 283 | "metadata": { 284 | "colab": {}, 285 | "colab_type": "code", 286 | "id": "U3N2nKHs-NDf" 287 | }, 288 | "outputs": [ 289 | { 290 | "name": "stdout", 291 | "output_type": "stream", 292 | "text": [ 293 | "\n", 294 | "Please wait a moment while I gather a list of all available modules...\n", 295 | "\n" 296 | ] 297 | }, 298 | { 299 | "name": "stderr", 300 | "output_type": "stream", 301 | "text": [ 302 | "/home/moury/anaconda3/envs/tf2/lib/python3.7/site-packages/IPython/kernel/__init__.py:13: ShimWarning: The `IPython.kernel` package has been deprecated since IPython 4.0.You should import from ipykernel or jupyter_client instead.\n", 303 | " \"You should import from ipykernel or jupyter_client instead.\", ShimWarning)\n" 304 | ] 305 | }, 306 | { 307 | "name": "stdout", 308 | "output_type": "stream", 309 | "text": [ 310 | "IPython autoreload json5 runpy\n", 311 | "PyQt5 backcall jsonschema sched\n", 312 | "__future__ base64 jupyter scipy\n", 313 | "_abc bdb jupyter_client secrets\n", 314 | "_ast binascii jupyter_core select\n", 315 | "_asyncio binhex jupyterlab selectors\n", 316 | "_bisect bisect jupyterlab_server send2trash\n", 317 | "_blake2 bleach keras_applications setuptools\n", 318 | "_bootlocale builtins keras_preprocessing shelve\n", 319 | "_bz2 bz2 keyword shlex\n", 320 | "_codecs cProfile kiwisolver shutil\n", 321 | "_codecs_cn cachetools lib2to3 signal\n", 322 | "_codecs_hk calendar linecache sip\n", 323 | "_codecs_iso2022 certifi locale sipconfig\n", 324 | "_codecs_jp cgi logging sipdistutils\n", 325 | "_codecs_kr cgitb lzma site\n", 326 | "_codecs_tw chardet macpath six\n", 327 | "_collections chunk mailbox smtpd\n", 328 | "_collections_abc cmath mailcap smtplib\n", 329 | "_compat_pickle cmd markdown sndhdr\n", 330 | "_compression code markupsafe socket\n", 331 | "_contextvars codecs marshal socketserver\n", 332 | "_crypt codeop math spwd\n", 333 | "_csv collections matplotlib sqlite3\n", 334 | "_ctypes colorsys mimetypes sre_compile\n", 335 | "_ctypes_test compileall mistune sre_constants\n", 336 | "_curses concurrent mkl sre_parse\n", 337 | "_curses_panel configparser mkl_fft ssl\n", 338 | "_datetime contextlib mkl_random stat\n", 339 | "_decimal contextvars mmap statistics\n", 340 | "_dummy_thread copy modulefinder storemagic\n", 341 | "_elementtree copyreg more_itertools string\n", 342 | "_functools crypt multiprocessing stringprep\n", 343 | "_hashlib csv nbconvert struct\n", 344 | "_heapq ctypes nbformat subprocess\n", 345 | "_imp curses netrc sunau\n", 346 | "_io cycler nis symbol\n", 347 | "_json cythonmagic nntplib sympyprinting\n", 348 | "_locale dataclasses notebook symtable\n", 349 | "_lsprof datetime ntpath sys\n", 350 | "_lzma dateutil nturl2path sysconfig\n", 351 | "_markupbase dbm numbers syslog\n", 352 | "_md5 decimal numpy tabnanny\n", 353 | "_multibytecodec decorator oauthlib tarfile\n", 354 | "_multiprocessing defusedxml opcode telnetlib\n", 355 | "_opcode difflib operator tempfile\n", 356 | "_operator dis opt_einsum tensorboard\n", 357 | "_osx_support distutils optparse tensorflow\n", 358 | "_pickle doctest os tensorflow_core\n", 359 | "_posixsubprocess dummy_threading ossaudiodev tensorflow_estimator\n", 360 | "_py_abc easy_install pandas termcolor\n", 361 | "_pydecimal email pandocfilters terminado\n", 362 | "_pyio encodings parser termios\n", 363 | "_pyrsistent_version ensurepip parso test\n", 364 | "_queue entrypoints pasta testpath\n", 365 | "_random enum pathlib tests\n", 366 | "_sha1 errno pdb textwrap\n", 367 | "_sha256 faulthandler pexpect this\n", 368 | "_sha3 fcntl pickle threading\n", 369 | "_sha512 filecmp pickleshare time\n", 370 | "_signal fileinput pickletools timeit\n", 371 | "_sitebuiltins fnmatch pip tkinter\n", 372 | "_socket formatter pipes token\n", 373 | "_sqlite3 fractions pkg_resources tokenize\n", 374 | "_sre ftplib pkgutil tornado\n", 375 | "_ssl functools platform trace\n", 376 | "_stat gast plistlib traceback\n", 377 | "_string gc poplib tracemalloc\n", 378 | "_strptime genericpath posix traitlets\n", 379 | "_struct getopt posixpath tty\n", 380 | "_symtable getpass pprint turtle\n", 381 | "_sysconfigdata_aarch64_conda_cos7_linux_gnu gettext profile turtledemo\n", 382 | "_sysconfigdata_i686_conda_cos6_linux_gnu glob prometheus_client types\n", 383 | "_sysconfigdata_m_linux_x86_64-linux-gnu google_auth_oauthlib prompt_toolkit typing\n", 384 | "_sysconfigdata_powerpc64le_conda_cos7_linux_gnu grp pstats unicodedata\n", 385 | "_sysconfigdata_x86_64_apple_darwin13_4_0 grpc pty unittest\n", 386 | "_sysconfigdata_x86_64_conda_cos6_linux_gnu gzip ptyprocess urllib\n", 387 | "_testbuffer h5py pvectorc urllib3\n", 388 | "_testcapi hashlib pwd uu\n", 389 | "_testimportmultiple heapq py_compile uuid\n", 390 | "_testmultiphase hmac pyasn1 venv\n", 391 | "_thread html pyasn1_modules warnings\n", 392 | "_threading_local http pyclbr wave\n", 393 | "_tkinter idlelib pydoc wcwidth\n", 394 | "_tracemalloc idna pydoc_data weakref\n", 395 | "_warnings imaplib pyexpat webbrowser\n", 396 | "_weakref imghdr pygments webencodings\n", 397 | "_weakrefset imp pylab werkzeug\n", 398 | "_xxtestfuzz importlib pyparsing wheel\n", 399 | "abc importlib_metadata pyrsistent widgetsnbextension\n", 400 | "absl inflect pytz wrapt\n", 401 | "aifc inspect queue wsgiref\n", 402 | "antigravity io quopri xdrlib\n", 403 | "argparse ipaddress random xml\n", 404 | "array ipykernel re xmlrpc\n", 405 | "ast ipykernel_launcher readline xxlimited\n", 406 | "astor ipython_genutils reprlib xxsubtype\n", 407 | "asynchat ipywidgets requests zipapp\n", 408 | "asyncio itertools requests_oauthlib zipfile\n", 409 | "asyncore jaraco resource zipimport\n", 410 | "atexit jedi rlcompleter zipp\n", 411 | "attr jinja2 rmagic zlib\n", 412 | "audioop json rsa zmq\n", 413 | "\n", 414 | "Enter any module name to get more help. Or, type \"modules spam\" to search\n", 415 | "for modules whose name or summary contain the string \"spam\".\n", 416 | "\n" 417 | ] 418 | }, 419 | { 420 | "name": "stderr", 421 | "output_type": "stream", 422 | "text": [ 423 | "/home/moury/anaconda3/envs/tf2/lib/python3.7/pkgutil.py:107: VisibleDeprecationWarning: zmq.eventloop.minitornado is deprecated in pyzmq 14.0 and will be removed.\n", 424 | " Install tornado itself to use zmq with the tornado IOLoop.\n", 425 | " \n", 426 | " yield from walk_packages(path, info.name+'.', onerror)\n" 427 | ] 428 | } 429 | ], 430 | "source": [ 431 | "help(\"modules\")" 432 | ] 433 | }, 434 | { 435 | "cell_type": "markdown", 436 | "metadata": { 437 | "colab_type": "text", 438 | "id": "9KaScJd5-NDh" 439 | }, 440 | "source": [ 441 | "**Parece que es una lista bastante larga...**\n", 442 | "\n", 443 | "Veamos alguna documentación de alguno de los módulos y sus atributos.\n", 444 | "\n", 445 | "Por ejemplo random." 446 | ] 447 | }, 448 | { 449 | "cell_type": "code", 450 | "execution_count": 4, 451 | "metadata": { 452 | "colab": {}, 453 | "colab_type": "code", 454 | "id": "EwrihqyM-NDh" 455 | }, 456 | "outputs": [], 457 | "source": [ 458 | "#help(\"random\") # Muestra toda la documentación\n", 459 | "\n", 460 | "import random\n", 461 | "\n", 462 | "#?random # Muestra una pequeña documentación" 463 | ] 464 | }, 465 | { 466 | "cell_type": "markdown", 467 | "metadata": { 468 | "colab_type": "text", 469 | "id": "VHC2Wr2p-NDk" 470 | }, 471 | "source": [ 472 | "Para acceder a los atributos del mósulo, basta colocar ```dir(modulo)```" 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "execution_count": 5, 478 | "metadata": { 479 | "colab": {}, 480 | "colab_type": "code", 481 | "id": "enWNETIy-NDk" 482 | }, 483 | "outputs": [ 484 | { 485 | "data": { 486 | "text/plain": [ 487 | "['BPF',\n", 488 | " 'LOG4',\n", 489 | " 'NV_MAGICCONST',\n", 490 | " 'RECIP_BPF',\n", 491 | " 'Random',\n", 492 | " 'SG_MAGICCONST',\n", 493 | " 'SystemRandom',\n", 494 | " 'TWOPI',\n", 495 | " '_BuiltinMethodType',\n", 496 | " '_MethodType',\n", 497 | " '_Sequence',\n", 498 | " '_Set',\n", 499 | " '__all__',\n", 500 | " '__builtins__',\n", 501 | " '__cached__',\n", 502 | " '__doc__',\n", 503 | " '__file__',\n", 504 | " '__loader__',\n", 505 | " '__name__',\n", 506 | " '__package__',\n", 507 | " '__spec__',\n", 508 | " '_acos',\n", 509 | " '_bisect',\n", 510 | " '_ceil',\n", 511 | " '_cos',\n", 512 | " '_e',\n", 513 | " '_exp',\n", 514 | " '_inst',\n", 515 | " '_itertools',\n", 516 | " '_log',\n", 517 | " '_os',\n", 518 | " '_pi',\n", 519 | " '_random',\n", 520 | " '_sha512',\n", 521 | " '_sin',\n", 522 | " '_sqrt',\n", 523 | " '_test',\n", 524 | " '_test_generator',\n", 525 | " '_urandom',\n", 526 | " '_warn',\n", 527 | " 'betavariate',\n", 528 | " 'choice',\n", 529 | " 'choices',\n", 530 | " 'expovariate',\n", 531 | " 'gammavariate',\n", 532 | " 'gauss',\n", 533 | " 'getrandbits',\n", 534 | " 'getstate',\n", 535 | " 'lognormvariate',\n", 536 | " 'normalvariate',\n", 537 | " 'paretovariate',\n", 538 | " 'randint',\n", 539 | " 'random',\n", 540 | " 'randrange',\n", 541 | " 'sample',\n", 542 | " 'seed',\n", 543 | " 'setstate',\n", 544 | " 'shuffle',\n", 545 | " 'triangular',\n", 546 | " 'uniform',\n", 547 | " 'vonmisesvariate',\n", 548 | " 'weibullvariate']" 549 | ] 550 | }, 551 | "execution_count": 5, 552 | "metadata": {}, 553 | "output_type": "execute_result" 554 | } 555 | ], 556 | "source": [ 557 | "dir(random)" 558 | ] 559 | }, 560 | { 561 | "cell_type": "markdown", 562 | "metadata": { 563 | "colab_type": "text", 564 | "id": "wiM6us6L-NDn" 565 | }, 566 | "source": [ 567 | "Vaya que la lista sigue siendo larga...\n", 568 | "\n", 569 | "Sigamos metiendo dentro de cada cosa (algún día llegaremos al fin...no?)" 570 | ] 571 | }, 572 | { 573 | "cell_type": "code", 574 | "execution_count": 6, 575 | "metadata": { 576 | "colab": {}, 577 | "colab_type": "code", 578 | "id": "PySeb2Wk-NDo" 579 | }, 580 | "outputs": [ 581 | { 582 | "data": { 583 | "text/plain": [ 584 | "\u001b[0;31mDocstring:\u001b[0m random() -> x in the interval [0, 1).\n", 585 | "\u001b[0;31mType:\u001b[0m builtin_function_or_method\n" 586 | ] 587 | }, 588 | "metadata": {}, 589 | "output_type": "display_data" 590 | } 591 | ], 592 | "source": [ 593 | "?random.random" 594 | ] 595 | }, 596 | { 597 | "cell_type": "markdown", 598 | "metadata": { 599 | "colab_type": "text", 600 | "id": "X1_wQC94-NDq" 601 | }, 602 | "source": [ 603 | "**Bingo!** Al fin algo que podemos usar:" 604 | ] 605 | }, 606 | { 607 | "cell_type": "code", 608 | "execution_count": 7, 609 | "metadata": { 610 | "colab": {}, 611 | "colab_type": "code", 612 | "id": "xnMlKKRG-NDq" 613 | }, 614 | "outputs": [ 615 | { 616 | "name": "stdout", 617 | "output_type": "stream", 618 | "text": [ 619 | "Número aleatorio en [0,1]: 0.673482013112875\n" 620 | ] 621 | } 622 | ], 623 | "source": [ 624 | "x = random.random()\n", 625 | "print(\"Número aleatorio en [0,1]: \",x)" 626 | ] 627 | }, 628 | { 629 | "cell_type": "code", 630 | "execution_count": 8, 631 | "metadata": { 632 | "colab": {}, 633 | "colab_type": "code", 634 | "id": "KchaPexs-NDs" 635 | }, 636 | "outputs": [ 637 | { 638 | "data": { 639 | "text/plain": [ 640 | "\u001b[0;31mSignature:\u001b[0m \u001b[0mrandom\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrandint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 641 | "\u001b[0;31mDocstring:\u001b[0m\n", 642 | "Return random integer in range [a, b], including both end points.\n", 643 | " \n", 644 | "\u001b[0;31mFile:\u001b[0m ~/anaconda3/envs/tf2/lib/python3.7/random.py\n", 645 | "\u001b[0;31mType:\u001b[0m method\n" 646 | ] 647 | }, 648 | "metadata": {}, 649 | "output_type": "display_data" 650 | } 651 | ], 652 | "source": [ 653 | "?random.randint" 654 | ] 655 | }, 656 | { 657 | "cell_type": "code", 658 | "execution_count": 9, 659 | "metadata": { 660 | "colab": {}, 661 | "colab_type": "code", 662 | "id": "AKKSIXOr-NDv" 663 | }, 664 | "outputs": [ 665 | { 666 | "name": "stdout", 667 | "output_type": "stream", 668 | "text": [ 669 | "Número entero aleatorio entre 3 y 6: 4\n" 670 | ] 671 | } 672 | ], 673 | "source": [ 674 | "y=random.randint(3,6)\n", 675 | "print(\"Número entero aleatorio entre 3 y 6: \",y)" 676 | ] 677 | }, 678 | { 679 | "cell_type": "markdown", 680 | "metadata": { 681 | "colab_type": "text", 682 | "id": "uwdXWH3c-NDx" 683 | }, 684 | "source": [ 685 | "# Alias para módulos\n", 686 | "\n", 687 | "Otra propiedad genial de Python es su capacidad para reducir la cantidad de código escrito usando unos secretos milenarios: aliases.\n", 688 | "\n", 689 | "Por ejemplo, si me llamo Daniel, mi **alias** puede ser Dani.\n", 690 | "\n", 691 | "Entonces, acada vez que me digan Dani, yo miraré en respuesta.\n", 692 | "\n", 693 | "Traducir a Python luce así:\n", 694 | "\n", 695 | "```import modulo as alias```\n", 696 | "\n", 697 | "**Ejemplo:**" 698 | ] 699 | }, 700 | { 701 | "cell_type": "code", 702 | "execution_count": 10, 703 | "metadata": { 704 | "colab": {}, 705 | "colab_type": "code", 706 | "id": "Dr0ek4Hq-NDy" 707 | }, 708 | "outputs": [ 709 | { 710 | "data": { 711 | "text/plain": [ 712 | "['__doc__',\n", 713 | " '__file__',\n", 714 | " '__loader__',\n", 715 | " '__name__',\n", 716 | " '__package__',\n", 717 | " '__spec__',\n", 718 | " 'acos',\n", 719 | " 'acosh',\n", 720 | " 'asin',\n", 721 | " 'asinh',\n", 722 | " 'atan',\n", 723 | " 'atan2',\n", 724 | " 'atanh',\n", 725 | " 'ceil',\n", 726 | " 'copysign',\n", 727 | " 'cos',\n", 728 | " 'cosh',\n", 729 | " 'degrees',\n", 730 | " 'e',\n", 731 | " 'erf',\n", 732 | " 'erfc',\n", 733 | " 'exp',\n", 734 | " 'expm1',\n", 735 | " 'fabs',\n", 736 | " 'factorial',\n", 737 | " 'floor',\n", 738 | " 'fmod',\n", 739 | " 'frexp',\n", 740 | " 'fsum',\n", 741 | " 'gamma',\n", 742 | " 'gcd',\n", 743 | " 'hypot',\n", 744 | " 'inf',\n", 745 | " 'isclose',\n", 746 | " 'isfinite',\n", 747 | " 'isinf',\n", 748 | " 'isnan',\n", 749 | " 'ldexp',\n", 750 | " 'lgamma',\n", 751 | " 'log',\n", 752 | " 'log10',\n", 753 | " 'log1p',\n", 754 | " 'log2',\n", 755 | " 'modf',\n", 756 | " 'nan',\n", 757 | " 'pi',\n", 758 | " 'pow',\n", 759 | " 'radians',\n", 760 | " 'remainder',\n", 761 | " 'sin',\n", 762 | " 'sinh',\n", 763 | " 'sqrt',\n", 764 | " 'tan',\n", 765 | " 'tanh',\n", 766 | " 'tau',\n", 767 | " 'trunc']" 768 | ] 769 | }, 770 | "execution_count": 10, 771 | "metadata": {}, 772 | "output_type": "execute_result" 773 | } 774 | ], 775 | "source": [ 776 | "import math as m\n", 777 | "\n", 778 | "# Una vez nombrado el alias, siempre se debe referir a ese alias y no al nombre principal\n", 779 | "\n", 780 | "dir(m) #dir(math) genera error" 781 | ] 782 | }, 783 | { 784 | "cell_type": "markdown", 785 | "metadata": { 786 | "colab_type": "text", 787 | "id": "c4nWmwgO-ND0" 788 | }, 789 | "source": [ 790 | "# Aplicación:\n", 791 | "\n", 792 | "Una pequeña aplicación de Matemáticas:\n", 793 | "\n", 794 | "**Área de una circunferencia de radio r:**\n", 795 | "\n", 796 | "$A = \\pi r²$" 797 | ] 798 | }, 799 | { 800 | "cell_type": "code", 801 | "execution_count": 11, 802 | "metadata": { 803 | "colab": {}, 804 | "colab_type": "code", 805 | "id": "ksUNn8WQ-ND0" 806 | }, 807 | "outputs": [ 808 | { 809 | "name": "stdout", 810 | "output_type": "stream", 811 | "text": [ 812 | "El Área del círculo es: 314.1592653589793 cm²\n" 813 | ] 814 | } 815 | ], 816 | "source": [ 817 | "# Aplicación: Área de un círculo de radio 10 cm \n", 818 | "\n", 819 | "r = 10; # Declarar el radio\n", 820 | "z = m.pi*(r**2) # Escribir la fórmula matemática\n", 821 | "print(\"El Área del círculo es: \",z,\"cm²\")" 822 | ] 823 | }, 824 | { 825 | "cell_type": "markdown", 826 | "metadata": { 827 | "colab_type": "text", 828 | "id": "EjlNxo93-ND3" 829 | }, 830 | "source": [ 831 | "Como pueden observar, los módulos son el **alma de Python**.\n", 832 | "\n", 833 | "# Tareas:\n", 834 | "\n", 835 | "- Conocer los 10 módulos de Python más usados.\n", 836 | "- Hacer un ejercicio práctico con cada módulo investigado.\n", 837 | "- Investigar si es posible crear un módulo de Python. En caso afirmativo, crear uno simple.\n", 838 | "- Explicar la lógica subyacente de la siguiente línea:" 839 | ] 840 | }, 841 | { 842 | "cell_type": "code", 843 | "execution_count": 12, 844 | "metadata": { 845 | "colab": {}, 846 | "colab_type": "code", 847 | "id": "smXggFjI-ND3" 848 | }, 849 | "outputs": [ 850 | { 851 | "name": "stdout", 852 | "output_type": "stream", 853 | "text": [ 854 | "314.1592653589793\n" 855 | ] 856 | } 857 | ], 858 | "source": [ 859 | "# You Must Reset Kernel 0,0\n", 860 | "\n", 861 | "from math import pi\n", 862 | "\n", 863 | "A = pi*r**2\n", 864 | "\n", 865 | "print(A)" 866 | ] 867 | }, 868 | { 869 | "cell_type": "code", 870 | "execution_count": 13, 871 | "metadata": { 872 | "colab": {}, 873 | "colab_type": "code", 874 | "id": "9aWXXD3O-ND6" 875 | }, 876 | "outputs": [ 877 | { 878 | "ename": "NameError", 879 | "evalue": "name 'math' is not defined", 880 | "output_type": "error", 881 | "traceback": [ 882 | "\u001b[0;31m----------------------------------------------------------------------\u001b[0m", 883 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 884 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpi\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 885 | "\u001b[0;31mNameError\u001b[0m: name 'math' is not defined" 886 | ] 887 | } 888 | ], 889 | "source": [ 890 | "math.pi" 891 | ] 892 | }, 893 | { 894 | "cell_type": "markdown", 895 | "metadata": { 896 | "colab_type": "text", 897 | "id": "b5CfhNZJ-ND8" 898 | }, 899 | "source": [ 900 | "# Bonus: Fractales\n", 901 | "\n", 902 | "Usando un módulo llamado ```turtle``` podemos crear un árbolito bonito." 903 | ] 904 | }, 905 | { 906 | "cell_type": "code", 907 | "execution_count": null, 908 | "metadata": { 909 | "colab": {}, 910 | "colab_type": "code", 911 | "id": "Wqayl5NU-ND8" 912 | }, 913 | "outputs": [], 914 | "source": [ 915 | "import turtle\n", 916 | "\n", 917 | "def tree(length,n):\n", 918 | " if length < (length/n):\n", 919 | " return\n", 920 | " turtle.forward(length)\n", 921 | " turtle.left(45)\n", 922 | " tree(length * 0.5,length/n)\n", 923 | " turtle.left(20)\n", 924 | " tree(length * 0.5,length/n)\n", 925 | " turtle.right(75)\n", 926 | " tree(length * 0.5,length/n)\n", 927 | " turtle.right(20)\n", 928 | " tree(length * 0.5,length/n)\n", 929 | " turtle.left(30)\n", 930 | " turtle.backward(length)\n", 931 | " return\n", 932 | "\n", 933 | "turtle.left(90)\n", 934 | "turtle.backward(30)\n", 935 | "tree(200,4)" 936 | ] 937 | }, 938 | { 939 | "cell_type": "markdown", 940 | "metadata": { 941 | "colab_type": "text", 942 | "id": "KW6t1aZG-ND_" 943 | }, 944 | "source": [ 945 | "Y también formas que tienen forma de pedazos de copitos de nieve (Koch Curve):" 946 | ] 947 | }, 948 | { 949 | "cell_type": "code", 950 | "execution_count": null, 951 | "metadata": { 952 | "colab": {}, 953 | "colab_type": "code", 954 | "id": "bxFm2p5--ND_" 955 | }, 956 | "outputs": [], 957 | "source": [ 958 | "from turtle import *\n", 959 | "\n", 960 | "def Recursive_Koch(length, depth):\n", 961 | " if depth == 0:\n", 962 | " forward(length)\n", 963 | " else:\n", 964 | " Recursive_Koch(length, depth-1)\n", 965 | " right(60)\n", 966 | " Recursive_Koch(length, depth-1)\n", 967 | " left(120)\n", 968 | " #Recursive_Koch(length, depth-1)\n", 969 | " Recursive_Koch(length, depth-1)\n", 970 | " right(60)\n", 971 | " Recursive_Koch(length, depth-1)\n", 972 | " \n", 973 | "# ----------\n", 974 | "Recursive_Koch(3, 6)" 975 | ] 976 | } 977 | ], 978 | "metadata": { 979 | "colab": { 980 | "name": "Paquetes.ipynb", 981 | "provenance": [] 982 | }, 983 | "kernelspec": { 984 | "display_name": "Python 3", 985 | "language": "python", 986 | "name": "python3" 987 | }, 988 | "language_info": { 989 | "codemirror_mode": { 990 | "name": "ipython", 991 | "version": 3 992 | }, 993 | "file_extension": ".py", 994 | "mimetype": "text/x-python", 995 | "name": "python", 996 | "nbconvert_exporter": "python", 997 | "pygments_lexer": "ipython3", 998 | "version": "3.7.6" 999 | } 1000 | }, 1001 | "nbformat": 4, 1002 | "nbformat_minor": 4 1003 | } 1004 | -------------------------------------------------------------------------------- /Cuadernos/MN_Butcher.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# La Tabla del Carnicero (Butcher's Table)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Introducción" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Ya hemos introducido dos métodos numéricos para resolver ecuaciones diferenciales, a saber el método de **Euler** y el de **Runge-Kutta*.\n", 22 | "\n", 23 | "Se preguntará el espectador, ¿Existen más?\n", 24 | "\n", 25 | "**¡Por suspuesto que sí!**\n", 26 | "\n", 27 | "Hoy veremos una forma de construir muchos más mediante un proceso mnemotécino llamado la **Tabla de Butcher**." 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "**No olvidemos nuestro foco de atención**,\n", 35 | "\n", 36 | "$$\\frac{dx}{dt}=f(t,x),\\text{ }x(t_{0})=x_{0}$$\n", 37 | "\n", 38 | "esto es, la tasa de cambio instantáneo de la cantidad dependiente $x$, se puede modelar mediante la función $f(t,x)$. Además el experimento comienza en el momento $t_0$ con una cantidad inicial $x_0$ de la cantidad $x$." 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "## Definición" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "La tabla del carnicero es una regla mnemotécnica que ayuda a construir métodos numéricos ya conocidos mediante una tabla que resume su información. \n", 53 | "\n", 54 | "El objetivo de esta lección será acostumbrarnos a la notación de tabla para construir y programar el respectivo método, así como el proceso inverso, esto es, ir del método numérico a la tabla.\n", 55 | "\n", 56 | "Esto es muy importante, pues el entender la tabla genera un proceso de abstracción importante en nuestro cerebro que nos hará entender la estrucutra interna de los llamados **métodos numéricos explícitos** para resolver ecuaciones diferenciales.\n", 57 | "\n", 58 | "El proceso se puede resumir con las siguiente gráficas (Tomadas de [Wikipedia](https://wikimedia.org/api/rest_v1/media/math/render/svg/44d56b38e104bfdf185d1307337e5c6e074b16c9)):\n", 59 | "\n", 60 | "**Ir de**\n", 61 | "\n", 62 | "![Tabla](/files/Pictures/Butcher.png)\n", 63 | "\n", 64 | "\n", 65 | "**Para construir el método**\n", 66 | "\n", 67 | "![MetNum](https://wikimedia.org/api/rest_v1/media/math/render/svg/44d56b38e104bfdf185d1307337e5c6e074b16c9)\n", 68 | "\n", 69 | "![Predictor](https://wikimedia.org/api/rest_v1/media/math/render/svg/84fa47cf3289c5ab2067fe46f748f33d4b6be48c)\n", 70 | "\n", 71 | "**y vicerversa. Recuerde que en nuestro problema, $x$ hace el papel de la $y$ mostrada arriba.**" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "Aunque esto puede ser un poco confuso al principio, iremos paso a paso a paso para ver cómo se hace dicha transformación.\n", 79 | "\n", 80 | "- **c's:** Representan dos cosas:\n", 81 | "\n", 82 | " 1. Cuántos **k's** necesitamos definir para construir todo el método numérico.\n", 83 | " 2. Cuánto se le va a sumar a $t_i$ en multiplcación con $h$ en $f(t_i,\\dots)$ **antes de la coma**.\n", 84 | " \n", 85 | " \n", 86 | "- **a's:** Representan cuánto de cada k se le debe agregar a la función en multiplicación con $h$ $f(\\dots,x_i)$ **después de la coma**.\n", 87 | "\n", 88 | "- **b's:** Ayudan a construir la función **predictora** del método (futuro = presente + paso\\*( comb. lineal de **b's** y **k's**). " 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "## Ejemplos básicos" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "### Método de Euler" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "![Tabla](/files/Pictures/BEuler.png)\n", 110 | "\n", 111 | "Como podemos ver, en este método, necesitamos una k y sumar $hk_1$ en el predictor.\n", 112 | "\n", 113 | "El método se escribe entonces, como:\n", 114 | "\n", 115 | "$$k_1=f(t_i,x_i)$$\n", 116 | "$$x_{i+1}=x_i + hk_1$$\n", 117 | "\n", 118 | "que si recordamos, es lo mismo que tener:\n", 119 | "\n", 120 | "$$x_{i+1}=x_i + hf(t_i,x_i)$$" 121 | ] 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "metadata": {}, 126 | "source": [ 127 | "### Método del Punto Medio" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": {}, 133 | "source": [ 134 | "![Tabla](/files/Pictures/BMidPt.png)\n", 135 | "\n", 136 | "En este método, necesitamos dos k's y sumar $h\\bigl(\\frac{1}{2}k_1+\\frac{1}{2}k_2\\bigr)$ en el predictor.\n", 137 | "\n", 138 | "El método se escribe entonces, como:\n", 139 | "\n", 140 | "$$\n", 141 | "\\begin{split}\n", 142 | "k_1 &=f(t_i,x_i) \\\\\n", 143 | "k_2 &=f\\biggl(t_i+\\frac{h}{2},x_i+h\\frac{k_1}{2}\\biggr) \\\\\n", 144 | "x_{i+1} &=x_i + h\\frac{k_2}{2} \\\\\n", 145 | "\\end{split}$$" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": {}, 151 | "source": [ 152 | "### Método de Ralston" 153 | ] 154 | }, 155 | { 156 | "cell_type": "markdown", 157 | "metadata": {}, 158 | "source": [ 159 | "![Tabla](/files/Pictures/BRalston.png)\n", 160 | "\n", 161 | "En este método, necesitamos dos k's y sumar $h\\bigl(\\frac{1}{4}k_1+\\frac{3}{4}k_2\\bigr)$ en el predictor.\n", 162 | "\n", 163 | "El método se escribe entonces, como:\n", 164 | "\n", 165 | "$$\n", 166 | "\\begin{split}\n", 167 | "k_1 &=f(t_i,x_i) \\\\\n", 168 | "k_2 &=f\\biggl(t_i+\\frac{2h}{3},x_i+h\\frac{2k_1}{3}\\biggr) \\\\\n", 169 | "x_{i+1} &=x_i + h\\biggl(\\frac{1}{4}k_1+\\frac{3}{4}k_2\\biggr) \\\\\n", 170 | "\\end{split}$$" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "Ahora veremos un caso curioso, llamado **Runge-Kutta 3/8**:" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "metadata": {}, 183 | "source": [ 184 | "### Implementación" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": {}, 190 | "source": [ 191 | "Haremos la implementación de Runge-Kutta, Regla 3/8.\n", 192 | "\n", 193 | "Los demás métodos mostrados y existentes son deber el estudiante.\n", 194 | "\n", 195 | "**Por favor, documentar adecuadamente el siguiente código:**" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": 8, 201 | "metadata": {}, 202 | "outputs": [], 203 | "source": [ 204 | "def RK38(f,x0,t0,tf,n):\n", 205 | " t=np.linspace(t0,tf,n)\n", 206 | " h=abs(t[1]-t[0])\n", 207 | " x=np.empty(n)\n", 208 | " x[0]=x0\n", 209 | " \n", 210 | " for i in range(n-1):\n", 211 | " k1=f(t[i],x[i])\n", 212 | " k2=f(t[i]+h/3 ,x[i]+h*k1/3)\n", 213 | " k3=f(t[i]+2*h/3,x[i]+h*(-k1/3+k2))\n", 214 | " k4=f(t[i]+h ,x[i]+h*(k1-k2+k3))\n", 215 | " \n", 216 | " x[i+1]=x[i]+h*(k1/8+3*k2/8+3*k3/8+k4/8)\n", 217 | " return t,x" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "Es claro que esta debe ser la función de un módulo, junto con ```EulerM```, ```RK4``` y todos los demás métodos.\n", 225 | "\n", 226 | "**Observación:** El método RK38 contiene meno error que el método clásico RK4 (aunque requiere un poquito más de cálculos, pero la diferencia en tiempo de cómputo es insignificante).\n", 227 | "\n", 228 | "Resolvamos la siguiente ecuación con la regla 3/8:\n", 229 | "\n", 230 | "$$\\frac{dx}{dt}=\\tan(x)+1,\\text{ }x(1)=1$$" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": 14, 236 | "metadata": {}, 237 | "outputs": [ 238 | { 239 | "data": { 240 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAtwAAAGLCAYAAAD0ykW7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzdd3hVVdbH8e9KAgmkQRI6ISBIMfQqZRQsCCooFhQBUextZJDXGRswgjo4lnEKMhbEgljGShEVNShSBAuMqFSRQJQqkIQkkGS/f5ybTAipmOSm/D7Pcx9yzz5lnbMDrLvvOvuYcw4RERERESkfAf4OQERERESkOlPCLSIiIiJSjpRwi4iIiIiUIyXcIiIiIiLlSAm3iIiIiEg5UsItIiIiIlKOlHCLSKVlZo+Y2TdmVsffsYiIiJwoJdwiUi7MbKqZOTPbVEj7Zl/71ELaBwDjgIucc2l5lvcubJvfEOsaM5tTlvvMs++OvvMcWAb72ubblzOzI2a2ycxmmFloGYTqN77zuTXfst5mdtDMFptZcCn2dWf+a21mtX2/j13LKOSc/V7s+z0O9L0fmKd/nJkdMLNVZnZhAdtuM7NH8i07ycx2mNlXZlavgG3eLuRaLTSz+8ry3ESkbCnhFpHylA60MrOeeReaWS8gztd+HF8CORsY45zbmq+5NzClHGKtKl4G+gJnAS8AfwCe8GtEZcyXGC8GvgRGOOcySrH5ncDAfMtq4/3OlFnCbWYBwJ+BvzrnsvI1j8broyuAfcCbZnZaMftrAXwM/AoMds4dyNc+GDi1kM3/AkwsKEkXkcpBCbeIlKdUvCTi8nzLL/ctTy1oI+dcqnOurXPu/XKOryr62Tm30jn3qXNuGr4PJr4EsMozs3jgQ+A7YFjebzcqmTOB1ngfgPJb5+ujRcAleEn0mMJ2ZGZNgY/wPoCe5Zzbm6+9Ft6HqnsK2t459xleYj/2BM5DRCpAtfgHWkQqtVeAkWZmAL4/R/qWH8fMBpjZUjM7bGb7zOxpMwv3tV0F/MP3c87X9gl5tj3D9xV+upntMrOZZhaWb/8dzexz3zrfm9nwQuIYaWb/NbMMM0s0swfMLKi4kzWzm33rp5rZfKBJAesEmNmffOUIGWa20czGFbfvQqwFgoEGefafYGb/yXfMnHKHjr73LX3vR5rZv33lGzvM7M/5k3czu9RXvpJmZp+YWTfftlflW+9aM1vvO6efzOzO0pyImbUFlgBbgXOdc6l52qaa2d4CtsktsTCzbUA0MCXP78dAINm3+nN5lrf0bfMXXz+n+M5/rpk1LkG444APnHPJRa3knDsMbAZiCznnhnjJtgFnOOd2FbDa7UAa8FwRh3oDuLIEcYuIHyjhFpHy9ibQCBjge/87vOTwrfwrmll/vOTjF7yRwQnAufwv0VgIPOr7ua/vdbNv21PwyhD2AhfjlRBcAeQmnubdfPk+EOZrmw78DWiRL47BwKvAV8AFeEn+JOCfRZ2omV0A/AtYAFwE/BdvBDq/fwD3Ak8B5/muxWwzO7+o/ReiBV5CeVwyWkIPAyl41/slYLLvZwB85UCv4F2LEcC7eNfmGGb2f8CTwNvA+b6fp+WvNy5CK7y+/xk4xzl36ATOZQRwEHiW//1+fAWc4Wufnmf5z75lDYEH8fphAnAS8LH56rKLcAawvLiAfB9emgM/FtAchfcBow5esp1UwPaNgfuACc657CIOtRzoYWb1i4tJRCpesaM1IiK/hXPugJktxisj+cz352Lf8vyr/wVY7py7LGeBme0EPjKzjs65b32jmDjnVubbdjLwEzA8p6bWzPYDr5pZX+fcCuBqvASrj3Nuh2+dbcCyfPu6H0hwzuWMOi/2xfqQmU3P2bYA9/jO7Sbf+/fNrAFwbZ7zaQPcBFztnHvet3iJmTXB+5CwoJB959mFBeHVJZ8G3Ag8UEAdcUl96py7w/fzh2Y2BO/Dwmu+ZX8Evgcud845vGtRC5iRJ6AIX+zTnXN/zrOvusC9ZvZkCeKbiDeK2yt//XJJOee+NrNMYEfe3w8zW+37cUv+3xvn3Pg86wUCK4AdQH/g04KO4ysBaQJ8W0gogb4+qo9XUx5KwXX2VwMO6Oac217Ivh4G3nfOFRhLHmvxRsl74pXkiEglohFuEakIrwCXmDfbxCUUUE7iS876Aq+ZWVDOCy8ZPgr0KOYYvYG38iV2bwCZ/G90vTfwZd6E2Tn3ObA7TxyBQHfg9Xz7fxXv38y+BR3ct1034J18TW/me38mkA28le88PwK6lmBkdSLe9UgF3gM+cc7NKHqTIn2Q7/13eCOyOXoB833Jdo53823TFy+pfD3fOX2M9+1Gc/ME5XnlP88leKUxf7ECPomVFzMbambLzewg3u9Kzu9G2yI2yyk5KexbhW/w+mg3Xn9d5ZzbUMB6n+HVbT9iZrULiK0v3t+X/yv2RP4XS0nKYUSkginhFpGK8C5eGccDeInZ/ALWqQ8EAjPxkpWcVwZQi0JqYPNoAhxT/+pLvvfhfXUPXjKym+PlXRbjO17+Wtqc91EUrAHet4b595//fQzeeR7k2POc49v+uJrvfF7CS4IH4pXajDCzm4rcomj5R5OPACF53jcG9uRbJ//7GN+f6zn2nD7xLY8FTs/X9lG+fbwD3IZXG/1bPkCUmHmz5byLl2SPxfvgkDMTSEhh2+VpK2z2lMvx+uhiYANe7XjTAtb7wrfuIOCFAj5o/A34N3DQzOrZ/2YhqWNmkfnWzYmlqLhFxE9UUiIi5c45l2pmC/CmsHs9781weRzA+3p9KrCogPbj6lvz+RmvXCSXbxQ1GtjvW/QL0L6AbfNutxcvIWyYb51Gvj/3U7A9eCOk+bfL/36/b73+eCPd+RX0gSCvXc65Nb6fl5pZHHC/mb2Q57qm45Wc5FXYB4Xi/EKeGzJ98r/PuSbnc/wHFfCSTvCS0BzH3WzonJuZU7NsZr845x7L03zcOZVBvfIIvH67LGcE33c9i5NzvoVNw7feOfctsMbM1uJ9a3AfXinRMZxz75rZ9Xh157uB3+dpbof3rcyEfJs9DDzEsf+H58RS2O+niPiREm4RqShP4pUMzCqo0ZeUrwTaOefuL2I/RwDMLMQ5l3ce71V4o7135ykruQjv37mcGu3VwGgza56nhrs/eZJi51yWmX0JXOqLOcdIvAR5RSHxZ5nZN3g3WeY9x4vyrfox3gh3pHOuLGpt78I792uAv/uW7cCr787r7BPc/2pgmO+65pSV5J/ZZQVe/XVT59zCIva1pog2AJxzk30zdzxiZrudcy/5mnYA4WbWzDm307dscAG7yD9Cn7OMApbXAY7mK5cZXVyMeDdAHsG70TOhqBWdc1vM7BlgvJlNcc4d94HKOTfbzBoBD5rZLufcA76m8zn+/+lP8Po5f6lSS9+fG0sQv4hUMCXcIlIhnHMJFJOc4N1g9pGZZePNLpKMNwvHecA9zrmNwA++dW83s4+BQ7762OnA18DbZvYkXh3yDLwbznKS5OfwZgdZaN7TKusA0zi+FncK3g2Pz+HVm3fyrfd0ETdMgjfbxZu+47+FV0YxJN912GBms4BXzOxhvCQ0BIgH2jrnrqUUnHNfmNmHwB/M7F++DxtvAdeY2eN4M7sMAs4pzX7zmIGX0L/iux4dgOt8bdm+GA74rucTvhHiT/FKFtsCg5xzI0p5zJvxPgTNNrO9zrnFeDPQpPmWPYqX7N5YwLY/AOf5btRNATY455LN7Ee86Sm/xRstX4d3c+EEM/sbXplTP4qYLzuHcy7D96GsB0VP1ZfjYbxrdhveSHdB+3zIN7o/3Te6/6xzLv/NvPiqTjY555bma+qJV6a0vgTxiEhFc87ppZdeepX5C680ZG8x6+wFpuZb1gcvuTqEd2Pgd8BjeCPC4M3E8DBeiUk23mwiOdueiZccpuN9PT8TCMu3/854U6hl4JU6XIiX9M7Jt95leNP6HcEbXX0ACCrBed/qW/8wXmnMYLxSmYF51jG8MoH1vjj2AEuBK4vZ9zbgkQKWn+Y7xqg8y+4CEvE+tLyENyrtgI6+9pa+9+fn29ccYE2+ZSPx5pJOx/u24CzfthfmW28M3tMh0/Ae9rIKmFiCa+aAW/MtC8b7gJaCN6sMwFDfNTuMd8Nhh/zb4iXBK32/O7nX3dcP63zn4ICWvuV3+q5TKt6NmycXFE8BMU8CNudbNjDvNc7XNhvvfoLQwvrS93vxMl7J0QUlvVa+5e8Az/n7771eeulV8Mucy/tNmoiISNHMbAzwInCSc66g+aWrPV8JyHZggHNudXHrl3MskXi182e5AkbFRcT/lHCLiEiRfCUyH+KNWnfHK8v53Dl3Ig/qqTbM7F9437wUW4ZSznH8CRjinBvozzhEpHCq4RYRkeJE45XnROOVRbyKV4pR003Dq5UPdCf+4KGycJBjZzcRkUpGI9wiIiIiIuVID74RERERESlHSrhFRERERMpRhddwm9lsvMn8dzvnOhbQfgFeXVw23tRIE3LuujazLLxpugC2O+fyP3zhODExMa5ly5ZlFH3ppKamEhoa6pdjS8VQH9cM6ueaQf1c/amPawZ/9vOXX3651zmX/2m8FV/DbWan4c2r+kIhCXcYkOqcc2bWGXjNOdfe15binAsrzfF69uzp1qwp9uFm5SIhIYGBAwf65dhSMdTHNYP6uWZQP1d/6uOawZ/9bGZfOud65l9e4SUlzrlPgf1FtKe4/30KCMWb5F9EREREpEqqlDXcZjbCzH7AeyTx+DxNIWa2xsxWmtmFfgpPRERERKTE/DItoJm1BBYUVFKSb73TgMnOubN875s655LM7CTgY+BM59yWAra7HrgeoFGjRj1eeeWVMj6DkklJSSEsrFQVMFLFqI9rBvVzzaB+rv7UxzWDP/t50KBBBZaUVOoH3zjnPjWz1mYW45zb65xL8i3famYJQDfguITbOfcU8BR4Ndz+quNRrVj1pz6uGdTPNYP6ufpTH9cMlbGfK13CbWZtgC2+mya7A7WBfWZWHzjsnMswsxigP/DwiR7n6NGj7Nixg/T09LIJvACRkZF8//335bZ/8T/1cc2Q08+BgYHUq1ePmJgYAgIqZUWeiIhUQv6YFnAeMBCIMbMdwBSgFoBzbhZwMXClmR0F0oDLfMl3B+DfZpaNV3v+F+fcdycax44dOwgPD6dly5aY2W87qUIkJycTHh5eLvuWykF9XDMkJycTFhbG0aNH2bVrFzt27KBFixb+DktERKqICk+4nXOjimmfAcwoYPlyoFNZxZGenl6uybaIVC9mRu3atWnWrBkbNmzwdzgiIlKF1OjvRJVsi0hpqZRERERKS/9ziIiIiIiUIyXc1ci2bdswMzIzM3/Tfm688UamTZt23PLXXnuNc845h4yMjN+0f3/4/PPP6dWrF/v3F/rMJQDi4+NJSEiomKBERESkRlDCXQktW7aMfv36ERkZSVRUFP3792f16tUVdvxZs2Zx3333HbPs66+/5tlnn+Wtt94iODj4hPY7depUzIzXX389d1lmZiZmxrZt235LyEVKTEzk7rvvZuHChURFRRW57vr16yvdVEIlMWfOHAIDAwkLCyMiIoIuXbqwYMGC3Pb8H8acc9x22220b9+enTt38sknn9CpUyfq1atHdHQ0I0aMYOfOnbnb79+/n8suu4yYmBhiYmIYPXo0hw4dqvDzLMp9991Hp06dCAoKYurUqce1v/zyy8TFxREaGsqFF154zIev/fv3M2LECEJDQ4mLi+Pll1+uwMhFRKS6U8JdyRw6dIjzzz+f2267jf3797Nz506mTJlywkluWenWrRvvv/8+devW/U37iYqKYvLkyWRlZZVRZMWLjY1l6dKlNGzYsNB1fuu3ApVB3759SUlJ4cCBA9x8881cfvnlHDhw4Lj1nHPccMMNJCQksHTpUpo1a8Ypp5zC+++/z4EDB0hKSuLkk0/mpptuyt3m3nvv5ddff2Xr1q1s2bKFXbt2FZjU+lObNm14+OGHOe+8845rW79+PTfccAMvvvgiu3btom7dutx888257bfccgu1a9dm165dzJ07l5tuuon169dXZPgiIlIGjmZl+zuEAinhrmQ2btwIwKhRowgMDKROnToMHjyYzp07A5Cdnc306dOJi4ujYcOGXHnllRw8eLDAfbVs2ZIlS5bkvp86dSpjxozJfZ8zkl6vXj1iY2OZM2cOAFdddRX33ntv7npPP/00bdq0ISoqiuHDh5OUlJTbZmbMmjWLk08+mfr163PLLbdQ1NNLhwwZQu3atXnppZcKbB84cCDPPPNM7vs5c+YwYMCAY443c+ZMTj75ZMLDw7nvvvvYsmULffv2JSIigpEjR3LkyJHc9RcsWEDXrl2pV68e/fr1Y926dcdcnxkzZtC5c2dCQ0PJzMw85pplZWXx4IMP0rp1a8LDw+nRoweJiYkA3H777cTGxtKsWTN69OjBZ599Vug5p6WlcccddxAXF0dkZCQDBgwgLS0NgHfffZf4+Hjq1avHwIEDj5nTu2XLljzyyCN07tyZyMhILrvsshLNGx8QEMDYsWNJTU1l06ZNx7RlZWVx1VVXsWbNGhISEmjUqBEAjRo1omnTprnrBQYGsnnz5tz3P/74IxdeeCERERFERkYyYsSIEiekOX04adIk6tevT6tWrXjvvfdKtG1pjBs3jqFDhxY4TePcuXMZNmwYp512GmFhYUybNo0333yT5ORkUlNTeeONN5g2bRphYWEMGDCA4cOH8+KLL5Z5jCIiUn7WJh7grMeW8u3eyjeIVukefONPl/17xXHLzu/chLF9W5J2JIurnvviuPZLejTn0p6x7E89wk0vfXlMW1ZWFuP6n8SwLk1JOpBG03p1io2hbdu2BAYGMm7cOC6//HJOPfVU6tevn9s+Z84c5syZwyeffJKbcN96662lTg62b9/O0KFDeeqpp7jkkks4dOhQbjKZ18cff8xdd93FBx98QHx8PJMmTeLyyy/n008/zV1nwYIFrF69mkOHDtGjRw+GDRvGkCFDCjyumTFt2jQmTJjAFVdccUIzxSxevJgvv/ySxMREunfvzvLly5k7dy7R0dH07duXefPmMW7cOL766ivGjx/P/Pnz6dmzJy+99BLDhw9nw4YNud8YzJs3j4ULFxITE0NQ0LF/HR577DHmzZvHokWLaNu2LevWrcsd4e/VqxeTJ08mICCA2bNnc+mll7Jt2zZCQkKOi3fSpEmsX7+e5cuX07hxY1atWkVAQAAbN25k1KhRvP322wwcOJDHH3+cYcOG8d1331G7dm3Aq5tfvHgxISEh9O/fnzlz5nDjjTcWeX2ysrJ47rnnqFWrFnFxcce0jR49msTERD7++GPq1at3TNv27dvp3Lkzhw4dIjAwkKeffjq37ZZbbmHmzJmMGuXN6vnGG28wfPjwknQXAKtWrWLcuHHs3buXp556imuuuYadO3cW2P/nn38+y5YtK3A/AwYMOKZUpqTWr19Pv379ct+3bt2a2rVrs3HjRgICAggMDKRt27a57V26dGHp0qWlPo6IiPjHnM9/5IFF39MgLJiQwMo3C51GuCuZiIgIli1bhplx3XXX0aBBA4YPH86uXbsAb6Ru4sSJnHTSSYSFhfHQQw/xyiuvlLokYu7cuZx11lmMGjWKWrVqER0dTdeuXQtcb/z48XTv3p3g4GAeeughVqxYcUzN9Z/+9Cfq1atHixYtGDRoEN98802Rxx4+fDgNGjQ4ZiS7NP74xz8SERFBfHw8HTt2ZPDgwZx00klERkYydOhQvv76a8Abmb/hhhvo06dP7oeY4OBgVq5cmbuv3//+98TGxlKnzvEfhp555hmmT59Ou3btMDO6dOlCdHQ0AGPGjCE6OpqgoCDuuOMOMjIyCpybOTs7m9mzZ/PEE0/QrFkzAgMD6devH8HBwbz66qucd955nH322dSqVYtJkyaRlpbG8uXLj4mvadOmREVFMWzYsCKv7cqVK6lXrx4hISFMmjSJl1566bgymg8++ICRI0cel2wDtGjRggMHDrB3716mT59O+/btc9u6d+/OkSNHiI6OJjo6msDAwGNKMooTFxfHddddl9sPP//8c+7vdH4LFizgwIEDBb5OJNkGSElJITIy8phlkZGRJCcnF9kmIiJVw67kDE5v24BFt/+ONvUD/R3OcTTCncerN/QttK1O7cAi26NCax/XnvcphCUZ3c7RoUOH3PKOH374gTFjxjBhwgTmzZtHUlLSMaOWcXFxZGZmFpq8FCYxMZHWrVsXu15SUhLdu3fPfR8WFkZ0dDQ7d+6kZcuWADRu3Di3vW7duqSkpBS73+nTp3P11VczduzYUsUN5JZBANSpU+e497/88gsAP/30E88//zz/+Mc/ctuPHDlyTElMbGxsoccp6ho9+uijPPPMMyQlJWFmHDp0iL179x633t69e0lPTy9wP/n7MiAggNjY2GNuVsx/bfPGnt+pp57KsmXLSElJ4ZprruGzzz5j5MiRx6yzYMECzj//fOrXr8/48eML3E9UVBTjxo2jS5cu7Ny5k6CgIC699FK6dOnCO++8g3OOSZMmMWbMGF577bVC48kr/3kAJfo9KSthYWHH3eR56NAhwsPDCQgIKLRNREQqr6+2/0p2tqNnyygmDW5HgFXeZ6xohLuSa9++PVdddRXffvstAE2bNuWnn37Kbd++fTtBQUHHJJ05QkNDOXz4cO77nEQUvERzy5YtxR4///FSU1PZt28fzZo1O6HzyXH22WfTpk0bZs6cWeKYSys2NpZ77rnnmBHSw4cP55ZFQNF/MQu7Rp999hkzZszgtddeY/v27Rw4cIDIyMgCa9djYmIICQkpcD/5r61zjsTExN98bcPCwpg5cyYvvvhi7mh/jn79+jF//nxuv/32ImfiyMzMZPfu3bmJ6Nq1a7nhhhsIDQ0lLCyMG2+8kUWLFv2mOAszdOhQwsLCCnwNHTr0hPYZHx/P2rVrc99v3bqVjIwM2rZtS9u2bcnMzDym3n3t2rXEx8f/5nMREZGyl53t+PfSLYyctYIZi3/AOUdggFXaZBuUcFc6P/zwA48++ig7duwAvFHWefPmceqppwLezZSPP/44P/74IykpKdx9991cdtllx9UfA3Tt2pVXXnmFo0ePsmbNGv7zn//kto0ePZolS5bw2muvkZmZyb59+wosV7jiiit47rnn+Oabb8jIyODuu++mT58+uaPbv8UDDzzAww8/fFzMb775JocPH2bz5s08++yzJ7z/6667jlmzZrFq1Sqcc6SmprJw4cISlwpce+213HfffWzatAnnHOvWrWPfvn0kJycTFBREgwYNyMzM5P777y90iryAgADGjx/PxIkTSUpKIisrixUrVpCRkcHIkSNZuHAhH330EUePHuXRRx8lODj4mFrjExUdHc21117L/ffff1zb6aefzptvvsn111+f+zvx5ptvsmHDBrKzs9mzZw8TJ06kW7duudMo9urVi2eeeYa0tDTS0tJ46qmn6NKlS+4+Bw4cWGazlrz33nukpKQU+CrqZsujR4+Snp5OdnY2mZmZpKen586GM3r0aObPn89nn31GamoqkydP5qKLLiI8PJzQ0FAuuugiJk+eTGpqKp9//jnvvPPOCX37IiIi5WtPcgZXzVnNQ+/9wNmnNOKZcb0qdaKdQwl3JRMeHs6qVavo06cPoaGhnHrqqXTs2JFHH30UgPHjxzN27FhOO+00WrVqRUhIyDElE3lNmzaNLVu2UL9+faZMmcIVV1yR29aiRQsWLVrEo48+SlRUFF27dj1mBDDHmWeeybRp07j44otp0qQJW7Zs4ZVXXimTc+3fvz+9e/c+Ztkf/vAHateuTaNGjRg3bhyjR48+4f337NmTp59+mltvvZX69evTpk2b3FKdkpg4cSIjR45k8ODBREREcM0115CWlsY555zD0KFDadu2LfHx8YSEhBRZmvLII4/QqVMnevXqRVRUFH/84x/Jzs6mXbt2vPTSS9x2223ExMQwf/585s+fn3vD5G81YcIEFi1adMzMLDnOPvtsXn31Va666irmz5/Pzp07GTJkCOHh4XTq1ImAgADeeuut3PVnz57Ntm3baN68Oc2aNWPr1q3HXMvExET69+9fJnGfqOuuu446deowb948HnjgAerUqZN7M3F8fDyzZs1i9OjRNGzYkOTk5GO+XZk5cyZpaWk0bNiQUaNG8eSTT2qEW0Skkkncf5ihT3zGqq37mH5hR2aO7k5knVr+DqtErKgp3KqDnj17ujVr1hy3/Pvvv6dDhw7leuy8NdxSPamPYceOHVx66aWsWHH8LD/VRf5+roh/P6TiJSQkVMkHX0nJqY+rtuxsx/0LvmNU7xa0a1z4/73+7Gcz+9I51zP/co1wi8hv0rx582qdbIuIiP8k7j/MVc99wc4DaQQEGFOHxxeZbFdWmqVERERERCqdd77Zyb1veZNG/LgnlWalmPGtslHCLSIiIiKVRkpGJpPf+ZY3v9pJ9xb1eOLybsRG1fV3WL+JEm4RERERqTSeWLKRt7/eye1nnsxtZ7QhKLDqV0Ar4RYRERERv8rKduxPPUKD8GB+f+bJDOnYmB5xUf4Oq8xU/Y8MIiIiIlJlJR1IY/QzKxn77CqOZGYTHlKrWiXboBFuEREREfGT+WuTuOet/5KV7ZgyPJ5agZX/ITYnQgm3iIiIiFSo1IxM7nv7W978eifdWtTjb5d1JS461N9hlRuVlNRwc+bMYcCAAbnvw8LC2Lp1a5HbbN++nbCwsNzHZudIS0ujf//+LF68uFxizS8+Pp6EhIRi1yvJOQFs27YNMyMzM7MMohMREZHCBAUam/ekcPuZJ/P6DX2rdbINSrgrrZdffpmePXsSFhZGkyZNGDp0KMuWLSv346akpHDSSScVuU6LFi1ISUkhMDDwmOU33HADkyZNYsiQISd8fDNj8+bNJVp3/fr1JXqSVEnOSURERMrX0axsZi3dwsG0owQHBfLGTf34w9ltq8UsJMWp/mdYHubOhZYtISDA+3Pu3DLd/WOPPcaECRO4++672bVrF9u3b+fmm2/mnXfeKdPjlLUXXniBESNG+DsMERERqaFjVmgAACAASURBVGQ2707hopnL+ct7P7Bw3c8A1KoBiXaOmnOmZWXuXLj+evjpJ3DO+/P668ss6T548CCTJ0/mX//6FxdddBGhoaHUqlWLYcOG8de//hWAjIwMJkyYQNOmTWnatCkTJkwgIyMDgISEBJo3b86jjz5Kw4YNadKkCc8991zu/vft28fw4cOJiIigd+/ebNmy5Zjj5x1hTktL44477iAuLo7IyEgGDBhAWlracaUXSUlJDB8+nKioKNq0acPTTz+du7+pU6cycuRIrrzySsLDw4mPj2fNmjUluhbFbduyZUuWLFkCQFZWFg8++CCtW7cmPDycHj16kJiYeNw5LVy4kG7duhEREUFsbCxTp04tcd+IiIhI6TjneH75Ns77+2fs+PUwT47uzhV9Wvg7rAqnhLu07rkHDh8+dtnhw97yMrBixQrS09OLHCl+4IEHWLlyJd988w1r167liy++YPr06bntv/zyCwcPHmTnzp08++yz3HLLLfz6668A3HLLLYSEhPDzzz8ze/ZsZs+eXehxJk2axJdffsny5cvZv38/Dz/8MAEBx//KjBo1iubNm5OUlMR//vMf7r77bj766KPc9nfffZfLL7+cAwcOMHz4cG699dYSX4+SbvvYY48xb948Fi1axKFDh5g9ezZ16x7/VKrQ0FBeeOEFDhw4wMKFC3nyySd5++23SxyPiIiIlNxjH25kyrvr6ds6mvcnnMbQTk38HZJfKOEure3bS7e8lPbt20dMTAxBQYVPIDN37lwmT55Mw4YNadCgAVOmTOHFF1/Mba9VqxaTJ0+mVq1anHvuuYSFhbFhwwaysrJ44403uP/++wkNDaVjx46MGzeuwGNkZ2cze/ZsnnjiCZo1a0ZgYCD9+vUjODj4mPUSExNZtmwZM2bMICQkhK5du3LttdceE8+AAQM499xzCQwMZOzYsaxdu7bE16Ok2z7zzDNMnz6ddu3aYWZ06dKF6Ojo49YbOHAgnTp1IiAggM6dOzNq1CiWLl1a4nhERESkeOlHvYkVrujTggdGdOS5q3rRMCLEz1H5jxLu0mpRyNcghS0vpejoaPbu3VvkTBlJSUnExcXlvo+LiyMpKemYfeRN2OvWrUtKSgp79uwhMzOT2NjYY7YtyN69e0lPT6d169ZFxpuUlERUVBTh4eHH7HPnzp257xs3bnxMLOnp6SWeCaSk2yYmJhYbK8CqVasYNGgQDRo0IDIyklmzZrF3794SxSIiIiJFO3j4KLe/8jXXvbCG7GxHk8g6jO4Th1n1nF+7pJRwl9YDD0D+UoW6db3lZaBv376EhIQUWebQtGlTfvrpp9z327dvp2nTpsXuu0GDBgQFBeXWNudsW5CYmBhCQkKOq/EuKJb9+/eTnJx8zD6bNWtWbDxlKTY2tthYAa644gqGDx9OYmIiBw8e5MYbb8Q5VwERioiIVG9LN+5h8N+WsnDdz/SMi0L/u/6PEu7SGj0annoK4uLAzPvzqae85WUgMjKS+++/n1tuuYW3336bw4cPc/ToUd577z3uvPNOwKuZnj59Onv27GHv3r3cf//9jBkzpth9BwYGctFFFzF16lQOHz7Md999x/PPP1/gugEBAYwfP56JEyeSlJREVlYWK1asyL05M0dsbCz9+vXjrrvuIj09nXXr1vHss88yuoyuR0lde+213HfffWzatAnnHOvWrWPfvn3HrZecnExUVBQhISF88cUXvPzyyxUap4iISHVz+Egm97z1X8bN/oKIkFq8dXN/bj/rZAIDavaodl560uSJGD26zBLsgkycOJFGjRoxffp0Ro8enTvrxj2+GzPvvfdeDh06ROfOnQG49NJLuffee0u073/+859cffXVNG7cmPbt23P11VfzySefFLjuI488wl133UWvXr1ISUmhS5cuvP/++8etN2/ePG688UaaNm1K/fr1+fOf/8zZZ599gmd/YiZOnEhGRgaDBw9m7969tG/fnrfeeuu49WbOnMkdd9zBrbfeyumnn87IkSM5cOBAhcYqIiJSnWRmOxI27OG637XijsHtCKkVWPxGNYxV96/Te/bs6Qqahu77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\n", 241 | "text/plain": [ 242 | "
" 243 | ] 244 | }, 245 | "metadata": { 246 | "needs_background": "light" 247 | }, 248 | "output_type": "display_data" 249 | } 250 | ], 251 | "source": [ 252 | "import numpy as np\n", 253 | "import matplotlib.pyplot as plt\n", 254 | "f = lambda t,x: np.tan(x)+1\n", 255 | "x0=1\n", 256 | "t0=1\n", 257 | "tf=1.1\n", 258 | "n=100\n", 259 | "t,x=RK38(f,x0,t0,tf,n)\n", 260 | "plt.figure(figsize=(12,6))\n", 261 | "plt.plot(t,x,'--',label=\"Solución Numérica con RK38, n = \"+str(n))\n", 262 | "plt.plot(t[0],x[0],'ro', label=\"Condición Inicial\")\n", 263 | "plt.xlabel(\"Tiempo (t)\",fontsize=15)\n", 264 | "plt.ylabel(\"Solución Numérica de x(t)\",fontsize=15)\n", 265 | "plt.title(\"Método de Runge-Kutta (RK4)\",fontsize=15)\n", 266 | "plt.legend(fontsize=12)\n", 267 | "plt.grid()\n", 268 | "plt.show()" 269 | ] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": {}, 274 | "source": [ 275 | "Ahora tenemos **muchos métodos numéricos a nuestra disposición** para resolver muchas ecuaciones diferenciales.\n", 276 | "\n", 277 | "¡Buenas noticias!" 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": {}, 283 | "source": [ 284 | "### Tarea" 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "metadata": {}, 290 | "source": [ 291 | "Construya y programe los siguientes métodos numéricos usando la Tabla del Carnicero correspondiente:\n", 292 | "\n", 293 | "- Heun.\n", 294 | "- Punto Medio.\n", 295 | "- Ralston.\n", 296 | "- Dormand-Prince (Opcional).\n", 297 | "\n", 298 | "Una todas esas definiciones y los métodos ya construídos (Euler, RK4, RK38) en un módulo llamado ```Solver_EDO```.\n", 299 | "\n", 300 | "Resuelva las siguientes ecuaciones, usando cada método numérico en el módulo creado y comparando los errores correspondientes.\n", 301 | "\n", 302 | "1.\n", 303 | "$$\\frac{dP}{dt}=kP,\\text{ }P(0)=2,\\text{ en }T=[0,100]$$\n", 304 | "2.\n", 305 | "$$\\frac{dP}{dt}=kP\\biggl(1-\\frac{P}{S}\\biggr),\\text{ }P(0)=2,\\text{ en }T=[0,100],\\text{ }S=100000$$\n", 306 | "3.\n", 307 | "$$\\frac{dv}{dt}=g-\\frac{c_d}{m}v^{2},\\text{ }v(0)=-3,\\text{ en }T=[0,30]$$\n", 308 | "4.\n", 309 | "$$\\frac{dx}{dt}=e^{-t^2}\\sinh(x), \\text{ }x(-5)=0$$\n", 310 | "5.\n", 311 | "$$\\frac{dx}{dt}=\\tanh(xt)+\\ln(t^2)e^{-x^2}, \\text{ }x(-1)=2$$\n", 312 | "\n", 313 | "Decida cuál es el método numérico más apropiado para cada ecuación." 314 | ] 315 | } 316 | ], 317 | "metadata": { 318 | "kernelspec": { 319 | "display_name": "Python 3", 320 | "language": "python", 321 | "name": "python3" 322 | }, 323 | "language_info": { 324 | "codemirror_mode": { 325 | "name": "ipython", 326 | "version": 3 327 | }, 328 | "file_extension": ".py", 329 | "mimetype": "text/x-python", 330 | "name": "python", 331 | "nbconvert_exporter": "python", 332 | "pygments_lexer": "ipython3", 333 | "version": "3.7.7" 334 | } 335 | }, 336 | "nbformat": 4, 337 | "nbformat_minor": 4 338 | } 339 | --------------------------------------------------------------------------------