├── 01_AritmeticaPuntoFlotante ├── test ├── PF.py ├── 02_MetodoEstableEstudiante.ipynb └── PreAritmeticaFlotanteEstudiante.ipynb ├── README.md ├── 02_ResolucionDeSistemasLineales ├── PostClase_NormasVectoriales.ipynb ├── Cholesky.ipynb ├── Substituciones.ipynb ├── Estabilidad.ipynb └── NumeroCondicion.ipynb ├── 00_Introduccion └── DecToBinaryToDec.ipynb ├── 06_EcuacionesNoLineales └── 02_SistemasNoLineales.ipynb └── 03_Interpolacion └── SeriesDeTaylor_aplicaciones.ipynb /01_AritmeticaPuntoFlotante/test: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AnalisisNumerico 2 | Repositorio para el curso de análisis numérico. 3 | -------------------------------------------------------------------------------- /01_AritmeticaPuntoFlotante/PF.py: -------------------------------------------------------------------------------- 1 | from math import trunc 2 | import numpy as np 3 | from math import log10, floor 4 | 5 | def truncar(x,t): 6 | if x==0: 7 | fl=0 8 | else: 9 | e=trunc(np.log10(abs(x))) 10 | if np.log10(abs(x))>0: 11 | e=e+1 12 | fl=trunc(x*10**(t-e))*10**(e-t) 13 | return fl 14 | 15 | def rdnd(x, t): 16 | 17 | return round(x, t-int(floor(log10(abs(x))))-1) 18 | 19 | 20 | # Python3 program to convert fractional 21 | # decimal to binary number 22 | 23 | # Function to convert decimal to binary 24 | # upto k-precision after decimal point 25 | def decimalToBinary(num, k_prec) : 26 | 27 | binary = "" 28 | 29 | # Fetch the integral part of 30 | # decimal number 31 | Integral = int(num) 32 | 33 | # Fetch the fractional part 34 | # decimal number 35 | fractional = num - Integral 36 | 37 | # Conversion of integral part to 38 | # binary equivalent 39 | while (Integral) : 40 | 41 | rem = Integral % 2 42 | 43 | # Append 0 in binary 44 | binary += str(rem); 45 | 46 | Integral //= 2 47 | 48 | # Reverse string to get original 49 | # binary equivalent 50 | binary = binary[ : : -1] 51 | 52 | # Append point before conversion 53 | # of fractional part 54 | binary += '.' 55 | 56 | # Conversion of fractional part 57 | # to binary equivalent 58 | while (k_prec) : 59 | 60 | # Find next bit in fraction 61 | fractional *= 2 62 | fract_bit = int(fractional) 63 | 64 | if (fract_bit == 1) : 65 | 66 | fractional -= fract_bit 67 | binary += '1' 68 | 69 | else : 70 | binary += '0' 71 | 72 | 73 | k_prec -= 1 74 | 75 | return binary 76 | 77 | 78 | -------------------------------------------------------------------------------- /02_ResolucionDeSistemasLineales/PostClase_NormasVectoriales.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "view-in-github", 7 | "colab_type": "text" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "id": "7d38fc4b", 16 | "metadata": { 17 | "deletable": false, 18 | "editable": false, 19 | "nbgrader": { 20 | "cell_type": "markdown", 21 | "checksum": "a48066b425bb0f353b5e99b5b7734df8", 22 | "grade": false, 23 | "grade_id": "cell-e6b4757d31fefa8a", 24 | "locked": true, 25 | "schema_version": 3, 26 | "solution": false, 27 | "task": false 28 | }, 29 | "id": "7d38fc4b" 30 | }, 31 | "source": [ 32 | "# Normas Vectoriales y Matriciales\n", 33 | "\n", 34 | "## Notebook post-clase\n", 35 | "\n", 36 | "---" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "id": "5f3db96e", 42 | "metadata": { 43 | "deletable": false, 44 | "editable": false, 45 | "nbgrader": { 46 | "cell_type": "markdown", 47 | "checksum": "f617899a32ba7335ea2da55f051014ee", 48 | "grade": false, 49 | "grade_id": "cell-17d5ee032f68cc4b", 50 | "locked": true, 51 | "schema_version": 3, 52 | "solution": false, 53 | "task": false 54 | }, 55 | "id": "5f3db96e" 56 | }, 57 | "source": [ 58 | "## Recapitulación\n", 59 | "\n", 60 | "### Normas vectoriales\n", 61 | "\n", 62 | "Sea $p \\geq 1$, las normas de Hölder, o *normas-p* están definidas por:\n", 63 | "\n", 64 | "$$\n", 65 | "\\left\\Vert\\vec{x}\\right\\Vert_{p}=\\left[\\sum_{i=1}^{n}\\left|x_{i}\\right|^{p}\\right]^{1/p} \\qquad \\text{para}\\,1\\leq p<\\infty\n", 66 | "$$\n", 67 | "\n", 68 | "Los casos más importantes de está norma son:\n", 69 | "\n", 70 | "* Norma-1 ($p = 1$):\n", 71 | "\n", 72 | "$$\n", 73 | "\\left\\Vert \\vec{x}\\right\\Vert _{1}=\\sum_{i=1}^{n}\\left|x_{i}\\right|\n", 74 | "$$\n", 75 | "\n", 76 | "* Norma-2 o norma euclideana ($p = 2$)\n", 77 | "\n", 78 | "$$\n", 79 | "\\left\\Vert\\vec{x}\\right\\Vert_{2}=\\left[\\sum_{i=1}^{n}\\left|x_{i}\\right|^{2}\\right]^{1/2}\n", 80 | "$$\n", 81 | "\n", 82 | "* Y la norma-$\\infty$ o norma del supremo ($p = \\infty$)\n", 83 | "\n", 84 | "$$\n", 85 | "\\lim_{p \\rightarrow \\infty} \\left\\Vert \\vec{x}\\right\\Vert _{p} = \\left\\Vert \\vec{x}\\right\\Vert _{\\infty}= \\max_{1 \\leq i \\leq n} \\left| x_i \\right|\n", 86 | "$$\n", 87 | "\n", 88 | "### Normas matriciales\n", 89 | "\n", 90 | "Sea $p\\geq1,\\:\\vec{x}\\in\\mathbb{R}^{n}$, la p-norma de una matriz $\\mathbf{A}\\in \\mathbf{M}_{n\\times n}$ esta definida por.\n", 91 | "\n", 92 | "$$\n", 93 | "\\left\\Vert \\mathbf{A}\\right\\Vert _{p} = \\sup_{\\vec{x}\\neq\\vec{0}}\\frac{\\left\\Vert A\\vec{x}\\right\\Vert _{p}}{\\left\\Vert \\vec{x}\\right\\Vert _{p}}\n", 94 | "$$\n", 95 | "\n", 96 | "* Norma matricial inducida por la norma-1 vectorial ($p = 1$).\n", 97 | "\n", 98 | "$$\n", 99 | "\\left\\Vert \\mathbf{A}\\right\\Vert _{1}\\ = \\sup_{\\vec{x}\\neq\\vec{0}}\\frac{\\left\\Vert A\\vec{x}\\right\\Vert _{1}}{\\left\\Vert\\vec{x}\\right\\Vert _{1}} = \\max_{1\\leq j\\leq n}\\sum_{i=1}^{n}\\left|a_{ij}\\right| = \\max_{1\\leq j\\leq n}\\left\\Vert \\vec{a}_{j}\\right\\Vert _{1} \\quad \\text{suma de columnas}\n", 100 | "$$\n", 101 | "\n", 102 | "* Norma matricial inducida por la norma del supremo ($p = \\infty$).\n", 103 | "\n", 104 | "$$\n", 105 | "\\left\\Vert \\mathbf{A}\\right\\Vert _{\\infty} = \\sup_{\\vec{x}\\neq\\vec{0}}\\frac{\\left\\Vert A\\vec{x}\\right\\Vert _{\\infty}}{\\left\\Vert \\vec{x}\\right\\Vert _{\\infty}} = \\max_{1\\leq i\\leq n}\\sum_{j=1}^{n}\\left|a_{ij}\\right| = \\max_{1\\leq i\\leq n}\\left\\Vert \\vec{a}_{i}\\right\\Vert _{1} \\quad \\text{suma de renglones}\n", 106 | "$$\n", 107 | "\n", 108 | "* El caso particular de $p=2$ es conocido como norma euclidiana:\n", 109 | "$$\\left\\Vert \\mathbf{A}\\right\\Vert _{2}=\\sqrt{\\max{\\text{eig}(\\mathbf{A}^{T}\\mathbf{A})}}$$\n", 110 | "\n", 111 | "* Además de estas, existe la norma de Frobenius:\n", 112 | "\n", 113 | "$$\n", 114 | "\\left\\Vert \\mathbf{A} \\right\\Vert_{F} = \\sqrt{\\sum_{i = 1}^{m} \\sum_{j = 1}^{n} |a_{ij}^2|} = \\sqrt{\\text{tr}\\,\\left(\\mathbf{A}^{*}\\mathbf{A}\\right)} = \\sqrt{\\sum_{i = 1}^{\\min{m, n}} \\sigma_{i}^2}\n", 115 | "$$\n", 116 | "\n", 117 | "donde $\\mathbf{A^{*}}$ es la traspuesta conjugada y $\\sigma_{i}$ son los valores singulares de $\\mathbf{A}$" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "id": "73f53148", 123 | "metadata": { 124 | "deletable": false, 125 | "editable": false, 126 | "nbgrader": { 127 | "cell_type": "markdown", 128 | "checksum": "32b1e4a63dde7790968acc9600320ed5", 129 | "grade": false, 130 | "grade_id": "cell-7f1d0b87a5928780", 131 | "locked": true, 132 | "schema_version": 3, 133 | "solution": false, 134 | "task": false 135 | }, 136 | "id": "73f53148" 137 | }, 138 | "source": [ 139 | "## Proyecto de tema\n", 140 | "\n", 141 | "Hasta ahora, se ha trabajado de manera sencilla y práctica el manejo de la norma para las matrices. A manera de cimentar tus conocimientos y desarrollar tu pensamiento computacional, la tarea a elaborar esta ocasión es la siguiente:\n", 142 | "\n", 143 | "Escribir la función ```normMat```, la cual recibe como parámetro una matriz de $n \\times n$. Dicha función debe calcular la norma-2 para matrices siguiendo el ejemplo 2 del notebook de clase o siguiendo alguno de los métodos que se presentan en dicho notebook. Recuerda evaluar las condiciones necesarias para llevar a cabo este cálculo.\n", 144 | "\n", 145 | "**NOTA**: Está permitido el uso del módulo ```numpy``` para el la manipulación de arreglo/matrices. No está permitido el uso de las funciones ```np.linalg.norm()``` y ```np.linalg.eigvals```. El cálculo de los eigenvalores debe ser explícito en la función." 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": null, 151 | "id": "b207e4e6", 152 | "metadata": { 153 | "deletable": false, 154 | "nbgrader": { 155 | "cell_type": "code", 156 | "checksum": "a53183a8a63399e4dbcfcfea3c1c9684", 157 | "grade": false, 158 | "grade_id": "cell-51dcbfcf368e0cfd", 159 | "locked": false, 160 | "schema_version": 3, 161 | "solution": true, 162 | "task": false 163 | }, 164 | "id": "b207e4e6" 165 | }, 166 | "outputs": [], 167 | "source": [ 168 | "import numpy as np\n", 169 | "\n", 170 | "def normMat(matriz):\n", 171 | " \n", 172 | " # YOUR CODE HERE\n", 173 | " raise NotImplementedError()\n", 174 | " \n", 175 | " return norma" 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": null, 181 | "id": "8ce8f01d", 182 | "metadata": { 183 | "deletable": false, 184 | "editable": false, 185 | "nbgrader": { 186 | "cell_type": "code", 187 | "checksum": "84208055f076a93d6f4e413ea440b4e4", 188 | "grade": true, 189 | "grade_id": "cell-c21d43e621e9f322", 190 | "locked": true, 191 | "points": 100, 192 | "schema_version": 3, 193 | "solution": false, 194 | "task": false 195 | }, 196 | "id": "8ce8f01d" 197 | }, 198 | "outputs": [], 199 | "source": [ 200 | "\"\"\"Prueba: Evaluación de la función normMat\"\"\"\n", 201 | "from numpy.testing import assert_approx_equal\n", 202 | "from numpy.linalg import norm\n", 203 | "\n", 204 | "# Norma-2 de matrices\n", 205 | "# Casos válidos\n", 206 | "assert_approx_equal(normMat(np.array([[2, 5], [1, 3]])), norm(np.array([[2, 5], [1, 3]])), 2)\n", 207 | "print(\"Norma-2 de la matriz\\n\", np.array([[2, 5], [1, 3]]), \"\\nes:\", normMat(np.array([[2, 5], [1, 3]])), \"\\n\")\n", 208 | "\n", 209 | "assert_approx_equal(normMat(np.array([[3, 7, 10], [20, 40, 10], [4, 5, 2]])), norm(np.array([[3, 7, 10], [20, 40, 10], [4, 5, 2]])), 2)\n", 210 | "print(\"Norma-2 de la matriz\\n\", np.array([[3, 7, 10], [20, 40, 10], [4, 5, 2]]), \"\\nes:\", \n", 211 | " normMat(np.array([[3, 7, 10], [20, 40, 10], [4, 5, 2]])), \"\\n\")\n", 212 | "\n", 213 | "assert_approx_equal(normMat(np.array([[0, 1, 2, -1], [1, -1, -3, 1], [4, 0, 0, 1], [2, 3, 8, -2]])), \n", 214 | " norm(np.array([[0, 1, 2, -1], [1, -1, -3, 1], [4, 0, 0, 1], [2, 3, 8, -2]])), 2)\n", 215 | "print(\"Norma-2 de la matriz\\n\", np.array([[0, 1, 2, -1], [1, -1, -3, 1], [4, 0, 0, 1], [2, 3, 8, -2]]), \"\\nes:\", \n", 216 | " normMat(np.array([[0, 1, 2, -1], [1, -1, -3, 1], [4, 0, 0, 1], [2, 3, 8, -2]])), \"\\n\")" 217 | ] 218 | } 219 | ], 220 | "metadata": { 221 | "kernelspec": { 222 | "display_name": "Python 3 (ipykernel)", 223 | "language": "python", 224 | "name": "python3" 225 | }, 226 | "language_info": { 227 | "codemirror_mode": { 228 | "name": "ipython", 229 | "version": 3 230 | }, 231 | "file_extension": ".py", 232 | "mimetype": "text/x-python", 233 | "name": "python", 234 | "nbconvert_exporter": "python", 235 | "pygments_lexer": "ipython3", 236 | "version": "3.8.12" 237 | }, 238 | "colab": { 239 | "name": "PostClase_NormasVectorialesYMatriciales_Alumno.ipynb", 240 | "provenance": [], 241 | "toc_visible": true, 242 | "include_colab_link": true 243 | } 244 | }, 245 | "nbformat": 4, 246 | "nbformat_minor": 5 247 | } -------------------------------------------------------------------------------- /02_ResolucionDeSistemasLineales/Cholesky.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Cholesky.ipynb", 7 | "provenance": [], 8 | "toc_visible": true, 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "name": "python3", 13 | "display_name": "Python 3" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "id": "view-in-github", 21 | "colab_type": "text" 22 | }, 23 | "source": [ 24 | "\"Open" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": { 30 | "id": "u0LEt1hen0wM" 31 | }, 32 | "source": [ 33 | "\n", 34 | "

Cholesky

\n", 35 | "
\n", 36 | " \n", 37 | "
Profesora: \tUrsula Xiomara Iturrarán Viveros
\n", 38 | "
Ayudante: Juan Pablo Cordero Santiago
\n", 39 | "
Materia: Análisis Numérico
\n", 40 | "
" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": { 46 | "id": "UF5p3sW3oXXs" 47 | }, 48 | "source": [ 49 | "# Introducción\n", 50 | "\n", 51 | "Así como se puede realizar la factorización de una matriz mediante $LU$ o $QR$, otra forma de factorizar una matriz $A\\in M_{n\\times n}$ sobre $\\mathbb{R}$ es mediante la factorización de Cholesky.\n", 52 | "\n", 53 | "Igual que en el caso de la factorización $QR$, un prerrequisito para poder emplear el método de Cholesky es que la matriz $A$ sea **simétrica y positiva definida**. Existen diferentes definiciones para que una matriz cumpla con ser positiva definida (todas ellas equivalentes).\n", 54 | "\n", 55 | "Una matriz $A\\in M_{n\\times n}$ sobre $\\mathbb{R}$\n", 56 | "1. Es simétrica si: $A=A^{T}$\n", 57 | "2. Es positiva definida si todos sus determinantes superiores izquierdos de $i\\times i\\quad i=1,\\ldots,n$ son positivos." 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": { 63 | "id": "5Sshr1SyvYb9" 64 | }, 65 | "source": [ 66 | "## Teorema\n", 67 | "\n", 68 | "El matemático **André-Louis Cholesky**, planteó el siguiente teorema:\n", 69 | "\n", 70 | "Sea $A\\in M_{n\\times n}$ sobre $\\mathbb{R}$ una matriz simétrica definida positiva puede ser descompuesta como el producto de una matriz triangular inferior $L$ y la traspuesta de la matriz triangular $L^{T}$ inferior, es decir.\n", 71 | "\n", 72 | "$$A=LL^{T}$$" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": { 78 | "id": "AauzTvcOwkfq" 79 | }, 80 | "source": [ 81 | "# Método de Cholesky\n", 82 | "El método de Cholesky para matrices $A\\in M_{n\\times n}$ sobre $\\mathbb{R}$ que cumplan con los requisitos, se puede reducir a 3 sencillos pasos:\n", 83 | "\n", 84 | "\n", 85 | "1. A patir de la matriz $A$ calcular la matríz $L$.\n", 86 | "2. Transponer la matríz $L$.\n", 87 | "3. Comprobar que $LL^{T}=A$.\n", 88 | "\n", 89 | "Para calcular la matríz $L$ empleamos las siguientes fórmulas:\n", 90 | "\n", 91 | "La primer fórmula es empleada para calcular las entradas de $L$ debajo de la diagonal.\n", 92 | "\n", 93 | "$$l_{ki}=\\frac{a_{ki}-\\displaystyle\\sum_{j=0}^{i-1}l_{ij}l_{kj}}{l_{ii}}\\quad i\"Open" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "id": "v9Lg54U9F9Wo" 33 | }, 34 | "source": [ 35 | "\n", 36 | "

Substituciones

\n", 37 | "
\n", 38 | " \n", 39 | "
Profesora: \tUrsula Xiomara Iturrarán Viveros
\n", 40 | "
Ayudante: Juan Pablo Cordero Santiago
\n", 41 | "
Materia: Análisis Numérico
\n", 42 | "
" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": { 48 | "id": "NRd3lPDrGH3r" 49 | }, 50 | "source": [ 51 | "## Introducción\n", 52 | "\n", 53 | "Gran parte de las factorizaciones empleadas para evitar el cálculo de la matriz inversa (si no es que todas) hacen uso de la substitución hacia adelante y substitución hacia atrás.\n", 54 | "\n", 55 | "Es por eso que realizar un análisis detallado del mismo es muy buena idea, antes de continuar." 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": { 61 | "id": "09GNFtNsMWEu" 62 | }, 63 | "source": [ 64 | "# Substituciones (hacia adelante, hacia atras)\n", 65 | "\n", 66 | "Una vez que ya se tiene una matriz triangular (superior o inferior) es muy sencillo resolver un sistema de ecuaciones empleando alguna de estas substituciones.\n", 67 | "\n", 68 | "La idea general es que dado un sistema del tipo $A\\vec{x}=\\vec{b}$, la matriz $A\\in M_{n\\times n}$ puede ser factorizada empleando alguno de los métodos previamente mencionados *(LU, QR, Cholesky)* y una vez que se tenga alguna de estas factorizaciones es posible emplear algun tipo de subtitución para resolver el sistema original." 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": { 74 | "id": "ydYY5dOGYoU-" 75 | }, 76 | "source": [ 77 | "## Substitución hacia adelante\n", 78 | "\n", 79 | "Supongamos que se tiene una matríz triangular inferior $L\\in M_{n\\times n}$ sobre $\\mathbb{R}$ y los correspondientes vectores, $\\vec{y},\\vec{b}\\in\\mathbb{R}^{n}$ podemos pensar en resolver el sistema:\n", 80 | "\n", 81 | "$$L\\vec{y}=\\vec{b}$$\n", 82 | "\n", 83 | "Para resolver dicho sistema empleamos el siguiente algoritmo de substitución:\n", 84 | "\n", 85 | "$$y_{i}=\\frac{b_{i}-\\displaystyle\\sum_{j=0}^{i-1}l_{ij}y_{j}}{l_{ii}}\\quad i=0,\\ldots,(n-1)$$" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": { 91 | "id": "xiTTv4n5HiwY" 92 | }, 93 | "source": [ 94 | "### Ejemplo\n", 95 | "\n", 96 | "$$\\left(\\begin{array}{ccc}\n", 97 | "1 & 0 & 0\\\\\n", 98 | "-2 & 1 & 0\\\\\n", 99 | "-1 & 3 & 1\n", 100 | "\\end{array}\\right)\\left(\\begin{array}{c}\n", 101 | "y_{0}\\\\\n", 102 | "y_{1}\\\\\n", 103 | "y_{2}\n", 104 | "\\end{array}\\right)=\\left(\\begin{array}{c}\n", 105 | "5\\\\\n", 106 | "6\\\\\n", 107 | "1\n", 108 | "\\end{array}\\right)$$\n", 109 | "\n", 110 | "Encontrar la primera entada del vector $\\vec{y}$ es trivial\n", 111 | "\n", 112 | "$$y_{0}=5$$\n", 113 | "\n", 114 | "La siguiente entrada involucra a $y_{0}$, es decir:\n", 115 | "\n", 116 | "$$y_{1}=\\frac{6-\\left(\\left(-2\\right)\\left(y_{0}\\right)\\right)}{l_{11}}=\\frac{6-\\left(\\left(-2\\right)\\left(5\\right)\\right)}{1}=16$$\n", 117 | "\n", 118 | "Finalmente, la última entrada de $\\vec{y}$ se calcula empleando $y_{1}$ y $y_{0}$:\n", 119 | "\n", 120 | "$$y_{2}=\\frac{1-\\left(\\left(-1\\right)\\left(y_{0}\\right)+\\left(3\\right)\\left(y_{1}\\right)\\right)}{l_{22}}=\\frac{1-\\left(\\left(-1\\right)\\left(5\\right)+\\left(3\\right)\\left(16\\right)\\right)}{1}=-42$$\n", 121 | "\n", 122 | "Empleando **substitución hacia adelante** se tiene que:\n", 123 | "\n", 124 | "$$\\vec{y}=\\left(\\begin{array}{c}\n", 125 | "5\\\\\n", 126 | "16\\\\\n", 127 | "-42\n", 128 | "\\end{array}\\right)$$" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": { 134 | "id": "yEXaRqlETprP" 135 | }, 136 | "source": [ 137 | "## Substitución hacia atras\n", 138 | "\n", 139 | "Supongamos que se tiene una matríz triangular superior $U \\in M_{n\\times n}$ sobre $\\mathbb{R}$ y los correspondientes vectores, $\\vec{x},\\vec{y}\\in\\mathbb{R}^{n}$ podemos pensar en resolver el sistema. \n", 140 | "\n", 141 | "$$U\\vec{x}=\\vec{y}$$\n", 142 | "\n", 143 | "Para resolver dicho sistema empleamos el siguiente algoritmo de substitución.\n", 144 | "\n", 145 | "$$x_{i}=\\frac{y_{i}-\\displaystyle\\sum_{j=i+1}^{n-1}u_{ij}x_{j}}{u_{ii}}\\quad i=(n-1),\\ldots,0$$" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": { 151 | "id": "EqgNgNelJNr_" 152 | }, 153 | "source": [ 154 | "### Ejemplo\n", 155 | "\n", 156 | "$$\n", 157 | "\\left(\\begin{array}{ccc}\n", 158 | "-4 & -3 & 1\\\\\n", 159 | "0 & 5 & 1\\\\\n", 160 | "0 & 0 & 3\n", 161 | "\\end{array}\\right)\\left(\\begin{array}{c}\n", 162 | "x_{0}\\\\\n", 163 | "x_{1}\\\\\n", 164 | "x_{2}\n", 165 | "\\end{array}\\right)=\\left(\\begin{array}{c}\n", 166 | "5\\\\\n", 167 | "16\\\\\n", 168 | "-42\n", 169 | "\\end{array}\\right)\n", 170 | "$$\n", 171 | "\n", 172 | "Encontrar la última entada del vector $\\vec{x}$ es trivial\n", 173 | "\n", 174 | "$$x_{2}=\\frac{-42}{u_{22}}=\\frac{-42}{3}=-14$$\n", 175 | "\n", 176 | "La siguiente entrada involucra a $x_{2}$, es decir:\n", 177 | "\n", 178 | "$$x_{1}=\\frac{16-\\left(\\left(1\\right)\\left(x_{2}\\right)\\right)}{u_{11}}=\\frac{16-\\left(\\left(1\\right)\\left(-14\\right)\\right)}{5}=6$$\n", 179 | "\n", 180 | "Finalmente la primer entrada de $x$ se calcula empleando $x_{2}$ y $x_{1}$:\n", 181 | "\n", 182 | "$$x_{0}=\\frac{5-\\left(\\left(1\\right)\\left(x_{2}\\right)+\\left(-3\\right)\\left(x_{1}\\right)\\right)}{u_{00}}=\\frac{5-\\left(\\left(1\\right)\\left(-14\\right)+\\left(-3\\right)\\left(6\\right)\\right)}{-4}=-9.25$$\n", 183 | "\n", 184 | "Por último, mediante **substitución hacia atras** se tiene que:\n", 185 | "\n", 186 | "$$\\vec{x}=\\left(\\begin{array}{c}\n", 187 | "-9.25\\\\\n", 188 | "6\\\\\n", 189 | "-14\n", 190 | "\\end{array}\\right)$$\n", 191 | "\n", 192 | "En python ambos algoritmos lucen así:" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "metadata": { 198 | "id": "Ln6srzOGQBiC" 199 | }, 200 | "source": [ 201 | "import numpy as np\n", 202 | "\n", 203 | "# algoritmo para sustitucion hacia delante\n", 204 | "# n es el tamano de la dimension del problema\n", 205 | "# matriz L, vector b ya estan dados como parametros\n", 206 | "# guardar los resultados en el vector y\n", 207 | "# Ly=b\n", 208 | "def sustDelante(L, b):\n", 209 | " n=len(L)\n", 210 | " y=np.empty_like(b)\n", 211 | " y[0] = b[0]\n", 212 | " for i in range(1,n):\n", 213 | " y[i] = b[i]\n", 214 | " for j in range(0,i):\n", 215 | " y[i] -= L[i][j]*y[j]\n", 216 | " return y\n", 217 | "\n", 218 | "# algoritmo para sustitucion hacia atras\n", 219 | "# n es el tamano de la dimension del problema\n", 220 | "# matriz U, vector y ya estan dados como parametros\n", 221 | "# guardar los resultados en el vector x\n", 222 | "# Ux=y\n", 223 | "def sustAtras(U, y):\n", 224 | " n=len(U)\n", 225 | " x=np.empty_like(y)\n", 226 | " x[n-1] = y[n-1]/U[n-1][n-1]\n", 227 | " for i in range(n-2,-1,-1):\n", 228 | " x[i] = y[i]\n", 229 | " for j in range(i+1,n):\n", 230 | " x[i] -= U[i][j]*x[j]\n", 231 | " x[i] /= U[i][i]\n", 232 | " return x\n" 233 | ], 234 | "execution_count": null, 235 | "outputs": [] 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "metadata": { 240 | "id": "0v6F2b98RVQR" 241 | }, 242 | "source": [ 243 | "#Ejemplo con un sistema de ecuaciones\n", 244 | "\n", 245 | "Supongamos que tenemos el sistema $A\\vec{x}=\\vec{b}$.\n", 246 | "\n", 247 | "$$\\left(\\begin{array}{ccc}\n", 248 | "-4 & -3 & 1\\\\\n", 249 | "8 & 11 & -1\\\\\n", 250 | "4 & 18 & 5\n", 251 | "\\end{array}\\right)\\left(\\begin{array}{c}\n", 252 | "x_{0}\\\\\n", 253 | "x_{1}\\\\\n", 254 | "x_{2}\n", 255 | "\\end{array}\\right)=\\left(\\begin{array}{c}\n", 256 | "5\\\\\n", 257 | "6\\\\\n", 258 | "1\n", 259 | "\\end{array}\\right)$$\n", 260 | "\n", 261 | "Y su respectiva factorización $A=LU$.\n", 262 | "\n", 263 | "$$U=\\left(\\begin{array}{ccc}\n", 264 | "-4 & -3 & 1\\\\\n", 265 | "0 & 5 & 1\\\\\n", 266 | "0 & 0 & 3\n", 267 | "\\end{array}\\right)\\quad L=\\left(\\begin{array}{ccc}\n", 268 | "1 & 0 & 0\\\\\n", 269 | "-2 & 1 & 0\\\\\n", 270 | "-1 &{3} & 1\n", 271 | "\\end{array}\\right)$$" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "metadata": { 277 | "id": "InAwWrSRT9B_", 278 | "colab": { 279 | "base_uri": "https://localhost:8080/" 280 | }, 281 | "outputId": "b1785680-df99-4e3a-b5cc-c3e9c15325d7" 282 | }, 283 | "source": [ 284 | "U = np.array([[-4,-3,1],[0,5,1],[0,0,3]])\n", 285 | "L = np.array([[1,0,0],[-2,1,0],[-1,3,1]])\n", 286 | "\n", 287 | "# Comprobamos que la factorizacion es correcta\n", 288 | "print(np.matmul(L,U))" 289 | ], 290 | "execution_count": null, 291 | "outputs": [ 292 | { 293 | "output_type": "stream", 294 | "text": [ 295 | "[[-4 -3 1]\n", 296 | " [ 8 11 -1]\n", 297 | " [ 4 18 5]]\n" 298 | ], 299 | "name": "stdout" 300 | } 301 | ] 302 | }, 303 | { 304 | "cell_type": "markdown", 305 | "metadata": { 306 | "id": "nf7TjQ6-VVyU" 307 | }, 308 | "source": [ 309 | "Primero encontramos la solución del sistema $L\\vec{y}=\\vec{b}$ empleando sistitución hacia adelante." 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "metadata": { 315 | "id": "L3o4ZsCYVcNs", 316 | "colab": { 317 | "base_uri": "https://localhost:8080/" 318 | }, 319 | "outputId": "08c2a9c8-2ce7-4c51-d14e-4fd824f0b942" 320 | }, 321 | "source": [ 322 | "# Se definene los vectores\n", 323 | "b = np.array([5.0,6.0,1.0])\n", 324 | "# Usamos el algoritmo para encontrar la solucion\n", 325 | "y = sustDelante(L, b)\n", 326 | "\n", 327 | "# Se imprime el resultado\n", 328 | "print(y)" 329 | ], 330 | "execution_count": null, 331 | "outputs": [ 332 | { 333 | "output_type": "stream", 334 | "text": [ 335 | "[ 5. 16. -42.]\n" 336 | ], 337 | "name": "stdout" 338 | } 339 | ] 340 | }, 341 | { 342 | "cell_type": "markdown", 343 | "metadata": { 344 | "id": "zqSey-W3XsXo" 345 | }, 346 | "source": [ 347 | "Ya que se conoce el valor del vector $\\vec{y}$ ahora podemos resolver el sistema $U\\vec{x}=\\vec{y}$" 348 | ] 349 | }, 350 | { 351 | "cell_type": "code", 352 | "metadata": { 353 | "id": "JSAjOTm2YKEJ", 354 | "colab": { 355 | "base_uri": "https://localhost:8080/" 356 | }, 357 | "outputId": "f4b67f50-79a9-4dab-97a4-33904c73032a" 358 | }, 359 | "source": [ 360 | "# Usamos el algoritmo para encontrar la solucion\n", 361 | "x = sustAtras(U, y)\n", 362 | "\n", 363 | "# Se imprime el resultado\n", 364 | "print(x)" 365 | ], 366 | "execution_count": null, 367 | "outputs": [ 368 | { 369 | "output_type": "stream", 370 | "text": [ 371 | "[ -9.25 6. -14. ]\n" 372 | ], 373 | "name": "stdout" 374 | } 375 | ] 376 | }, 377 | { 378 | "cell_type": "markdown", 379 | "metadata": { 380 | "id": "YjwDihYZYWu4" 381 | }, 382 | "source": [ 383 | "Por lo tanto la solución al sistema original $A\\vec{x}=\\vec{b}$, es.\n", 384 | "\n", 385 | "$$\\vec{x}=\\left(\\begin{array}{c}\n", 386 | "-9.25\\\\\n", 387 | "6\\\\\n", 388 | "-14\n", 389 | "\\end{array}\\right)$$" 390 | ] 391 | }, 392 | { 393 | "cell_type": "markdown", 394 | "metadata": { 395 | "id": "P15Oh28GZKHm" 396 | }, 397 | "source": [ 398 | "#Resúmen\n", 399 | "\n", 400 | "Ya que se tienen una factorización, digamos $\\left(LU\\right)$ ambas matrices podemos substituirlas en el sistema original, de tal manera que ahora el sistema luce así.\n", 401 | "\n", 402 | "$$A\\vec{x}=LU\\vec{x}=\\vec{b}$$\n", 403 | "\n", 404 | "Posteriormente podemos replantear la solución del sistema de la siguiente forma.\n", 405 | "\n", 406 | "$$LU\\vec{x}=\\vec{b}\\Longrightarrow L^{-1}LU\\vec{x}=L^{-1}\\vec{b}\\Longrightarrow U\\vec{x}=L^{-1}\\vec{b}\\tag{1}$$\n", 407 | "\n", 408 | "De manera tal, que ahora nos interesa primero encontrar una solución al sistema $L^{-1}\\vec{b}=\\vec{y}$, mismo que podemos reescribir.\n", 409 | "\n", 410 | "$$L^{-1}\\vec{b}=\\vec{y}\\Longrightarrow LL^{-1}\\vec{b}=L\\vec{y}\\Longrightarrow\\vec{b}=L\\vec{y}\\Longrightarrow L\\vec{y}=\\vec{b}\\tag{2}$$\n", 411 | "\n", 412 | "La ecuación (2) tiene la ventaja de ser un sistema triangular inferior, es por eso que la solución $\\vec{y}$ puede ser calculada fácilmente empleando **substitución hacia adelante**. Y una vez calculada, podemos proceder a resolver el segundo sistema empleando **substitución hacia atrás**.\n", 413 | "\n", 414 | "$$U\\vec{x}=\\vec{y}\\tag{3}$$\n", 415 | "\n", 416 | "Los algoritmos de substitución hacia atrás y hacia adelante son de los algoritmos más elementales para resolver un sistema de ecuaciones, sin embargo vale la pena notar algunas cosas.\n", 417 | "\n", 418 | "* ¿Por que es buena idea emplear estos algoritmos en lugar de buscar la inversa de la matriz $A$?.\n", 419 | "* En términos de elementales (+, -, *, /), ¿cuántas operaciones se realizan al emplear el algoritmo de sustitución hacia adelante?.\n", 420 | "* En términos de operaciones (+, -, *, /), ¿cuántas operaciones se realizan al emplear el algoritmo de sustitución hacia atras?.\n", 421 | "* En total, ¿cuántas operaciones se realizan cuando se resuelve un sistema $LU\\vec{x}=\\vec{b}$ empleando sustitución hacia adelante y despues hacia atrás?.\n", 422 | "\n", 423 | "\n", 424 | "\n" 425 | ] 426 | }, 427 | { 428 | "cell_type": "markdown", 429 | "metadata": { 430 | "id": "oDop6nTliDFd" 431 | }, 432 | "source": [ 433 | "##Referencias\n", 434 | "\n", 435 | "Justin Solomon: Numerical Algorithms.\n", 436 | "\n", 437 | "Jaan Kiusalaas: Numerical Methods in Engineering with Python.\n", 438 | "\n", 439 | "Richard L. Burden, J. Douglas Faires: Análisis Numérico, Math Learning.\n", 440 | "\n", 441 | "Riswan Butt: Numerical Analysys Using Matlab, Jones and Bartlett.\n", 442 | "\n", 443 | "Ward Cheney, David Kincaid: Métodos Numéricos y Computación, Cenage Learning." 444 | ] 445 | } 446 | ] 447 | } 448 | -------------------------------------------------------------------------------- /02_ResolucionDeSistemasLineales/Estabilidad.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "kernelspec": { 6 | "display_name": "Python 3.7 (tensorflow)", 7 | "language": "python", 8 | "name": "tensorflow" 9 | }, 10 | "language_info": { 11 | "codemirror_mode": { 12 | "name": "ipython", 13 | "version": 3 14 | }, 15 | "file_extension": ".py", 16 | "mimetype": "text/x-python", 17 | "name": "python", 18 | "nbconvert_exporter": "python", 19 | "pygments_lexer": "ipython3", 20 | "version": "3.7.7" 21 | }, 22 | "colab": { 23 | "name": "04_Estabilidad.ipynb", 24 | "provenance": [], 25 | "toc_visible": true, 26 | "include_colab_link": true 27 | } 28 | }, 29 | "cells": [ 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "view-in-github", 34 | "colab_type": "text" 35 | }, 36 | "source": [ 37 | "\"Open" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": { 43 | "id": "lYyeRSFmYTw5" 44 | }, 45 | "source": [ 46 | "\n", 47 | "

Estabilidad Numérica

\n", 48 | "
\n", 49 | " \n", 50 | "
Profesora: \tUrsula Xiomara Iturrarán Viveros
\n", 51 | "
Ayudante: Juan Pablo Cordero Santiago
\n", 52 | "
Materia: Análisis Numérico
\n", 53 | "
" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": { 59 | "id": "vS-z7mqKYTw_" 60 | }, 61 | "source": [ 62 | "## Introducción\n", 63 | "\n", 64 | "Sea $X$ un conjunto de datos de entrada y $Y$ el conjunto de datos de salida y $f$ la forma en la cual se relacionan $X$ y $Y$. Entonces\n", 65 | "\n", 66 | "$$f\\,:\\,X\\longmapsto Y$$\n", 67 | "\n", 68 | "Sin embargo para poder encontrar una solución a este problema es necesario aproximar dicha solución mediante algún algoritmo $(\\widehat{f})$ computacional.\n", 69 | "\n", 70 | "Pero como la computadora esta basada en un **sistema de punto flotante**, debemos considerar las siguientes observaciones.\n", 71 | " \n", 72 | "Originalmente $f\\,:\\,X\\longmapsto Y$, sin embargo $\\widehat{f}\\,:\\,\\widehat{x}\\in fl(X)\\longmapsto\\widehat{y}\\in fl(Y)$\n", 73 | " \n", 74 | "¿Que significa esto?.\n", 75 | "\n", 76 | "$$\\begin{array}{ccc}\n", 77 | "Datos & Algoritmo & Resultado\\\\\n", 78 | "error\\,represenentaci\\acute{o}n & \\Longleftrightarrow propagaci\\acute{o}n\\,error\\Longleftrightarrow & aproximado\n", 79 | "\\end{array}$$ " 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": { 85 | "id": "UahaClImf2Yj" 86 | }, 87 | "source": [ 88 | "## Estabilidad\n", 89 | "\n", 90 | "De manera intuitiva un algoritmo sera estable si, pequeños cambios en los datos de entrada producen pequeños cambios en los datos de salida.\n", 91 | "\n", 92 | "Por el contrario, un algoritmo es inestable si, pequeños cambios en los datos de entrada se magnifican en los datos de salida.\n", 93 | "\n", 94 | "Lo mas importante que se le puede pedir a un algoritmo $\\widehat{f}$ es que proporcione una buena aproximación al problema $f$, ya sea tomando\n", 95 | "\n", 96 | "$$\\left\\Vert f(x)-\\widehat{f}(x)\\right\\Vert \\qquad\\acute{o}\\qquad\\frac{\\left\\Vert f(x)-\\widehat{f}(x)\\right\\Vert }{\\left\\Vert f(x)\\right\\Vert }$$\n", 97 | "\n", 98 | "Si $\\widehat{f}$ es un buen algoritmo se podría esperar un error relativo pequeño, del orden de $\\epsilon_{M}$, es decir $O\\left(\\epsilon_{M}\\right)$.\n", 99 | "\n", 100 | "En otras palabras, se puede decir que un algoritmo $\\widehat{f}$ para un problema $f$ es preciso si \n", 101 | " \n", 102 | "$$\\forall x\\in X\\quad\\frac{\\left\\Vert f(x)-\\widehat{f}(x)\\right\\Vert }{\\left\\Vert f(x)\\right\\Vert }=O\\left(\\epsilon_{M}\\right)$$\n", 103 | " \n", 104 | "De manera vaga, el símbolo $O\\left(\\epsilon_{M}\\right)$ significa \" del orden del épsilon de la máquina\". \n", 105 | "\n", 106 | "Haciendo un poco de memoria, la notación $g(t)=O\\left(f(t)\\right)$ es estándar en el lenguaje matemático y significa que $\\exists\\, c,t>0$ tales que \n", 107 | "\n", 108 | "$$ 0 \\leq \\left|g(t)\\right|\\leq c\\left|f(t)\\right|$$\n", 109 | "\n", 110 | "En este contexto que algo pertenezca al $O\\left(\\epsilon_{M}\\right)$ en realidad significa que el error relativo ó absoluto entre la solución real y la aproximación serán a los más $\\epsilon_{M}$.\n", 111 | "\n", 112 | "Y recuerden que se hace un abuso de notación cuando se escribe $=O\\left(\\epsilon_{M}\\right)$, ya que en realidad lo que eso significa es $\\in \\left(\\epsilon_{M}\\right)$.\n", 113 | "\n", 114 | "Volviendo a la precisión de un algoritmo , si el problema $f$ esta mal condicionado para alguna $x$, el objetivo de precisión dado por el error relativo es poco razonable, simplemente por el error de redondeo. \n", 115 | "\n", 116 | "Así que en lugar de pedir precisión en todos los cálculos, asociados a la aproximación $\\widehat{f}$, lo más que se puede pedir, es **estabilidad.**\n" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": { 122 | "id": "RtPE1hDkhYzc" 123 | }, 124 | "source": [ 125 | "### Definición\n", 126 | "\n", 127 | "Un algoritmo $\\widehat{f}$ para un problema $f$, se dice que es estable si $\\forall x\\in X\\:\\exists\\:\\widehat{x}$ tal que\n", 128 | "\n", 129 | "$$\\frac{\\left\\Vert x-\\widehat{x}\\right\\Vert }{\\left\\Vert x\\right\\Vert }=O\\left(\\epsilon_{M}\\right)\\quad y\\quad\\frac{\\left\\Vert f(\\widehat{x})-\\widehat{f}(x)\\right\\Vert }{\\left\\Vert f(\\widehat{x})\\right\\Vert }=O\\left(\\epsilon_{M}\\right)$$\n", 130 | "\n", 131 | "La definición de estabilidad lo que expresa en términos comunes es, \"**Un algoritmo estable es el que produce una respuesta casi correcta a una pregunta casi correcta**\"." 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": { 137 | "id": "qNZzGBP3gDlZ" 138 | }, 139 | "source": [ 140 | "## Estabilidad hacia atrás\n", 141 | "\n", 142 | "La condición de estabilidad hacia atrás es más fuerte que la condición de estabilidad, ya que el término $O\\left(\\epsilon_{M}\\right)$ en la segunda igualdad de la definición previa ha sido substituido por 0." 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": { 148 | "id": "WWjLEyAbjdhW" 149 | }, 150 | "source": [ 151 | "### Definición\n", 152 | "\n", 153 | "Un algoritmo $\\widehat{f}$ para un problema $f$, se dice que es estable hacia atrás si $\\forall x\\in X\\:\\exists\\:\\widehat{x}$ tal que \n", 154 | "\n", 155 | "$$\\frac{\\left\\Vert x-\\widehat{x}\\right\\Vert }{\\left\\Vert x\\right\\Vert }=O\\left(\\epsilon_{M}\\right)\\quad y\\quad\\widehat{f}(x)=f(\\widehat{x})$$\n", 156 | "\n", 157 | "Lo que expresa la definición de estabilidad hacia atrás es, \"**Un algoritmo estable hacia atrás es el que produce una respuesta correcta a una pregunta casi correcta**\".\n" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": { 163 | "id": "Bvp3tp63jqWa" 164 | }, 165 | "source": [ 166 | "### Ejemplo\n", 167 | "\n", 168 | "Sea $$A=\\left(\\begin{array}{cc}\n", 169 | "3.000 & 2.000\\\\\n", 170 | "1.000 & 2.000\n", 171 | "\\end{array}\\right)$$\n", 172 | "\n", 173 | "y se busca su forma triangular superior (para resolver el sistema $A\\vec{x}=\\vec{b}$) con una aritmética de 4-cifras (es decir $\\epsilon_{M}=10^{-3}$).\n", 174 | "\n", 175 | "Tomemos \n", 176 | "\n", 177 | "$$m=fl(\\frac{1.000}{3.000})=0.3333$$\n", 178 | "\n", 179 | "Ahora multiplicamos $m$ por el primer renglón y lo sumamos al segundo renglón, es decir \n", 180 | "\n", 181 | "$$a_{21'}\t=\tfl(a_{21}-(m\\times a_{11}))=fl(1.000-(0.3333\\times3.000))=fl(1.000-0.9999)=0$$\n", 182 | "$$a_{22'}\t=\tfl(a_{22}-(m\\times a_{12}))=fl(2.000-(0.3333\\times2.000))=fl(1.3334)=1.333 $$\n", 183 | "\n", 184 | "Así que, esta es la aproximación del problema $f$ aplicado a la matriz $A$. \n", 185 | "\n", 186 | "$$\\widehat{f}(A)=\\left(\\begin{array}{cc}\n", 187 | "3.000 & 2.000\\\\\n", 188 | "0 & 1.333\n", 189 | "\\end{array}\\right)$$\n", 190 | "\n", 191 | "Ahora tenemos que encontrar un dato inicial $\\widehat{A}$ tal que $f(\\widehat{A})=\\widehat{f}(A)$.\n", 192 | "\n", 193 | "$$Como\\quad\\widehat{a}_{21}-m\\times a_{11}\t=\t0\\Rightarrow\\widehat{a}_{21}=0.3333\\times3.000\\quad\\therefore\\widehat{a}_{21}=0.9999$$\n", 194 | "\n", 195 | "$$Como\\quad \\widehat{a}_{22}-m\\times a_{12}\t=\t1.333\\Rightarrow\\widehat{a}_{22}=1.333+(0.3333\\times2)\\quad\\therefore\\widehat{a}_{22}=1.9996$$\n", 196 | "\n", 197 | "$$\\widehat{A}=\\left(\\begin{array}{cc}\n", 198 | "3 & 2\\\\\n", 199 | "0.9999 & 1.9996\n", 200 | "\\end{array}\\right)$$\n", 201 | "\n", 202 | "Por lo que se cumple que $f(\\widehat{A})=\\widehat{f}(A)$, compruébalo. \n", 203 | "\n", 204 | "Ahora para que el algoritmo sea estable hacia atrás se debe cumplir que \n", 205 | "\n", 206 | "$$\\frac{\\left\\Vert A-\\widehat{A}\\right\\Vert }{\\left\\Vert A\\right\\Vert }=O\\left(\\epsilon_{M}\\right)$$\n", 207 | "\n", 208 | "Dado que hemos comprobado la equivalencia de normas, podemos tomar la 1-norma inducida y ver que sucede con \n", 209 | "\n", 210 | "$$ A-\\widehat{A}=\\left(\\begin{array}{cc}\n", 211 | "3 & 2\\\\\n", 212 | "1 & 2\n", 213 | "\\end{array}\\right)-\\left(\\begin{array}{cc}\n", 214 | "3 & 2\\\\\n", 215 | "0.9999 & 1.9996\n", 216 | "\\end{array}\\right)=\\left(\\begin{array}{cc}\n", 217 | "0 & 0\\\\\n", 218 | "10^{-4} & 4\\times10^{-4}\n", 219 | "\\end{array}\\right)$$\n", 220 | "\n", 221 | "$$\\frac{\\left\\Vert A-\\widehat{A}\\right\\Vert _{1}}{\\left\\Vert A\\right\\Vert _{1}}=\\frac{4}{4}10^{-4}\\in O\\left(\\epsilon_{M}\\right)$$\n", 222 | "\n", 223 | "Así que hemos mostrado que este algoritmo es estable hacia atras." 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": { 229 | "id": "2InND3B0gUb2" 230 | }, 231 | "source": [ 232 | "## Estabilidad en matrices\n", 233 | "\n", 234 | "Ya es facíl comprender el por que nos interesa ver a un algoritmo como una matriz o a una solución como un vector.\n", 235 | "\n", 236 | "Dado que muchos de los problemas que analizaremos en el resto del curso toman la forma de una matriz, es importante poder identificar que tan estables son estos algoritmos." 237 | ] 238 | }, 239 | { 240 | "cell_type": "markdown", 241 | "metadata": { 242 | "id": "mSFCaDmJgQ75" 243 | }, 244 | "source": [ 245 | "### Estabilidad en sistemas del tipo $A\\vec{x}=\\vec{b}$\n", 246 | "\n", 247 | "Como hemos podido observar a lo largo del curso, muchas veces la solución de un problema viene dada en forma de matriz o de vector, así que tiene mucho sentido definir cuando se considerara o no estable un algoritmo para resolver un sistema $A\\vec{x}=\\vec{b}$.\n", 248 | "\n", 249 | "Un algoritmo para solucionar $Ax=b$ es llamado estable hacia atrás, si la solución computacional $\\widehat{x}$ es tal que \n", 250 | "\n", 251 | "$$\\left(A+E\\right)\\widehat{x}=\\vec{b}+\\delta b$$\n", 252 | "\n", 253 | "con $E$ y $\\delta b$ pequeños.\n", 254 | "\n", 255 | "El proceso de substitución hacia atrás para resolver un sistema triangular superior es un ejemplo de un algoritmo estable hacia atrás.\n", 256 | "\n", 257 | "La solución computacional $\\widehat{x}$ obtenida mediante la resolución de un sistema triangular superior empleando substitución hacia atrás satisface que \n", 258 | "\n", 259 | "$$\\left(T+E\\right)\\widehat{x}=\\vec{b}$$\n", 260 | "\n", 261 | "Donde las entradas de la matriz error $E$ son bastante pequeñas." 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": { 267 | "id": "XOBbfw8BpXNw" 268 | }, 269 | "source": [ 270 | "### Ejemplo\n", 271 | "\n", 272 | "Sea el sistema $U\\vec{x}=\\vec{b}$ con,\n", 273 | "\n", 274 | "$$ U=\\left(\\begin{array}{ccc}\n", 275 | "u_{00} & u_{01} & u_{02}\\\\\n", 276 | "0 & u_{11} & u_{12}\\\\\n", 277 | "0 & 0 & u_{22}\n", 278 | "\\end{array}\\right),\\,\\,\\vec{x}=\\left(\\begin{array}{c}\n", 279 | "x_{0}\\\\\n", 280 | "x_{1}\\\\\n", 281 | "x_{2}\n", 282 | "\\end{array}\\right),\\,\\,\\vec{b}=\\left(\\begin{array}{c}\n", 283 | "b_{0}\\\\\n", 284 | "b_{1}\\\\\n", 285 | "b_{2}\n", 286 | "\\end{array}\\right)$$\n", 287 | "\n", 288 | "Empleando substitución hacia atrás, podemos encontrar la solución de este sistema.\n", 289 | "\n", 290 | "Empezamos despejando $x_{2}$ ya que es la variable más sencilla de despejar. \n", 291 | "\n", 292 | "$$u_{22}x_{2}=b_{2}\\Longrightarrow x_{2}=b_{2}/u_{22}$$\n", 293 | "\n", 294 | "Procedemos con $x_{1}$.\n", 295 | "\n", 296 | "$$u_{11}x_{1}+u_{12}x_{2}=b_{1}\\Longrightarrow x_{1}=\\left(b_{1}-u_{12}x_{2}\\right)/u_{11}$$\n", 297 | "\n", 298 | "Por ultimo $x_{0}$.\n", 299 | "\n", 300 | "$$u_{00}x_{0}+u_{01}x_{1}+u_{02}x_{2}=b_{0}\\Longrightarrow x_{0}=\\left(b_{0}-u_{01}x_{1}-u_{02}x_{2}\\right)/u_{00}$$\n", 301 | "\n", 302 | "De tal manera que podemos pensar en el $\\vec{x}$ de la siguiente forma.\n", 303 | "\n", 304 | "$$\\vec{x}=\\left(\\begin{array}{c}\n", 305 | "x_{0}\\\\\n", 306 | "x_{1}\\\\\n", 307 | "x_{2}\n", 308 | "\\end{array}\\right)=\\left(\\begin{array}{c}\n", 309 | "\\left(b_{0}-u_{01}x_{1}-u_{02}x_{2}\\right)/u_{00}\\\\\n", 310 | "\\left(b_{1}-u_{12}x_{2}\\right)/u_{11}\\\\\n", 311 | "b_{2}/u_{22}\n", 312 | "\\end{array}\\right)$$\n", 313 | "\n", 314 | "Poniendo especial atención en los indices de las variables podemos notar que cada entrada del vector $\\vec{x}$ se puede ver como una suma de $u_{ij}x_{j}$ seguida de una única división por $u_{ii}$.\n", 315 | "\n", 316 | "Si lo pensamos en notación vectorial, cada entrada del vector $\\vec{x}\\in\\mathbb{R}^{n}$ se ve de la siguiente forma.\n", 317 | "\n", 318 | "$$x_{i}=\\left(b_{i}-\\sum_{j=i+1}^{n}u_{ij}x_{j}\\right)/u_{ii}\\quad \\quad i=n-1,n-2,....,0$$\n", 319 | "\n", 320 | "Ahora si esto lo pensamos en cualquier lenguaje de programación, tenemos que un par de ciclos anidados (uno para las i's y otro para las j's) son suficientes para calcular la solución del sistema.\n", 321 | "\n", 322 | "También es importante notar que en este ejemplo no se establecio algún tipo de restricción sobre los cálculos realizados, asi que el algoritmo y la solución mostradas en este desarrollo son $f$ y $\\vec{x}$ respectivamente. \n", 323 | "\n", 324 | "Aunque se puede mostrar que si consideramos emplear la versión computacional de este algoritmo $\\widehat{f}$ para encontrar la solución $\\widehat{x}$, esta solución cumple con la propiedad de estabilidad hacia atras, es decir.\n", 325 | "\n", 326 | "$$\\left(A+E\\right)\\widehat{x}=\\vec{b}+\\delta b$$\n", 327 | "\n", 328 | "Y más en específico.\n", 329 | "\n", 330 | "$$\\left(T+E\\right)\\widehat{x}=\\vec{b}$$\n", 331 | "\n", 332 | "" 333 | ] 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "metadata": { 338 | "id": "KyEsjazguRcb" 339 | }, 340 | "source": [ 341 | "### Análisis de la complejidad\n", 342 | "\n", 343 | "Una vez que se tiene una idea de como luce el pseudocodigo, vale la pena hacerse un par de preguntas.\n", 344 | "\n", 345 | "• ¿Cuantos flop's (en términos de n) requiere unicamente el algoritmo de la substitución hacia atrás?.\n", 346 | "\n", 347 | "• ¿A que orden de complejidad pertenece este algoritmo?.\n", 348 | "\n", 349 | "• Considerando las operaciones elementales que se tienen que realizar para llevar una matriz a su forma triangular superior. ¿Que es menos costoso en términos de flop's, para resolver un sistema del tipo $A\\vec{x}=\\vec{b}$, calcular $A^{-1}$ y después multiplicar por la derecha a $\\vec{b}$ para poder encontrar la solución del sistema o llevar a la matriz A a su forma triangular superior y después emplear la substitución hacia atrás?. " 350 | ] 351 | }, 352 | { 353 | "cell_type": "markdown", 354 | "metadata": { 355 | "id": "k7X3EzHGYTxB" 356 | }, 357 | "source": [ 358 | "## Referencias\n", 359 | "\n", 360 | "* Riswan Butt, Numerical Analysys Using Matlab, Jones and Bartlett.\n", 361 | "* Ward Cheney, David Kincaid, Métodos Numéricos y Computación, Cenage Learning.\n", 362 | "* Richard L. Burden, J. Douglas Faires, Análisis Numérico, Math Learning.\n", 363 | "* Yuri N. Skiba, Introducción a los Métodos Numéricos." 364 | ] 365 | } 366 | ] 367 | } 368 | -------------------------------------------------------------------------------- /00_Introduccion/DecToBinaryToDec.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "view-in-github", 7 | "colab_type": "text" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "CKkAPHkQgVZP" 17 | }, 18 | "source": [ 19 | "# Conversion de binario a decimal y viceversa usando utilireias de Python" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": { 25 | "id": "TJxxQu5lgVZT" 26 | }, 27 | "source": [ 28 | "## Como se expresa un número en base 10 " 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": { 34 | "id": "_4SNTlxIgVZU" 35 | }, 36 | "source": [ 37 | "Sea $N$ un número natural, entonces existen $k+1$ cifras $a_0,a_1,\\ldots,a_k$\n", 38 | "tomadas del conjunto $\\{0,1,2,\\ldots,9\\}$ tales que $N$ admite el siguiente desarrollo:\n", 39 | "$$\n", 40 | "N=a_k \\cdot 10^{k}+a_{k-1}\\cdot 10^{k-1}+ \\ldots + a_0 \\cdot 10^0\n", 41 | "$$\n", 42 | "Por lo que en notaci\\'on en base 10 tenemos:\n", 43 | "$$\n", 44 | "N=a_ka_{k-1}\\ldots a_1 a_0\n", 45 | "$$\n", 46 | "Sea $N$ un número natural, entonces existen $j+1$ cifras $b_0,b_1,\\ldots,b_j$\n", 47 | "tomadas del conjunto $\\{0,1\\}$ tales que $N$ admite el siguiente desarrollo:\n", 48 | "$$\n", 49 | "N=b_j \\cdot 2^{j}+b_{j-1}\\cdot 2^{j-1}+ \\ldots + b_0 \\cdot 2^0\n", 50 | "$$\n", 51 | "\n", 52 | "Por lo que en notación en base 2 (binaria) tenemos:\n", 53 | "$$\n", 54 | "N=b_j b_{j-1}\\ldots b_1 b_0\n", 55 | "$$\n", 56 | "con $b_i \\, \\in \\, \\{0,1\\}$\n" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": { 62 | "id": "EHhJ3LI5gVZV" 63 | }, 64 | "source": [ 65 | "## Algoritmo para encontrar la representación en base 2 de un número natural" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": { 71 | "id": "B12IsSx4gVZW" 72 | }, 73 | "source": [ 74 | "$$\n", 75 | "N = b_j \\cdot 2^{j}+b_{j-1}\\cdot 2^{j-1}+ \\ldots + b_0 \\cdot 2^0 \\\\\n", 76 | "\\Rightarrow \\frac{N}{2} =\\frac{b_j \\cdot 2^j}{2}+\\frac{b_{j-1} \\cdot 2^{j-1}}{2}+ \\cdots\\frac{b_1 \\cdot 2^1}{2}+\\frac{b_0 \\cdot 2^0}{2} \\\\\n", 77 | "=b_j \\cdot 2^{j-1}+b_{j-1}\\cdot 2^{j-2}+ \\ldots + b_1 \\cdot 2^0+\\frac{b_0}{2} \\\\\n", 78 | "\\frac{N}{2}=Q_0+\\frac{b_0}{2} \\\\\n", 79 | "\\frac{Q_0}{2} = b_j \\cdot 2^{j-2}+b_{j-1} \\cdot 2^{j-3}+ \\ldots +b_2+\\frac{b_1}{2}\n", 80 | "$$\n", 81 | "\n", 82 | "con $Q_0=b_j \\cdot 2^{j-1}+b_{j-1}\\cdot 2{j-2}+ \\ldots + b_1 \\cdot 2^0$. Continuando\n", 83 | "el proceso generamos sucesiones $\\{Q_k\\}$ y $\\{b_k\\}$ de cocientes y residuos. El proceso\n", 84 | "termina cuando encontramos un número natrual $j$ tal que $Q_j=0$. Es decir:\n", 85 | "$$\n", 86 | "N = 2Q_0+b_0 \\\\\n", 87 | "Q_0 = 2 Q_1 + b_1 \\\\\n", 88 | "Q_1 = 2Q_2 + b_2 \\\\\n", 89 | " \\vdots \\\\\n", 90 | "Q_{j-2} = 2Q_{j-1}+b_{j-1} \\\\\n", 91 | "Q_{j-1} = 2Q_j+b_j \\;\\;\\; (Q_j=0) \n", 92 | "$$\n" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": { 98 | "id": "9pgjYxhTgVZW" 99 | }, 100 | "source": [ 101 | "### Ejemplo: convertir a binario el número $N=2021$" 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": { 107 | "id": "xD3kmNqkgVZX" 108 | }, 109 | "source": [ 110 | "$$\n", 111 | "2021 = 2*1010+1 \\; \\Leftarrow \\; b_0 \\\\\n", 112 | "1010 = 2*505 + 0 \\; \\Leftarrow \\; b_1 \\\\\n", 113 | "505 = 2*252 + 1 \\; \\Leftarrow \\; b_2 \\\\\n", 114 | "252 = 2*126 +0 \\; \\Leftarrow \\; b_3 \\\\\n", 115 | "126 = 2*63+0 \\; \\Leftarrow \\; b_4 \\\\\n", 116 | "63 = 2*31+1 \\; \\Leftarrow \\; b_5 \\\\\n", 117 | "31=2*15+1 \\; \\Leftarrow \\; b_6 \\\\\n", 118 | "15=2*7+1 \\; \\Leftarrow \\; b_7 \\\\\n", 119 | "7=2*3+1 \\; \\Leftarrow \\; b_8 \\\\\n", 120 | "3=2*1+1 \\; \\Leftarrow \\; b_9 \\\\\n", 121 | "1=2*0+1 \\; \\Leftarrow \\; b_{10} \\;\\;\\; (Q_{10}=0) \n", 122 | "$$\n", 123 | "\n", 124 | "Tenemos entonces que $N$ se puede escribir en base 2 como sigue:\n", 125 | "\n", 126 | "$$\n", 127 | "N=b_{10} b_{9}\\ldots b_1 b_0 =(11111100101)_2\n", 128 | "$$\n" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": { 134 | "id": "B3V_qgC2gVZY" 135 | }, 136 | "source": [ 137 | "### Codigo que implementa esta algoritmo" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": { 143 | "id": "pnejIHU0gVZY" 144 | }, 145 | "source": [ 146 | "**Parte Entera:** \n", 147 | "\n", 148 | "Repetir los siguientes dos pasos mientras el entero a dividir sea diferente de cero\n", 149 | "\n", 150 | "**Paso 1:** Dividir la parte entera entre 2 y guardar su residuo que será 0 o 1.\n", 151 | "\n", 152 | "**Paso 2:** Volver a dividir la parte entera (obtenida en el Paso 1) entre 2 y guardar su residuo que será 0 o \n", 153 | "\n", 154 | "**Paso 3:** Escribir la secuencia de residuos en orden invertido (el primero obtenido será el último en la representación binaria). Este resultado corresponde a la representación binaria de la parte entera del número en base 10." 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": null, 160 | "metadata": { 161 | "id": "IsgbXXmxgVZZ" 162 | }, 163 | "outputs": [], 164 | "source": [ 165 | "# Funcion que convierte la parte entera (en base 10) en binario \n", 166 | "def intpartbinary(m):\n", 167 | " \n", 168 | " a = []\n", 169 | " n = int(m) #Tomo la parte entera\n", 170 | " \n", 171 | " while n != 0:\n", 172 | " \n", 173 | " a.append(n % 2)\n", 174 | " n = n//2 #Obtiene el cociente entero de dividir el operando de la izquierda por el de la derecha\n", 175 | " \n", 176 | " a.reverse()\n", 177 | " return a\n", 178 | " \n" 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "metadata": { 184 | "id": "x5xS-aSwgVZb" 185 | }, 186 | "source": [ 187 | "## Fracciones binarias" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": { 193 | "id": "Q2NHUrurgVZc" 194 | }, 195 | "source": [ 196 | "Las fracciones binarias pueden expresarse como sumas en las que aparecen potencias negativas de 2.\n", 197 | "Si $R \\in \\mathbb{R}$ tal que $0 < R <1$ entonces existe una sucesión de cifras $d_1,d_2, \\ldots, d_n$\n", 198 | "todas ellas en $\\{0,1\\}$ tales que queremos:\n", 199 | "\n", 200 | "$$\n", 201 | "R = \\left(d_1 \\times 2^{-1}\\right)+\\left(d_2 \\times 2^{-2}\\right)+\\ldots + \\left(d_n \\times 2^{-n}\\right) \\\\\n", 202 | " = 0.d_1 d_2 \\ldots d_n \n", 203 | "$$\n", 204 | "\n", 205 | "Algoritmo: Multiplicando por 2 ambos lados de la ecuación anterior obtenemos:\n", 206 | "\n", 207 | "$$\n", 208 | "2R = \\underbrace{d_1}_{\\mathrm{parte\\; entera\\; de \\; }2R} \\\\\n", 209 | "+ \\underbrace{ \\left(d_2 \\times 2^{-1}\\right)+ \\ldots +\\left(d_n \\times 2^{-n+1}\\right) }_{\\mathrm{numero\\; positivo\\; menor\\; que \\; 1}} \\label{Rbinfrac} \\\\\n", 210 | "d_1 = \\mathrm{ent}(2R) \\;\\mathrm{Para} \\; \\mathrm{continuar} \\; \\mathrm{tomamos} \\; \\mathrm{la} \\; \\mathrm{parte} \\; \\mathrm{fraccionaria} \\\\\n", 211 | "F_1 = \\mathrm{frac}(2R) \\\\\n", 212 | "= \\left(d_2 \\times 2^{-1}\\right)+\\left(d_3 \\times 2^{-2}\\right)+ \\ldots + d_n \\times 2^{-n+1} \\\\\n", 213 | "2F_1 = d_2+ \\underbrace{d_3\\times 2^{-1}+d_3 \\times 2^{-2}+ \\ldots + d_n 2^{-n+2}} \\\\\n", 214 | "d_2=\\mathrm{ent}(2F_1) \n", 215 | "$$\n", 216 | "\n", 217 | "Se genera de forma recurrente las dos sucesiones $\\{d_k\\}$ y $\\{F_k\\}$ \n", 218 | "$$\n", 219 | "d_k=\\mathrm{ent}(2F_{k-1}) \\;\\;\\;\\;\\; \\mathrm{donde} \\;\\;\\;\\;\\;\\; d_1=\\mathrm{ent}(2R)\n", 220 | "$$\n", 221 | "\n", 222 | "$$\n", 223 | "F_k=\\mathrm{frac}(2F_{k-1}) \\;\\;\\;\\;\\; \\mathrm{y} \\;\\;\\;\\;\\;\\; F_1=\\mathrm{frac}(2R)\n", 224 | "$$\n", 225 | "\n", 226 | "La representación binaria de $R$ esta dada entonces por la serie convergente:\n", 227 | "$$\n", 228 | "R=\\sum\\limits_{j=1}^{\\infty} d_j(2^{-j}) \\;\\;\\;\\;\\; \\mathrm{que}\\; \\mathrm{es}\\; \\mathrm{una} \\; \\mathrm{serie}\\; \\mathrm{geometrica}\\;\n", 229 | "$$\n" 230 | ] 231 | }, 232 | { 233 | "cell_type": "markdown", 234 | "metadata": { 235 | "id": "J0LfNr5SgVZd" 236 | }, 237 | "source": [ 238 | "### Ejemplo: Sea $R=\\frac{7}{10}=0.7$ encontrar su representación binaria " 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": { 244 | "id": "U2tRdq7RgVZe" 245 | }, 246 | "source": [ 247 | "$$\n", 248 | "2R = 1.4 \\;\\;\\; d_1=\\mathrm{ent}(1.4)=1 \\;\\;\\; F_1=\\mathrm{frac}(1.4)=0.4 \\\\\n", 249 | "2F_1 = 0.8 \\;\\;\\; d_2=\\mathrm{ent}(0.8)=0 \\;\\;\\; F_2=\\mathrm{frac}(0.8)=0.8 \\\\\n", 250 | "2F_2 = 1.6 \\;\\;\\; d_3=\\mathrm{ent}(1.6)=1 \\;\\;\\; F_3=\\mathrm{frac}(1.6)=0.6 \\\\\n", 251 | "2F_3 = 1.2 \\;\\;\\; d_4=\\mathrm{ent}(1.2)=1 \\;\\;\\; F_4=\\mathrm{frac}(1.2)=0.2 \\\\\n", 252 | "2F_4 = 0.4 \\;\\;\\; d_2=\\mathrm{ent}(0.4)=0 \\;\\;\\; F_5=\\mathrm{frac}(0.4)=0.4 \\\\\n", 253 | "2F_5 = 0.8 \\;\\;\\; d_2=\\mathrm{ent}(0.8)=0 \\;\\;\\; F_6=\\mathrm{frac}(0.8)=0.8 \\\\\n", 254 | "2F_6 = 1.6 \\;\\;\\; d_2=\\mathrm{ent}(1.6)=1 \\;\\;\\; F_7=\\mathrm{frac}(1.6)=0.6 \n", 255 | "$$\n", 256 | "\n", 257 | "de donde concluimos que:\n", 258 | "$$\n", 259 | "R=\\left(\\frac{7}{10}\\right)_{\\mathrm{base}\\; 10}=\\left(0.7\\right)_{\\mathrm{base}\\; 10}=\\left(0.1\\underbrace{0110}_{\\mathrm{se}\\;\\mathrm{repite}}\\right)_{\\mathrm{base}\\; 2}\n", 260 | "$$\n", 261 | "\n", 262 | "\n" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": { 268 | "id": "p6zR1BPrgVZe" 269 | }, 270 | "source": [ 271 | "### Otro ejemplo: Convertir $0.2$ de base 10 a base 2:" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": { 277 | "id": "Wy6layMtgVZf" 278 | }, 279 | "source": [ 280 | "$$\n", 281 | "2R = 0.4 \\;\\;\\; d_1=\\mathrm{ent}(0.4)=0 \\;\\;\\; F_1=\\mathrm{frac}(0.4)=0.4 \\\\\n", 282 | "2F_1 = 0.8 \\;\\;\\; d_2=\\mathrm{ent}(0.8)=0 \\;\\;\\; F_2=\\mathrm{frac}(0.8)=0.8 \\\\\n", 283 | "2F_2 = 1.6 \\;\\;\\; d_3=\\mathrm{ent}(1.6)=1 \\;\\;\\; F_3=\\mathrm{frac}(1.6)=0.6 \\\\\n", 284 | "2F_3 = 1.2 \\;\\;\\; d_4=\\mathrm{ent}(1.2)=1 \\;\\;\\; F_4=\\mathrm{frac}(1.2)=0.2 \\\\\n", 285 | "2F_4 = 0.4 \\;\\;\\; d_2=\\mathrm{ent}(0.4)=0 \\;\\;\\; F_5=\\mathrm{frac}(0.4)=0.4 \\\\\n", 286 | "$$" 287 | ] 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "metadata": { 292 | "id": "TS45sE3ngVZf" 293 | }, 294 | "source": [ 295 | "### Codigo que implementa esta algoritmo" 296 | ] 297 | }, 298 | { 299 | "cell_type": "markdown", 300 | "metadata": { 301 | "id": "oa1MFGfugVZg" 302 | }, 303 | "source": [ 304 | "**Parte Fraccionaria:**\n", 305 | " \n", 306 | "**Paso 1:** Multiplicar la parte fraccionaria por 2 y escribir solamente el entero (parte entera) resultante.\n", 307 | "\n", 308 | "**Paso 2:** Restar la parte entera del número obtaenido en el Paso 1 (multiplicar la fracción por 2) and y otra vez multiplicar la parte fraccionaria por 2.\n", 309 | "Repetir estos pasos mientras la parte Fraccionaria no se haga cero. La sequencia obtenida es la representación binaria de la parte fraccionaria dada." 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": null, 315 | "metadata": { 316 | "id": "7Bn-WXe3gVZg" 317 | }, 318 | "outputs": [], 319 | "source": [ 320 | "# Funcion que convierte la parte fraccionaria (en base 10) a binario\n", 321 | "def decimalpartbinary(m):\n", 322 | " \n", 323 | " a = []\n", 324 | " n = m-int(m) #Tomo la parte fraccionaria quitando la parte entera\n", 325 | " \n", 326 | " while n != 0:\n", 327 | " \n", 328 | " x = 2 * n\n", 329 | " y = int(x)\n", 330 | " a.append(y)\n", 331 | " n = x-y\n", 332 | " \n", 333 | " return a\n" 334 | ] 335 | }, 336 | { 337 | "cell_type": "markdown", 338 | "metadata": { 339 | "id": "YcH8ZjLYgVZh" 340 | }, 341 | "source": [ 342 | "Combinando las conversiones de la parte entera y fraccionaria. Primero se escribe la secuencia invertida (de la parte entera) y se escribe un punto \".\" despues se escribe la parte fraccionaria que se obtuvo multiplicando por 2 esta parte y guardando la parte entera. Se define una lista vacia c=[], primero para almacenar la lista invertida de residuos obtenidos dividiendo la parte entera por 2. Despues almacenar la lista de enteros obtenidos multiplicando por 2 la parte fraccionaria. Imprimir la lista c que será la representacion binaria del número en base 10 dado. " 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": null, 348 | "metadata": { 349 | "id": "eQlp7GXbgVZi" 350 | }, 351 | "outputs": [], 352 | "source": [ 353 | "# Escribir los datos en forma adecuada, separando la parte entera de la fraccionaria y convirtiendolas a binarios\n", 354 | "def binarycode(m):\n", 355 | " \n", 356 | " \n", 357 | " a = intpartbinary(m) #Parte entera convertida a binario\n", 358 | " b = decimalpartbinary(m) #Parte fraccionaria convertida a binario\n", 359 | " c =[]\n", 360 | " \n", 361 | " for i in range(0, len(a)):\n", 362 | " c.append(a[i])\n", 363 | " \n", 364 | " c.append('.')\n", 365 | " \n", 366 | " for j in range(0, len(b)):\n", 367 | " c.append(b[j])\n", 368 | " \n", 369 | " print('El numero en base 10 convertido a binario es:\\n')\n", 370 | " \n", 371 | " for k in range(0, len(c)):\n", 372 | " print(c[k], end =' ')\n", 373 | " \n", 374 | " \n" 375 | ] 376 | }, 377 | { 378 | "cell_type": "code", 379 | "execution_count": null, 380 | "metadata": { 381 | "id": "jnC6YdB_gVZi", 382 | "outputId": "b77728bf-8065-448c-a165-d44aac5d8626" 383 | }, 384 | "outputs": [ 385 | { 386 | "name": "stdout", 387 | "output_type": "stream", 388 | "text": [ 389 | "El numero en base 10 convertido a binario es:\n", 390 | "\n", 391 | "1 1 0 0 1 0 1 1 0 0 . 0 0 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 " 392 | ] 393 | } 394 | ], 395 | "source": [ 396 | "# Correr el programa con un numero real en base 10 para obtener su representacion binaria\n", 397 | "binarycode(812.15)" 398 | ] 399 | }, 400 | { 401 | "cell_type": "markdown", 402 | "metadata": { 403 | "id": "JUAsInTJgVZj" 404 | }, 405 | "source": [ 406 | "#### Algunos trucos con Python para obtener este resultado" 407 | ] 408 | }, 409 | { 410 | "cell_type": "code", 411 | "execution_count": null, 412 | "metadata": { 413 | "id": "_TD-TGC_gVZj", 414 | "outputId": "e75df87e-eacb-4a40-f7f5-6510d8c4c670" 415 | }, 416 | "outputs": [ 417 | { 418 | "data": { 419 | "text/plain": [ 420 | "255" 421 | ] 422 | }, 423 | "execution_count": 26, 424 | "metadata": {}, 425 | "output_type": "execute_result" 426 | } 427 | ], 428 | "source": [ 429 | "binary_string = '11111111' \n", 430 | "int(binary_string,2) " 431 | ] 432 | }, 433 | { 434 | "cell_type": "code", 435 | "execution_count": null, 436 | "metadata": { 437 | "id": "gp_YjuDIgVZk", 438 | "outputId": "61ff1b6f-1909-4287-e250-046c55dd6b0e" 439 | }, 440 | "outputs": [ 441 | { 442 | "data": { 443 | "text/plain": [ 444 | "'11111111'" 445 | ] 446 | }, 447 | "execution_count": 27, 448 | "metadata": {}, 449 | "output_type": "execute_result" 450 | } 451 | ], 452 | "source": [ 453 | "decimal_number = 255 \n", 454 | "\"{:b}\".format(decimal_number) " 455 | ] 456 | }, 457 | { 458 | "cell_type": "markdown", 459 | "metadata": { 460 | "id": "ZKrfSpNLgVZk" 461 | }, 462 | "source": [ 463 | "Este código esta tomado/adaptado del original en:\n", 464 | "" 465 | ] 466 | }, 467 | { 468 | "cell_type": "markdown", 469 | "metadata": { 470 | "id": "pnbrwCqFgVZl" 471 | }, 472 | "source": [ 473 | "## Números de punto flotante representados en la computadora como fracciones binarias" 474 | ] 475 | }, 476 | { 477 | "cell_type": "markdown", 478 | "metadata": { 479 | "id": "v3znyLT-gVZl" 480 | }, 481 | "source": [ 482 | "Ejempo: La fracción en base 10:\n", 483 | "$$\n", 484 | "0.25=\\frac{1}{10}+\\frac{2}{100}+\\frac{5}{1000}\n", 485 | "$$\n", 486 | "Por otro lado la fracción binaria\n", 487 | "$$\n", 488 | "0.001=\\frac{0}{2}+\\frac{0}{4}+\\frac{1}{8}\n", 489 | "$$\n", 490 | "Estas dos fracciones son idénticas, solo que la primera esta en base 10\n", 491 | "y la seguna esta en base 2. Desafortunadamente la mayoría de las fracciones en base 10 no \n", 492 | "se pueden representar de forma exacta en base 2." 493 | ] 494 | }, 495 | { 496 | "cell_type": "markdown", 497 | "metadata": { 498 | "id": "MNInwJMYgVZl" 499 | }, 500 | "source": [ 501 | "## N\\'umeros en base 10 que no se pueden representar exactamente en binario" 502 | ] 503 | }, 504 | { 505 | "cell_type": "markdown", 506 | "metadata": { 507 | "id": "Um3yPt2igVZm" 508 | }, 509 | "source": [ 510 | "La fracción $\\frac{1}{3}$ se puede aproximar en base 10, como $0.3$, ó como $0.33$ o mejor aún $0.333$, \n", 511 | "esto continua y sin importar cuantos dígitos agreguemos, el resultado no será nunca exacto, pues esta \n", 512 | "fracción tiene una expansión decimal periódica e infinita. Lo mismo pasa con las fracciones binarias. \n", 513 | "\n", 514 | "Representación en base 2 de la fracción en base 10: $\\frac{1}{10}$\n", 515 | "En base 2, la fracción $\\frac{1}{10}$ tiene una representación periódica, infinita:\n", 516 | "$$\n", 517 | "\\frac{1}{10}=0.0001100110011001100110011001100110011001100110011...\n", 518 | "$$\n" 519 | ] 520 | } 521 | ], 522 | "metadata": { 523 | "kernelspec": { 524 | "display_name": "Python 3", 525 | "language": "python", 526 | "name": "python3" 527 | }, 528 | "language_info": { 529 | "codemirror_mode": { 530 | "name": "ipython", 531 | "version": 3 532 | }, 533 | "file_extension": ".py", 534 | "mimetype": "text/x-python", 535 | "name": "python", 536 | "nbconvert_exporter": "python", 537 | "pygments_lexer": "ipython3", 538 | "version": "3.8.5" 539 | }, 540 | "colab": { 541 | "name": "DecToBinaryToDec.ipynb", 542 | "provenance": [], 543 | "toc_visible": true, 544 | "include_colab_link": true 545 | } 546 | }, 547 | "nbformat": 4, 548 | "nbformat_minor": 0 549 | } -------------------------------------------------------------------------------- /01_AritmeticaPuntoFlotante/02_MetodoEstableEstudiante.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "view-in-github", 7 | "colab_type": "text" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "id": "1bbc3bff", 16 | "metadata": { 17 | "deletable": false, 18 | "editable": false, 19 | "nbgrader": { 20 | "cell_type": "markdown", 21 | "checksum": "e290683858ddcaccde0bf37f46db5888", 22 | "grade": false, 23 | "grade_id": "cell-213723258773d10e", 24 | "locked": true, 25 | "schema_version": 3, 26 | "solution": false, 27 | "task": false 28 | }, 29 | "id": "1bbc3bff" 30 | }, 31 | "source": [ 32 | "\n", 33 | "

Noción de método numéricamente estable

\n", 34 | "
\n", 35 | " \n", 36 | "
Profesora: \tUrsula Xiomara Iturrarán Viveros
\n", 37 | "
Ayudante: Juan Pablo Cordero Santiago
\n", 38 | "
MACTII: Edgar Dominguez Rosas y José Antonio Borras Gutiérrez
\n", 39 | "
Materia: Análisis Numérico
\n", 40 | "
" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "id": "34030541", 47 | "metadata": { 48 | "id": "34030541" 49 | }, 50 | "outputs": [], 51 | "source": [ 52 | "import numpy as np\n", 53 | "import matplotlib.pyplot as plt" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "id": "b44075f6", 59 | "metadata": { 60 | "deletable": false, 61 | "editable": false, 62 | "nbgrader": { 63 | "cell_type": "markdown", 64 | "checksum": "ba1c3c8cd8c0f193e07ee610c6181caf", 65 | "grade": false, 66 | "grade_id": "cell-96817423271a859b", 67 | "locked": true, 68 | "schema_version": 3, 69 | "solution": false, 70 | "task": false 71 | }, 72 | "id": "b44075f6" 73 | }, 74 | "source": [ 75 | "En el análisis numérico, para resolver un problema puede existir más de un método númerico que aproxime la solución y puede preferirse un método sobre otro, dependiendo de las características de dichos métodos. Un algoritmo, puede llegar a la solución en menos iteraciones que otro, por ejemplo. Otra catacterística que resulta clave es la estabilidad numérica, pues cuando un método no es estable se debe tener especial precaución en los valores de entrada que se utilizan. A continuación se muestran una definición y un algoritmo que ilustran el concepto de *método numéricamente estable*." 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "id": "e08447fa", 81 | "metadata": { 82 | "deletable": false, 83 | "editable": false, 84 | "nbgrader": { 85 | "cell_type": "markdown", 86 | "checksum": "601d35e451a0ff4a448da00f277e1507", 87 | "grade": false, 88 | "grade_id": "cell-a3466ccd7e2f3e63", 89 | "locked": true, 90 | "schema_version": 3, 91 | "solution": false, 92 | "task": false 93 | }, 94 | "id": "e08447fa" 95 | }, 96 | "source": [ 97 | "## Noción de método numéricamente estable\n", 98 | "\n", 99 | "Un método, es considerado estable si pequeños cambios (o perturbaciones) en los valores iniciales producen cambios pequeños en el resultado final. Cuando es posible tener pequeños cambios en los valores iniciales, que se traducen a grandes cambios en los resultados finales, el método es inestable. Algunos métodos solo son estables para cierta se selección de datos iniciales, este tipo de métodos se nombran condicionalmente estables." 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "id": "3504a57c", 105 | "metadata": { 106 | "deletable": false, 107 | "editable": false, 108 | "nbgrader": { 109 | "cell_type": "markdown", 110 | "checksum": "754adb4a36dcecff9578f3442b113043", 111 | "grade": false, 112 | "grade_id": "cell-be565e572df2c065", 113 | "locked": true, 114 | "schema_version": 3, 115 | "solution": false, 116 | "task": false 117 | }, 118 | "id": "3504a57c" 119 | }, 120 | "source": [ 121 | "## Ecuación logística\n", 122 | "\n", 123 | "Consideremos, por ejemplo, un algoritmo que calcule la sucesión de números $x_n$ definidos por la siguiente fórmula de recurrencia:\n", 124 | "\n", 125 | "\n", 126 | "$$ x_{n+1} = r x_n \\left( 1 - x_n \\right) $$\n", 127 | "Con $x \\in [0,1]$ y $r \\in [0,4]$\n", 128 | "\n", 129 | "La ecuación anterior es conocida como <*logistic map*> o *ecuación logísitica* y poder describir su comportamiento, en general requiere de un estudio más detallado; sin embargo, por el momento solo tomaremos la fórmula de recurrencia como ejemplo para introducir la noción de método numéricamente estable.\n", 130 | "\n", 131 | "Comencemos por calcular los 15 primeros términos de la sucesión que se obtiene si $x_0=0.8$ y $r=2.6$:" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "id": "7514dcbf", 138 | "metadata": { 139 | "id": "7514dcbf" 140 | }, 141 | "outputs": [], 142 | "source": [ 143 | "num_iters=15\n", 144 | "\n", 145 | "x=0.8 ; n=0\n", 146 | "print('x_0={}'.format(x) ) #imprime primer valor\n", 147 | "while nnum_iters\n", 148 | " x_sig=2.6*x*(1-x) #ec. logísitca\n", 149 | " x=x_sig \n", 150 | " n=n+1 # n <-- (n+1)\n", 151 | " print('x_{}={}'.format(n,x) ) #imprime nuevo valor\n" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "id": "22884ea0", 157 | "metadata": { 158 | "deletable": false, 159 | "editable": false, 160 | "nbgrader": { 161 | "cell_type": "markdown", 162 | "checksum": "4eff94e8ad264ed863a17afd24d8fec7", 163 | "grade": false, 164 | "grade_id": "cell-7a738a1d6f12b484", 165 | "locked": true, 166 | "schema_version": 3, 167 | "solution": false, 168 | "task": false 169 | }, 170 | "id": "22884ea0" 171 | }, 172 | "source": [ 173 | "## Ejercicio\n", 174 | "\n", 175 | "Modifica el código anterior para que se detenga, no por el número de iteraciones, sino cuando $|x_{n+1}-x_n|<0.0001$" 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": null, 181 | "id": "de8bc40c", 182 | "metadata": { 183 | "deletable": false, 184 | "nbgrader": { 185 | "cell_type": "code", 186 | "checksum": "a2c187efef54ac8f2027546a45aebf7f", 187 | "grade": true, 188 | "grade_id": "cell-203e8f98fe74522e", 189 | "locked": false, 190 | "points": 0, 191 | "schema_version": 3, 192 | "solution": true, 193 | "task": false 194 | }, 195 | "id": "de8bc40c" 196 | }, 197 | "outputs": [], 198 | "source": [ 199 | "# YOUR CODE HERE\n", 200 | "raise NotImplementedError()" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "id": "e65f647b", 206 | "metadata": { 207 | "deletable": false, 208 | "editable": false, 209 | "nbgrader": { 210 | "cell_type": "markdown", 211 | "checksum": "9c8b9a357ff43975a67c486209981a89", 212 | "grade": false, 213 | "grade_id": "cell-9c2b067f07c69d43", 214 | "locked": true, 215 | "schema_version": 3, 216 | "solution": false, 217 | "task": false 218 | }, 219 | "id": "e65f647b" 220 | }, 221 | "source": [ 222 | "Como podemos ver, la sucesión parece estar convergiendo a un número. Para ilustrar mejor este comportamiento podemos graficar estos valores y para ello podemos definir una función que almacene los valores de la sucesión en una lista." 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": null, 228 | "id": "d44be3f1", 229 | "metadata": { 230 | "id": "d44be3f1" 231 | }, 232 | "outputs": [], 233 | "source": [ 234 | "def logmapN(x0,r,N):\n", 235 | " x=x0 # valor inicial x0\n", 236 | " suc_x=[x] #inicia la lista suc_x con el valor de x\n", 237 | " for i in range(N): # comienza iteración\n", 238 | " x_sig=r*x*(1-x) #ec. logística\n", 239 | " x=x_sig \n", 240 | " suc_x.append(x) #el nuevo valor se anexa a la lista\n", 241 | " return np.array(suc_x)\n", 242 | "\n", 243 | "x0=0.8 ; r=2.6 ; num_iters=10\n", 244 | "logmapN(x0,r,num_iters) #probamos función logmapN" 245 | ] 246 | }, 247 | { 248 | "cell_type": "markdown", 249 | "id": "2777fef6", 250 | "metadata": { 251 | "deletable": false, 252 | "editable": false, 253 | "nbgrader": { 254 | "cell_type": "markdown", 255 | "checksum": "e0606dbb41e6b25bf3d51ac9ca54c7dc", 256 | "grade": false, 257 | "grade_id": "cell-cdf5f8056a3a15df", 258 | "locked": true, 259 | "schema_version": 3, 260 | "solution": false, 261 | "task": false 262 | }, 263 | "id": "2777fef6" 264 | }, 265 | "source": [ 266 | "Graficando estos valores:" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": null, 272 | "id": "cbea1791", 273 | "metadata": { 274 | "id": "cbea1791" 275 | }, 276 | "outputs": [], 277 | "source": [ 278 | "x0=0.8 ; r=2.6 ; num_iters=10\n", 279 | "lista_x=range(num_iters+1)\n", 280 | "lista_y=logmapN(x0,r,num_iters)\n", 281 | "\n", 282 | "fg=plt.figure(figsize=(8,6))\n", 283 | "plt.plot(lista_x,lista_y,marker='o',markerfacecolor='r')\n", 284 | "plt.title(r'$x_{n+1}= '+str(r)+'x_n(1-x_n)$')\n", 285 | "plt.xticks(lista_x)\n", 286 | "plt.xlabel('n')\n", 287 | "plt.ylabel('x(n)')\n", 288 | "plt.grid()\n", 289 | "plt.show()" 290 | ] 291 | }, 292 | { 293 | "cell_type": "markdown", 294 | "id": "56b441ed", 295 | "metadata": { 296 | "deletable": false, 297 | "editable": false, 298 | "nbgrader": { 299 | "cell_type": "markdown", 300 | "checksum": "51d5fc14ea5e13f03a806575472c536b", 301 | "grade": false, 302 | "grade_id": "cell-592f1f5ba489b36d", 303 | "locked": true, 304 | "schema_version": 3, 305 | "solution": false, 306 | "task": false 307 | }, 308 | "id": "56b441ed" 309 | }, 310 | "source": [ 311 | "Ahora, veamos qué sucede si conservamos el mismo valor de $r=2.6$ y usamos dos valores iniciales diferentes $x_0^{(a)}=0.8$ y $x_0^{(b)}=0.7$:" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": null, 317 | "id": "3ba0e61c", 318 | "metadata": { 319 | "id": "3ba0e61c" 320 | }, 321 | "outputs": [], 322 | "source": [ 323 | "def logmapPlot(x0_a,x0_b,r,num_iters):\n", 324 | " \n", 325 | " lista_x=range(num_iters+1) #lista de enteros n\n", 326 | " \n", 327 | " #----------- Cálculo de los valores de la sucesión -------------\n", 328 | " lista_y1=logmapN(x0_a,r,num_iters) #lista de valores x_n obtenidos para el valor inicial x0_a\n", 329 | " lista_y2=logmapN(x0_b,r,num_iters) #lista de valores x_n obtenidos para el valor inicial x0_b\n", 330 | " \n", 331 | " #-------------------- Graficación #----------------------------\n", 332 | " fg=plt.figure(figsize=(8,6)) #tamaño de la gráfica\n", 333 | " plt.plot(lista_x,lista_y1,marker='+',color='b',label=r'$x_0={}$'.format(x0_a) )#Gráfica usando el valor inicial x0_a\n", 334 | " plt.plot(lista_x,lista_y2,marker='x',color='g',label=r'$x_0={}$'.format(x0_b) )#Gráfica usando el valor inicial x0_b\n", 335 | " plt.legend() \n", 336 | " plt.title(r'$x_{n+1}= '+str(r)+'x_n(1-x_n)$') #título\n", 337 | " plt.xticks(lista_x) \n", 338 | " plt.xlabel('n') # etiqueta eje X\n", 339 | " plt.ylabel('x(n)') #etiqueta eje y\n", 340 | " plt.grid() #cuadrícula\n", 341 | " plt.show()\n", 342 | " #----------------------------------------------------------------\n", 343 | " \n", 344 | " return None\n", 345 | "\n", 346 | "x0_a=0.8; x0_b=0.7\n", 347 | "r=2.6 ; num_iter=10\n", 348 | "logmapPlot(x0_a,x0_b,r,num_iter)" 349 | ] 350 | }, 351 | { 352 | "cell_type": "markdown", 353 | "id": "ea53fbce", 354 | "metadata": { 355 | "deletable": false, 356 | "editable": false, 357 | "nbgrader": { 358 | "cell_type": "markdown", 359 | "checksum": "f2b8e2a8b548a347cad08a8333b98a05", 360 | "grade": false, 361 | "grade_id": "cell-caa5c43ba901cf88", 362 | "locked": true, 363 | "schema_version": 3, 364 | "solution": false, 365 | "task": false 366 | }, 367 | "id": "ea53fbce" 368 | }, 369 | "source": [ 370 | "Ahora, observemos el comportamiento de las sucesiones si:\n", 371 | "\n", 372 | "**(a)** Permanece $r=2.6$, pero alejamos más los valores iniciales, por ejemplo, tomando $x_0^{(a)}=0.95$ y $x_0^{(b)}=0.14$:\n", 373 | "\n", 374 | "**(b)** Cambiamos los parámetros a $x_0^{(a)}=0.95 , \\quad x_0^{(b)}=0.15,\\quad r=0.9,\\quad n_{iter}=12 $ \n", 375 | "\n", 376 | "**(c)** Cambiamos los parámetros a $x_0^{(a)}=0.3333 , \\quad x_0^{(b)}=0.3332,\\quad r=4,\\quad n_{iter}=30 $ " 377 | ] 378 | }, 379 | { 380 | "cell_type": "markdown", 381 | "id": "ff64672f", 382 | "metadata": { 383 | "deletable": false, 384 | "editable": false, 385 | "nbgrader": { 386 | "cell_type": "markdown", 387 | "checksum": "b95668bf85c4f6a17a414971fdf72c19", 388 | "grade": false, 389 | "grade_id": "cell-4e55f09a748ca44a", 390 | "locked": true, 391 | "schema_version": 3, 392 | "solution": false, 393 | "task": false 394 | }, 395 | "id": "ff64672f" 396 | }, 397 | "source": [ 398 | "## (a)" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": null, 404 | "id": "5cb2f9fb", 405 | "metadata": { 406 | "id": "5cb2f9fb" 407 | }, 408 | "outputs": [], 409 | "source": [ 410 | "x0_a=0.95 ; x0_b=0.14\n", 411 | "r=2.6 ; num_iter=10\n", 412 | "logmapPlot(x0_a,x0_b,r,num_iter)" 413 | ] 414 | }, 415 | { 416 | "cell_type": "markdown", 417 | "id": "3206ce44", 418 | "metadata": { 419 | "deletable": false, 420 | "editable": false, 421 | "nbgrader": { 422 | "cell_type": "markdown", 423 | "checksum": "637c21e2f5b72ef2656564b90d8c882c", 424 | "grade": false, 425 | "grade_id": "cell-13a39099ddcf787f", 426 | "locked": true, 427 | "schema_version": 3, 428 | "solution": false, 429 | "task": false 430 | }, 431 | "id": "3206ce44" 432 | }, 433 | "source": [ 434 | "## (b)" 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": null, 440 | "id": "e652e769", 441 | "metadata": { 442 | "id": "e652e769" 443 | }, 444 | "outputs": [], 445 | "source": [ 446 | "x0_a=0.55 ; x0_b=0.15\n", 447 | "r=0.9 ; num_iter=12\n", 448 | "logmapPlot(x0_a,x0_b,r,num_iter)" 449 | ] 450 | }, 451 | { 452 | "cell_type": "markdown", 453 | "id": "62d27929", 454 | "metadata": { 455 | "deletable": false, 456 | "editable": false, 457 | "nbgrader": { 458 | "cell_type": "markdown", 459 | "checksum": "d8d39a8c43ae8820fb84e2075fd4b8cc", 460 | "grade": false, 461 | "grade_id": "cell-1e5aaea639822d94", 462 | "locked": true, 463 | "schema_version": 3, 464 | "solution": false, 465 | "task": false 466 | }, 467 | "id": "62d27929" 468 | }, 469 | "source": [ 470 | "## (c)" 471 | ] 472 | }, 473 | { 474 | "cell_type": "code", 475 | "execution_count": null, 476 | "id": "464ae9ec", 477 | "metadata": { 478 | "id": "464ae9ec" 479 | }, 480 | "outputs": [], 481 | "source": [ 482 | "x0_a=0.3333 ; x0_b=0.3332\n", 483 | "r=4.0 ; num_iter=35\n", 484 | "logmapPlot(x0_a,x0_b,r,num_iter)" 485 | ] 486 | }, 487 | { 488 | "cell_type": "markdown", 489 | "id": "d67bea46", 490 | "metadata": { 491 | "deletable": false, 492 | "editable": false, 493 | "nbgrader": { 494 | "cell_type": "markdown", 495 | "checksum": "0b02e3a3b29bb966b80686784a26f81c", 496 | "grade": false, 497 | "grade_id": "cell-25584faad527425e", 498 | "locked": true, 499 | "schema_version": 3, 500 | "solution": false, 501 | "task": false 502 | }, 503 | "id": "d67bea46" 504 | }, 505 | "source": [ 506 | "Observando las gráficas de los tres incisos podemos decir que en el inciso **(a)** los valores convergen al mismo valor a pesar de estar muy alejados entre sí. Después, al cambiar el valor de $r$ en el inciso **(b)** se tiene un nuevo valor de convergencia; pero también puede notarse que a medida que las iteraciones avanzan, los valores $x_n$ de ambas sucesiones se van aproximando entre sí. Sin embargo, en el caso **(c)** se tiene que, aunque los valores iniciales están muy próximos entre sí las sucesiones se van alejando poco a poco hasta tener un comportamiento totalmente distinto.\n", 507 | "\n", 508 | "Así, los ejemplos **(a)** y **(b)** nos sirven para ilustrar un método numéricamente estable mientras que el inciso **(c)** sirve para ilustrar un método inestable.\n", 509 | "\n", 510 | "La estabilidad es un concepto que reaparece frecuentemente en el análisis numérico. En efecto, en la exposición de algunos de los métodos y algoritmos posteriores se analiza a detalle bajo qué condiciones se da la estabilidad; sin embargo, la idea es que con la noción introducida por estos ejemplos baste para seguir la discución acerca de la estabilidad del método, cuando sea el caso." 511 | ] 512 | }, 513 | { 514 | "cell_type": "markdown", 515 | "id": "d72d906f", 516 | "metadata": { 517 | "deletable": false, 518 | "editable": false, 519 | "nbgrader": { 520 | "cell_type": "markdown", 521 | "checksum": "4082a1a835dbc6a2041ab8bcb6feb897", 522 | "grade": false, 523 | "grade_id": "cell-7e46b4ca2f44b279", 524 | "locked": true, 525 | "schema_version": 3, 526 | "solution": false, 527 | "task": false 528 | }, 529 | "id": "d72d906f" 530 | }, 531 | "source": [ 532 | "## Ejercicio\n", 533 | "\n", 534 | "Modifica la función $\\texttt{logmapPlot}$ para definir una nueva función $\\texttt{logmapPlotDiff}$ que en lugar de graficar ambas sucesiones grafique la diferencia de las suceciones con respecto a la diferencia de los valores iniciales, esto es:\n", 535 | "$$ w_n = \\frac{|x_n^{(a)}- x_n^{(b)}|}{|x_0^{(a)}- x_0^{(b)}|}$$" 536 | ] 537 | }, 538 | { 539 | "cell_type": "code", 540 | "execution_count": null, 541 | "id": "8f327a47", 542 | "metadata": { 543 | "deletable": false, 544 | "nbgrader": { 545 | "cell_type": "code", 546 | "checksum": "fa12e713df9cb4fd642aba209afc82b0", 547 | "grade": true, 548 | "grade_id": "cell-44b36c3e77151ddc", 549 | "locked": false, 550 | "points": 0, 551 | "schema_version": 3, 552 | "solution": true, 553 | "task": false 554 | }, 555 | "id": "8f327a47" 556 | }, 557 | "outputs": [], 558 | "source": [ 559 | "def logmapPlotDiff(x0_a,x0_b,r,num_iters):\n", 560 | " # YOUR CODE HERE\n", 561 | " raise NotImplementedError()\n", 562 | " return None" 563 | ] 564 | }, 565 | { 566 | "cell_type": "code", 567 | "execution_count": null, 568 | "id": "0c38d013", 569 | "metadata": { 570 | "id": "0c38d013" 571 | }, 572 | "outputs": [], 573 | "source": [ 574 | "x0_a=0.3333 ; x0_b=0.3332\n", 575 | "r=4.0 ; num_iter=35\n", 576 | "logmapPlotDiff(x0_a,x0_b,r,num_iter)" 577 | ] 578 | }, 579 | { 580 | "cell_type": "code", 581 | "execution_count": null, 582 | "id": "14c16075", 583 | "metadata": { 584 | "id": "14c16075" 585 | }, 586 | "outputs": [], 587 | "source": [ 588 | "x0_a=0.95 ; x0_b=0.14\n", 589 | "r=2.6 ; num_iter=10\n", 590 | "logmapPlotDiff(x0_a,x0_b,r,num_iter)" 591 | ] 592 | } 593 | ], 594 | "metadata": { 595 | "kernelspec": { 596 | "display_name": "Python 3 (ipykernel)", 597 | "language": "python", 598 | "name": "python3" 599 | }, 600 | "language_info": { 601 | "codemirror_mode": { 602 | "name": "ipython", 603 | "version": 3 604 | }, 605 | "file_extension": ".py", 606 | "mimetype": "text/x-python", 607 | "name": "python", 608 | "nbconvert_exporter": "python", 609 | "pygments_lexer": "ipython3", 610 | "version": "3.8.10" 611 | }, 612 | "colab": { 613 | "name": "02_MetodoEstableEstudiante.ipynb", 614 | "provenance": [], 615 | "include_colab_link": true 616 | } 617 | }, 618 | "nbformat": 4, 619 | "nbformat_minor": 5 620 | } -------------------------------------------------------------------------------- /06_EcuacionesNoLineales/02_SistemasNoLineales.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "02_SistemasNoLineales.ipynb", 7 | "provenance": [], 8 | "toc_visible": true, 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "display_name": "Python 3", 13 | "language": "python", 14 | "name": "python3" 15 | }, 16 | "language_info": { 17 | "codemirror_mode": { 18 | "name": "ipython", 19 | "version": 3 20 | }, 21 | "file_extension": ".py", 22 | "mimetype": "text/x-python", 23 | "name": "python", 24 | "nbconvert_exporter": "python", 25 | "pygments_lexer": "ipython3", 26 | "version": "3.7.6" 27 | } 28 | }, 29 | "cells": [ 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "view-in-github", 34 | "colab_type": "text" 35 | }, 36 | "source": [ 37 | "\"Open" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": { 43 | "id": "eXH23mwZcxi-" 44 | }, 45 | "source": [ 46 | "\n", 47 | "

Sistemas No Lineales

\n", 48 | "
\n", 49 | " \n", 50 | "
Profesora: \tUrsula Xiomara Iturrarán Viveros
\n", 51 | "
Ayudante: Juan Pablo Cordero Santiago
\n", 52 | "
Materia: Análisis Numérico
\n", 53 | "
" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": { 59 | "id": "Eh716bKucxjA" 60 | }, 61 | "source": [ 62 | "## Introducción\n", 63 | "\n", 64 | "Múltiples problemas de las ciencias exactas implican la resolución de sistemas de $N$ ecuaciones no lineales con $N$ incógnitas\n", 65 | "\n", 66 | "Un método es linealizar y resolver, repetidamente. Esta es la misma estrategia que usa el método de Newton para resolver una sola ecuación no lineal.\n", 67 | "\n", 68 | "Así que es natural pensar en una forma de extender esta forma de resolver ecuaciones no lineales, de manera que sea posible resolver un sistema de ecuaciones no lineales.\n", 69 | "\n", 70 | "En el caso general, un sistema de *N ecuaciones no lineales con N incógnitas* $x_{i}$ se puede presentar en la forma.\n", 71 | "\n", 72 | "$$Sistema = \\begin{cases}\n", 73 | "f_{1}(x_{1},x_{2},\\ldots,x_{n}) & =0\\\\\n", 74 | "f_{2}(x_{1},x_{2},\\ldots,x_{n}) & =0 \\\\\n", 75 | "\\vdots \\\\\n", 76 | "f_{n}(x_{1},x_{2},\\ldots,x_{n}) & =0\n", 77 | "\\end{cases}$$\n", 78 | "\n", 79 | "En caso de que el sistema fuera de ecuaciones lineales, podemos representar este sistema de *N ecuaciones con N incognitas* mediante su forma matricial.\n", 80 | "\n", 81 | "$$A\\vec{x}=\\vec{0}$$\n", 82 | "\n", 83 | "Con $A\\in M_{n\\times n}$ y $\\vec{x}, \\vec{b} \\in \\mathbb{R}^{n}$, es decir.\n", 84 | "\n", 85 | "$$\\left(\\begin{array}{ccccccc}\n", 86 | "a_{11} & a_{12} & \\cdots & \\cdots & \\cdots & \\cdots & a_{1n}\\\\\n", 87 | "a_{21} & a_{22} & \\cdots & \\cdots & \\cdots & \\cdots & a_{2n}\\\\\n", 88 | "\\vdots & \\ddots & \\ddots & \\ddots & \\ddots & \\ddots & \\vdots\\\\\n", 89 | "\\vdots & \\ddots & \\ddots & \\ddots & \\ddots & \\ddots & \\vdots\\\\\n", 90 | "\\vdots & \\ddots & \\ddots & \\ddots & \\ddots & \\ddots & \\vdots\\\\\n", 91 | "a_{n1} & \\cdots & \\cdots & \\cdots & \\cdots & \\cdots & a_{nn}\n", 92 | "\\end{array}\\right)\\left(\\begin{array}{c}\n", 93 | "x_{1}\\\\\n", 94 | "x_{2}\\\\\n", 95 | "\\vdots\\\\\n", 96 | "\\vdots\\\\\n", 97 | "\\vdots\\\\\n", 98 | "x_{n}\n", 99 | "\\end{array}\\right)=\\left(\\begin{array}{c}\n", 100 | "0\\\\\n", 101 | "0\\\\\n", 102 | "\\vdots\\\\\n", 103 | "\\vdots\\\\\n", 104 | "\\vdots\\\\\n", 105 | "0\n", 106 | "\\end{array}\\right)$$\n", 107 | "\n", 108 | "Usando notación vectorial, podemos reescribir el sistema en una forma más elegante:\n", 109 | "\n", 110 | "$$ F(\\vec{X})=\\vec{0}$$\n", 111 | "\n", 112 | "Definiendo vectores columna como\n", 113 | "\n", 114 | "$$F\t=\t\\left[f_{1},f_{2},\\ldots,f_{N}\\right]^{T}$$\n", 115 | "\n", 116 | "$$ \\vec{X}\t=\t\\left[x_{1,}x_{2},\\ldots,x_{N}\\right]$$\n", 117 | "\n", 118 | "$$ \\vec{0}\t=\t\\left[x_{1,}x_{2},\\ldots,x_{N}\\right]^{T}$$\n", 119 | "\n", 120 | "Si recordamos la expresión del método de Newton para ecuaciones no lineales es.\n", 121 | "\n", 122 | "$$ x_{k+1}=x_{k}-\\frac{f\\left(x_{k}\\right)}{f^{'}\\left(x_{k}\\right)}$$\n", 123 | "\n", 124 | "Donde el subíndice $k$ indica el número de la iteración actual.\n", 125 | "\n", 126 | "No es muy difícil extender la expresión anterior a sistemas de ecuaciones no lineales, lo que nos da como resultado la forma iterativa para resolver sistemas de ecuaciones no lineales mediante el metodo de Newton.\n", 127 | "\n", 128 | "$$\\vec{X}^{\\left(k+1\\right)}=\\vec{X}^{\\left(k\\right)}-\\left[F'\\left(\\vec{X}^{(k)}\\right)\\right]^{-1}F\\left(\\vec{X}^{(k)}\\right)$$" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": { 134 | "id": "ORb_b64xcxjA" 135 | }, 136 | "source": [ 137 | "## Desarrollo\n", 138 | "\n", 139 | "El desarrollo para llegar al método de Newton para sistemas de ecuaciones lineales se mostrara a continuación y para ello tomaremos las siguientes 3 ecuaciones no lineales\n", 140 | "\n", 141 | "$$Sistema =\\begin{cases}\n", 142 | "f_{1}(x_{1},x_{2},x_{3}) & =0\\\\\n", 143 | "f_{2}(x_{1},x_{2},x_{3}) & =0 \\quad \\tag{1}\\\\\n", 144 | "f_{3}(x_{1},x_{2},x_{3}) & =0\n", 145 | "\\end{cases}$$\n", 146 | "\n", 147 | "Si se aplica el desarrollo del polinomio de Taylor centrado en $\\vec{0}$ para 3 variables $i=1,2,3$, se tiene una solución aproximada para cada $f_{i}$.\n", 148 | "\n", 149 | "$$P_{i}(x_{1},x_{2},x_{3}) \\thickapprox f_{i}(0,0,0)+\\frac{\\delta f_{i}}{\\delta x_{1}}x_{1}+\\frac{\\delta f_{i}}{\\delta x_{2}}x_{2}+\\frac{\\delta f_{i}}{\\delta x_{3}}x_{3}$$ \n", 150 | "\n", 151 | "Supongamos que el vector $\\vec{X}^{(0)}=(x_{1}^{(0)},x_{2}^{(0)},x_{3}^{(0)})$ es una solución aproximada de (1). Sea $\\vec{H}= \\left(h_{1},h_{2},h_{3}\\right)$ una corrección de la solución inicial, de modo que.\n", 152 | "\n", 153 | "$$\\vec{X}^{(1)}=\\vec{X}^{(0)}+\\vec{H}=(x_{1}^{(0)}+h_{1},x_{2}^{(0)}+h_{2},x_{3}^{(0)}+h_{3})$$ \n", 154 | " \n", 155 | "La aproximación $\\vec{X}^{(1)}$ es una mejor aproximación y además.\n", 156 | "\n", 157 | "$$\\vec{H}=\\vec{X}^{(1)}-\\vec{X}^{(0)}=(x_{1}^{(1)}-x_{1}^{(0)},x_{2}^{(1)}-x_{2}^{(0)},x_{3}^{(1)}-x_{3}^{(0)})$$\n", 158 | "\n", 159 | "Descartando los términos de orden superior en el desarrollo de Taylor, una mejor aproximación esta dada por.\n", 160 | "\n", 161 | "$$f_{i}(x_{1}^{(1)},x_{2}^{(1)},x_{3}^{(1)})=f_{i}(x_{1}^{(0)},x_{2}^{(0)},x_{3}^{(0)})+\\frac{\\delta f_{i}}{\\delta x_{1}}(x_{1}^{(1)}-x_{1}^{(0)})+\\frac{\\delta f_{i}}{\\delta x_{2}}(x_{2}^{(1)}-x_{2}^{(0)})+\\frac{\\delta f_{i}}{\\delta x_{3}}(x_{3}^{(1)}-x_{3}^{(0)})$$\n", 162 | "\n", 163 | "Reescribiendo la ecuación anterior de manera más compacta.\n", 164 | "\n", 165 | "$$f_{i}(x_{1}+h_{1},x_{2}+h_{2},x_{3}+h_{1})=f_{i}(x_{1},x_{2},x_{3})+\\frac{\\delta f_{i}}{\\delta x_{1}}h_{1}+\\frac{\\delta f_{i}}{\\delta x_{2}}h_{2}+\\frac{\\delta f_{i}}{\\delta x_{3}}h_{3}\\tag{2} $$\n", 166 | "\n", 167 | "Ya que en $(1)$ el sistema esta igualado a $\\vec{0}$, entonces.\n", 168 | "\n", 169 | "$$f_{i}(x_{1}+h_{1},x_{2}+h_{2},x_{3}+h_{1})\\thickapprox 0$$\n", 170 | "\n", 171 | "En notación vectorial, se tiene.\n", 172 | "\n", 173 | "$$\\vec{0}\\thickapprox F\\left(\\vec{X}^{(0)}+\\vec{H}\\right)\\thickapprox F\\left(\\vec{X}^{(0)}\\right)+F'\\left(\\vec{X}^{(0)}\\right)\\vec{H} \\tag{3}$$\n", 174 | "\n", 175 | "Donde la **matriz Jacobiana ó Jacobiano**, esta definida por \n", 176 | "\n", 177 | "$$F'\\left(\\vec{X}^{(0)}\\right)=\\left[\\begin{array}{ccc}\n", 178 | "\\frac{\\delta f_{1}}{\\delta x_{1}} & \\frac{\\delta f_{1}}{\\delta x_{2}} & \\frac{\\delta f_{1}}{\\delta x_{3}}\\\\\n", 179 | "\\frac{\\delta f_{2}}{\\delta x_{1}} & \\frac{\\delta f_{2}}{\\delta x_{2}} & \\frac{\\delta f_{2}}{\\delta x_{3}}\\\\\n", 180 | "\\frac{\\delta f_{3}}{\\delta x_{1}} & \\frac{\\delta f_{3}}{\\delta x_{2}} & \\frac{\\delta f_{3}}{\\delta x_{3}}\n", 181 | "\\end{array}\\right] $$\n", 182 | "\n", 183 | "En la primera iteración todas las derivadas parciales se evalúan en $\\vec{X}^{(0)}$, es decir.\n", 184 | "\n", 185 | "$$\\begin{array}{cc}\n", 186 | "\\frac{\\delta f_{i}}{x_{j}}=\\frac{\\delta f_{i}\\left(\\vec{X}^{(0)}\\right)}{x_{j}} & \\quad\\forall i,j=1,2,3\\end{array}$$\n", 187 | "\n", 188 | "También suponemos que la matriz Jacobiana es no singular, por lo que su inversa existe. Por lo tanto resolviendo para $H$ en (3), se tiene.\n", 189 | "\n", 190 | "$$\\vec{0}\\thickapprox F\\left(\\vec{X}^{(0)}\\right)+F'\\left(\\vec{X}^{(0)}\\right)\\vec{H}$$\n", 191 | "\n", 192 | "$$ \\Rightarrow F'\\left(\\vec{X}^{(0)}\\right)\\vec{H} \\thickapprox -F\\left(\\vec{X}^{(0)}\\right) $$\n", 193 | "\n", 194 | "$$ \\Rightarrow \\left[F'\\left(\\vec{X}^{(0)}\\right)\\right]^{-1}F'\\left(\\vec{X}^{(0)}\\right)\\vec{H} \\thickapprox-\\left[F'\\left(\\vec{X}^{(0)}\\right)\\right]^{-1}F\\left(\\vec{X}^{(0)}\\right) $$\n", 195 | "\n", 196 | "$$\\Rightarrow \\vec{H}\\thickapprox-\\left[F'\\left(\\vec{X}^{(0)}\\right)\\right]^{-1}F\\left(\\vec{X}^{(0)}\\right) $$\n", 197 | "\n", 198 | "De tal manera que $\\vec{H}$ nos dice cuanto se tiene que modificar la solución anterior para encontrar una nueva mejor solución y el término. \n", 199 | "\n", 200 | "$$\\left[F'\\left(\\vec{X}^{(0)}\\right)\\right]^{-1}$$\n", 201 | "\n", 202 | "Es la inversa de la matriz Jacobiaba. En general el método de Newton se ve de la siguiente manera. \n", 203 | "\n", 204 | "$$ \\vec{X}^{(k+1)}=\\vec{X}^{(k)}-\\left[F'\\left(\\vec{X}^{(k)}\\right)\\right]^{-1}F\\left(\\vec{X}^{(k)}\\right) $$\n", 205 | "\n", 206 | "En la práctica el método de Newton **no implica invertir la matriz Jacobiana**, solo resolver los sistemas lineales jacobianos.\n", 207 | "\n", 208 | "$$ \\left[F'\\left(\\vec{X}^{(k)}\\right)\\right]\\vec{H}^{(k)}=-F\\left(\\vec{X}^{(k)}\\right) \\tag{4}$$ \n", 209 | "\n", 210 | "Podemos asegurara que $(4)$ representa un sistema lineal, ya que la incógnita es $\\vec{H}$ y los coeficientes de la matriz jacobiana no dependen $\\vec{H}$. \n", 211 | "\n", 212 | "Esto significa que para resolver un sistema de ecuaciones no lineales necesitamos resolver un sistema de ecuaciones lineales, es decir que **para resolver un problema que parece complejo, se resuelve un problema equivalente pero menos complejo**." 213 | ] 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "metadata": { 218 | "id": "lSjQ3bDLU-rh" 219 | }, 220 | "source": [ 221 | "## Ejemplo\n", 222 | "\n", 223 | "Emplea el método de Newton para resolver el siguiente sistema de ecuaciones con una tolerancia de $10^{-8}$.\n", 224 | "\n", 225 | "$$2x_{1}-x_{2}-e^{-x_{1}}=0, \\quad -x_{1}+2x_{2}-e^{-x_{2}}=0$$" 226 | ] 227 | }, 228 | { 229 | "cell_type": "markdown", 230 | "metadata": { 231 | "id": "T93clcxIVInd" 232 | }, 233 | "source": [ 234 | "### Solución\n", 235 | "\n", 236 | "Este sistema de ecuaciones se puede expresar en notación vectorial de la siguiente manera.\n", 237 | "\n", 238 | "\n", 239 | "$$F\\left(\\vec{X}\\right)=\\begin{cases}\n", 240 | "2x_{1}-x_{2}-e^{-x_{1}} & =0\\\\\n", 241 | "-x_{1}+2x_{2}-e^{-x_{2}} & =0\n", 242 | "\\end{cases}$$\n", 243 | "\n", 244 | "De tal manera que la matriz Jacobina asociada a este sistema esta definida por.\n", 245 | "\n", 246 | "$$\\begin{array}{cc}\n", 247 | "F'(\\vec{X})= & \\left(\\begin{array}{cc}\n", 248 | "2+e^{-x_{1}} & -1\\\\\n", 249 | "-1 & 2+e^{-x_{2}}\n", 250 | "\\end{array}\\right)\\end{array}$$\n", 251 | "\n", 252 | "Para calcular la inversa de $F'(\\vec{X})$ es necesario calcular el determinante, el cual esta dado por\n", 253 | "\n", 254 | "$$det(F'(\\vec{X}))=\\left(2+e^{-x_{1}}\\right)\\left(2+e^{-x_{2}}\\right)-\\left(-1\\times-1\\right)=4+2e^{-x_{2}}+2e^{-x_{1}}+e^{-x_{1}-x_{2}}-1$$\n", 255 | "\n", 256 | "Y la inversa de $F'(\\vec{X})$ se define como\n", 257 | "\n", 258 | "$$F'(\\vec{X})^{-1}=\\frac{1}{det(F'(\\vec{X}))}\\left(\\begin{array}{cc}\n", 259 | "2+e^{-x_{2}} & 1\\\\\n", 260 | "1 & 2+e^{-x_{1}}\n", 261 | "\\end{array}\\right)\\\\=\\left(\\begin{array}{cc}\n", 262 | "\\frac{2+e^{-x_{2}}}{4+2e^{-x_{2}}+2e^{-x_{1}}+e^{-x_{1}-x_{2}}-1} & \\frac{1}{4+2e^{-x_{2}}+2e^{-x_{1}}+e^{-x_{1}-x_{2}}-1}\\\\\n", 263 | "\\frac{1}{4+2e^{-x_{2}}+2e^{-x_{1}}+e^{-x_{1}-x_{2}}-1} & \\frac{2+e^{-x_{1}}}{4+2e^{-x_{2}}+2e^{-x_{1}}+e^{-x_{1}-x_{2}}-1}\n", 264 | "\\end{array}\\right) $$\n", 265 | "\n", 266 | "Ahora solo nos hace falta una primera aproximación\n", 267 | "\n", 268 | "$$ \\vec{X}^{(0)}=(0,0) $$\n", 269 | "\n", 270 | "No forzosamente tiene que ser el vector $\\vec{0}$, pero este método no tiene restricciones al respecto\n", 271 | "\n", 272 | "De manera tal que ahora podemos aplicar la definición del método de Newton para sistemas de ecuaciones y resolver para \n", 273 | "\n", 274 | "$$\\vec{X}^{(1)}=\\vec{X}^{(0)}-\\left[F'\\left(\\vec{X}^{(0)}\\right)\\right]^{-1}F\\left(\\vec{X}^{(0)}\\right)\\tag{5}$$\n", 275 | "\n", 276 | "Al evaluar $$\\vec{X}^{(0)}=(0,0)$$ en (5), se tiene\n", 277 | "\n", 278 | "$$\\vec{X}^{(1)}=\\left(0,0\\right)-\\left[F'\\left(0,0\\right)\\right]^{-1}F\\left(0,0\\right)$$\n", 279 | "\n", 280 | "$$=\\left(0,0\\right)-\\left(\\begin{array}{cc}\n", 281 | "\\frac{3}{8} & \\frac{1}{8}\\\\\n", 282 | "\\frac{1}{8} & \\frac{3}{8}\n", 283 | "\\end{array}\\right) \\left(\\begin{array}{c}\n", 284 | "-1\\\\\n", 285 | "-1\n", 286 | "\\end{array}\\right) $$\n", 287 | "\n", 288 | "$$ =\\left(0,0\\right)-\\left(\\begin{array}{c}\n", 289 | "\\left(\\frac{3}{8}\\cdot-1\\right)+\\left(\\frac{1}{8}\\cdot-1\\right)\\\\\n", 290 | "\\left(\\frac{1}{8}\\cdot-1\\right)+\\left(\\frac{3}{8}\\cdot-1\\right)\n", 291 | "\\end{array}\\right) $$\n", 292 | "\n", 293 | "$$=\\left(0,0\\right)-\\left(\\begin{array}{c}\n", 294 | "-\\frac{1}{2}\\\\\n", 295 | "-\\frac{1}{2}\n", 296 | "\\end{array}\\right) $$\n", 297 | "\n", 298 | "$$\\vec{X}^{(1)}=\\left(\\begin{array}{c}\n", 299 | "\\frac{1}{2}\\\\\n", 300 | "\\frac{1}{2}\n", 301 | "\\end{array}\\right)$$\n", 302 | "\n", 303 | "Después de $k$ iteraciones con el método de Newton podemos ver que la solución converge al valor\n", 304 | "\n", 305 | "$$\\vec{X}^{(k)}=\\left(\\begin{array}{c}\n", 306 | "5.6714329040978384\\times10^{-1}\\\\\n", 307 | "5.6714329040978384\\times10^{-1}\n", 308 | "\\end{array}\\right)$$\n", 309 | "\n", 310 | "Lo que significa que si evaluamos $F\\left(\\vec{X}^{(k)}\\right)$ obtendremos un vector muy cercano al vector $\\vec{0}$\n", 311 | "\n", 312 | "$$F\\left(\\vec{X}^{(k)}\\right)=\\left(\\begin{array}{c}\n", 313 | "0.000000001\\\\\n", 314 | "0.000000001\n", 315 | "\\end{array}\\right)$$\n", 316 | "\n", 317 | "En *python* este algoritmo se ve asi." 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "metadata": { 323 | "id": "Vdz_pIvQcxjD", 324 | "colab": { 325 | "base_uri": "https://localhost:8080/" 326 | }, 327 | "outputId": "ab3aca86-9c48-4906-dc13-0a3d33e622ce" 328 | }, 329 | "source": [ 330 | "import numpy as np\n", 331 | "import math\n", 332 | "\n", 333 | "# funcion f1\n", 334 | "def f1(x1, x2):\n", 335 | " return 2*x1-x2-math.e**(-x1)\n", 336 | "\n", 337 | "# funcion f2\n", 338 | "def f2(x1, x2):\n", 339 | " return -x1+2*x2-math.e**(-x2)\n", 340 | "\n", 341 | "# denominador de la matriz jacobiana\n", 342 | "def denominador(x1,x2):\n", 343 | " return 3+2*math.e**(-x2)+2*math.e**(-x1)+math.e**(-x1-x2)\n", 344 | "\n", 345 | "# parcial (en este caso la parcial de f1 y f2 es la misma)\n", 346 | "def par(x):\n", 347 | " return 2+math.e**(-x)\n", 348 | "\n", 349 | "'''Metodo de Newton para sistemas\n", 350 | " de ecuaciones no lineales\n", 351 | " aprox: es la primera aproximacion\n", 352 | " en forma de vector'''\n", 353 | "def JimyNewtron(aprox):\n", 354 | " # contador de iteraciones\n", 355 | " n = 0 \n", 356 | " while n < 100: # maximo numero de iteraciones 100\n", 357 | " '''es necesario calcular la matriz jacobiana\n", 358 | " y para ello se necesita una matriz vacia de 2x2'''\n", 359 | " jacobinv = np.zeros([2,2])\n", 360 | " \n", 361 | " # valores de la matriz jacobiana en todas sus entradas\n", 362 | " jacobinv[0][0] = par(aprox[1])/denominador(aprox[0], aprox[1])\n", 363 | " jacobinv[0][1] = 1/denominador(aprox[0], aprox[1])\n", 364 | " jacobinv[1][0] = 1/denominador(aprox[0], aprox[1])\n", 365 | " jacobinv[1][1] = par(aprox[0])/denominador(aprox[0], aprox[1])\n", 366 | " \n", 367 | " # guarda la evalucion de f1 y f2 en forma de vector\n", 368 | " fx = np.array(aprox)\n", 369 | " fx[0] = f1(aprox[0], aprox[1])\n", 370 | " fx[1] = f2(aprox[0], aprox[1])\n", 371 | " \n", 372 | " # FORMA ITERATIVA DEL METODO DE NEWTON PARA SISTEMAS NO LIENALES\n", 373 | " aprox = aprox - np.matmul(jacobinv, fx)\n", 374 | " \n", 375 | " # se incrementa el contador\n", 376 | " n+=1\n", 377 | " \n", 378 | " # El valor devuelto es la aproximacion\n", 379 | " return aprox \n", 380 | " \n", 381 | "def main():\n", 382 | " #Aproximacion inicial (X=(0.0,0.0))\n", 383 | " ap = np.zeros([2])\n", 384 | " sol = JimyNewtron(ap)\n", 385 | " print('Aproximacion de la solucion')\n", 386 | " print(sol)\n", 387 | " print('Aproximacion evaluada en f1')\n", 388 | " print(f1(sol[0], sol[1]))\n", 389 | " print('Aproximacion evaluada en f2')\n", 390 | " print(f2(sol[0], sol[1]))\n", 391 | "\n", 392 | "main()" 393 | ], 394 | "execution_count": null, 395 | "outputs": [ 396 | { 397 | "output_type": "stream", 398 | "text": [ 399 | "Aproximacion de la solucion\n", 400 | "[0.56714329 0.56714329]\n", 401 | "Aproximacion evaluada en f1\n", 402 | "-1.1102230246251565e-16\n", 403 | "Aproximacion evaluada en f2\n", 404 | "-1.1102230246251565e-16\n" 405 | ], 406 | "name": "stdout" 407 | } 408 | ] 409 | }, 410 | { 411 | "cell_type": "markdown", 412 | "metadata": { 413 | "id": "gS2sGnusWylD" 414 | }, 415 | "source": [ 416 | "### Mejoras\n", 417 | "\n", 418 | "Puedes comprobar el resultado usando [wolfram alpha](https://www.wolframalpha.com/input/?i=solve++%282x-y-e%5E%7B-x%7D%3D0%2C+-x%2B2y-e%5E%7B-y%7D%3D0%29).\n", 419 | "\n", 420 | "Y vale la pena recalcar que el ejemplo y su implementación en código son **versiones del método de Newton que pueden ser mejoradas**.\n", 421 | "\n", 422 | "Una de estas mejoras corresponde a incluir **criterios adicionales de paro**, además del limite de iteraciones. Uno de estos criterios es medir la distancia entre la solución $\\vec{X}^{(k)}$ y la solución $\\vec{X}^{(k+1)}$ para determinar cuánto ha cambiado la solución.\n", 423 | "\n", 424 | "Otro criterio es medir la distancia entre $F(\\vec{X}^{(k+1)})$ y el vector $\\vec{0}$, si esa distancia es menor que una cierta **tolerancia**, podemos afirmar que este criterio se cumple.\n", 425 | "\n", 426 | "Para poder medir estas distancias es necesario comprender el concepto de **norma**, que puedes revisar en este enlace.\n", 427 | "\n", 428 | "Por otro lado es importante recordar que el calculo de la matriz inversa es muy costoso por lo tanto, otra mejora que se puede realizar es, **substituir el cálculo de la matriz inversa**, y en su lugar resolver el **sistema lineal Jacobiano** descrito en la sección de [Desarrollo](#scrollTo=ORb_b64xcxjA).\n", 429 | "\n", 430 | "\n", 431 | "Finalmente, hay que notar que el cálculo de las derivadas parciales se realiza en código duro ([*hard code*](https://es.wikipedia.org/wiki/Hard_code#:~:text=Hard%2Dcode%2C%20t%C3%A9rmino%20del%20mundo,par%C3%A1metros%20de%20la%20l%C3%ADnea%20de)), pero la definición de `def par(x)`, puede substiruise por una función que aproxime la derivada parcial de cualquier función $F(\\vec{X})$, digamos `def parcial(F, X, var, Tol)` y que **devuelva la aproximación de la derivada parcial** de `F`, en el punto `X` con respecto a la variable `var` y con una tolerancia de `Tol`." 432 | ] 433 | }, 434 | { 435 | "cell_type": "markdown", 436 | "metadata": { 437 | "id": "Zg1KC-XOcxjB" 438 | }, 439 | "source": [ 440 | "## Resumen\n", 441 | "\n", 442 | "Para poder resolver un sistema de ecuaciones no lineales, es posible emplear el método de Newton para iterar hasta encontrar una solución lo suficientemente buena.\n", 443 | "\n", 444 | "Se puede resolver un problema que inicialmente parece complejo, resolviendo un problema similar pero de menor complejidad.\n", 445 | "\n", 446 | "A partir de este momento, la solución a un problema o la solución que aproxima un algoritmo ya no es un número real $x$, ya debemos pensar en que una solución es un vector $\\vec{X}$.\n", 447 | "\n", 448 | "¿Pero, cómo podemos decidir cuando una solución es adecuada?.\n", 449 | "\n", 450 | "¿Que significa el concepto de **norma** y por que es importante para este curso?.\n", 451 | "\n", 452 | "La ecuación (4) se puede reducir a un sistema lineal Jacobiano.\n", 453 | "\n", 454 | "¿Por que es importante encontrar una forma eficiente de resolver un sistema de ecuaciones lineales sin necesidad de encontrar la inversa de la matriz asociada a un sistema?.\n", 455 | "\n", 456 | "$$A\\vec{x}=\\vec{b}$$" 457 | ] 458 | }, 459 | { 460 | "cell_type": "markdown", 461 | "metadata": { 462 | "id": "7SL8ZW2IcxjD" 463 | }, 464 | "source": [ 465 | "## Referencias\n", 466 | "\n", 467 | "* Riswan Butt, Numerical Analysys Using Matlab, Jones and Bartlett.\n", 468 | "* Ward Cheney, David Kincaid, Métodos Numéricos y Computación, Cenage Learning.\n", 469 | "* Richard L. Burden, J. Douglas Faires, Análisis Numérico, Math Learning.\n", 470 | "* Yuri N. Skiba, Introducción a los Métodos Numéricos. " 471 | ] 472 | } 473 | ] 474 | } 475 | -------------------------------------------------------------------------------- /03_Interpolacion/SeriesDeTaylor_aplicaciones.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "02_SeriesDeTaylor_aplicaciones.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [], 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "display_name": "Python 3", 13 | "language": "python", 14 | "name": "python3" 15 | }, 16 | "language_info": { 17 | "codemirror_mode": { 18 | "name": "ipython", 19 | "version": 3 20 | }, 21 | "file_extension": ".py", 22 | "mimetype": "text/x-python", 23 | "name": "python", 24 | "nbconvert_exporter": "python", 25 | "pygments_lexer": "ipython3", 26 | "version": "3.7.6" 27 | } 28 | }, 29 | "cells": [ 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "view-in-github", 34 | "colab_type": "text" 35 | }, 36 | "source": [ 37 | "\"Open" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": { 43 | "id": "9sy0X23KG4Je" 44 | }, 45 | "source": [ 46 | "# Transferencia de calor con Series de Taylor\n", 47 | "### Trabajo realizado con el apoyo del Programa UNAM-DGAPA-PAPIME PE101019\n", 48 | "* Autores: \n", 49 | " - Luis M. de la Cruz Salas\n", 50 | "* Rev: mié nov 18 17:31:23 CST 2020" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "metadata": { 56 | "id": "fd5cjNdTCdPC" 57 | }, 58 | "source": [ 59 | "# COLAB\n", 60 | "#!git clone https://github.com/jugernaut/Prometeo.gitb #rama master\n", 61 | "#!git clone --branch desarrollo https://github.com/jugernaut/Prometeo.git #rama desarrollo \n", 62 | "#import Prometeo.Utils.gutils as vis\n", 63 | "\n", 64 | "# Linux, MacOS y windows\n", 65 | "import os, sys\n", 66 | "sys.path.insert(0, os.path.abspath('../../'))\n", 67 | "import Utils.gutils as vis\n", 68 | "\n", 69 | "import numpy as np" 70 | ], 71 | "execution_count": null, 72 | "outputs": [] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": { 77 | "id": "ggZ0k4gqG4Jn" 78 | }, 79 | "source": [ 80 | "## Modelo matemático\n", 81 | "Un modelo matemático que describe la conducción de calor es el siguiente:\n", 82 | "\n", 83 | "$\\displaystyle\n", 84 | "\\nabla \\cdot \\left( \\kappa \\nabla T \\right) = -q\n", 85 | "$\n", 86 | "\n", 87 | "donde $\\kappa$ representa la conductividad térmica y $q$ una fuente de energía calorífica.\n", 88 | "\n", 89 | "Si quisieramos determinar la distribución de temperaturas en una barra de metal, con $\\kappa$ = cte., usaríamos un modelo en una dimensión que se puede escribir como sigue:\n", 90 | "\n", 91 | "$\n", 92 | "\\displaystyle\n", 93 | "\\kappa \\frac{d^2 T}{d x^2} = -q\n", 94 | "$\n", 95 | "\n", 96 | "La barra tiene una temperatura $T_A$ en su extremo izquierdo y otra temperatura $T_B$ en su extremo derecho y además consideramos que $q$ = cte.\n", 97 | "\n", 98 | "A continuación veremos como encontrar una solución, es decir una función $T(x)$, que me de la temperatura en cada posición $x$, usando dos estrategias basadas en Series de Taylor." 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": { 104 | "id": "BMVAQypGG4Jo" 105 | }, 106 | "source": [ 107 | "## Solución analítica\n", 108 | "Es posible obtener una función $T(x)$ que describa la distribución de temperaturas a lo largo de dicha barra. Para ello vamos a escribir $T(x)$ en forma de una serie Taylor\n", 109 | "\n", 110 | "$\n", 111 | "\\displaystyle\n", 112 | "T_n(x) = \\sum_{i=0}^n T^{(i)}(a)\\frac{(x-a)^i}{i!} = \\sum_{i=0}^n c_i (x-a)^i\n", 113 | "$\n", 114 | "\n", 115 | "donde $\\displaystyle c_i = \\frac{T^{(i)}(a)}{i!}$.\n", 116 | "\n", 117 | "Definimos ahora una aproximación alrededor de $a = 0$ para $n = 2$ con lo que obtenemos:\n", 118 | "\n", 119 | "\n", 120 | "$\\displaystyle\n", 121 | "T(x) = c_0 + c_1 *x + c_2 * x^2\n", 122 | "$\n", 123 | "\n", 124 | "Calculamos la primera y segunda derivadas de $T(x)$:\n", 125 | "\n", 126 | "$\n", 127 | "\\begin{eqnarray}\n", 128 | "\\frac{d T(x)}{d x} & = & c_1 + 2 * c_2 * x \\\\\n", 129 | "\\frac{d^2 T(x)}{d x^2} & = & 2 * c_2 \\\\\n", 130 | "\\end{eqnarray}\n", 131 | "$\n", 132 | "\n", 133 | "Sustituyendo esta segunda derivada en la ecuación de conducción de calor obtenemos:\n", 134 | "\n", 135 | "$\n", 136 | "\\displaystyle\n", 137 | "\\kappa (2 * c_2 ) = -q \\Longrightarrow \\boxed{c_2 = -\\frac{q}{2 \\kappa}}\n", 138 | "$\n", 139 | "\n", 140 | "Para obtener $c_0$ y $c_1$ hacemos uso de las condiciones de frontera en $T(x)$:\n", 141 | "\n", 142 | "$\\displaystyle\n", 143 | "\\begin{eqnarray}\n", 144 | "\\text{Extremo izquierdo: } T(x=0) & = & c_0 + c_1 * 0 + c_2 * 0^2 = T_A \\\\\n", 145 | "&\\Longrightarrow& \\boxed{c_0 = T_A} \\\\\n", 146 | "\\text{Extremo derecho: } T(x=L) & = & c_0 + c_1 * L + c_2 * L^2 = T_A + c_1 * L - \\frac{q}{2 \\kappa} * L^2 =\n", 147 | "T_B \\\\\n", 148 | "&\\Longrightarrow& \\boxed{c_1 = \\left(T_B - T_A + \\frac{q L^2}{2 \\kappa}\\right)\\frac{1}{L}}\n", 149 | "\\end{eqnarray}\n", 150 | "$\n", 151 | "\n", 152 | "De esta manera tenemos que la solución final es:\n", 153 | "\n", 154 | "$\\displaystyle\n", 155 | "T(x) = T_A + \\left(T_B - T_A + \\frac{q L^2}{2 \\kappa}\\right)\\frac{1}{L} x - \\frac{q}{2 \\kappa} x^2 =\n", 156 | "\\boxed{\\left(\\frac{T_B - T_A}{L} + \\frac{q}{2\\kappa} \\left(L - x\\right) \\right)x + T_A}\n", 157 | "$\n", 158 | "\n", 159 | "Implementamos esta solución en una función de Python:" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "metadata": { 165 | "id": "wF7hM0nuG4Jp" 166 | }, 167 | "source": [ 168 | "def temperatura(x, TA, TB, q, L, k):\n", 169 | " \"\"\"\n", 170 | " Calcula la temperatura usando la fórmula obtenida con Series de Taylor.\n", 171 | " \"\"\"\n", 172 | " return ((TB - TA)/L + q /(2*k) * (L - x) ) * x + TA" 173 | ], 174 | "execution_count": null, 175 | "outputs": [] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": { 180 | "id": "-u_GDzyDG4Ju" 181 | }, 182 | "source": [ 183 | "### Ejemplo 1\n", 184 | "\n", 185 | "Este ejemplo representa una barra aislada con temperaturas $T_A$ y $T_B$ en sus extremos. \n", 186 | "\n", 187 | "Datos del problema:\n", 188 | "- $\\kappa = 1000$ [W /m $^o$C]\n", 189 | "- $L = 0.5$ [m]\n", 190 | "- $T_A = 100$ [$^o$C]\n", 191 | "- $T_B = 500$ [$^o$C]\n", 192 | "- $q = 0$" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "metadata": { 198 | "id": "Y-M2C5W2G4Jv" 199 | }, 200 | "source": [ 201 | "k = 1000\n", 202 | "L = 0.5\n", 203 | "TA = 100\n", 204 | "TB = 500\n", 205 | "q = 0\n", 206 | "\n", 207 | "# Calculamos la temperatura con la solución analítica\n", 208 | "x = np.linspace(0, L, 100)\n", 209 | "T = temperatura(x, TA, TB, q, L, k)\n", 210 | "\n", 211 | "# Definimos algunos parámetros para la gráfica\n", 212 | "par = [{'title':'Transferencia de calor', \n", 213 | " 'xlabel':'x [m]',\n", 214 | " 'ylabel':'T [$^oC$]'}]\n", 215 | "\n", 216 | "# Inicializamos el plano Cartesiano\n", 217 | "graf = vis.planoCartesiano(par=par)\n", 218 | "\n", 219 | "# Realizamos la gráfica con una línea y puntos que tienen un color \n", 220 | "# dependiendo de su temperatura\n", 221 | "graf.plot(x = x, y = T, par={'color':'k', 'lw':1.0})\n", 222 | "s = graf.scatter(x = x, y=T, par = {'c':T, 'cmap':'jet', 'alpha':0.5})\n", 223 | "graf.colorbar(m=s) # Se muestra una barra de color \n", 224 | "\n", 225 | "graf.show()" 226 | ], 227 | "execution_count": null, 228 | "outputs": [] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": { 233 | "id": "KI590ExEG4J1" 234 | }, 235 | "source": [ 236 | "### Ejemplo 2\n", 237 | "\n", 238 | "Este ejemplo representa una barra que en cada uno de sus puntos recibe un flujo de calor $q$ y con temperaturas $T_A$ y $T_B$ en sus extremos. Véase [2].\n", 239 | "\n", 240 | "Datos:\n", 241 | "- $\\kappa = 0.5$ [W /m $^o$C]\n", 242 | "- $L = 0.02$ [m]\n", 243 | "- $T_A = 100$ [$^o$C]\n", 244 | "- $T_B = 200$ [$^o$C]\n", 245 | "- $q = 10^6$ [W/m$^3$]" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "metadata": { 251 | "id": "MZU5ij7oG4J2" 252 | }, 253 | "source": [ 254 | "# Datos del problema\n", 255 | "k = 0.5\n", 256 | "L = 0.02\n", 257 | "TA = 100\n", 258 | "TB = 200\n", 259 | "q = 1e+6\n", 260 | "\n", 261 | "# Calculamos la temperatura con la solución analítica\n", 262 | "x = np.linspace(0,L,100)\n", 263 | "T = temperatura(x, TA, TB, q, L, k)\n", 264 | "\n", 265 | "# Definimos algunos parámetros para la gráfica\n", 266 | "par = [{'title':'Transferencia de calor', \n", 267 | " 'xlabel':'x [m]',\n", 268 | " 'ylabel':'T [$^oC$]'}]\n", 269 | "\n", 270 | "# Inicializamos el plano Cartesiano\n", 271 | "graf = vis.planoCartesiano(par=par)\n", 272 | "\n", 273 | "# Realizamos la gráfica con una línea y puntos que tienen un color \n", 274 | "# dependiendo de su temperatura\n", 275 | "graf.plot(x = x, y = T, par={'color':'k', 'lw':1.0})\n", 276 | "s = graf.scatter(x = x, y=T, par = {'c':T, 'cmap':'jet', 'alpha':0.5})\n", 277 | "graf.colorbar(m=s) # Se muestra una barra de color \n", 278 | "\n", 279 | "graf.show()" 280 | ], 281 | "execution_count": null, 282 | "outputs": [] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "metadata": { 287 | "id": "ZwlkKlm7G4J8" 288 | }, 289 | "source": [ 290 | "## Solución numérica\n", 291 | "Los ejemplos anteriores también se pueden resolver usando el método numérico conocido como diferencias finitas, el cual se obtiene también usando Series de Taylor. Veamos como:" 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": { 297 | "id": "KBOVXfhVG4J9" 298 | }, 299 | "source": [ 300 | "### Derivadas de primer orden\n", 301 | "Supongamos que $u(x)$ es una función bien comportada con $n$ derivadas continuas.\n", 302 | "Entonces podemos escribir la siguiente serie de Taylor alrededor de $x_0$:\n", 303 | "\n", 304 | "$\\displaystyle\n", 305 | "u(x_0+h) = u(x_0) + u^\\prime(x_0)h + \\frac{u^{\\prime\\prime}(x_0)}{2!}h^2 + \\dots + \\frac{u^{(n)}(x_0)}{n!}h^n + R_n(x)$ \n", 306 | "\n", 307 | "donde $h = x-x_0$ y de aquí se tiene que $x = x_0 + h$. Si truncamos el polinomio de Taylor a primer orden tenemos:\n", 308 | "\n", 309 | "$\\displaystyle\n", 310 | "u(x_0+h) = u(x_0) + u^\\prime(x_0)h + R_1(x)$ \n", 311 | "\n", 312 | "Luego despejamos $u^\\prime(x_0)$:\n", 313 | "\n", 314 | "$\\displaystyle\n", 315 | "\\begin{eqnarray}\n", 316 | "\\Longrightarrow u^\\prime(x_0) & = & \\frac{u(x_0+h) - u(x_0)}{h} - \\frac{R_1(x)}{h} \\\\\n", 317 | "\\Longrightarrow u^\\prime(x_0) & = & \\frac{u(x_0+h) - u(x_0)}{h} - \\frac{u^{(2)}(\\xi) h^2 / 2!}{h} \\\\ \n", 318 | "\\Longrightarrow u^\\prime(x_0) & = & \\frac{u(x_0+h) - u(x_0)}{h} - \\frac{u^{(2)}(\\xi)}{2} h\\\\\n", 319 | "\\Longrightarrow u^\\prime(x_0) & = & \\frac{u(x_0+h) - u(x_0)}{h} - \\mathcal{O}(h)\\\\\n", 320 | "\\end{eqnarray}\n", 321 | "$\n", 322 | "\n", 323 | "Observaciones:\n", 324 | "1. La última ecuación no es más que la definición de la derivada, hacia adelante:\n", 325 | "\n", 326 | "$\\displaystyle\n", 327 | "u^\\prime(x_0) = \\lim_{h \\rightarrow 0 } \\frac{u(x_0+h) - u(x_0)}{h}\n", 328 | "$\n", 329 | "\n", 330 | "2. La expresión $\\mathcal{O}(h)$ significa que el último término es de orden $h$.\n", 331 | "\n", 332 | "3. Si eliminamos ese último término tendremos una aproximación de la derivada hacia adelante de orden $h$:\n", 333 | "\n", 334 | "$\\displaystyle\n", 335 | "u^\\prime(x_0) \\approx \\frac{u(x_0+h) - u(x_0)}{h}\n", 336 | "$" 337 | ] 338 | }, 339 | { 340 | "cell_type": "markdown", 341 | "metadata": { 342 | "id": "got4RY3SCdPD" 343 | }, 344 | "source": [ 345 | "### Ejercicio\n", 346 | "Mostrar que la aproximación de la derivada hacia atrás de orden $h$ se escribe como:\n", 347 | "\n", 348 | "$\\displaystyle\n", 349 | "u^\\prime(x_0) \\approx \\frac{u(x_0) - u(x_0-h)}{h}\n", 350 | "$\n", 351 | "\n", 352 | "**Hint**: Escriba la expansión en series de Taylor de $u(x_0-h)$ y despeje $u^\\prime(x_0)$" 353 | ] 354 | }, 355 | { 356 | "cell_type": "markdown", 357 | "metadata": { 358 | "id": "lZlRZLbwG4J-" 359 | }, 360 | "source": [ 361 | "### Derivadas de segundo orden\n", 362 | "\n", 363 | "Las expansiones en series de Taylor de $u(x_0 + h)$ y de $u(x_0 - h)$ son: \n", 364 | "\n", 365 | "$\\displaystyle\n", 366 | "u(x_0+h) = u(x_0) + u^\\prime(x_0)h + \\frac{u^{\\prime\\prime}(x_0)}{2!}h^2 + \\frac{u^{\\prime\\prime\\prime}(x_0)}{3!}h^3 + \\dots + \\frac{u^{(n)}(x_0)}{n!}h^n + R_n(x)\n", 367 | "$ \n", 368 | "\n", 369 | "$\\displaystyle\n", 370 | "u(x_0-h) = u(x_0) - u^\\prime(x_0)h + \\frac{u^{\\prime\\prime}(x_0)}{2!}h^2 - \\frac{u^{\\prime\\prime\\prime}(x_0)}{3!}h^3 + \\dots + \\frac{u^{(n)}(x_0)}{n!}h^n + R_n(x)\n", 371 | "$ \n", 372 | "\n", 373 | "Ahora sumamos a las dos ecuaciones para obtener:\n", 374 | "\n", 375 | "$\\displaystyle\n", 376 | "u(x_0+h) + u(x_0-h) = 2u(x_0) + u^{\\prime\\prime}(x_0) h^2 + \\frac{2 u^{(4)}(x_0)}{4!}h^4 + \n", 377 | "\\frac{2 u^{(6)}(x_0)}{6!}h^6 + \\dots + \\mathcal{O}(h^{(n+1)})$ \n", 378 | "\n", 379 | "Observamos que todos los términos de orden impar se han eliminado, esto debido a que esta aproximación es simétrica y está centrada en $x_0$. Truncamos la serie hasta orden 4 y despejamos $u^{\\prime\\prime}(x_0)$ :\n", 380 | "\n", 381 | "$\\displaystyle\n", 382 | "u^{\\prime\\prime}(x_0) = \\frac{u(x_0-h) - 2u(x_0) + u(x_0+h)}{h^2} + \\mathcal{O}(h^2)$ \n", 383 | "\n", 384 | "Tenemos entonces una aproximación a la segunda derivada de orden $h^2$." 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "metadata": { 390 | "id": "ehRLEdlACdPD" 391 | }, 392 | "source": [ 393 | "## Aproximación de la ecuación de calor\n", 394 | "Usando la aproximación de la segunda derivada obtenida anteriormente, se puede escribir la ecuación de calor\n", 395 | "$\n", 396 | "\\displaystyle\n", 397 | "\\kappa \\frac{d^2 T}{d x^2} = q\n", 398 | "$\n", 399 | "como sigue:\n", 400 | "\n", 401 | "$$\n", 402 | "\\displaystyle\n", 403 | "\\begin{eqnarray}\n", 404 | "\\kappa \\left( \\frac{T(x_0-h) - 2T(x_0) + T(x_0+h)}{h^2} \\right) & = & q \\\\\n", 405 | "\\Longrightarrow T(x_0-h) - 2T(x_0) + T(x_0+h) & = & \\frac{q h^2}{\\kappa}\n", 406 | "\\end{eqnarray}\n", 407 | "$$\n", 408 | "\n", 409 | "Lo que nos dice esta última ecuación es que se puede aproximar la temperatura en $x_0$ con un error de orden $\\mathcal{O}(h^2)$. Entonces entre más pequeño sea el $h$ mejor es la aproximación. Para obtener una solución en toda la barra, se construye una ecuación como la anterior para cada punto de la barra donde se desea conocer la temperatura, véase el siguiente video:" 410 | ] 411 | }, 412 | { 413 | "cell_type": "markdown", 414 | "metadata": { 415 | "id": "QxhMEq0ECdPD" 416 | }, 417 | "source": [ 418 | "" 419 | ] 420 | }, 421 | { 422 | "cell_type": "markdown", 423 | "metadata": { 424 | "id": "U2eKbEGiG4J_" 425 | }, 426 | "source": [ 427 | "Los puntos estarán equidistantes de tal manera que la distancia entre ellos, $h$, se puede disminuir agregando cada vez más puntos. Obsérvese también que hay dos puntos especiales en los extremos de la barra, donde la temperatura es conocida (condiciones de frontera).\n", 428 | "Si escribimos las ecuaciones para todos los puntos, digamos que tenemos $N$ puntos, entonces obtendremos un sistema lineal de ecuaciones como el siguiente:\n", 429 | "\n", 430 | "$\n", 431 | "\\begin{eqnarray}\n", 432 | "T_0 - 2T_1 + T_2 & = & -Q \\\\\n", 433 | "T_1 - 2T_2 + T_3 & = & -Q \\\\\n", 434 | "& \\vdots & \\\\\n", 435 | "T_{N-2} - 2T_{N-1} + T_N & = & -Q \n", 436 | "\\end{eqnarray}\n", 437 | "$\n", 438 | "\n", 439 | "donde $\\displaystyle Q = \\frac{q h^2}{\\kappa}$, $T_0 = T_A$ (temperatura en el extremo izquierdo) y $T_N = T_B$ (temperatura en el extremo derecho). \n", 440 | "\n", 441 | "Se puede escribir este sistemal en forma matricial :\n", 442 | "\n", 443 | "$\n", 444 | "\\left(\n", 445 | "\\begin{array}{ccccccccc}\n", 446 | "-2 & 1 & 0 & \\dots & & & 0\\\\ \n", 447 | " 1 &-2 & 1 & 0 & \\dots & &0\\\\ \n", 448 | " 0 & 1 &-2 & 1 & 0 & & 0\\\\ \n", 449 | " \\vdots &\\ddots&\\ddots&\\ddots&\\ddots&\\ddots&\\vdots\\\\\n", 450 | "0 & \\dots & 0 & 1 &-2 & 1 & 0 \\\\\n", 451 | "0 & \\dots && 0 & 1 &-2 & 1 \\\\\n", 452 | "0 & \\dots &&& 0 & 1 &-2 \\\\\n", 453 | "\\end{array}\\right)\n", 454 | "\\left(\n", 455 | "\\begin{array}{c}\n", 456 | "T_1 \\\\ T_2 \\\\ T_3 \\\\ \\vdots \\\\ T_{N-3} \\\\ T_{N-2} \\\\ T_{N-1}\n", 457 | "\\end{array}\\right) = \n", 458 | "-\\left(\n", 459 | "\\begin{array}{c}\n", 460 | "Q + T_A \\\\ Q \\\\ Q \\\\ \\vdots \\\\ Q \\\\ Q \\\\ Q + T_{B}\n", 461 | "\\end{array}\\right)\n", 462 | "$\n", 463 | "\n", 464 | "Resolviendo el sistema obtendremos las temperaturas en todos los puntos y por lo tanto una aproximación a la solución. La siguiente función de Python genera el sistema lineal, lo resuelve y regresa la temperatura en los diferentes puntos de la barra:" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "metadata": { 470 | "id": "hXaNAAKQG4KA" 471 | }, 472 | "source": [ 473 | "def resuelveDF(TA, TB, q, L, k, N):\n", 474 | " h = L / (N-1)\n", 475 | "\n", 476 | " # Construcción del vector del lado derecho (RHS)\n", 477 | " Q = np.zeros(N)\n", 478 | " \n", 479 | " # Construcción de la matriz\n", 480 | " A = np.identity(N)\n", 481 | " for i in range(1,N-1):\n", 482 | " A[i,i-1] = 1\n", 483 | " A[i,i] = -2\n", 484 | " A[i,i+1] = 1\n", 485 | " Q[i] = -q * h**2 / k\n", 486 | " \n", 487 | " # Aplicación de las condiciones de frontera\n", 488 | " Q[1] -= TA\n", 489 | " Q[-2] -= TB\n", 490 | " \n", 491 | " # Solución del sistema y regreso de la solución\n", 492 | " return np.linalg.solve(A[1:-1,1:-1], Q[1:-1])" 493 | ], 494 | "execution_count": null, 495 | "outputs": [] 496 | }, 497 | { 498 | "cell_type": "markdown", 499 | "metadata": { 500 | "id": "3-qSyQKyG4KE" 501 | }, 502 | "source": [ 503 | "### Aplicación al Ejemplo 1" 504 | ] 505 | }, 506 | { 507 | "cell_type": "code", 508 | "metadata": { 509 | "id": "W1IwIQI4G4KF" 510 | }, 511 | "source": [ 512 | "# Datos del problema\n", 513 | "k = 1000\n", 514 | "L = 0.5\n", 515 | "TA = 100\n", 516 | "TB = 500\n", 517 | "q = 0\n", 518 | "N = 21 # Número de puntos de la aproximación\n", 519 | "\n", 520 | "# Arreglo para almacenar la solución numérica\n", 521 | "T = np.zeros(N)\n", 522 | "\n", 523 | "# Condiciones de frontera\n", 524 | "T[0] = TA\n", 525 | "T[-1] = TB\n", 526 | "\n", 527 | "# Calculamos la temperatura con el método numérico\n", 528 | "x = np.linspace(0, L, N)\n", 529 | "T[1:-1] = resuelveDF(TA, TB, q, L, k, N)\n", 530 | "\n", 531 | "# Definimos algunos parámetros para la gráfica\n", 532 | "par = [{'title':'Transferencia de calor', \n", 533 | " 'xlabel':'x [m]',\n", 534 | " 'ylabel':'T [$^oC$]'}]\n", 535 | "\n", 536 | "# Inicializamos el plano Cartesiano\n", 537 | "graf = vis.planoCartesiano(par=par)\n", 538 | "\n", 539 | "# Realizamos la gráfica con una línea y puntos que tienen un color \n", 540 | "# dependiendo de su temperatura\n", 541 | "graf.plot(x = x, y = T, par={'color':'k', 'lw':1.0})\n", 542 | "s = graf.scatter(x = x, y=T, par = {'c':T, 'ec':'black', 's':50, 'cmap':'jet', 'alpha':0.5})\n", 543 | "graf.colorbar(m=s) # Se muestra una barra de color \n", 544 | "\n", 545 | "graf.show()" 546 | ], 547 | "execution_count": null, 548 | "outputs": [] 549 | }, 550 | { 551 | "cell_type": "markdown", 552 | "metadata": { 553 | "id": "DmjcJ4rEG4KL" 554 | }, 555 | "source": [ 556 | "### Aplicación al Ejemplo 2" 557 | ] 558 | }, 559 | { 560 | "cell_type": "code", 561 | "metadata": { 562 | "id": "6EAcrRKIG4KM" 563 | }, 564 | "source": [ 565 | "# Datos del problema\n", 566 | "k = 0.5\n", 567 | "L = 0.02\n", 568 | "TA = 100\n", 569 | "TB = 200\n", 570 | "q = 1e+6\n", 571 | "N = 21 # Número de puntos de la aproximación\n", 572 | "\n", 573 | "# Arreglo para almacenar la solución numérica\n", 574 | "T = np.zeros(N)\n", 575 | "\n", 576 | "# Condiciones de frontera\n", 577 | "T[0] = TA\n", 578 | "T[-1] = TB\n", 579 | "\n", 580 | "# Calculamos la temperatura con el método numérico\n", 581 | "x = np.linspace(0, L, N)\n", 582 | "T[1:-1] = resuelveDF(TA, TB, q, L, k, N)\n", 583 | "\n", 584 | "# Definimos algunos parámetros para la gráfica\n", 585 | "par = [{'title':'Transferencia de calor', \n", 586 | " 'xlabel':'x [m]',\n", 587 | " 'ylabel':'T [$^oC$]'}]\n", 588 | "\n", 589 | "# Inicializamos el plano Cartesiano\n", 590 | "graf = vis.planoCartesiano(par=par)\n", 591 | "\n", 592 | "# Realizamos la gráfica con una línea y puntos que tienen un color \n", 593 | "# dependiendo de su temperatura\n", 594 | "graf.plot(x = x, y = T, par={'color':'k', 'lw':1.0})\n", 595 | "s = graf.scatter(x = x, y=T, par = {'c':T, 'cmap':'jet', 'alpha':0.5})\n", 596 | "graf.colorbar(m=s) # Se muestra una barra de color \n", 597 | "\n", 598 | "graf.show()" 599 | ], 600 | "execution_count": null, 601 | "outputs": [] 602 | }, 603 | { 604 | "cell_type": "markdown", 605 | "metadata": { 606 | "id": "gAHH6z_UG4KP" 607 | }, 608 | "source": [ 609 | "Observamos que en los dos ejemplos, las soluciones son similares a las obtenidas usando la solución analítica. Intente aumentar el número de puntos ($N$) de la aproximación y vea lo que sucede. Para evaluar la precisión del método, se propone al estudiante que calcule la norma del error entre solución analítica y la solución numérica." 610 | ] 611 | } 612 | ] 613 | } -------------------------------------------------------------------------------- /01_AritmeticaPuntoFlotante/PreAritmeticaFlotanteEstudiante.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "view-in-github", 7 | "colab_type": "text" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "deletable": false, 17 | "editable": false, 18 | "id": "wQUx70fo1Ghp", 19 | "nbgrader": { 20 | "cell_type": "markdown", 21 | "checksum": "9728cac940bec66536e1912a245c3c61", 22 | "grade": false, 23 | "grade_id": "cell-e78e615406853e83", 24 | "locked": true, 25 | "schema_version": 3, 26 | "solution": false, 27 | "task": false 28 | } 29 | }, 30 | "source": [ 31 | "\n", 32 | "

Aritmética de punto flotante

\n", 33 | "
\n", 34 | " \n", 35 | "
Profesora: \tUrsula Xiomara Iturrarán Viveros
\n", 36 | "
Ayudante: Juan Pablo Cordero Santiago
\n", 37 | "
Materia: Análisis Numérico
\n", 38 | "
" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": { 44 | "deletable": false, 45 | "editable": false, 46 | "id": "0PSr9b03qaOC", 47 | "nbgrader": { 48 | "cell_type": "markdown", 49 | "checksum": "3f8508b48d37a0f62a96eb6aee39185e", 50 | "grade": false, 51 | "grade_id": "cell-3eb9f120a746c5a9", 52 | "locked": true, 53 | "schema_version": 3, 54 | "solution": false, 55 | "task": false 56 | } 57 | }, 58 | "source": [ 59 | "### Introducción\n", 60 | "La aritmética realizada por una computadora es diferente a nuestro álgebra que utilizamos día a día, por ejemplo cuando **sumamos** $3+6=9$, o **multiplicamos** $5 \\times 6 = 30$ no hay ningún problema, pero al realizar operaciones como **raíces** y **exponentes** $(\\sqrt(3))^2=3$ no necesariamente obtendremos lo mismo de una computadora.\n", 61 | "\n", 62 | "De manera computacional: cada número esta representado unicamente por un valor fijo de dígitos. Por ejemplo; solo los **números racionales** y **no pares** pueden ser expresados exactamente. Entonces retomando el caso de $\\sqrt(3)$, este es un **número no racional** y estará representado en una computadora por un número fijo de dígitos, estos logrando una buena aproximación, pero tenemos casos donde esta discrepancia se incrementa de manera indeseable.\n", 63 | "\n", 64 | "Para ello analizemos los siguientes ejercicios de igualdad:" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": { 71 | "id": "RCMsHPDPQSST" 72 | }, 73 | "outputs": [], 74 | "source": [ 75 | "(0.1+0.1+0.1) == 0.3" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": { 81 | "deletable": false, 82 | "editable": false, 83 | "id": "8g63QunZQnij", 84 | "nbgrader": { 85 | "cell_type": "markdown", 86 | "checksum": "a0d8a2650e870d5ae90d46f99f2bc07c", 87 | "grade": false, 88 | "grade_id": "cell-bbfb5051f18c290d", 89 | "locked": true, 90 | "schema_version": 3, 91 | "solution": false, 92 | "task": false 93 | } 94 | }, 95 | "source": [ 96 | "
¿Estas de acuerdo con la respuesta? ¿Qué crees que este pasando?
\n", 97 | "\n", 98 | "
Analicemos el caso ahora de $\\sqrt(3))^2=3$
" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": { 105 | "id": "WfCFdWHsRPJ4" 106 | }, 107 | "outputs": [], 108 | "source": [ 109 | "( (3)**(0.5) )**(2) == 3" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": { 115 | "deletable": false, 116 | "editable": false, 117 | "id": "EHLonNcoqVeQ", 118 | "nbgrader": { 119 | "cell_type": "markdown", 120 | "checksum": "91e9339c22884ac79fdcad433fd4d9de", 121 | "grade": false, 122 | "grade_id": "cell-28ba3d6b4bbe37e3", 123 | "locked": true, 124 | "schema_version": 3, 125 | "solution": false, 126 | "task": false 127 | } 128 | }, 129 | "source": [ 130 | "## Número en una computadora (64-Bits)\n", 131 | "Una computadora funciona en base a dos dígitos **0** o **1**. Consideremos el siguiente ejemplo de 64 bits:\n", 132 | "\n", 133 | "$$ \\underset{Signo}{\\underbrace{0}} \\quad \\underset{Parte Entera}{\\underbrace{10000000011}} \\quad \\underset{Parte Fraccionaria}{\\underbrace{1011100100010000000000000000000000000000000000000000}},$$\n", 134 | "\n", 135 | "\n", 136 | "el primer dígito indica el signo y se denota como $s$, los siguientes $11$ dígitos se denotan como $c$ y representan un exponente y los otros $54$ son la parte fraccionaria $f$:\n", 137 | "\n", 138 | "$$(-1)^s2^{c-1023}(1+f)$$\n", 139 | "\n", 140 | "el $1$ que se suma a la parte fraccionaria tiene que ver con el concepto de **bit implícito**, que veremos más adelante.\n", 141 | "\n", 142 | "Desarrollando el ejemplo pasado, obtenemos que: $s$ es cero indicando que el número es positivo, para $c$ cada dígito representa el factor multiplicando a la potencia del número $2$ elevado a la posición donde se encuentra:\n", 143 | "\n", 144 | "$$c= 1 \\cdot 2^{10}+0 \\cdot 2^{9}+\\cdot \\cdot \\cdot +0 \\cdot 2^{2}+1 \\cdot 2^{1}+1 \\cdot 2^{0}=1024+2+1=1027$$\n", 145 | "\n", 146 | "$f$ representa la parte fraccionaria del número, tambien denominada mantisa y está expresada como:\n", 147 | "\n", 148 | "$$f=1\\cdot\\left(\\frac{1}{2}\\right)^1+0\\cdot\\left(\\frac{1}{2}\\right)^2+1\\cdot\\left(\\frac{1}{2}\\right)^3+1\\cdot\\left(\\frac{1}{2}\\right)^4+1\\cdot\\left(\\frac{1}{2}\\right)^5+\\cdot\\cdot\\cdot1\\cdot\\left(\\frac{1}{2}\\right)^8 +\\cdot\\cdot\\cdot1\\cdot\\left(\\frac{1}{2}\\right)^{12}+\\cdot\\cdot\\cdot$$\n", 149 | "\n", 150 | "donde de nuevo la posición del dígito indica la potencia de la fracción. Finalmente obtenemos que:\n", 151 | "\n", 152 | "$$ \\quad(-1)^s2^{c-1023}(1+f)=(-1)^02^{1027-1023}\\left(1+\\frac{1}{2}+\\frac{1}{8}+\\frac{1}{16}+\\frac{1}{32}+\\frac{1}{256}+\\frac{1}{4096}\\right)$$\n", 153 | "\n", 154 | "$$(-1)^s2^{c-1023}(1+f)= 16 \\cdot (1.722900391)$$\n", 155 | "\n", 156 | "$$(-1)^s2^{c-1023}(1+f)= 27.56640625$$" 157 | ] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "metadata": { 162 | "deletable": false, 163 | "editable": false, 164 | "id": "E6xA2WFjoIaC", 165 | "nbgrader": { 166 | "cell_type": "markdown", 167 | "checksum": "c693638fd1ca1af20d170aa4a4d7b629", 168 | "grade": false, 169 | "grade_id": "cell-048589a583d0d617", 170 | "locked": true, 171 | "schema_version": 3, 172 | "solution": false, 173 | "task": false 174 | } 175 | }, 176 | "source": [ 177 | "### Limitaciones\n", 178 | "\n", 179 | "Calculemos los dos número más cercanos a nuestro ejemplo, para el más pequeño cambiamos nuestro último $1$ a $0$ y todos los números a continuación a $1$, obteniendo:\n", 180 | "\n", 181 | "$$0 \\quad 10000000011 \\quad 1011100100001111111111111111111111111111111111111111$$\n", 182 | "\n", 183 | "y para el valor más grande, solo cambiamos el último $0$ a $1$:\n", 184 | "\n", 185 | "$$0 \\quad 10000000011 \\quad 1011100100010000000000000000000000000000000000000001$$\n", 186 | "\n", 187 | "Esto implica que nuestro número calculado no solo representa ese valor, si no la mitad de números reales entre $27.56640625$ y sus dos números más cercanos.\n", 188 | "\n", 189 | "Marco En pocas palabras esto significa que su pudiéramos ubicar estos 3 valores en la recta numérica, podríamos ver que hay mucho espacio entre ellos, y eso se traduce en que **no sería posible representar un valor que se encuentre en estos huecos**." 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": { 195 | "deletable": false, 196 | "editable": false, 197 | "id": "tThAmp3WVtMN", 198 | "nbgrader": { 199 | "cell_type": "markdown", 200 | "checksum": "9f7942b1046d4c964ed21f643d687a9f", 201 | "grade": false, 202 | "grade_id": "cell-9641fa41b7a86af4", 203 | "locked": true, 204 | "schema_version": 3, 205 | "solution": false, 206 | "task": false 207 | } 208 | }, 209 | "source": [ 210 | "## Notación Decimal\n", 211 | "\n", 212 | "Veamos como se construye un valor en notación **decimal** ($\\beta=10$);\n", 213 | "\n", 214 | "$$\\pm0.d_1 d_2 \\cdot \\cdot \\cdot d_k \\times 10^n, \\quad 1< d_1 < 9, \\quad 0 < d_i < 9$$\n", 215 | "\n", 216 | "para cada $i=2,...,k.$ \n", 217 | "\n", 218 | "Cualquier número real y positivo en el rango de la computadora puede ser normalizado para ser expresado como:\n", 219 | "\n", 220 | "$$\\pm0.d_1 d_2 \\cdot \\cdot \\cdot d_k d_{k+1} d_{k+2} \\cdot \\cdot \\cdot \\times 10^n$$" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": { 226 | "deletable": false, 227 | "editable": false, 228 | "id": "ePR2k6RBXtQ2", 229 | "nbgrader": { 230 | "cell_type": "markdown", 231 | "checksum": "0126a243758e4fa72f9da085a31f7e5c", 232 | "grade": false, 233 | "grade_id": "cell-e94a8568552b2dc1", 234 | "locked": true, 235 | "schema_version": 3, 236 | "solution": false, 237 | "task": false 238 | } 239 | }, 240 | "source": [ 241 | "## Notación de punto flotante (truncamiento y redondeo)\n", 242 | "\n", 243 | "Se denota como $fl(y)$ y se obtiene delimitando el tamaño de la **mantisa**, una de ellas puede ser simplemente **truncando** en el término $d_{k+1}$:\n", 244 | "\n", 245 | "$$ fl(y) = 0.d_1 d_2 \\cdot \\cdot \\cdot \\times 10^n$$\n", 246 | "\n", 247 | "otra manera es **redondeando**, si el dígito $k+1$ es menor a cinco, cortamos, obteniendo el mismo resultado, pero si este es cinco o mayor, se agrega el valor de uno al $k$-ésimo término.\n", 248 | "\n", 249 | "$$fl(y)=\\pm 0.d_{1}d_{2}...\\tilde{d_{k}}\\times10^{n} \\qquad \\tilde{d_{k}}=\\begin{cases}\n", 250 | "\\begin{array}{c}\n", 251 | "d_{k} \\quad si\\,d_{k+1}<10/2\\\\\n", 252 | "d_{k}+1 \\quad si\\,d_{k+1}\\geq 10/2\n", 253 | "\\end{array}\\end{cases}$$" 254 | ] 255 | }, 256 | { 257 | "cell_type": "markdown", 258 | "metadata": { 259 | "deletable": false, 260 | "editable": false, 261 | "id": "Gx00UlJmwwkz", 262 | "nbgrader": { 263 | "cell_type": "markdown", 264 | "checksum": "9a2dbf273d048fe2b75a5cc1cd5f43d1", 265 | "grade": false, 266 | "grade_id": "cell-c249cf1775acec42", 267 | "locked": true, 268 | "schema_version": 3, 269 | "solution": false, 270 | "task": false 271 | } 272 | }, 273 | "source": [ 274 | "### Limitaciones en *Python*\n", 275 | "\n", 276 | "Empleando la versión de *Python* que usa *google colab* por default, responde las siguientes preguntas y actividades:\n", 277 | "\n", 278 | "* ¿Qué tipo de precisión se emplea en *python*?.\n", 279 | "* ¿Por qué la operación de la celda inferior devuelve `False`, aunque claramente debería devolver `True`?.\n", 280 | "* La función `round()` se emplea para redondear un valor a un cierto número de cifras significativas. Modifica el segundo *prtint* de la celda inferior para que el resultado sea `True`." 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": null, 286 | "metadata": { 287 | "deletable": false, 288 | "id": "YM488a98w1bw", 289 | "nbgrader": { 290 | "cell_type": "code", 291 | "checksum": "f6099bacdf8112c59d09508706f736fb", 292 | "grade": false, 293 | "grade_id": "cell-2179c16f0d85b6f8", 294 | "locked": false, 295 | "schema_version": 3, 296 | "solution": true, 297 | "task": false 298 | } 299 | }, 300 | "outputs": [], 301 | "source": [ 302 | "print(.1 + .1 + .1 == .3)\n", 303 | "\n", 304 | "print(round(.1, 1) + round(.1, 1) + round(.1, 1) == round(.3, 1))\n", 305 | "\n", 306 | "# YOUR CODE HERE\n", 307 | "raise NotImplementedError()" 308 | ] 309 | }, 310 | { 311 | "cell_type": "markdown", 312 | "metadata": { 313 | "deletable": false, 314 | "editable": false, 315 | "nbgrader": { 316 | "cell_type": "markdown", 317 | "checksum": "b5b742e2cc2e5d3432b662d0968bd196", 318 | "grade": false, 319 | "grade_id": "cell-ecae02f3d7425fea", 320 | "locked": true, 321 | "schema_version": 3, 322 | "solution": false, 323 | "task": false 324 | }, 325 | "id": "QGYsmHdhi9o8" 326 | }, 327 | "source": [ 328 | "### Ejercicio\n", 329 | "\n", 330 | "Define una función llamada `SumRound(a,b,c)` que sea capaz de redondear la suma de $a+b+c$ a dos dígitos después del punto decimal." 331 | ] 332 | }, 333 | { 334 | "cell_type": "code", 335 | "execution_count": null, 336 | "metadata": { 337 | "deletable": false, 338 | "id": "ntl0YrtHPboF", 339 | "nbgrader": { 340 | "cell_type": "code", 341 | "checksum": "9dbf92d813453d231caf31a270f6de40", 342 | "grade": false, 343 | "grade_id": "cell-39a456858bbf6cf4", 344 | "locked": false, 345 | "schema_version": 3, 346 | "solution": true, 347 | "task": false 348 | } 349 | }, 350 | "outputs": [], 351 | "source": [ 352 | "def SumRound(a,b,c):\n", 353 | " #Escribe un codigo donde sea capaz de redondear la suma de tres numeros a dos digitos despues del punto\n", 354 | " # YOUR CODE HERE\n", 355 | " raise NotImplementedError()" 356 | ] 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": { 361 | "deletable": false, 362 | "editable": false, 363 | "id": "QWQ6I3QKPboG", 364 | "nbgrader": { 365 | "cell_type": "markdown", 366 | "checksum": "a0ae9febc458fd8943fe305be9f0a782", 367 | "grade": false, 368 | "grade_id": "cell-ca06b53f6dba3642", 369 | "locked": true, 370 | "schema_version": 3, 371 | "solution": false, 372 | "task": false 373 | } 374 | }, 375 | "source": [ 376 | "Vamos a comprobar que la función previamente definida es la correcta." 377 | ] 378 | }, 379 | { 380 | "cell_type": "code", 381 | "execution_count": null, 382 | "metadata": { 383 | "id": "kvs6p0zjPboG" 384 | }, 385 | "outputs": [], 386 | "source": [ 387 | "SumRound(0.001,2.1,-2.1)\n", 388 | "#0.001+2.1-2.1 = 0.001" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": null, 394 | "metadata": { 395 | "deletable": false, 396 | "editable": false, 397 | "id": "UIK3_8L9PboG", 398 | "nbgrader": { 399 | "cell_type": "code", 400 | "checksum": "940bf866ad55bf56319d680ba47e9ece", 401 | "grade": true, 402 | "grade_id": "cell-17b2aa31e64bc5a1", 403 | "locked": true, 404 | "points": 3, 405 | "schema_version": 3, 406 | "solution": false, 407 | "task": false 408 | } 409 | }, 410 | "outputs": [], 411 | "source": [ 412 | "\"\"\"Verificando el resultado obtenido con la función SumRound(a,b,c)\"\"\"\n", 413 | "assert (SumRound(0.111,10.1,0.1) == 10.31 and SumRound(0.1,0.1,0.1) == 0.3 and \n", 414 | " SumRound(0.001,2.1,-2.1) == 0.0), \"Error en el resultado, revisa tu función\"\n", 415 | "\n", 416 | "print(\"La funcion SumRound pasa la prueba\")" 417 | ] 418 | }, 419 | { 420 | "cell_type": "markdown", 421 | "metadata": { 422 | "deletable": false, 423 | "editable": false, 424 | "id": "6svVvyrE5dNR", 425 | "nbgrader": { 426 | "cell_type": "markdown", 427 | "checksum": "8ee397c4d364e7272d37f8405edf7ddb", 428 | "grade": false, 429 | "grade_id": "cell-06991c30ccae9c80", 430 | "locked": true, 431 | "schema_version": 3, 432 | "solution": false, 433 | "task": false 434 | } 435 | }, 436 | "source": [ 437 | "## Aritmética de punto flotante (Error en cómputo científico)\n", 438 | "\n", 439 | "Con lo abordado en los temas previos, es claro que el cálculo de una computadora está limitado, lo cual implica que tiene **errores**. Uno de estos errores es el aproximar un número en su forma de punto flotante ya sea por **redondeo** o **truncamiento**.\n", 440 | "\n", 441 | "Es por este motivo que es importante conocer las diferentes formas de medir la magnitud de un error. Sea $fl(x)$ el número de máquina generado en el sistema $\\mathcal F$ asociado al valor real $x$, tendremos 2 formas de evaluar la magnitud del error." 442 | ] 443 | }, 444 | { 445 | "cell_type": "markdown", 446 | "metadata": { 447 | "deletable": false, 448 | "editable": false, 449 | "id": "uzbeMDwP7rq4", 450 | "nbgrader": { 451 | "cell_type": "markdown", 452 | "checksum": "5ba24a969769ff7624bc8678a06a3a63", 453 | "grade": false, 454 | "grade_id": "cell-b14fd45952a9c2f8", 455 | "locked": true, 456 | "schema_version": 3, 457 | "solution": false, 458 | "task": false 459 | } 460 | }, 461 | "source": [ 462 | "### Error relativo\n", 463 | "Esta forma de medir el error de un valor real con respeto de su aproximación considera la magnitud del valor real, y esta dada por la expresión.\n", 464 | "\n", 465 | "$$\\left|\\frac{y-fl(y)}{y}\\right|$$\n", 466 | "\n", 467 | "De la expresión anterior podemos ver que esta normalizada, de modo que podemos generar la diferencia porcentual entre la aproximación y el valor real.\n" 468 | ] 469 | }, 470 | { 471 | "cell_type": "markdown", 472 | "metadata": { 473 | "deletable": false, 474 | "editable": false, 475 | "id": "nsnSPhae8149", 476 | "nbgrader": { 477 | "cell_type": "markdown", 478 | "checksum": "d539b771be165037f57718f13a197ebc", 479 | "grade": false, 480 | "grade_id": "cell-c9e04e0b6fdaceee", 481 | "locked": true, 482 | "schema_version": 3, 483 | "solution": false, 484 | "task": false 485 | } 486 | }, 487 | "source": [ 488 | "### Error absoluto\n", 489 | "\n", 490 | "El error absoluto únicamente considera la magnitud de la diferencia entre $y$ y su aproximación $fl(y)$, es decir.\n", 491 | "\n", 492 | "$$\\left|y-fl(y)\\right|$$\n", 493 | "\n", 494 | "El error absoluto muestra la diferencia entre la aproximación $fl(y)$ y el valor $y$. En otras palabras, existe un número real $\\delta$ que depende de $y$, tal que\n", 495 | "\n", 496 | "$$fl(y)=y(1+\\delta)\\quad $$ siendo $$ \\,\\left|\\delta\\right|\\leq u$$\n", 497 | "\n", 498 | "Por otra parte, debido a que los números de punto flotante no están igualmente espaciados, es necesario tratar de encontrar una cota para el error absoluto.\n", 499 | "\n", 500 | "El error absoluto está acotado por la siguiente expresión.\n", 501 | "\n", 502 | "$$\\left|y-fl(y)\\right|\\leq\\frac{1}{2}\\beta^{-n+e}$$" 503 | ] 504 | }, 505 | { 506 | "cell_type": "markdown", 507 | "metadata": { 508 | "deletable": false, 509 | "editable": false, 510 | "id": "ueMk4P85-XP0", 511 | "nbgrader": { 512 | "cell_type": "markdown", 513 | "checksum": "b276053851f747e26c9f80316ace71bb", 514 | "grade": false, 515 | "grade_id": "cell-ec88d39abfa0b0b0", 516 | "locked": true, 517 | "schema_version": 3, 518 | "solution": false, 519 | "task": false 520 | } 521 | }, 522 | "source": [ 523 | "## Ejemplos y ejercicios\n", 524 | "\n", 525 | "\n", 526 | "**1. Ejemplo:**\n", 527 | "\n", 528 | "Calcular el error relativo y absoluto del valor $\\pi=3.14159265...$ al utilizar el método de truncamiento y el de redondeo a cinco dígitos (Hint: para el valor de $y$ utiliza $\\pi$ a cinco dígitos):\n", 529 | "\n", 530 | "Por truncamiento $fl(y)=0.31415\\times 10^1$, y para el redondeo tenemos un nueve en el sexto digito, por lo que;\n", 531 | "$$ fl(y)=(0.31415+0.00001)\\times 10^1=0.31416\\times10^1$$\n", 532 | "\n", 533 | "El error absoluto y relativo para el método de truncamiento es cero, mientras que para el caso del redondeo:\n", 534 | "$$\\left|y-fl(y)\\right|=\\left| 3.1415-3.1416 \\right|=0.0001$$\n", 535 | "\n", 536 | "$$\\left|\\frac{y-fl(y)}{y}\\right|=\\left|\\frac{0.0001}{0.31415\\times10^1}\\right|\\approx 0.00031$$\n", 537 | "\n", 538 | "**Ejercicios:**\n", 539 | "\n", 540 | "\n", 541 | "Calcula el el error absoluto y relativo para los siguientes casos, redondeando a 4 dígitos el resultado final:\n", 542 | "\n", 543 | "\n", 544 | "a) $y=e, \\quad f(y)=2.718$ $\\qquad \\qquad$ b) $y=e^{10}, \\quad f(y)=1400$\n", 545 | "\n", 546 | "c) $y=\\sqrt(2), \\quad f(y)=1.414$ $\\,\\,$ $\\qquad$ d) $y=9!, \\quad f(y)=\\sqrt(18\\pi)(9/e)^9$" 547 | ] 548 | }, 549 | { 550 | "cell_type": "markdown", 551 | "metadata": { 552 | "deletable": false, 553 | "editable": false, 554 | "id": "OyChikLBPboJ", 555 | "nbgrader": { 556 | "cell_type": "markdown", 557 | "checksum": "0e5de9a6fc406f22944e80ea8e34129d", 558 | "grade": false, 559 | "grade_id": "cell-9b0f5e53de4bd489", 560 | "locked": true, 561 | "schema_version": 3, 562 | "solution": false, 563 | "task": false 564 | } 565 | }, 566 | "source": [ 567 | "Ahora de ejercicio crearemos un función que calcule el error absoluto y relativo." 568 | ] 569 | }, 570 | { 571 | "cell_type": "code", 572 | "execution_count": null, 573 | "metadata": { 574 | "deletable": false, 575 | "id": "rkilQijIPboK", 576 | "nbgrader": { 577 | "cell_type": "code", 578 | "checksum": "779bf43bf997c6a52df5c4de81dbbdec", 579 | "grade": false, 580 | "grade_id": "cell-07d543d1aa19ec0f", 581 | "locked": false, 582 | "schema_version": 3, 583 | "solution": true, 584 | "task": false 585 | } 586 | }, 587 | "outputs": [], 588 | "source": [ 589 | "def ErrorAbsolutoyRelativo(y,f):\n", 590 | " import math\n", 591 | " #y es el valor y f su aproximacion\n", 592 | " #define el valor Relativo, nombre de la variable \"ErrorRelativo\"\n", 593 | " # YOUR CODE HERE\n", 594 | " raise NotImplementedError()\n", 595 | " return round(ErrorRelativo, 4)" 596 | ] 597 | }, 598 | { 599 | "cell_type": "markdown", 600 | "metadata": { 601 | "deletable": false, 602 | "editable": false, 603 | "id": "RVrVimwmPboK", 604 | "nbgrader": { 605 | "cell_type": "markdown", 606 | "checksum": "d941ed00bd65e5036593aa787936b165", 607 | "grade": false, 608 | "grade_id": "cell-262f3ce7e7fa2518", 609 | "locked": true, 610 | "schema_version": 3, 611 | "solution": false, 612 | "task": false 613 | } 614 | }, 615 | "source": [ 616 | "La segunda parte del ejercicio de va a evaluar la función diseñada con los ejemplos propuestos, cada una vale un punto. Procura ejecutar tu código para revisar que funcione correctamente." 617 | ] 618 | }, 619 | { 620 | "cell_type": "code", 621 | "execution_count": null, 622 | "metadata": { 623 | "id": "Zd1DRXLfPboK" 624 | }, 625 | "outputs": [], 626 | "source": [ 627 | "from math import e\n", 628 | "import math\n", 629 | "ErrorAbsolutoyRelativo(math.factorial(9),math.sqrt(18/math.pi)*(9/e)**9)" 630 | ] 631 | }, 632 | { 633 | "cell_type": "code", 634 | "execution_count": null, 635 | "metadata": { 636 | "deletable": false, 637 | "editable": false, 638 | "id": "SGnSBj0UPboM", 639 | "nbgrader": { 640 | "cell_type": "code", 641 | "checksum": "6e00ff66cf580425f20dbf35c41ec365", 642 | "grade": true, 643 | "grade_id": "cell-c350336521d99eee", 644 | "locked": true, 645 | "points": 4, 646 | "schema_version": 3, 647 | "solution": false, 648 | "task": false 649 | } 650 | }, 651 | "outputs": [], 652 | "source": [ 653 | "from math import e\n", 654 | "import math\n", 655 | "\n", 656 | "\"\"\"Verificando el resultado obtenido con la función ErrorAbsolutoyRelativo(y,f)\"\"\"\n", 657 | "assert (ErrorAbsolutoyRelativo(e,2.718) == 0.0001 and ErrorAbsolutoyRelativo(math.sqrt(2),1.414) == 0.0002 and \n", 658 | " ErrorAbsolutoyRelativo(e**(10),1400) == 0.9364 and\n", 659 | " ErrorAbsolutoyRelativo(math.factorial(9),math.sqrt(18/math.pi)*(9/e)**9) == 0.6846), \"Error en el resultado, revisa tu función\"\n", 660 | "\n", 661 | "print(\"La funcion ErrorAbsolutoyRelativo pasa la prueba\")" 662 | ] 663 | }, 664 | { 665 | "cell_type": "markdown", 666 | "metadata": { 667 | "deletable": false, 668 | "editable": false, 669 | "id": "74sdWNFcX_Xv", 670 | "nbgrader": { 671 | "cell_type": "markdown", 672 | "checksum": "7ed4a1b7bae81b8c491dc1fd056b0258", 673 | "grade": false, 674 | "grade_id": "cell-574d0a9567921fdd", 675 | "locked": true, 676 | "schema_version": 3, 677 | "solution": false, 678 | "task": false 679 | } 680 | }, 681 | "source": [ 682 | "## Bibliografía\n", 683 | "1. Numerical Methods, Third Edition, J. Douglas Faires\n", 684 | "2. Notas del curso de Analisis Numerico, [Git](https://github.com/jugernaut/Numerico2021), Miguel Angel Pérez Leon.\n", 685 | "3. Riswan Butt: Numerical Analysys Using Matlab, Jones and Bartlett." 686 | ] 687 | } 688 | ], 689 | "metadata": { 690 | "colab": { 691 | "collapsed_sections": [], 692 | "name": "PreAritmeticaFlotanteEstudiante.ipynb", 693 | "provenance": [], 694 | "toc_visible": true, 695 | "include_colab_link": true 696 | }, 697 | "kernelspec": { 698 | "display_name": "Python 3 (ipykernel)", 699 | "language": "python", 700 | "name": "python3" 701 | }, 702 | "language_info": { 703 | "codemirror_mode": { 704 | "name": "ipython", 705 | "version": 3 706 | }, 707 | "file_extension": ".py", 708 | "mimetype": "text/x-python", 709 | "name": "python", 710 | "nbconvert_exporter": "python", 711 | "pygments_lexer": "ipython3", 712 | "version": "3.8.10" 713 | } 714 | }, 715 | "nbformat": 4, 716 | "nbformat_minor": 0 717 | } -------------------------------------------------------------------------------- /02_ResolucionDeSistemasLineales/NumeroCondicion.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "kernelspec": { 6 | "display_name": "Python 3.7 (tensorflow)", 7 | "language": "python", 8 | "name": "tensorflow" 9 | }, 10 | "language_info": { 11 | "codemirror_mode": { 12 | "name": "ipython", 13 | "version": 3 14 | }, 15 | "file_extension": ".py", 16 | "mimetype": "text/x-python", 17 | "name": "python", 18 | "nbconvert_exporter": "python", 19 | "pygments_lexer": "ipython3", 20 | "version": "3.7.7" 21 | }, 22 | "colab": { 23 | "name": "05_Numero_condicion.ipynb", 24 | "provenance": [], 25 | "toc_visible": true, 26 | "include_colab_link": true 27 | } 28 | }, 29 | "cells": [ 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "view-in-github", 34 | "colab_type": "text" 35 | }, 36 | "source": [ 37 | "\"Open" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": { 43 | "id": "M618aCs2XLvO" 44 | }, 45 | "source": [ 46 | "\n", 47 | "

Número de Condición

\n", 48 | "
\n", 49 | " \n", 50 | "
Profesora: \tUrsula Xiomara Iturrarán Viveros
\n", 51 | "
Ayudante: Juan Pablo Cordero Santiago
\n", 52 | "
Materia: Análisis Numérico
\n", 53 | "
" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": { 59 | "id": "-bqM41e4XLvT" 60 | }, 61 | "source": [ 62 | "# Introducción\n", 63 | "\n", 64 | "Para este punto del curso ya debe ser claro que una de las principales características de cualquier solución (algoritmo) $\\widehat{f}$ es la estabilidad\n", 65 | "\n", 66 | "De tal manera que determinar que tan estable es esta solución es importante para el análisis numérico.\n", 67 | "\n", 68 | "Recordando un poco la definición de estabilidad para matrices, tenemos. \n", 69 | "\n" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": { 75 | "id": "2xCqZcd3Znq4" 76 | }, 77 | "source": [ 78 | "# Definición\n", 79 | "\n", 80 | "Un algoritmo es estable para una clase de matrices $C$ si $\\forall A\\in C$, la solución computacional $\\widehat{x}$ generada por el algoritmo es la solución exacta cercana a la solución del problema. Así que para el sistema lineal $Ax=b$, un algoritmo es estable si $\\forall A\\in C$ y para cada $b$, se produce una solución computacional $\\widehat{x}$ que satisface $\\left(A+E\\right)\\widehat{x}=b+\\delta b$\n", 81 | "\n", 82 | "Para alguna $E$ y $\\delta b$, donde $\\left(A+E\\right)$ es cercana a $A$ y $b+\\delta b$ es cercano a $b$." 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": { 88 | "id": "CvMOESPvZ7D9" 89 | }, 90 | "source": [ 91 | "# Condicionamiento\n", 92 | "\n", 93 | "Un problema (con respecto a un conjunto de datos) es llamado 'mal condicionado', si una pequeña perturbación relativa en los datos iniciales, produce un error relativo grande en la solución computacional, sin importar el método de solución. Por otro lado, es llamado 'bien condicionado', si toda pequeña perturbación en los datos iniciales, produce pequeños errores relativos en la solución.\n", 94 | "\n", 95 | "Sea $x$ e $y$ el dato original y el dato perturbado ligeramente y sea $f(x)$ y $f(y)$ sus respectivas soluciones. Se tiene lo siguiente\n", 96 | "\n", 97 | "**Problema bien condicionado**: si $y$ es cercano a $x$ entonces $f(y)$ es cercano a $f(x)$.\n", 98 | "\n", 99 | "**Problema mal condicionado**: aunque $y$ sea cercano a $x$ entonces $f(y)$ puede alejarse en gran medida de $f(x)$.\n" 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "metadata": { 105 | "id": "FUGsj4qha1oq" 106 | }, 107 | "source": [ 108 | "## Número de Condición\n", 109 | "\n", 110 | "El numero de condición del problema $f$ con respecto al dato $x$ es definido como\n", 111 | "\n", 112 | "$$\\frac{Error\\,relativo\\,en\\,la\\,soluci\\acute{o}n}{Perturbaci\\acute{o}n\\,relativa\\,en\\,el\\,dato}=\\frac{\\frac{\\left||f(x)-f(y)\\right|}{\\left||f(x)\\right||}}{\\frac{\\left||x-y\\right||}{\\left||x\\right||}}$$\n", 113 | "\n", 114 | "Si $f:\\mathbb{R}^{n}\\longrightarrow\\mathbb{R}^{m}$ y $x,y\\in\\mathbb{R}^{n}$, entonces el número de condición se define formalmente como\n", 115 | "\n", 116 | "$$\\underset{\\epsilon_{M}\\rightarrow0}{\\limsup}\\left\\{ \\frac{\\frac{\\left\\Vert f(x)-f(y)\\right\\Vert }{\\left\\Vert f(x)\\right\\Vert }}{\\frac{\\left\\Vert x-y\\right\\Vert }{\\left\\Vert x\\right\\Vert }}\\quad tal\\,que\\quad\\left\\Vert x-y\\right\\Vert \\leq\\epsilon_{M}\\right\\} $$\n", 117 | "\n", 118 | "Observación: Un problema es mal condicionado si el numero de condición es $\\gg1$ (mucho mayor que 1)." 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": { 124 | "id": "Em9NqX70aSjR" 125 | }, 126 | "source": [ 127 | "## Ejemplo\n", 128 | "\n", 129 | "El problema de encontrar raíces de un polinomio puede ser altamente mal condicionado. Considere resolver la ecuación \n", 130 | "\n", 131 | "$$f(x)=x^{2}-2x+1$$\n", 132 | "\n", 133 | "Ahora perturbe el coeficiente 2 por 0.00001, es decir $$\\widehat{f}(x)=x^{2}+2.00001x+1$$\n", 134 | "\n", 135 | "y analice que sucede con las soluciones y sus respectivos errores relativos.\n", 136 | "\n", 137 | "En general, si un algoritmo **estable hacia atrás** es aplicado a un problema con numero de condición $\\kappa$, entonces la precisión de la solución dependerá de $\\kappa$.\n", 138 | "\n", 139 | "Si $\\kappa$ es muy pequeño, el resultado sera preciso; en caso contrario la precisión no tiene garantía. Por lo que podemos decir que **la precisión depende del numero de condicionamiento** $\\kappa$." 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "metadata": { 145 | "id": "v5tE8x_XQdbT", 146 | "colab": { 147 | "base_uri": "https://localhost:8080/" 148 | }, 149 | "outputId": "871b28f1-d51a-4d27-d3e5-c21ac81f01f5" 150 | }, 151 | "source": [ 152 | "# se clona el proyecto y se agrega a la sesion\n", 153 | "!git clone https://github.com/jugernaut/Numerico2021.git\n", 154 | "# importamos la biblioteca correspondiente gutils\n", 155 | "import Numerico2021.Utils.gutils as vis\n", 156 | "\n", 157 | "# f sin la perturbacion\n", 158 | "def fsingorro(x):\n", 159 | " return (x*x)-2*x+1\n", 160 | "\n", 161 | "# f con una diminuta perturbacion\n", 162 | "def fcongorro(x):\n", 163 | " return (x*x)-2.00001*x+1\n", 164 | "\n", 165 | "# evaluaciones de las respectivas funciones\n", 166 | "fngorro = vis.newton(fsingorro, 0.0001, 100, -2)\n", 167 | "fgorro = vis.newton(fcongorro, 0.0001, 100, -2)\n", 168 | "# error relativo entre las f's\n", 169 | "errorrel = abs(fgorro-fngorro)/abs(fngorro)\n", 170 | "\n", 171 | "# se imprimen los resultados\n", 172 | "print(fngorro)\n", 173 | "print(fgorro)\n", 174 | "\n", 175 | "# error relativo 'grande' aunque la perturbacion fue diminuta\n", 176 | "print(errorrel)" 177 | ], 178 | "execution_count": null, 179 | "outputs": [ 180 | { 181 | "output_type": "stream", 182 | "text": [ 183 | "fatal: destination path 'Numerico2021' already exists and is not an empty directory.\n", 184 | "0.9999686826426051\n", 185 | "0.9968430501939348\n", 186 | "0.003125730338284381\n" 187 | ], 188 | "name": "stdout" 189 | } 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": { 195 | "id": "DbbcgymQbVH-" 196 | }, 197 | "source": [ 198 | "# Análisis de la Perturbación sobre $x$ y $b$\n", 199 | "\n", 200 | "Cuando un analista numérico se propone resolver un problema, normalmente los datos con los que trabaja no son los datos originales, si no con datos que han sido perturbados. La pregunta que surge naturalmente es:\n", 201 | "\n", 202 | "¿De que manera afectaran estas perturbaciones a la solución?.\n", 203 | "\n", 204 | "Una técnica teórica del análisis numérico que investiga estos cambios, la cual es independiente del algoritmo usado para resolver el problema, se llama **análisis de la perturbación**." 205 | ] 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "metadata": { 210 | "id": "S58NUe1PYs6B" 211 | }, 212 | "source": [ 213 | "## Nomenclatura y efectos de las perturbaciones\n", 214 | "\n", 215 | "Sea $A\\in M_{n\\times n}$ y $\\vec{x}, \\vec{b} \\in \\mathbb{R}^{n}$. Supongamos que $\\vec{x}$ y $\\vec{b}$ han sido perturbados y que la matriz $A$ es exacta.\n", 216 | "\n", 217 | "$$\\begin{array}{c}\n", 218 | "A\\longrightarrow A\\quad(sin\\,cambios)\\\\\n", 219 | "\\vec{b}\\longrightarrow \\vec{b}+\\vec{\\delta b}\\quad(\\vec{\\delta b}=perturbaci\\acute{o}n\\,en\\,el\\,vector\\,b)\\\\\n", 220 | "\\vec{x}\\longrightarrow \\vec{x}+\\vec{\\delta x}\\quad(\\vec{\\delta x}=cambio\\,en\\,la\\,soluci\\acute{o}n)\n", 221 | "\\end{array}$$\n", 222 | "\n", 223 | "Nota: En lo subsiguiente, para mayor claridad se omite el simbolo $( \\vec{} )$, en los respectivos vectores $\\vec{x}, \\vec{b}, \\vec{\\delta x}, \\vec{\\delta b}$, sin embargo siguen siendo vectores." 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": { 229 | "id": "dab-rd4ZbsiO" 230 | }, 231 | "source": [ 232 | "## Teorema (Cota del condicionamiento)\n", 233 | "\n", 234 | "Si $\\delta x$ y $\\delta b$ son, respectivamente las perturbaciones de $x$ y $b$ en el sistema lineal $Ax=b$, con $A$ no singular y $b\\neq \\vec{0}$ , entonces \n", 235 | "\n", 236 | "$$\\left\\Vert A\\right\\Vert \\left\\Vert A^{-1}\\right\\Vert \\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert b\\right\\Vert }\\geq\\frac{\\left\\Vert \\delta x\\right\\Vert }{\\left\\Vert x\\right\\Vert }\\geq \\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert A\\right\\Vert \\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert }$$\n", 237 | "\n", 238 | "Como $Ax=b$ y $A\\left(x+\\delta x\\right)=b+\\delta b$, tenemos que \n", 239 | "\n", 240 | "$$\n", 241 | "\\begin{eqnarray*}\n", 242 | "A\\left(x+\\delta x\\right)&\t=\t& b+\\delta b \\\\\n", 243 | "Ax+A\\delta x &=&\tb+\\delta b \\\\\n", 244 | "b+A\\delta x\t&=&\tb+\\delta b\\quad(ya\\,que\\,Ax=b) \\\\\n", 245 | "A\\delta x\t&=&\t\\delta b \\\\\n", 246 | "\\Rightarrow\t\\delta x\t&=& A^{-1}\\delta b\n", 247 | "\\end{eqnarray*}\n", 248 | "$$\n", 249 | "\n", 250 | "Tomando cualquier norma matricial subordinada tenemos\n", 251 | "\n", 252 | "$$\\left\\Vert \\delta x\\right\\Vert \\overset{\\underbrace{prop\\,5\\,nor.}}{\\leq} \\left\\Vert A^{-1}\\right\\Vert \\left\\Vert \\delta b\\right\\Vert \\tag{1}$$\n", 253 | "\n", 254 | "De nuevo, tomando la misma norma y aplicando en ambos lados de $Ax=b$, se tiene $\\left\\Vert Ax\\right\\Vert =\\left\\Vert b\\right\\Vert$ ó\n", 255 | "\n", 256 | "$$\\left\\Vert b\\right\\Vert =\\left\\Vert Ax\\right\\Vert \\leq\\left\\Vert A\\right\\Vert \\left\\Vert x\\right\\Vert \\Rightarrow\\left\\Vert b\\right\\Vert \\leq\\left\\Vert A\\right\\Vert \\left\\Vert x\\right\\Vert \\tag{2} $$\n", 257 | "\n", 258 | "Ahora si combinamos (1) y (2), se obtiene\n", 259 | "\n", 260 | "$$\n", 261 | "\\begin{eqnarray*}\n", 262 | "\\left\\Vert \\delta x\\right\\Vert \\left\\Vert b\\right\\Vert \t&\\leq&\\left\\Vert A\\right\\Vert \\left\\Vert A^{-1}\\right\\Vert \\left\\Vert x\\right\\Vert \\left\\Vert \\delta b\\right\\Vert \\\\\n", 263 | "\\Rightarrow\t\\frac{\\left\\Vert \\delta x\\right\\Vert }{\\left\\Vert x\\right\\Vert } &\\leq&\t\\left\\Vert A\\right\\Vert \\left\\Vert A^{-1}\\right\\Vert \\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert b\\right\\Vert }\n", 264 | "\\end{eqnarray*} \\tag{3}\n", 265 | "$$\n", 266 | "\n", 267 | "Por otra parte $A\\delta x=\\delta b\\Longrightarrow\\left\\Vert A\\right\\Vert \\left\\Vert \\delta x\\right\\Vert \\geq\\left\\Vert \\delta b\\right\\Vert $ por lo tanto \n", 268 | "\n", 269 | "$$\\left\\Vert \\delta x\\right\\Vert \\geq\\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert A\\right\\Vert } \\tag{4}$$\n", 270 | "\n", 271 | "De igual manera de $Ax=b$, se tiene que \n", 272 | "\n", 273 | "$$ \n", 274 | "\\begin{eqnarray*}\n", 275 | "Ax &=& b\\\\\n", 276 | "x &=& A^{-1}b\\\\\n", 277 | "\\left\\Vert x\\right\\Vert &\\leq &\\left\\Vert A^{-1}\\right\\Vert\n", 278 | "\\left\\Vert b \\right\\Vert \\\\\n", 279 | "\\frac{\\left\\Vert x\\right\\Vert}{\\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert} & \\leq &\\frac{\\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert}{\\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert }\\\\\n", 280 | "\\frac{\\left\\Vert x\\right\\Vert}{\\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert} & \\leq & 1\\\\\n", 281 | "\\frac{\\left\\Vert x\\right\\Vert}{\\left\\Vert x\\right\\Vert\\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert} & \\leq &\\frac{1}{\\left\\Vert x\\right\\Vert}\\\\\n", 282 | "\\frac{1}{\\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert} & \\leq &\\frac{1}{\\left\\Vert x\\right\\Vert}\\\\\n", 283 | "\\Rightarrow\\frac{1}{\\left\\Vert x\\right\\Vert } &\\geq&\\frac{1}{\\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert } \\tag{5}\n", 284 | "\\end{eqnarray*}\n", 285 | "$$\n", 286 | "\n", 287 | "Combinando (4) y (5), tenemos\n", 288 | "\n", 289 | "$$\\frac{\\left\\Vert \\delta x\\right\\Vert }{\\left\\Vert x\\right\\Vert }\\geq\\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert A\\right\\Vert \\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert }$$\n", 290 | "\n", 291 | "Finalmente, si combinamos (3) y (5) podemos concluir que.\n", 292 | "\n", 293 | "$$\\left\\Vert A\\right\\Vert \\left\\Vert A^{-1}\\right\\Vert \\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert b\\right\\Vert }\\geq\\frac{\\left\\Vert \\delta x\\right\\Vert }{\\left\\Vert x\\right\\Vert }\\geq \\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert A\\right\\Vert \\left\\Vert A^{-1}\\right\\Vert \\left\\Vert b\\right\\Vert }$$" 294 | ] 295 | }, 296 | { 297 | "cell_type": "markdown", 298 | "metadata": { 299 | "id": "Y8v1ihCdcPM0" 300 | }, 301 | "source": [ 302 | "# Número de Condición\n", 303 | "\n", 304 | "El número de condición nos proporciona información valiosa sobre la estabilidad de un algoritmo que en este caso es representado por una matriz.\n" 305 | ] 306 | }, 307 | { 308 | "cell_type": "markdown", 309 | "metadata": { 310 | "id": "9-O2SL1jf4tL" 311 | }, 312 | "source": [ 313 | "## Definición\n", 314 | "\n", 315 | "El número $\\left\\Vert A\\right\\Vert \\left\\Vert A^{-1}\\right\\Vert$ es llamado el número de condición de $A$ y es denotado por $\\kappa\\left(A\\right)$ ó $ Cond\\left(A\\right)$\n", 316 | "\n", 317 | "El teorema sobre la cota de condicionamiento muestra que un cambio relativo en la solución puede ser tan grande como $\\kappa\\left(A\\right)$ multiplicado por el cambio relativo en el vector $b$. \n", 318 | "\n", 319 | "Lo que significa que **si $\\kappa\\left(A\\right)$ no es demasiado grande**, entonces una pequeña perturbación en el vector $b$ **tendrá muy poco efecto sobre la solución**. \n", 320 | "\n", 321 | "Por otro lado **si $\\kappa\\left(A\\right)$ es grande**, entonces incluso una pequeña perturbación en el vector $b$ **cambia drásticamente la solución**. " 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": { 327 | "id": "pFBxGHXHkqRZ" 328 | }, 329 | "source": [ 330 | "## Ejemplo\n", 331 | "\n", 332 | "Sea\n", 333 | "\n", 334 | "$$A=\\left(\\begin{array}{ccc}\n", 335 | "1 & 2 \\\\\n", 336 | "3 & 4\n", 337 | "\\end{array}\\right) \\Rightarrow {A}^{-1}=\\left(\\begin{array}{ccc}\n", 338 | "-2 & 1 \\\\\n", 339 | "1.5 & -0.5\n", 340 | "\\end{array}\\right)$$\n", 341 | "\n", 342 | "Tomamos la 1-norma (puede ser cualquiera) y las calculamos\n", 343 | "\n", 344 | "$$ {\\left\\Vert A\\right\\Vert}_1 = 6 \\quad {\\left\\Vert A^{-1}\\right\\Vert}_1 = 3.5 $$\n", 345 | "\n", 346 | "$\\kappa_{1}\\left(A\\right)={\\left\\Vert A\\right\\Vert}_1 {\\left\\Vert A^{-1}\\right\\Vert}_1 = 6\\times3.5=21$\n", 347 | "\n", 348 | "Tomamos la 2-norma (puede ser cualquiera) y las calculamos\n", 349 | "\n", 350 | "$$ {\\left\\Vert A\\right\\Vert}_2 = 5.46 \\quad {\\left\\Vert A^{-1}\\right\\Vert}_2 = 2.73 $$\n", 351 | "\n", 352 | "$\\kappa_{2}\\left(A\\right)={\\left\\Vert A\\right\\Vert}_2{\\left\\Vert A^{-1}\\right\\Vert}_2 = 5.46 \\times 2.73 = 14.9$\n" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "metadata": { 358 | "id": "H_QSIvrdljnf", 359 | "outputId": "4ca32c14-0aed-47d2-c0cb-331d53208640", 360 | "colab": { 361 | "base_uri": "https://localhost:8080/" 362 | } 363 | }, 364 | "source": [ 365 | "# matriz A\n", 366 | "A = np.array([[1,2],[3,4]])\n", 367 | "print(A)\n", 368 | "\n", 369 | "# matriz A\n", 370 | "inversaA = np.linalg.inv(A)\n", 371 | "print(inversaA)\n", 372 | "\n", 373 | "# comprobacion\n", 374 | "print(np.matmul(A, inversaA))\n", 375 | "\n", 376 | "# 1-norma de A\n", 377 | "normaA = np.linalg.norm(A,1)\n", 378 | "\n", 379 | "# 1-norma de A inversa\n", 380 | "normaAinversa = np.linalg.norm(inversaA,1)\n", 381 | "\n", 382 | "# numero de condición 1\n", 383 | "cond1 = normaA*normaAinversa\n", 384 | "print(cond1)\n", 385 | "print(np.linalg.cond(A,1))\n", 386 | "\n", 387 | "# 2-norma de A\n", 388 | "normaA = np.linalg.norm(A,2)\n", 389 | "\n", 390 | "# 2-norma de A inversa\n", 391 | "normaAinversa = np.linalg.norm(inversaA,2)\n", 392 | "\n", 393 | "# numero de condición 2\n", 394 | "cond2 = normaA*normaAinversa\n", 395 | "print(cond2)\n", 396 | "print(np.linalg.cond(A,2))" 397 | ], 398 | "execution_count": null, 399 | "outputs": [ 400 | { 401 | "output_type": "stream", 402 | "text": [ 403 | "[[1 2]\n", 404 | " [3 4]]\n", 405 | "[[-2. 1. ]\n", 406 | " [ 1.5 -0.5]]\n", 407 | "[[1.0000000e+00 0.0000000e+00]\n", 408 | " [8.8817842e-16 1.0000000e+00]]\n", 409 | "20.999999999999993\n", 410 | "20.999999999999993\n", 411 | "14.93303437365925\n", 412 | "14.933034373659268\n" 413 | ], 414 | "name": "stdout" 415 | } 416 | ] 417 | }, 418 | { 419 | "cell_type": "markdown", 420 | "metadata": { 421 | "id": "EisAYkZ4gNSQ" 422 | }, 423 | "source": [ 424 | "## Ejemplo en un sistema lineal\n", 425 | "\n", 426 | "Sean\n", 427 | "\n", 428 | "$$A=\\left(\\begin{array}{ccc}\n", 429 | "1 & 2 & 1\\\\\n", 430 | "2 & 4.0001 & 2.002\\\\\n", 431 | "1 & 2.002 & 2.004\n", 432 | "\\end{array}\\right) \\quad b=\\left(\\begin{array}{c}\n", 433 | "4\\\\\n", 434 | "8.0021\\\\\n", 435 | "5.006\n", 436 | "\\end{array}\\right)$$\n", 437 | "\n", 438 | "Encuentre $x$ y después cambie $b$ por $b'=\\left(\\begin{array}{c}\n", 439 | "4\\\\\n", 440 | "8.0020\\\\\n", 441 | "5.0061\n", 442 | "\\end{array}\\right)$\n", 443 | "\n", 444 | "La solución exacta es $x=\\left(1,1,1\\right)^{T}$. Veamos la perturbación relativa:\n", 445 | "\n", 446 | "$$\\frac{\\left\\Vert b'-b\\right\\Vert }{\\left\\Vert b\\right\\Vert }=\\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert b\\right\\Vert }=1.3795\\times10^{-5}\\qquad(muy\\,peque\\tilde{n}o)$$\n", 447 | "\n", 448 | "Ahora, si resolvemos el sistema $Ax'=b'$, tenemos que \n", 449 | "\n", 450 | "$$x'=x+\\delta x=\\left(\\begin{array}{c}\n", 451 | "3.0850\\\\\n", 452 | "-0.0436\\\\\n", 453 | "1.0022\n", 454 | "\\end{array}\\right)$$\n", 455 | "\n", 456 | "$x'$ es completamente diferente a $x$. Ademas $\\kappa\\left(A\\right)=322099.88$, lo cual corrobora el teorema.\n", 457 | "\n", 458 | "Por otra parte el error relativo en la solución es $\\frac{\\left\\Vert \\delta x\\right\\Vert }{\\left\\Vert x\\right\\Vert }=1.3461$ y se comprueba que la desigualdad de la cota de condicionamiento se cumple \n", 459 | "\n", 460 | "$$\\kappa\\left(A\\right)\\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert b\\right\\Vert }=4.4433>1.3461=\\frac{\\left\\Vert \\delta x\\right\\Vert }{\\left\\Vert x\\right\\Vert }$$" 461 | ] 462 | }, 463 | { 464 | "cell_type": "code", 465 | "metadata": { 466 | "colab": { 467 | "base_uri": "https://localhost:8080/" 468 | }, 469 | "id": "eRMdNTGOuCaS", 470 | "outputId": "977ae8fc-545a-4c6f-bda2-306e61ed5a51" 471 | }, 472 | "source": [ 473 | "import numpy as np\n", 474 | "# se define la matriz A\n", 475 | "A = np.array([[1,2,1],[2,4.0001,2.002],[1,2.002,2.004]])\n", 476 | "# vector b\n", 477 | "b = np.array([4,8.0021,5.006])\n", 478 | "# solucion del sistema\n", 479 | "x = np.linalg.solve(A,b)\n", 480 | "# veamos la solucion\n", 481 | "print(x)\n", 482 | "\n", 483 | "# ahora perturbemos un poco el vector b\n", 484 | "b = np.array([4,8.0020,5.0061])\n", 485 | "# nueva solucion del sistema\n", 486 | "xprima = np.linalg.solve(A,b)\n", 487 | "# veamos la solucion\n", 488 | "print(xprima)\n", 489 | "\n", 490 | "# numero de condicion de la matriz A\n", 491 | "print(np.linalg.cond(A))" 492 | ], 493 | "execution_count": null, 494 | "outputs": [ 495 | { 496 | "output_type": "stream", 497 | "text": [ 498 | "[1. 1. 1.]\n", 499 | "[ 3.08495851 -0.04356846 1.00217842]\n", 500 | "322099.88408211124\n" 501 | ], 502 | "name": "stdout" 503 | } 504 | ] 505 | }, 506 | { 507 | "cell_type": "markdown", 508 | "metadata": { 509 | "id": "_f44ROdLciFZ" 510 | }, 511 | "source": [ 512 | "# Análsis de la perturbación en la matriz A\n", 513 | "\n", 514 | "Supongamos que $A$ ha sido perturbada y que el vector $b$ es exacto \n", 515 | "\n", 516 | "$$\\begin{array}{c}\n", 517 | "A\\longrightarrow A+\\triangle A\\quad(\\triangle A=perturbaci\\acute{o}\\,en\\,matriz\\,A)\\\\\n", 518 | "b\\longrightarrow b\\quad(sin\\,cambios)\\\\\n", 519 | "x\\longrightarrow x+\\delta x\\quad(\\delta x=cambio\\,en\\,la\\,soluci\\acute{o}n)\n", 520 | "\\end{array} $$\n", 521 | "\n", 522 | "Suponga que $A$ es no singular y $b\\neq0$. Si $\\triangle A$ y $\\delta x$ son respectivamente, las perturbaciones de $A$ y $x$ en el sistema lineal $Ax=b$. Suponer que $\\triangle A$ es tal que $\\left\\Vert \\triangle A\\right\\Vert <\\frac{1}{\\left\\Vert A^{-1}\\right\\Vert }$. Entonces \n", 523 | "\n", 524 | "$$\\frac{\\left\\Vert \\delta x\\right\\Vert }{\\left\\Vert x\\right\\Vert }\\leq\\frac{\\kappa\\left(A\\right)\\frac{\\left\\Vert \\triangle A\\right\\Vert }{\\left\\Vert A\\right\\Vert }}{1-\\kappa\\left(A\\right)\\frac{\\left\\Vert \\triangle A\\right\\Vert }{\\left\\Vert A\\right\\Vert }}$$" 525 | ] 526 | }, 527 | { 528 | "cell_type": "markdown", 529 | "metadata": { 530 | "id": "0syQnzjThAxk" 531 | }, 532 | "source": [ 533 | "## Ejemplo\n", 534 | "\n", 535 | "Sean\n", 536 | "\n", 537 | "$$A=\\left(\\begin{array}{ccc}\n", 538 | "1 & 2 & 1\\\\\n", 539 | "2 & 4.0001 & 2.002\\\\\n", 540 | "1 & 2.002 & 2.004\n", 541 | "\\end{array}\\right) \\quad b=\\left(\\begin{array}{c}\n", 542 | "4\\\\\n", 543 | "8.0021\\\\\n", 544 | "5.006\n", 545 | "\\end{array}\\right)$$\n", 546 | "\n", 547 | "\n", 548 | "Encuentre $x$ y después cambie $a_{23}=2.002$ por $2.0021$\n", 549 | "\n", 550 | "La solución exacta es $x=(1,1,1)^{T}$. Veamos la perturbación relativa:\n", 551 | "\n", 552 | "$$\\triangle A=+10^{-4}\\left(\\begin{array}{ccc}\n", 553 | "0 & 0 & 0\\\\\n", 554 | "0 & 0 & 0.1000\\\\\n", 555 | "0 & 0 & 0\n", 556 | "\\end{array}\\right)\\quad(muy\\,peque\\tilde{n}o)$$\n", 557 | "\n", 558 | "Sin embargo, al resolver el sistema $\\left(A+\\triangle A\\right)x'=b$, tenemos que: \n", 559 | "\n", 560 | "$$x'=\\left(\\begin{array}{c}\n", 561 | "3.0852\\\\\n", 562 | "-0.0437\\\\\n", 563 | "1.0021\n", 564 | "\\end{array}\\right),\\quad\\delta x=x'-x=\\left(\\begin{array}{c}\n", 565 | "2.0852\\\\\n", 566 | "-1.0437\\\\\n", 567 | "0.0021\n", 568 | "\\end{array}\\right)$$\n", 569 | "\n", 570 | "Error relativo $=\\frac{\\left\\Vert \\delta x\\right\\Vert }{\\left\\Vert x\\right\\Vert }=1.3463$, lo cual es bastante grande.\n", 571 | "\n", 572 | "Ademas \n", 573 | "\n", 574 | "$$\\kappa\\left(A\\right)={\\left\\Vert A\\right\\Vert}_2 {\\left\\Vert A^{-1}\\right\\Vert}_2 =322758.59$$" 575 | ] 576 | }, 577 | { 578 | "cell_type": "code", 579 | "metadata": { 580 | "colab": { 581 | "base_uri": "https://localhost:8080/" 582 | }, 583 | "id": "03w1ddh4vwUU", 584 | "outputId": "42d94c35-8ed6-46f6-eba8-32bc14711554" 585 | }, 586 | "source": [ 587 | "# solucion del sistema\n", 588 | "x = np.linalg.solve(A,b)\n", 589 | "# veamos la solucion\n", 590 | "print(x)\n", 591 | "\n", 592 | "# cambiamos la entrada 2,3 perturbacion en la matriz\n", 593 | "deltaA = np.array([[1,2,1],[2,4.0001,2.0021],[1,2.002,2.004]])\n", 594 | "# solucion del sistema\n", 595 | "nuevaSol = np.linalg.solve(deltaA,b)\n", 596 | "# veamos la solucion\n", 597 | "print(nuevaSol)\n", 598 | "\n", 599 | "# deltax\n", 600 | "print(nuevaSol-x)\n", 601 | "\n", 602 | "# numero de condicion de la matriz perturbada\n", 603 | "print(np.linalg.cond(deltaA, 2))" 604 | ], 605 | "execution_count": null, 606 | "outputs": [ 607 | { 608 | "output_type": "stream", 609 | "text": [ 610 | "[ 3.08495851 -0.04356846 1.00217842]\n", 611 | "[ 5.17474012 -1.08950104 1.00426195]\n", 612 | "[ 2.08978162e+00 -1.04593257e+00 2.08353103e-03]\n", 613 | "500571.79804716085\n" 614 | ], 615 | "name": "stdout" 616 | } 617 | ] 618 | }, 619 | { 620 | "cell_type": "markdown", 621 | "metadata": { 622 | "id": "mrbRizKvugLX" 623 | }, 624 | "source": [ 625 | "# Análisis de la perturbación en $A$ y $b$\n", 626 | "\n", 627 | "Supongamos que $A$ ha sido perturbada y el vector $b$ también.\n", 628 | "\n", 629 | "$$\\begin{array}{c}\n", 630 | "A\\longrightarrow A+\\triangle A\\quad(\\triangle A=perturbaci\\acute{o}\\,en\\,matriz\\,A)\\\\\n", 631 | "b\\longrightarrow b+\\delta b\\quad(\\delta b=cambio\\,en\\,el\\,vector\\,b)\\\\\n", 632 | "x\\longrightarrow x+\\delta x\\quad(\\delta x=cambio\\,en\\,la\\,soluci\\acute{o}n)\n", 633 | "\\end{array}$$\n", 634 | "\n", 635 | "Suponga que $A$ es no singular y $b\\neq0$, y $\\left\\Vert \\triangle A\\right\\Vert <\\frac{1}{\\left\\Vert A^{-1}\\right\\Vert }$. Entonces\n", 636 | "\n", 637 | "$$\\frac{\\left\\Vert \\delta x\\right\\Vert }{\\left\\Vert x\\right\\Vert }\\leq\\left(\\frac{\\kappa\\left(A\\right)\\frac{\\left\\Vert \\triangle A\\right\\Vert }{\\left\\Vert A\\right\\Vert }}{1-\\kappa\\left(A\\right)\\frac{\\left\\Vert \\triangle A\\right\\Vert }{\\left\\Vert A\\right\\Vert }}\\right)\\left(\\frac{\\left\\Vert \\triangle A\\right\\Vert }{\\left\\Vert A\\right\\Vert }+\\frac{\\left\\Vert \\delta b\\right\\Vert }{\\left\\Vert b\\right\\Vert }\\right)$$" 638 | ] 639 | }, 640 | { 641 | "cell_type": "markdown", 642 | "metadata": { 643 | "id": "ENJ_tkZJ2ew2" 644 | }, 645 | "source": [ 646 | "# Resumen\n", 647 | "\n", 648 | "El numero de condición de una matriz $A\\in M_{n\\times n}$.\n", 649 | "\n", 650 | "* El numero de condición de una matriz $A\\in M_{n\\times n}$.\n", 651 | "$$\\kappa\\left(A\\right)=\\left\\Vert A\\right\\Vert \\left\\Vert A^{-1}\\right\\Vert$$\n", 652 | "\n", 653 | " Nos proporciona información importante sobre las caracteristicas de la matriz $A$.\n", 654 | "\n", 655 | "* Una vez que conocemos este valor, podemos determinar si nuestro problema está bien condicionado ó si por el contrario está mal condicionado.\n", 656 | "\n" 657 | ] 658 | }, 659 | { 660 | "cell_type": "markdown", 661 | "metadata": { 662 | "id": "j2Y-8p6vXLvU" 663 | }, 664 | "source": [ 665 | "# Referencias\n", 666 | "\n", 667 | "* Riswan Butt, Numerical Analysys Using Matlab, Jones and Bartlett.\n", 668 | "* Ward Cheney, David Kincaid, Métodos Numéricos y Computación, Cenage Learning.\n", 669 | "* Richard L. Burden, J. Douglas Faires, Análisis Numérico, Math Learning.\n", 670 | "* Yuri N. Skiba, Introducción a los Métodos Numéricos.\n", 671 | "* Quarteroni, A, Sacco R., Numerical mathematics, Springer. 2007.\n", 672 | "\n" 673 | ] 674 | } 675 | ] 676 | } --------------------------------------------------------------------------------