{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Linear Algebra using SymPy\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction\n", "\n", "This notebook is a short tutorial of Linear Algebra calculation using SymPy. For further information refer to SymPy official [tutorial](http://docs.sympy.org/latest/tutorial/index.html).\n", "\n", "You can also check the [SymPy in 10 minutes](./SymPy_in_10_minutes.ipynb) tutorial." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "IPython console for SymPy 1.0 (Python 2.7.13-64-bit) (ground types: python)\n", "\n", "These commands were executed:\n", ">>> from __future__ import division\n", ">>> from sympy import *\n", ">>> x, y, z, t = symbols('x y z t')\n", ">>> k, m, n = symbols('k m n', integer=True)\n", ">>> f, g, h = symbols('f g h', cls=Function)\n", ">>> init_printing()\n", "\n", "Documentation can be found at http://docs.sympy.org/1.0/\n" ] } ], "source": [ "from sympy import *\n", "init_session()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A matrix $A \\in \\mathbb{R}^{m\\times n}$ is a rectangular array of real number with $m$ rows and $n$ columns. To specify a matrix $A$, we specify the values for its components as a list of lists:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}3 & 2 & -1 & 1\\\\2 & -2 & 4 & -2\\\\-1 & \\frac{1}{2} & -1 & 0\\end{matrix}\\right]$$" ], "text/plain": [ "⎡3 2 -1 1 ⎤\n", "⎢ ⎥\n", "⎢2 -2 4 -2⎥\n", "⎢ ⎥\n", "⎣-1 1/2 -1 0 ⎦" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "A = Matrix([\n", " [3, 2, -1, 1],\n", " [2, -2, 4, -2],\n", " [-1, S(1)/2, -1, 0]])\n", "display(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can access the matrix elements using square brackets, we can also use it for submatrices" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAA0AAAASCAYAAACAa1QyAAAABHNCSVQICAgIfAhkiAAAAMJJREFU\nKJHF0j9LQlEYB+DH6BNYhJ/HxcmpD9CgQ0OImxAIbi5u7eLSJji5NzQGDRItDtHQ3J0aSnS4LxJy\ntBMN/eBw4XCe+77nD3/MCdqYYYkPFLhHC0cpdIk13nCLIcZ4j/kpKruojmbijzW8Bjz/TevXgW7s\n6zORz/h+5VY5xiIqNXLRKMA8F3QCPKOaA64CPClP8Md0AyxwlgN6AR5xmgP6AR4c2MP3Z3GBCVbK\nSywS619izTaDqHJo3OW0+8/ZALIVMPhgrAZWAAAAAElFTkSuQmCC\n", "text/latex": [ "$$2$$" ], "text/plain": [ "2" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A[0, 1] # row 0, column 1" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}3 & 2 & -1\\\\2 & -2 & 4\\end{matrix}\\right]$$" ], "text/plain": [ "⎡3 2 -1⎤\n", "⎢ ⎥\n", "⎣2 -2 4 ⎦" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A[0:2, 0:3] # top-left 2x3 submatrix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also create some common matrices. Let us create an identity matrix" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}1 & 0\\\\0 & 1\\end{matrix}\\right]$$" ], "text/plain": [ "⎡1 0⎤\n", "⎢ ⎥\n", "⎣0 1⎦" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eye(2)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}0 & 0 & 0\\\\0 & 0 & 0\\end{matrix}\\right]$$" ], "text/plain": [ "⎡0 0 0⎤\n", "⎢ ⎥\n", "⎣0 0 0⎦" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "zeros(2, 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use algebraic operations like addition $+$, substraction $-$, multiplication $*$, and exponentiation $**$ with ``Matrix`` objects." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "B = Matrix([\n", " [2, -3, -8],\n", " [-2, -1, 2],\n", " [1, 0, -3]])\n", "C = Matrix([\n", " [sin(x), exp(x**2), 1],\n", " [0, cos(x), 1/x],\n", " [1, 0, 2]])" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}\\sin{\\left (x \\right )} + 2 & e^{x^{2}} - 3 & -7\\\\-2 & \\cos{\\left (x \\right )} - 1 & 2 + \\frac{1}{x}\\\\2 & 0 & -1\\end{matrix}\\right]$$" ], "text/plain": [ "⎡ ⎛ 2⎞ ⎤\n", "⎢ ⎝x ⎠ ⎥\n", "⎢sin(x) + 2 ℯ - 3 -7 ⎥\n", "⎢ ⎥\n", "⎢ 1⎥\n", "⎢ -2 cos(x) - 1 2 + ─⎥\n", "⎢ x⎥\n", "⎢ ⎥\n", "⎣ 2 0 -1 ⎦" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "B + C" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}2 & -3 & 2\\\\0 & 7 & 8\\\\-1 & -3 & 1\\end{matrix}\\right]$$" ], "text/plain": [ "⎡2 -3 2⎤\n", "⎢ ⎥\n", "⎢0 7 8⎥\n", "⎢ ⎥\n", "⎣-1 -3 1⎦" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "B ** 2" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}\\sin^{2}{\\left (x \\right )} + 1 & e^{x^{2}} \\sin{\\left (x \\right )} + e^{x^{2}} \\cos{\\left (x \\right )} & \\sin{\\left (x \\right )} + 2 + \\frac{e^{x^{2}}}{x}\\\\\\frac{1}{x} & \\cos^{2}{\\left (x \\right )} & \\frac{1}{x} \\cos{\\left (x \\right )} + \\frac{2}{x}\\\\\\sin{\\left (x \\right )} + 2 & e^{x^{2}} & 5\\end{matrix}\\right]$$" ], "text/plain": [ "⎡ ⎛ 2⎞⎤\n", "⎢ ⎛ 2⎞ ⎛ 2⎞ ⎝x ⎠⎥\n", "⎢ 2 ⎝x ⎠ ⎝x ⎠ ℯ ⎥\n", "⎢sin (x) + 1 ℯ ⋅sin(x) + ℯ ⋅cos(x) sin(x) + 2 + ─────⎥\n", "⎢ x ⎥\n", "⎢ ⎥\n", "⎢ 1 2 cos(x) 2 ⎥\n", "⎢ ─ cos (x) ────── + ─ ⎥\n", "⎢ x x x ⎥\n", "⎢ ⎥\n", "⎢ ⎛ 2⎞ ⎥\n", "⎢ ⎝x ⎠ ⎥\n", "⎣sin(x) + 2 ℯ 5 ⎦" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "C ** 2" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}52 \\tan{\\left (x \\right )} & 27 \\tan{\\left (x \\right )} & - 28 \\tan{\\left (x \\right )}\\\\- 2 \\tan{\\left (x \\right )} & - \\tan{\\left (x \\right )} & - 78 \\tan{\\left (x \\right )}\\\\11 \\tan{\\left (x \\right )} & 30 \\tan{\\left (x \\right )} & 57 \\tan{\\left (x \\right )}\\end{matrix}\\right]$$" ], "text/plain": [ "⎡52⋅tan(x) 27⋅tan(x) -28⋅tan(x)⎤\n", "⎢ ⎥\n", "⎢-2⋅tan(x) -tan(x) -78⋅tan(x)⎥\n", "⎢ ⎥\n", "⎣11⋅tan(x) 30⋅tan(x) 57⋅tan(x) ⎦" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tan(x) * B ** 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And the ``transpose`` of the matrix, that flips the matrix through its main diagonal:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}3 & 2 & -1\\\\2 & -2 & \\frac{1}{2}\\\\-1 & 4 & -1\\\\1 & -2 & 0\\end{matrix}\\right]$$" ], "text/plain": [ "⎡3 2 -1 ⎤\n", "⎢ ⎥\n", "⎢2 -2 1/2⎥\n", "⎢ ⎥\n", "⎢-1 4 -1 ⎥\n", "⎢ ⎥\n", "⎣1 -2 0 ⎦" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.transpose() # the same as A.T" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Row operations" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "M = eye(4)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "M[1, :] = M[1, :] + 5*M[0, :]" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}1 & 0 & 0 & 0\\\\5 & 1 & 0 & 0\\\\0 & 0 & 1 & 0\\\\0 & 0 & 0 & 1\\end{matrix}\\right]$$" ], "text/plain": [ "⎡1 0 0 0⎤\n", "⎢ ⎥\n", "⎢5 1 0 0⎥\n", "⎢ ⎥\n", "⎢0 0 1 0⎥\n", "⎢ ⎥\n", "⎣0 0 0 1⎦" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "M" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The notation ``M[1, :]`` refers to entire rows of the matrix. The first argument specifies the 0-based row index, for example the first row of ``M`` is ``M[0, :]``. The code example above implements the row operation $R_2 \\leftarrow R_2 + 5R_1$. To scale a row by a constant $c$, use the ``M[1, :] = c*M[1, :]``. To swap rows $1$ and $j$, we can use the Python tuple-assignment syntax ``M[1, :], M[j, :] = M[j, :], M[1, :]``." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reduced row echelon form\n", "\n", "The Gauss-Jordan elimination procedure is a sequence of row operations that can be performed on any matrix to bring it to its _reduced row echelon form_ (RREF). In Sympy, matrices have a ``rref`` method that compute it:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left ( \\left[\\begin{matrix}1 & 0 & 0 & 1\\\\0 & 1 & 0 & -2\\\\0 & 0 & 1 & -2\\end{matrix}\\right], \\quad \\left [ 0, \\quad 1, \\quad 2\\right ]\\right )$$" ], "text/plain": [ "⎛⎡1 0 0 1 ⎤, [0, 1, 2]⎞\n", "⎜⎢ ⎥ ⎟\n", "⎜⎢0 1 0 -2⎥ ⎟\n", "⎜⎢ ⎥ ⎟\n", "⎝⎣0 0 1 -2⎦ ⎠" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.rref()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It return a tuple, the first value is the RREF of the matrix $A$, and the second tells the location of the leading ones (pivots). If we just want the RREF, we can just get the first entry of the matrix, i.e." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}1 & 0 & 0 & 1\\\\0 & 1 & 0 & -2\\\\0 & 0 & 1 & -2\\end{matrix}\\right]$$" ], "text/plain": [ "⎡1 0 0 1 ⎤\n", "⎢ ⎥\n", "⎢0 1 0 -2⎥\n", "⎢ ⎥\n", "⎣0 0 1 -2⎦" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.rref()[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Matrix fundamental spaces\n", "\n", "Consider the matrix $A \\in \\mathbb{R}^{m\\times n}$. The fundamental spaces of a matrix are its column space $\\mathcal{C}(A)$, its null space $\\mathcal{N}(A)$, and its row space $\\mathcal{R}(A)$. These vector spaces are importan when we consider the matrix product $A\\mathbf{x} = \\mathbf{y}$ as a linear transformation $T_A:\\mathbb{R}^n\\rightarrow \\mathbb{R}^n$ of the input vector $\\mathbf{x}\\in\\mathbb{R}^n$ to produce an output vector $\\mathbf{y} \\in \\mathbb{R}^m$.\n", "\n", "**Linear transformations** $T_A: \\mathbb{R}^n \\rightarrow \\mathbb{R}^m$ can be represented as $m\\times n$ matrices. The fundamental spaces of a matrix $A$ gives us information about the domain and image of the linear transformation $T_A$. The column space $\\mathcal{C}(A)$ is the same as the image space $\\mathrm{Im}(T_A)$ (the set of all possible outputs). The null space $\\mathcal{N}(A)$ is also called kernel $\\mathrm{Ker}(T_A)$, and is the set of all input vectors that are mapped to the zero vector. The row space $\\mathcal{R}(A)$ is the orthogonal complement of the null space, i.e., the vectors that are mapped to vectors different from zero. Input vectors in the row space of $A$ are in a one-to-one correspondence with the output vectors in the column space of $A$.\n", "\n", "Let us see how to compute these spaces, or a base for them!\n", "\n", "The non-zero rows in the reduced row echelon form $A$ are a basis for its row space, i.e." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left [ \\left[\\begin{matrix}1 & 0 & 0 & 1\\end{matrix}\\right], \\quad \\left[\\begin{matrix}0 & 1 & 0 & -2\\end{matrix}\\right], \\quad \\left[\\begin{matrix}0 & 0 & 1 & -2\\end{matrix}\\right]\\right ]$$" ], "text/plain": [ "[[1 0 0 1], [0 1 0 -2], [0 0 1 -2]]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[A.rref()[0][row, :] for row in A.rref()[1]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The column space of $A$ is the span of the columns of $A$ that contain the pivots." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left [ \\left[\\begin{matrix}3\\\\2\\\\-1\\end{matrix}\\right], \\quad \\left[\\begin{matrix}2\\\\-2\\\\\\frac{1}{2}\\end{matrix}\\right], \\quad \\left[\\begin{matrix}-1\\\\4\\\\-1\\end{matrix}\\right]\\right ]$$" ], "text/plain": [ "⎡⎡3 ⎤, ⎡ 2 ⎤, ⎡-1⎤⎤\n", "⎢⎢ ⎥ ⎢ ⎥ ⎢ ⎥⎥\n", "⎢⎢2 ⎥ ⎢-2 ⎥ ⎢4 ⎥⎥\n", "⎢⎢ ⎥ ⎢ ⎥ ⎢ ⎥⎥\n", "⎣⎣-1⎦ ⎣1/2⎦ ⎣-1⎦⎦" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[A[:, col] for col in A.rref()[1]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also use the ``columnspace`` method" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/latex": [ "$$\\left [ \\left[\\begin{matrix}3\\\\2\\\\-1\\end{matrix}\\right], \\quad \\left[\\begin{matrix}2\\\\-2\\\\\\frac{1}{2}\\end{matrix}\\right], \\quad \\left[\\begin{matrix}-1\\\\4\\\\-1\\end{matrix}\\right]\\right ]$$" ], "text/plain": [ "⎡⎡3 ⎤, ⎡ 2 ⎤, ⎡-1⎤⎤\n", "⎢⎢ ⎥ ⎢ ⎥ ⎢ ⎥⎥\n", "⎢⎢2 ⎥ ⎢-2 ⎥ ⎢4 ⎥⎥\n", "⎢⎢ ⎥ ⎢ ⎥ ⎢ ⎥⎥\n", "⎣⎣-1⎦ ⎣1/2⎦ ⎣-1⎦⎦" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.columnspace()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that we took columns from the original matrix and not from its RREF.\n", "\n", "To find (a base for) the null space of $A$ we use the ``nullspace`` method:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left [ \\left[\\begin{matrix}-1\\\\2\\\\2\\\\1\\end{matrix}\\right]\\right ]$$" ], "text/plain": [ "⎡⎡-1⎤⎤\n", "⎢⎢ ⎥⎥\n", "⎢⎢2 ⎥⎥\n", "⎢⎢ ⎥⎥\n", "⎢⎢2 ⎥⎥\n", "⎢⎢ ⎥⎥\n", "⎣⎣1 ⎦⎦" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.nullspace()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Determinants\n", "\n", "The determinant of a matrix, denoted by $\\det(A)$ or $|A|$, isis a useful value that can be computed from the elements of a square matrix. It can be viewed as the scaling factor of the transformation described by the matrix." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "M = Matrix([\n", " [1, 2, 2],\n", " [4, 5, 6],\n", " [7, 8, 9]])" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAA4AAAASCAYAAABrXO8xAAAABHNCSVQICAgIfAhkiAAAAOhJREFU\nOI3N0r1KQ0EUBODPYCEkIGggkEZIYSUIYmEhpLESLHwI38DeNEHsxVexEDutBBWRQCqLQBD/wEqU\nSCx2F8Mlyr2QIgPLLmfPcGaGw4RwhHP08IE33OAAi6ONMxniF67RwRPK2MA6+vHdGzdx7g8lbQxx\nUtTCaiSepUIpJ3En3nepkPWYsI8K5gV/m5G0hef/JjxGaemcopZTHbF5F10h1bUiZFjCJ+6LEgmL\nMESV/KlCPd7f2Y9lIcUsSn4X4DIVZ0catnGICzzgVQiniYaQ9N44KSs4xi1eMMA7rtDCQk5L04Yf\nBeYtAc2H2hEAAAAASUVORK5CYII=\n", "text/latex": [ "$$3$$" ], "text/plain": [ "3" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "M.det()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Matrix inverse\n", "\n", "For invertible matrices (those with $\\det(A)\\neq 0$), there is an inverse matrix $A^{-1}$ that have the _inverse_ effect (if we are thinking about linear transformations)." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": true }, "outputs": [], "source": [ "A = Matrix([\n", " [1, -1, -1],\n", " [0, 1, 0],\n", " [1, -2, 1]])" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}\\frac{1}{2} & \\frac{3}{2} & \\frac{1}{2}\\\\0 & 1 & 0\\\\- \\frac{1}{2} & \\frac{1}{2} & \\frac{1}{2}\\end{matrix}\\right]$$" ], "text/plain": [ "⎡1/2 3/2 1/2⎤\n", "⎢ ⎥\n", "⎢ 0 1 0 ⎥\n", "⎢ ⎥\n", "⎣-1/2 1/2 1/2⎦" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.inv()" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}1 & 0 & 0\\\\0 & 1 & 0\\\\0 & 0 & 1\\end{matrix}\\right]$$" ], "text/plain": [ "⎡1 0 0⎤\n", "⎢ ⎥\n", "⎢0 1 0⎥\n", "⎢ ⎥\n", "⎣0 0 1⎦" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.inv() * A" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}1 & 0 & 0\\\\0 & 1 & 0\\\\0 & 0 & 1\\end{matrix}\\right]$$" ], "text/plain": [ "⎡1 0 0⎤\n", "⎢ ⎥\n", "⎢0 1 0⎥\n", "⎢ ⎥\n", "⎣0 0 1⎦" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A * A.inv()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Eigenvectors and Eigenvalues\n", "\n", "To find the eigenvalues of a matrix, use ``eigenvals``. ``eigenvals`` returns a dictionary of ``eigenvalue:algebraic multiplicity``." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}3 & -2 & 4 & -2\\\\5 & 3 & -3 & -2\\\\5 & -2 & 2 & -2\\\\5 & -2 & -3 & 3\\end{matrix}\\right]$$" ], "text/plain": [ "⎡3 -2 4 -2⎤\n", "⎢ ⎥\n", "⎢5 3 -3 -2⎥\n", "⎢ ⎥\n", "⎢5 -2 2 -2⎥\n", "⎢ ⎥\n", "⎣5 -2 -3 3 ⎦" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "M = Matrix([\n", " [3, -2, 4, -2],\n", " [5, 3, -3, -2],\n", " [5, -2, 2, -2],\n", " [5, -2, -3, 3]])\n", "\n", "M" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAN4AAAAWCAYAAACv3CJuAAAABHNCSVQICAgIfAhkiAAABKxJREFU\neJzt22uoVFUUwPGfj9BK0h6oEZFZ2svIIoJIaLKiKKTEIIiopKKg0CChCEIpRIuEyAg/yQX1SwQW\nvfyQmSkVRRi97AXdnhhoaVJWlvVh7elede7MmTNn7p3R84fNGc7svdY666y9z9lr70NJSUnHcRPe\nwS78g+lDa05JSUezCHuxDc9jah4hZ2MfdmMlHsXEYuz7n+NxB9biK+wRnXwzbsfwgvXdgOXYhF/x\nL1YXrKMoHsN6fCf88jO2YKHwW5F0i196hW21yraCdeWJzQqWYl2y6d08iu9JjeflaZyRu5OOH7EG\nS0Qn35nOP4dhBer7IMndja06N8DgL/G2sVLczOV4T9j8A04uUFe3+KVXxMaiGmVBwbpajc33xYNr\nTLOKH04Krmy2YRPMxCwHjx4T8W3SP6dAfZdhinBYRecGGIwe4PxiYfczBerqFr/0pjIYtBqba1Kd\nmgNkvVe5Eem4N5OZ+XgdL4qRoT/bsCL9rhSobwO+FA7pdP4Y4Pyz6TilQF3d5JfBotXYrPabEbX+\nLHoOVSRVw//OULdHBM1t7TKmg5iVjh82qNfj0PTJKNyMhzBfPK1rBvcA9GjdL83EZk1G1vlvXDru\nySu8BUbilvR73RDo7yQWiHnCWFyIGaLTLR1Ko4aQiVh1wLmvMRcbB0F/1tisvrGMbUb4MH2Tw6Iz\nmVl4QoxKL2esfyLO1NxFVnTuXKY/2+yfvXsVEzK0y+MTOtsvC8XcawKOwjTx2rcPv+O8DDLy+qVK\n1th8MNWbn0Xo1VimL3u2on71uundWiXLzZyX6m7FcVmMzkmlCZs6gQmYjc9Fpu2CNump6C6/0NcZ\n1rZZTzOxeZLoH3vFvHwxJg1U+Ul9neQjnNNA+Hp81kR5vIG8e5PuT7T/SVvRfQEGp+BPfNwm+RXd\n55fThc072qgjT2zeJZ7E1T5VqVf5GFwn5nbfa27i2gr36evw4wdBX0X3BViVLcL2E9ogu6L7/DJW\n2DxQJrhV8sTmtanNZvEAOyKrstWp4bTmbMzFA0nXFu0JplpUdF+AVflJ2H5sG2RXdJ9frhI2f9oG\n2Xljc1lqd0WtP+stJ3yTju2cZxEL9UtFMudybM8ho9UJcz16DH5afqra1zJczBXG4y38UkdGO33C\n4PvlLBxd4/wkPJ1+ZxksmvFLK7FZHRR7a/1ZbzmhulbRzrW+W/GI2IC9Se3tab3iJtdjSZI1t0Hd\n61Oh7z394n5ttjt461H1+nOv2eTgGnFNm0WqfIdIrlyKySLTeWcDGVl9Qnf45UbcjzfFQ2E3ThOv\ndKPxikiyNCKrX1qNzbr+qdfxBmMXw6npOEK8R9dio8aBk5XpwqH9mZwKcUMPDLBzxU3OurRRBK+J\nhMEMnC/WVH/DF2IN6ymxaboousEvG3CG8Mcl4um3UwxOq1IpMmaLis2mbaquQ8xutuEhxDgx4jXK\nxh5ulH5pzAui/2RZc92POanhS2KjZydvL2sXs0SmbCg2EXQypV8GZhQuEp8Q7ZKj3xwp0qf9F8DL\nD2FLSgZmkf37y8KBKtab4+0RewNniozSGMV/bFhScijxhkim7MDb4jvHkpKSkpKSw5j/ACDHaiSK\n+mWvAAAAAElFTkSuQmCC\n", "text/latex": [ "$$\\left \\{ -2 : 1, \\quad 3 : 1, \\quad 5 : 2\\right \\}$$" ], "text/plain": [ "{-2: 1, 3: 1, 5: 2}" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "M.eigenvals()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This means that ``M`` has eigenvalues -2, 3, and 5, and that the eigenvalues -2 and 3 have algebraic multiplicity 1 and that the eigenvalue 5 has algebraic multiplicity 2.\n", "\n", "To find the eigenvectors of a matrix, use ``eigenvects``. ``eigenvects`` returns a list of tuples of the form ``(eigenvalue:algebraic multiplicity, [eigenvectors])``." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left [ \\left ( -2, \\quad 1, \\quad \\left [ \\left[\\begin{matrix}0\\\\1\\\\1\\\\1\\end{matrix}\\right]\\right ]\\right ), \\quad \\left ( 3, \\quad 1, \\quad \\left [ \\left[\\begin{matrix}1\\\\1\\\\1\\\\1\\end{matrix}\\right]\\right ]\\right ), \\quad \\left ( 5, \\quad 2, \\quad \\left [ \\left[\\begin{matrix}1\\\\1\\\\1\\\\0\\end{matrix}\\right], \\quad \\left[\\begin{matrix}0\\\\-1\\\\0\\\\1\\end{matrix}\\right]\\right ]\\right )\\right ]$$" ], "text/plain": [ "⎡⎛-2, 1, ⎡⎡0⎤⎤⎞, ⎛3, 1, ⎡⎡1⎤⎤⎞, ⎛5, 2, ⎡⎡1⎤, ⎡0 ⎤⎤⎞⎤\n", "⎢⎜ ⎢⎢ ⎥⎥⎟ ⎜ ⎢⎢ ⎥⎥⎟ ⎜ ⎢⎢ ⎥ ⎢ ⎥⎥⎟⎥\n", "⎢⎜ ⎢⎢1⎥⎥⎟ ⎜ ⎢⎢1⎥⎥⎟ ⎜ ⎢⎢1⎥ ⎢-1⎥⎥⎟⎥\n", "⎢⎜ ⎢⎢ ⎥⎥⎟ ⎜ ⎢⎢ ⎥⎥⎟ ⎜ ⎢⎢ ⎥ ⎢ ⎥⎥⎟⎥\n", "⎢⎜ ⎢⎢1⎥⎥⎟ ⎜ ⎢⎢1⎥⎥⎟ ⎜ ⎢⎢1⎥ ⎢0 ⎥⎥⎟⎥\n", "⎢⎜ ⎢⎢ ⎥⎥⎟ ⎜ ⎢⎢ ⎥⎥⎟ ⎜ ⎢⎢ ⎥ ⎢ ⎥⎥⎟⎥\n", "⎣⎝ ⎣⎣1⎦⎦⎠ ⎝ ⎣⎣1⎦⎦⎠ ⎝ ⎣⎣0⎦ ⎣1 ⎦⎦⎠⎦" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "M.eigenvects()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This shows us that, for example, the eigenvalue 5 also has geometric multiplicity 2, because it has two eigenvectors. Because the algebraic and geometric multiplicities are the same for all the eigenvalues, ``M`` is diagonalizable.\n", "\n", "To diagonalize a matrix, use diagonalize. diagonalize returns a tuple $(P,D)$, where $D$ is diagonal and $M=PDP^{−1}$." ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "P, D = M.diagonalize()" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}0 & 1 & 1 & 0\\\\1 & 1 & 1 & -1\\\\1 & 1 & 1 & 0\\\\1 & 1 & 0 & 1\\end{matrix}\\right]$$" ], "text/plain": [ "⎡0 1 1 0 ⎤\n", "⎢ ⎥\n", "⎢1 1 1 -1⎥\n", "⎢ ⎥\n", "⎢1 1 1 0 ⎥\n", "⎢ ⎥\n", "⎣1 1 0 1 ⎦" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "P" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}-2 & 0 & 0 & 0\\\\0 & 3 & 0 & 0\\\\0 & 0 & 5 & 0\\\\0 & 0 & 0 & 5\\end{matrix}\\right]$$" ], "text/plain": [ "⎡-2 0 0 0⎤\n", "⎢ ⎥\n", "⎢0 3 0 0⎥\n", "⎢ ⎥\n", "⎢0 0 5 0⎥\n", "⎢ ⎥\n", "⎣0 0 0 5⎦" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "D" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}3 & -2 & 4 & -2\\\\5 & 3 & -3 & -2\\\\5 & -2 & 2 & -2\\\\5 & -2 & -3 & 3\\end{matrix}\\right]$$" ], "text/plain": [ "⎡3 -2 4 -2⎤\n", "⎢ ⎥\n", "⎢5 3 -3 -2⎥\n", "⎢ ⎥\n", "⎢5 -2 2 -2⎥\n", "⎢ ⎥\n", "⎣5 -2 -3 3 ⎦" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "P * D * P.inv()" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "P * D * P.inv() == M" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that since ``eigenvects`` also includes the ``eigenvalues``, you should use it instead of ``eigenvals`` if you also want the ``eigenvectors``. However, as computing the eigenvectors may often be costly, ``eigenvals`` should be preferred if you only wish to find the eigenvalues.\n", "\n", "If all you want is the characteristic polynomial, use ``charpoly``. This is more efficient than ``eigenvals``, because sometimes symbolic roots can be expensive to calculate." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/latex": [ "$$\\left(\\lambda - 5\\right)^{2} \\left(\\lambda - 3\\right) \\left(\\lambda + 2\\right)$$" ], "text/plain": [ " 2 \n", "(λ - 5) ⋅(λ - 3)⋅(λ + 2)" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lamda = symbols('lamda')\n", "p = M.charpoly(lamda)\n", "factor(p)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Note:** ``lambda`` is a reserved keyword in Python, so to create a Symbol called λ, while using the same names for SymPy Symbols and Python variables, use ``lamda`` (without the b). It will still pretty print as λ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Non-square matrices don’t have eigenvectors and therefore don’t\n", "have an eigendecomposition. Instead, we can use the singular value\n", "decomposition to break up a non-square matrix A into left singular\n", "vectors, right singular vectors, and a diagonal matrix of singular\n", "values. Use the singular_values method on any matrix to find its\n", "singular values." ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$$\\left[\\begin{matrix}1 & -1 & -1\\\\0 & 1 & 0\\\\1 & -2 & 1\\end{matrix}\\right]$$" ], "text/plain": [ "⎡1 -1 -1⎤\n", "⎢ ⎥\n", "⎢0 1 0 ⎥\n", "⎢ ⎥\n", "⎣1 -2 1 ⎦" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/latex": [ "$$\\left [ \\sqrt{\\sqrt{14} + 4}, \\quad \\sqrt{- \\sqrt{14} + 4}, \\quad \\sqrt{2}\\right ]$$" ], "text/plain": [ "⎡ _________ __________ ⎤\n", "⎣╲╱ √14 + 4 , ╲╱ -√14 + 4 , √2⎦" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A.singular_values()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n", "\n", "1. SymPy Development Team (2016). [Sympy Tutorial: Matrices](http://docs.sympy.org/latest/tutorial/matrices.html)\n", "2. Ivan Savov (2016). [Taming math and physics using SymPy](https://minireference.com/static/tutorials/sympy_tutorial.pdf)" ] }, { "cell_type": "markdown", "metadata": { "scrolled": true }, "source": [ "The following cell change the style of the notebook." ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "<link href='http://fonts.googleapis.com/css?family=Fenix' rel='stylesheet' type='text/css'>\n", "<link href='http://fonts.googleapis.com/css?family=Alegreya+Sans:100,300,400,500,700,800,900,100italic,300italic,400italic,500italic,700italic,800italic,900italic' rel='stylesheet' type='text/css'>\n", "<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:300,400' rel='stylesheet' type='text/css'>\n", "<style>\n", "/* Based on Lorena Barba template available at: https://github.com/barbagroup/AeroPython/blob/master/styles/custom.css*/\n", "@font-face {\n", "font-family: \"Computer Modern\";\n", "src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');\n", "}\n", "div.cell{\n", "width:800px;\n", "margin-left:16% !important;\n", "margin-right:auto;\n", "}\n", "h1 {\n", "font-family: 'Alegreya Sans', sans-serif;\n", "}\n", "h2 {\n", "font-family: 'Fenix', serif;\n", "}\n", "h3{\n", "font-family: 'Fenix', serif;\n", "margin-top:12px;\n", "margin-bottom: 3px;\n", "}\n", "h4{\n", "font-family: 'Fenix', serif;\n", "}\n", "h5 {\n", "font-family: 'Alegreya Sans', sans-serif;\n", "}\t\n", "div.text_cell_render{\n", "font-family: 'Alegreya Sans',Computer Modern, \"Helvetica Neue\", Arial, Helvetica, Geneva, sans-serif;\n", "line-height: 135%;\n", "font-size: 120%;\n", "width:600px;\n", "margin-left:auto;\n", "margin-right:auto;\n", "}\n", ".CodeMirror{\n", "font-family: \"Source Code Pro\";\n", "font-size: 90%;\n", "}\n", "/* .prompt{\n", "display: None;\n", "}*/\n", ".text_cell_render h1 {\n", "font-weight: 200;\n", "font-size: 50pt;\n", "line-height: 100%;\n", "color:#CD2305;\n", "margin-bottom: 0.5em;\n", "margin-top: 0.5em;\n", "display: block;\n", "}\t\n", ".text_cell_render h5 {\n", "font-weight: 300;\n", "font-size: 16pt;\n", "color: #CD2305;\n", "font-style: italic;\n", "margin-bottom: .5em;\n", "margin-top: 0.5em;\n", "display: block;\n", "}\n", ".warning{\n", "color: rgb( 240, 20, 20 )\n", "}\n", "</style>\n", "<script>\n", "MathJax.Hub.Config({\n", "TeX: {\n", "extensions: [\"AMSmath.js\"]\n", "},\n", "tex2jax: {\n", "inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n", "displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n", "},\n", "displayAlign: 'center', // Change this to 'center' to center equations.\n", "\"HTML-CSS\": {\n", "styles: {'.MathJax_Display': {\"margin\": 4}}\n", "}\n", "});\n", "</script>\n", "\n", "\n" ], "text/plain": [ "<IPython.core.display.HTML object>" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.core.display import HTML\n", "def css_styling():\n", " styles = open('./styles/custom_barba.css', 'r').read()\n", " return HTML(styles)\n", "css_styling()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.6" } }, "nbformat": 4, "nbformat_minor": 1 }