{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Clase 4: Ecuaciones no lineales y EDOs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_¿Te acuerdas de todos esos esquemas numéricos para integrar ecuaciones diferenciales ordinarias? Es bueno saber que existen y qué peculiaridades tiene cada uno, pero en este curso no queremos implementar esos esquemas: queremos resolver las ecuaciones. Los problemas de evolución están por todas partes en ingeniería y son de los más divertidos de programar._"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"#Usaremos Arrays:\n"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"#Pintaremos cosas:\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##Ecuaciones algebraicas\n",
"\n",
"Como sabemos, las operaciones del álgebra lineal aparecen con mucha frecuencia a la hora de resolver sistemas de ecuaciones en derivadas parciales y en general al linealizar problemas de todo tipo, y suele ser necesario resolver sistemas con un número enorme de ecuaciones e incógnitas. Gracias a los arrays de NumPy podemos abordar este tipo de cálculos en Python, ya que todas las funciones están escritas en C o Fortran y tenemos la opción de usar bibliotecas optimizadas al límite.\n",
"\n",
"El paquete de álgebra lineal en NumPy se llama `linalg`, así que importando NumPy con la convención habitual podemos acceder a él escribiendo `np.linalg`. Si imprimimos la ayuda del paquete vemos que tenemos funciones para:\n",
"\n",
"* Funciones básicas (norma de un vector, inversa de una matriz, determinante, traza)\n",
"* Resolución de sistemas\n",
"* Autovalores y autovectores\n",
"* Descomposiciones matriciales (QR, SVD)\n",
"* Pseudoinversas"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"help(np.linalg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"El producto matricial usual (no el que se hace elemento a elemento, sino el del álgebra lineal) se calcula con la misma función que el producto matriz-vector y el producto escalar vector-vector: con la función `dot`, que **no** está en el paquete `linalg` sino directamente en `numpy`.\n",
"\n",
"Una consideración importante a tener en cuenta es que en NumPy no hace falta ser estricto a la hora de manejar vectores como si fueran matrices columna, siempre que la operación sea consistente. Un vector es una matriz con una sola dimensión: por eso si calculamos su traspuesta no funciona.\n",
"\n",
"Juguemos un poco con ella para ver cómo funciona!\n",
"\n",
"**Ejercicio:**\n",
"* Crear una matriz de 2x3, y otra matriz de 3x2\n",
"* Crear dos arrays de 3 elementos y otro de 2\n",
"* Multiplicar los arrays entre sí y observar el resultado"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"A = \n",
"B = \n",
"\n",
"v1 = \n",
"v2 = \n",
"v3 = \n",
"\n",
"print(A,'\\n\\n', B, '\\n\\n',v1, '\\n\\n',v2, '\\n\\n',v3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"np.dot(A,B)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Existe también otra función muy interesante: np.linalg.solve\n",
"La usaremos para: \n",
"\n",
"**Resolver el siguiente sistema:**\n",
"\n",
"$$ \\begin{pmatrix} 2 & 0 & 1 \\\\ -1 & 1 & 0 \\\\ 3 & 2 & -1 \\end{pmatrix} \\begin{pmatrix} x \\\\ y \\\\ z \\end{pmatrix} = \\begin{pmatrix} -1 \\\\ 3 \\\\ 0 \\end{pmatrix} $$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"M =\n",
"\n",
"M ="
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"x = np.??????(M, V)\n",
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Cargar y guardar datos**\n",
"\n",
"Numpy tiene dos funciones específicas para leer matrices y guardarlas: np.loadtxt y np.savetxt"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"np.?????('array.txt', x, fmt='%.4e', header='Nuestro array')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"z = np.??????('array.txt')\n",
"z"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Ecuaciones no lineales"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Visto cómo resolver sistemas de ecuaciones lineales, tal vez sea incluso más atractivo resolver ecuaciones no lineales. Para ello, importaremos el paquete `optimize` de SciPy:"
]
},
{
"cell_type": "code",
"execution_count": 0,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La ayuda de este paquete es bastante larga (puedes consultarla también en http://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html). El paquete `optimize` incluye multitud de métodos para **optimización**, **ajuste de curvas** y **búsqueda de raíces**. Vamos a centrarnos ahora en la búsqueda de raíces de funciones escalares. Para más información puedes leer http://pybonacci.org/2012/10/25/como-resolver-ecuaciones-algebraicas-en-python-con-scipy/"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"