{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](img/logocurso.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbpresent": {
     "id": "d9e822f9-0a52-43f2-90ef-e8fd6860aacc"
    }
   },
   "source": [
    "![](img/sesion7.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Ecuaciones, igualdades e asignaciones\n",
    "\n",
    "Una ecuación es una igualdad matemática en la que aparecen datos desconocidos. Es importante darse cuenta de que expresiones como las siguientes\n",
    "<p style=\"text-align:center;\">\n",
    "    $\\underbrace{\\displaystyle x^2-3x+2=0}_{\\text{ecuación}}$\n",
    "    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n",
    "    $\\underbrace{altura=3}_{\\text{asignación}}$,\n",
    "</p>\n",
    "tienen significados diferentes a pesar de que utilizan ambas un mismo signo, el símbolo de igualdad <b>=</b>. La primera es una ecuación en la que aparece un dato, $x$, que desconocemos. En la segunda establecemos el valor de una variable que interviene en algún problema y, por tanto, $altura$ no es un dato desconocido ya que es la propia expresión la que establece su valor, es una asignación. Cuando observamos ambas expresiones, el contexto del problema y nuestra propia experiencia nos permiten decidir, a veces de forma inadvertida, el correcto significado que en cada caso tiene el símbolo de igualdad. Sin embargo, un leguaje de programación necesita una notación precisa y estricta que no dependa de la interpretación. Para usos diferentes debemos emplear símbolos diferentes ya que, en principio, el sistema no podrá hacer uso de las capacidades interpretativas que nosotros aplicamos automáticamente. De este modo, en la mayoría de lenguajes de programación se utilizan difenrentes símbolos para expresiones que habitualmente, en la notación habitual, se representan mediante <b>=</b>. \n",
    "<div class=\"alert alert-info\">\n",
    "Las ecuaciones se representan en Sympy mediante <b>Eq</b>. De este modo la ecuación miembroizda=miembrodcha</b> se representa mediante\n",
    "<p style=\"text-align:center;\">Eq(miembroizda,miembrodcha).\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy import *\n",
    "init_printing()\n",
    "\n",
    "x,y,z=symbols(\"x y z\")\n",
    "\n",
    "Eq(x**2-3*x+2,0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "En la siguiente tabla repasamos los diferentes usos del símbolo <b>=</b>.\n",
    "<table>\n",
    "    <tr> <td><b>Denominación</b></td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>Matemáticas</b></td><td><b>Python</b></td></tr>\n",
    "    <tr><td>Asignación</td><td>$altura=3$</td><td>altura=3</td></tr>\n",
    "    <tr><td>Ecuación</td><td>$x^2-3x+2=0$</td><td>Eq(x**2-3*x+2,0)</td></tr>\n",
    "    <tr><td>Comparación lógica</td><td>Si x=2 entonces...</td><td>if x==2:</td></tr>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Si sustituimos el símbolo x por un valor que verifica la ecuación obtendremos resultado True, en caso contrario, False.\n",
    "\n",
    "Eq(x**2-3*x+2,0).subs(x,5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "En realidad **Eq** es un caso particular de objeto **Relational** y que de forma más general puede escribirse mediante la instrucción **Rel** que permite además expresar desigualdades:\n",
    "<table>\n",
    "    <tr> <td>x=y</td><td>Rel(x,y,\"==\")=Eq(x,y)</td></tr>\n",
    "    <tr><td>x$<$y</td><td>Rel(x,y,\"&lt;\")</td></tr>\n",
    "    <tr><td>x$\\leq$y</td><td>Rel(x,y,\"&lt;=\")</td></tr>\n",
    "    <tr><td>x$>$y</td><td>Rel(x,y,\"&gt;\")</td></tr>\n",
    "    <tr><td>x$\\geq$y</td><td>Rel(x,y,\"&gt;=\")</td></tr>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Rel(x**2+1,x+2,\"<\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Rel(x**2+1,x+2,\"<\").subs(x,1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Resolución de ecuaciones\n",
    "\n",
    "Disponemos de diferentes comandos para la resolución de ecuaciones.\n",
    "\n",
    "## Resolución de una ecuación o inecuación en términos de conjuntos\n",
    "\n",
    "La instrucción <b>solveset</b> permite resolver desde una ecuación hasta una desigualdad. Como resultado ofrece el conjunto de todas las soluciones que podría ser:\n",
    "* un conjunto finito de soluciones,\n",
    "* un intervalo,\n",
    "* un conjunto imagen.\n",
    "\n",
    "La sintaxis es simple:\n",
    "<div class=\"alert alert-info\">\n",
    "<p style=\"text-align:center;\">\n",
    "    <b>solveset(ecuación/inecuación/expresión,&nbsp;&nbsp;&nbsp;variable,&nbsp;&nbsp;&nbsp;domain)</b>\n",
    "</p>\n",
    "<ul>\n",
    "<li><b>ecuacion/inecuacion/expresión</b> que pretendemos resolver. Si es <b>expresión</b> se supone que estará igualada a cero.</li>\n",
    "<li><b>variable</b> es la variable a despejar. Si solo hay una, no es necesario indicarla.</li>\n",
    "<li><b>domain</b> es el dominio de números donde se buscará la solución. Si no se indica nada se sobrentiende que es el conjunto de los números complejos pero se puede especificar <b>domain=S.Reals</b> (reales), <b>domain=S.Naturals</b> (naturales),\n",
    "<b>domain=S.Integers</b> (enteros).</li>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La ecuación $x^2=-1$ tiene solamente dos soluciones $x=i$ y $x=-i$. solveset dará como resultado un conjunto con estas soluciones."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Puesto que la ecuación tiene una única variable, no es preciso indicarla en solveset.\n",
    "# Si no indicamos dominio, solveset proporcionará las soluciones complejas (que incluyen a las reales)\n",
    "solveset(Eq(x**2,-1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Es evidente que $x^2=-1$ es equivalente a $x^2+1=0$. Si en solveset solamente indicamos la expresión $x^2+1$, automáticamente la igualará a cero y ofrecerá entonces el mismo resultado."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "solveset(x**2+1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Si indicamos que el dominio es Reals, la ecuación no tendrá ninguna solución puesto que sabemos que las dós únicas soluciones son números complejos."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "solveset(x**2+1,domain=S.Reals)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La inecuación $x^2\\geq 1$ tiene infinitas soluciones y solveset nos la proporciona todas en forma de intervalos. Las desigualdades de este tipo no tienen sentido para números complejos así que para resolverlas habrá que indicar que el dominio son los números reales."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "solveset(Rel(x**2,1,\">=\"),domain=S.Reals)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La ecuación $\\sin(x)=0$ es una ecuación trigonométrica que tiene infinitas soluciones igualmente espaciadas. Para resolverla podemos utilizar solveset(sin(x)) o solveset(Eq(sin(x),0))."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "solveset(sin(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "En una ecuación pueden aparecer parámetros. Por ejemplo, la ecuación general de grado 2\n",
    "<p style=\"text-align:center;\">$ax^2+bx+c=0$</p>\n",
    "incluye aparte de la variable, $x$, los parámetros $a,b,c$. Sin embargo Sympy no puede saber de antemano cuál de entre $x,a,b,c$ deseamos despejar. Por ello, cuando en la ecuación aparece más de un símbolo es preciso indicar a solveset cuál deseamos despejar."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a,b,c=symbols(\"a b c\")\n",
    "\n",
    "# En solveset indicamos que la variable que deseamos despejar es x\n",
    "solveset(a*x**2+b*x+c,x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Resolución de un sistema lineal de ecuaciones\n",
    "\n",
    "La instrucción para resolver un sistema de ecuaciones es <b>linsolve</b>. Debemos indicar una lista con las ecuaciones del sistema y las variables a despejar.\n",
    "<div class=\"alert alert-info\">\n",
    "<p style=\"text-align:center;\">\n",
    "    <b>linsolve([listaecuaciones],(listavariables))</b>\n",
    "</p>\n",
    "Obtendremos las solución en una lista dispuesta en el mismo orden en el que indicamos las variables en <b>linsolve</b>.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Para resolver $\\left\\{\\begin{array}{l}x+y=3,\\\\x-y=4\\end{array}\\right.$ haremos"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "linsolve([Eq(x+y,3),Eq(x-y,4)],(x,y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La solución es entonces $\\left\\{\\begin{array}{l}x=\\frac{7}{2},\\\\y=-\\frac{1}{2}\\\\\\end{array}\\right.$. Téngase en cuenta que el sistema podríamos haberlo escrito también en la forma $\\left\\{\\begin{array}{l}x+y-3=0,\\\\x-y-4=0\\end{array}\\right.$ y podríamos haber resuelto igualmente con linsolve([x+y-3,x-y-4],(x,y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Para $\\left\\{\\begin{array}{l}x+y+z+w=1,\\\\x-y+3z-2w=1\\end{array}\\right.$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "w=symbols(\"w\")\n",
    "\n",
    "linsolve([Eq(x+y+z+w,1),Eq(x-y+3*z-2*w,1)],(z,w))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Obtenemos la solución para x e y, $\\left\\{\\begin{array}{l}x=\\frac{w}{2}-2z+1,\\\\y=-\\frac{3w}{2}+z\\\\\\end{array}\\right.$ en términos de z, w debido a que este sistema tiene infinitas soluciones."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sistemas no lineales\n",
    "\n",
    "Los sistemas no lineales de ecuaciones involucran potencias de las variables o funciones trascendentes y constituyen un caso considerablemente más complejo que los sitemas lineales. Sympy incorpora la instrucción **nonlinsolve** cuya sintaxis es análoga a la de **linsolve**."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Resolveremos $\\left\\{\\begin{array}{l}x^2+y^2=1,\\\\x-y=0\\end{array}\\right.$ mediante"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "nonlinsolve([x**2+y**2-1,x-y],(x,y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "En este caso, el sistema tiene dos soluciones distintas $\\left\\{\\begin{array}{l}x=-\\frac{\\sqrt{2}}{2},\\\\y=-\\frac{\\sqrt{2}}{2}\\\\\\end{array}\\right.$ y también $\\left\\{\\begin{array}{l}x=\\frac{\\sqrt{2}}{2},\\\\y=\\frac{\\sqrt{2}}{2}\\\\\\end{array}\\right.$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Raíces de una ecuación polinómica\n",
    "\n",
    "Cuando trabajamos con ecuaciones polinómicas sabemos que una solución puede aparecer repetida más de una vez. El número de veces que aparece una misma solución es lo que llamamos multiplicidad. solveset no nos indicará la multiplicidad con la que aparece cada solución para ello podemos utilizar en su lugar la instrucción **roots** cuya sintaxis es similar a la de solveset."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Las soluciones de $x^3-10x^2+33x-36=0$ las podemos obtener con"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "roots(Eq(x**3-10*x**2+33*x-36,0),x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Por tanto, tenemos dos soluciones $x=1$ con multiplicidad 2 (es decir, esta solución aparecerá dos veces) y $x=2$ que aparece una sola vez."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ejercicio 1\n",
    "Encontrar las soluciones de la ecuación de tercer grado $ax^3+bx^2+cx+d=0$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ejercicio 2\n",
    "Consideremos la ecuación \n",
    "<p style=\"text-align:center;\">\n",
    "    $x^3-(2a+1)x^2+(a^2+2a-b^2)x+b^2-a^2=0$.\n",
    "</p>\n",
    "Determinar para qué valores de $a$ y $b$ la ecuación tiene una única solución."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ejercicio 3\n",
    "Calcular las dimensiones de un triángulo rectángulo cuya hipotenusa es 2 y con perímetro igual a $\\frac{9}{2}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Matrices y cálculo matricial\n",
    "\n",
    "El cálculo matricial es esencial en matemáicas y es la base del álgebra lineal, modelos matemáticos de todo tipo o resolución de sistemas de ecuaciones diferenciales. Sympy proporciona clases y métodos que permiten articular las operaciones matriciales más importantes.\n",
    "\n",
    "<div class=\"alert alert-info\">\n",
    "Declaramos una matrix en Sympy mediante\n",
    "<p style=\"text-align:center;\">\n",
    "    <b>Matrix([[fila1],[fila2],...,[filam]])</b>.\n",
    "</p>\n",
    "Con\n",
    "<p style=\"text-align:center;\">\n",
    "    <b>Matrix([a1,a2,...,am])</b>\n",
    "</p>\n",
    "designamos un vector columna. Las operaciones habituales entre matrices utilizan la nomenclatura habitual de Python: si A y B son dos matrices, n un número entero y k un número real,\n",
    "<table>\n",
    "    <tr> <td>Suma de matrices</td><td>A+B</td></tr>\n",
    "    <tr> <td>Diferencia de matrices</td><td>A-B</td></tr>\n",
    "    <tr><td>Producto número matriz</td><td>k&#42;A</td></tr>\n",
    "    <tr><td>Producto de matrices</td><td>A&#42;B</td></tr>\n",
    "    <tr><td>Potencia de matrices</td><td>A&#42;&#42;n</td></tr>\n",
    "    <tr><td>Inversa de una matriz</td><td>A&#42;&#42;(-1)</td></tr>\n",
    "</table>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Podemos declarar las matrices $A=\\begin{pmatrix} 1&2&1\\\\-1&2&0\\end{pmatrix}$, $B=\\begin{pmatrix}2&1&1\\\\-1&3&2\\end{pmatrix}$ y $C=\\begin{pmatrix}2&1&1\\\\-1&0&1\\\\0&1&1\\end{pmatrix}$ del siguiente modo:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "A=Matrix([[1,2,1],[-1,2,0]])\n",
    "B=Matrix([[2,1,1],[-1,3,2]])\n",
    "C=Matrix([[2,1,1],[-1,0,1],[0,1,1]])\n",
    "\n",
    "#Ahora podremos realizar las operaciones habituales entre ellas como la suma\n",
    "A+B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Diferencia de matrices\n",
    "A-B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Producto de dos matrices\n",
    "A*C"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Inversa de una matriz cuadrada\n",
    "C**(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Potencia de matrices cuadradas\n",
    "C**3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Producto de una matriz por un número\n",
    "2*A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Matrix([1,2,1]) designa un vector columna que podemos utilizar también en operaciones matriciales\n",
    "C*Matrix([1,2,1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Las matrices son objetos mutables y disponemos de diferentes operaciones para modificarlas y para realizar sobre ellas las operación habituales del álgebra matricial.\n",
    "<div class=\"alert alert-info\"> Dada una matriz A:\n",
    "<ul>\n",
    "    <li><b>A.shape</b>: proporciona las dimensiones de la matriz.</li>\n",
    "    <li><b>A.row(i)</b>: proporciona la fila i de la matriz.</li>\n",
    "    <li><b>A.col(j)</b>: proporciona la columna j de la matriz.</li>\n",
    "    <li><b>A.row_del(i)</b>: elimina la columna i de la matriz.</li>\n",
    "    <li><b>A.col_del(j)</b>: elimina la columna j de la matriz.</li>\n",
    "    <li><b>A.row_insert(i,Matrix([filanueva]))</b>: inserta <b>filanueva</b> en la posición i.</li>\n",
    "    <li><b>A.col_insert(j,Matrix([columnanueva]))</b>: inserta <b>columnanueva<</b> en la posición j.</li>\n",
    "    <li><b>A.T</b>: proporciona la traspuesta de A.</li>\n",
    "    <li><b>det(A)</b> ó <b>A.det()</b>: calcula el determinante de A.</li>\n",
    "    <li><b>A.rank()</b>: calcula el rango de A.</li>\n",
    "    <li><b>eye(n)</b>: genera la matriz identidad de orden n.</li>\n",
    "    <li><b>zeros(m,n)</b>: genera una matriz de ceros con m filas y n columnas.</li>\n",
    "    <li><b>diag(a1,a2,...an)</b>: genera una matriz diagonal con los elementos indicados en la diagonal principal.</li>\n",
    "</ul>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "matriz=zeros(5,5)\n",
    "print(matriz[1,1])\n",
    "A=Matrix([[1,2,1],[-1,2,0]])\n",
    "print(A[1,0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "matriz=zeros(5,5)\n",
    "matriz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A es una matriz de tipo 2x3 con dos filas y tres columnas.\n",
    "A.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Podemos obtener la fila 1 de A\n",
    "A.row(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "display(B)\n",
    "# Podemos eliminar la última columna de B\n",
    "B.col_del(1)\n",
    "# Téngase en cuenta que esto modificará el objeto almacenado en la variable B eliminando la columna de forma permanente\n",
    "B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Insertamos un fila en B en la posición intermedia.\n",
    "# Téngase en cuenta que row_insert no modifica el valor de B y solamente ofrece un resultado\n",
    "B.row_insert(1,Matrix([[7,7]]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Añadimos ahora una nueva columna al final\n",
    "B.col_insert(2,Matrix([8,9]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# La matriz traspuesta de A sera\n",
    "A.T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# O el determinante y el rango de C\n",
    "det(C),C.rank()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# La matriz identidad de orden 3 es\n",
    "eye(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Podemos obtener una matriz de ceros con tres filas y dos columnas con\n",
    "zeros(3,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# O una matriz diagonal de tamaño 4 con los números 1,2,3,4 en la diagonal principal mediante\n",
    "diag(1,2,3,4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Disponemos asimismo de instrucciones más específicas para resolver diferentes problemas propios del álgebra matricial.\n",
    "<div class=\"alert alert-info\"> Dada una matriz A:\n",
    "<ul>\n",
    "    <li><b>linsolve(A,(variables))</b>: resuelve el sistema cuya matriz ampliada viene dada por A.</li>\n",
    "    <li><b>A.rref()</b>: reducción mediante operaciones elementales por filas de la matriz.</li>\n",
    "    <li><b>A.nullspace</b>: genera una base para el espacio de soluciones de $AX=0$.</li>\n",
    "    <li><b>A.columnspace</b>: proporciona una base para el espacio generado por las columnas de la matriz.</li>\n",
    "    <li><b>A.eigenvals()</b>: calcula los valores propios.</li>\n",
    "    <li><b>A.eigenvecs()</b>: calcula los vectores propios.</li>\n",
    "    <li><b>A.diagonalize()</b>: proporciona la diagonalización y la correspondiente matriz de paso.</li>\n",
    "    <li><b>A.charpoly(var)</b>: proporciona el polinomio característico en térmionos de la variable indicada.</li>\n",
    "</ul>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La matriz ampliada del sistema $\\left\\{\\begin{array}{l}x+y+z+w=3\\\\x-2y+3z-w=2\\end{array}\\right.$ es $\\left(\\begin{array}{cccc|c}1&1&1&1&3\\\\1&-2&3&-1&2\\end{array}\\right)$. Para resolver el sistema podemos utilizar **linsolve** indicando las ecuaciones en el modo que vimos más arriba en esta sesión o dando en su lugar la matriz ampliada"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "w=symbols(\"w\")\n",
    "linsolve(Matrix([[1,1,1,1,3],[1,-2,3,-1,2]]),(x,y,z,w))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La instrucción **rref** simplifica la matriz aplicando operaciones elementales por filas. Si a la matriz ampliada anterior le aplicamos **rref** obtenemos una matriz reducida por filas que corresponde al sistema diagonal $\\left\\{\\begin{array}{l}x\\ \\ \\  +\\frac{5}{3}z+\\frac{1}{3}w=\\frac{8}{3}\\\\\\ \\ \\ y-\\frac{2}{3}z+\\frac{2}{3}w=\\frac{1}{3}\\end{array}\\right.$ desde el que se puede obtener prácticamente sin cálculos la solución que nos acaba de proporcionar **linsolve**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Matrix([[1,1,1,1,3],[1,-2,3,-1,2]]).rref()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "El conjunto de soluciones del sistema homogéneo correspondiente a una matriz es lo que se denomina Kernel o Nullspace de la matriz. Para la matriz $\\begin{pmatrix}2&1&1\\\\-1&0&1\\\\1&1&2\\end{pmatrix}$, el sistema homogéneo correspondiente es $\\begin{pmatrix}2&1&1\\\\-1&0&1\\\\1&1&2\\end{pmatrix}\\cdot\\begin{pmatrix}x\\\\y\\\\z\\end{pmatrix}=\\begin{pmatrix}0\\\\0\\\\0\\end{pmatrix}$ o lo que es lo mismo $\\left\\{\\begin{array}{l}2x+y+z=0\\\\-x+z=0\\\\x+y+2z=0\\end{array}\\right.$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Matrix([[2,1,1],[-1,0,1],[1,1,2]]).nullspace()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La instrucción **nullspace** nos proporciona las columnas básicas que permiten obtener todas las soliciones del sistema homogéneo correspondiente mediante combinaciones lineales. En este caso tenemos que $\\begin{pmatrix}x\\\\y\\\\z\\end{pmatrix}=\\lambda\\begin{pmatrix}1\\\\-3\\\\1\\end{pmatrix}$ y por tanto $\\left\\{\\begin{array}{l}x=\\lambda\\\\y=-3\\lambda\\\\z=\\lambda\\end{array}\\right.$ es la solución, en forma paramétrica, del sistema."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Podemos calcular los valores y vectores propios de la matriz $M=\\begin{pmatrix}-1&-3&-3\\\\1&3&1\\\\1&1&3\\end{pmatrix}$ mediante"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Matrix([[-1,-3,-3],[1,3,1],[1,1,3]]).eigenvals()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Matrix([[-1,-3,-3],[1,3,1],[1,1,3]]).eigenvects()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "En ambos casos nos indica que los valores propios son $\\lambda=1$ con multiplicidad 1 y $\\lambda=2$ con multiplicidad 2. **diagonalize** nos proporciona directamente la matriz de paso, $C$, y la diagonalización, $D$, que diagonalizan a $M$ mediante la fórmula clásica de diagonalización $C^{-1}\\cdot M\\cdot C=D$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M=Matrix([[-1,-3,-3],[1,3,1],[1,1,3]])\n",
    "M.diagonalize()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Matrix([[-3,-1,-1],[1,1,0],[1,0,1]])**(-1)*M*Matrix([[-3,-1,-1],[1,1,0],[1,0,1]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "lamda=symbols(\"lamda\")\n",
    "M.charpoly(lamda)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ejercicio 4\n",
    "Encontra la matriz X que cumple $\\left(\\begin{pmatrix}2&1&-1\\\\1&2&1\\\\0&-1&1\\end{pmatrix}+X\\right)\\cdot\\begin{pmatrix}1&1&-1\\\\3&1&2\\\\1&0&1\\end{pmatrix}=\\begin{pmatrix}10&6&0\\\\12&2&12\\\\-3&-3&2\\end{pmatrix}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ejercicio 5\n",
    "Considerar la matriz $\\begin{pmatrix}1&2&2&3&4&4\\\\6&-1&2&4&2&3\\\\2&3&9&1&2&1\\end{pmatrix}$ y calcular su rango. Eliminar las columnas tercera, cuarta y quinta y calcular de nuevo el rango así como el determinante para la matriz resultante"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ejercicio 6\n",
    "Calcular una matriz que tenga valores propios: $\\lambda =1$ con vectores propios $\\begin{pmatrix}2&1&-1&0&1\\end{pmatrix}$ y $\\begin{pmatrix}2&1&2&-1&1\\end{pmatrix}$, $\\lambda=3$ con vector propio  $\\begin{pmatrix}2&2&1&1&0\\end{pmatrix}$, y $\\lambda=-2$ con vectores propios $\\begin{pmatrix}1&1&0&1&2\\end{pmatrix}$ y $\\begin{pmatrix}2&1&-1&2&1\\end{pmatrix}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Ejercicio 7\n",
    "Determinar cuántas matrices de tamaño $n=2\\quad (3,4,...)$ y con coeficientes enteros entre -9 y 9 (entre $-k$ y $k$ con $k\\leq 9$) tienen determinante nulo. ¿Cuál es la probabilidad de que una matriz de este tipo puesta al azar sea singular?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
