{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SymPy Cheat Notebook\n",
    "\n",
    "<div style=\"text-align: right\"> \n",
    "M. Pritzkoleit, J. Winkler, 01'2019 \n",
    "<br>\n",
    "Institut für Regelungs- und Steuerungstheorie\n",
    "<br>\n",
    "TU Dresden\n",
    "</div>\n",
    "\n",
    "This notebook provides an overview about frequently used SymPy functionalities especially useful for control purposes.\n",
    "\n",
    "The documentation of the latest SymPy release can be found at : https://docs.sympy.org/latest/index.html\n",
    "\n",
    "For keyboard shortcuts drastically improving the user experience in Jupyter notebook see the help menu or press the littel keyboard icon in the command symbol line at the top of the notebook. The most important ones are:\n",
    "\n",
    "``RET`` --> Enter a cell, i.e. start edit mode (green border around cell)\n",
    "\n",
    "``ESC`` --> Leave a cell, i.e. start command mode (blue border around cell)\n",
    "\n",
    "**In edit mode:**\n",
    "\n",
    "``STRG + RET`` --> Execute current cell\n",
    "\n",
    "``SHIFT + RET`` --> Execute current cell and jump to the next cell\n",
    "\n",
    "``ALT + RET`` --> Execute current cell, open a new cell below and jump to the new cell\n",
    "\n",
    "``STRG + SHIFT + -`` --> Split current cell at cursor position\n",
    "\n",
    "**In command mode:**\n",
    "\n",
    "``A`` --> Create new cell above\n",
    "\n",
    "``B`` --> Create new cell below\n",
    "\n",
    "``D`` ``D`` --> Delete current cell\n",
    "\n",
    "``C`` --> Copy cell to clipboard\n",
    "\n",
    "``X`` --> Cut cell to clipboard\n",
    "\n",
    "``V`` --> Insert cell from clipboard below currently selected cell\n",
    "\n",
    "``SHIFT + M`` Merge current cell with cell below\n",
    "\n",
    "``M`` Convert cell to a markdown cell used for text and comments only\n",
    "\n",
    "``Y`` Change cell to a code cell used for computations (the default)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Contents\n",
    "### Basics\n",
    "* [How to import SymPy?](#import)\n",
    "\n",
    "* [How to setup LaTeX printing?](#latex)\n",
    "\n",
    "### Definitions\n",
    "* [How to define a symbol?](#symbol)\n",
    "\n",
    "* [How to define multiple symbols at once?](#symbols)\n",
    "\n",
    "* [How to define a symbolic matrix expression?](#matrix-symbol)\n",
    "\n",
    "* [How to define a symbolic function of a variable?](#function)\n",
    "\n",
    "* [How to define a row vector?](#rowvector)\n",
    "\n",
    "* [How to define a column vector?](#colvector)\n",
    "\n",
    "* [How to define a 2D matrix?](#2dmatrix)\n",
    "\n",
    "### Operations\n",
    "* [How to simplify an expression?](#simplify)\n",
    "\n",
    "* [How to expand an expression?](#expand)\n",
    "\n",
    "* [How to concatenate vectors and matrices?](#concat)\n",
    "\n",
    "* [How to substitute variables by other variables?](#subs)\n",
    "\n",
    "* [How to find all symbols in an expression?](#free_symbols)\n",
    "\n",
    "### Computation\n",
    "* [How to solve an algebraic equation?](#solve)\n",
    "\n",
    "* [How to compute the rank of a matrix?](#rank)\n",
    "\n",
    "* [How to compute the inverse of a matrix?](#inverse)\n",
    "\n",
    "* [How to compute the transpose of a matrix?](#transpose)\n",
    "\n",
    "* [How to compute the eigenvalues and eigenvectors of a matrix?](#eigen)\n",
    "\n",
    "* [How to compute the controllability matrix?](#control)\n",
    "\n",
    "* [How to compute the observabiltiy matrix?](#obs)\n",
    "\n",
    "* [How to compute the jacobian of a vector?](#jacobian)\n",
    "\n",
    "* [How to compute the gradient of an expression?](#gradient)\n",
    "\n",
    "### Export\n",
    "* [How to create a callable function from an expression?](#callable)\n",
    "\n",
    "* [How to export an expression to C-code?](#ccode)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Basics"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to import SymPy? <a class=\"anchor\" id=\"import\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sympy as sp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to setup LaTeX printing? <a class=\"anchor\" id=\"latex\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sympy import init_printing\n",
    "init_printing()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Definitions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to define a symbol? <a class=\"anchor\" id=\"symbol\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAAcAAAANBAMAAACX52mGAAAALVBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMA3SJUmc2JRLt2EDKrZmgE\nTt4AAAAJcEhZcwAADsQAAA7EAZUrDhsAAABBSURBVAgdY2BgEGJgYGB+ACRYAoAEYwIDQ0lfywQG\nBjsgj8EVRIgBMddzIMH+gGEBA1sA8wYGlgMrGRiYei8wAAARQQqn78uQggAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$t$$"
      ],
      "text/plain": [
       "t"
      ]
     },
     "execution_count": 144,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t = sp.Symbol('t')\n",
    "t"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to define multiple symbols at once? <a class=\"anchor\" id=\"symbols\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAI4AAAAUBAMAAACpLhgeAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAImYQu82Z3XZU70SJ\nMqtHo0JKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABqElEQVQ4EaWUPUhCURiGX+/xB1PMKbe4BNF6\nB5No6FZDtGUELhG4CA1CQkMEEncSoQKjodH+qKGlLWhyEocGg3YtCBwtCRIb+s4lwvNjCL3TPc/7\nft8959x7DuAx8V8Fo9Qhru8Sv9ZzlT5d4Znoquq4JDWAq7iLacBIq4ZLugO4gkMdhB0E+No0IndI\nhXNgp4gNSJM7pHxpYB0FSnuymxdyka9VKMkMtWJdZmO1BuWqWCTjPupry769xt5kFit5kxILnWHF\nAiaxC7Bz+OclH2ULnzLLI0LvFjRrIkPgBDeAv4OAI7g0yIB9SYxyirYs5Ak2eJ+Redh1OZFCSP7y\nlFN0CdYj2ODrsisoK4F3Pk1RlJNFcw62Cd7xfbZLeHWPSH+qB1q6qFEC0v6wLiLJI77PVcDrGHth\n2Emh6gVLYB8C8jeRqEuxZUw1K0CWZgTWOhzfR2BbKEocmMCOJbCHCfr/xdhc8bF1C2z0nYtjocYd\nBMU+LtPEwHJ957Si9gmrCJoYP6dY+MkyepY1IwPaBEdl/N74vccMjW+qTBdz5+LRhNXyP4kRxTcR\nDlXCx7HOVQAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left ( a, \\quad b, \\quad c, \\quad d\\right )$$"
      ],
      "text/plain": [
       "(a, b, c, d)"
      ]
     },
     "execution_count": 145,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a, b, c, d = sp.symbols('a b c d')\n",
    "a, b, c, d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note:** Only the last symbol is printed. If you want to show several symbols simultaneously use the notation shown above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJBAMAAAASvxsjAAAALVBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMAiXYyIt1Uu82rmRDvZmBA\ngXkAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAA2SURBVAgdY2BgEFIyYGBwTWBvYGAIZOBMYOB6zQAE\nPAUgcp8AiOS7wMAAFJ/AsAuoUvCuAgMAxzEIWh8VKHoAAAAASUVORK5CYII=\n",
      "text/latex": [
       "$$c$$"
      ],
      "text/plain": [
       "c"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a\n",
    "b\n",
    "c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to define a symbolic matrix expression? <a class=\"anchor\" id=\"matrix-symbol\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAOBAMAAAACpFvcAAAALVBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMAMs1mEFSZInZEq7vv3dm3\ne6EAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABcSURBVAgdY2AAASEwCST0oAxmPQcIyzWvAMIw6JsA\nZnA6xBmAGZ4Mcg1gxgSGugQQg3FZ2roNIAYnAwOPAogRwMDAewBIswMZTA+AjFog5n7OwOD9ToWB\ndd/bBADGlRAhSLypNgAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$A$$"
      ],
      "text/plain": [
       "A"
      ]
     },
     "execution_count": 147,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = sp.MatrixSymbol('A', 3, 3) # 3x3 dimensions\n",
    "A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to define a symbolic function of a variable? <a class=\"anchor\" id=\"function\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUBAMAAABohZD3AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAiXZmMs27mSIQ70RU\n3asrZM3lAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA3ElEQVQYGT2Qu2pCQRCGv3OCl40KNsH2YNoU\ngSg+g1Us7CRgp6UKSSPIkkCqtNb6CFZ2wRRpQ7TzESxPFYJN/GeN/jCXf3YuOwNHvJgp+iMB1w3e\n7sQzHkqe6Yk35HxDlMgatpJHlc2NQH4ttZF0lFOtEQ8oPP2MoAJtemRvNSzVe518SpPSB+Ra4l+4\n/RguFxpXFr+H5V838Jli4m/EvyF/hYN3HiAN/a74tH594oRoABOXwJDn6xsorOH1TvVticH+KzjF\nA2wfIUqkDFkfzHnf/3v0Q9RUuNeF5wD3/yiHn00JagAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$s{\\left (t \\right )}$$"
      ],
      "text/plain": [
       "s(t)"
      ]
     },
     "execution_count": 148,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = sp.Function('s')(t)\n",
    "s"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note:** Definition of functions are useful if you need to differentiate the expression later, see [How to differentiate an expression?](#diff)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to define a row vector? <a class=\"anchor\" id=\"rowvector\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEcAAAAZBAMAAACRGi6rAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAq90imYl27xBEzWa7\nMlTp77j4AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABCElEQVQoFWMQUjJgwAsmKQUwKOBVAZJkFhgB\nikxC0hvQQ4LZ1a0CIgYJAs5ihvXoahimG3B9QFbUvoHBh4GB9wCyQo5qBpYDDKw+HrDA9G9gUGPg\ndVFAVsTyg4EpgSGYQQqmqIaB4y8DAyeKIvYDDP0XGJQZ7htAooXjKwMf0HpURf0BDO8ZGDQZ7CdA\nFf1jYFzwGF3RAwYpPmD6eN8AjeBjDJsEAtAU8SRwK7ICHakGc1Nj2mWxCWiKOMRyDTMZGFgdYIog\nvkJ1E0SMYQuQRk5P2BRxBnBeQFHEpwDVjUTdevcG5nCwKLPTxwQkaQiz/v9/VOswVMAEkN0EE8Og\niVWkpEQw3wkAAAibNDHFSPHCAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1} & a_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "[a₁  a₂]"
      ]
     },
     "execution_count": 149,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a1, a2 = sp.symbols('a1, a2')\n",
    "a = sp.Matrix([[a1, a2]])\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to define a column vector? <a class=\"anchor\" id=\"colvector\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACAAAAAyBAMAAADPSsRXAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA4klEQVQoFWOQ//+JAQ70/39kEHZxhfMZQlwM\nGcQQXBArkXYCLEUVolDLILZMdOD6wMCQA7eWVZqB/QBDei1cgP0rA28DA8NcuADjAYb4BGSBeAUG\ne6AsQkW8AcMrZgckAZ4G7ntMyCpYX7T5dSILgEwHAoQZED6DLYhGCg/3+y9QBSDqkFQMEwHsEcVU\nUwrzPiSiVBhewQQgEXWFId8BGmKQiLrJ4D8BKgCNKAb7AJgAJKIYbsDMgEYUUwFMABpR24F85Gjg\nVOBMQBHIMraBGQpSysAg//8/kCQrXjCyB3oGAgBVlU4HDjvicwAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1}\\\\a_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁⎤\n",
       "⎢  ⎥\n",
       "⎣a₂⎦"
      ]
     },
     "execution_count": 150,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a1, a2 = sp.symbols('a1, a2')\n",
    "a = sp.Matrix([[a1], [a2]])\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to define a 2D matrix?  <a class=\"anchor\" id=\"2dmatrix\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAFoAAAAyBAMAAAAuIdEGAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB0klEQVRIDe2Wv0tCURTHv/7GTJd+LAU6BI4V\nNhY6GG5l0JwGQRBBEUQNSrZEbdbQFgj9AbU1BS5Ro0NDLdUoTmUZtPQ6515/PN+9gzYFduDw3j3v\n4+F63nsfHoJGFZ3FuPGGgfhsZzAW45MY7pBlbLmHaOfW7pB2NInwftJ0Qc7kONb3CqxTnbMV3kFc\nAO4iEL7lXwnaNQJPEatZiKRqIxYukYF7pwR7LFCgoqA9NfhzwBmtOVuxl8QD4C3BH3N/UFnQtiJS\naR09CtenpPPOrwadCiFK50pvVxUO+j/UG3DUmvQEKo6Yhn5HoDAlad6q3El/zvdk1/TGHa5fQpIO\nE1yfSflg7khHLx2ulPOC9m02aT6hUPYty4I+wSmt5N2R5Rk6cFrDUYL7PHJDZROdeC6D0xrO7HfO\nZhg0HDNtpTRrU2/NVWvpn7ZOpLfm/Qv72DPbevuweRT7jKGitQ+bR7XPPTbke9+6K8I+bB7VPo+Y\nz1tcJezjJ/NwUhPxfNftg2iyna7bR5hHsQ87j9/7ZrikfYQkFfvYyRltdN0+YPMo9rmiYjst7cPm\nUezjDXnTFlruic2j2GctMp3U2YfNo9onaBha+7B5/qB9uvvi6Opr5gcWOq4TBT1rdgAAAABJRU5E\nrkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{11} & a_{12}\\\\a_{21} & a_{22}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁₁  a₁₂⎤\n",
       "⎢        ⎥\n",
       "⎣a₂₁  a₂₂⎦"
      ]
     },
     "execution_count": 151,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a11, a12, a21, a22 = sp.symbols('a11, a12, a21, a22')\n",
    "A = sp.Matrix([[a11, a12], [a21, a22]])\n",
    "A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Operations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to simplify an expression? <a class=\"anchor\" id=\"simplify\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {},
   "outputs": [],
   "source": [
    "a, b, c = sp.symbols('a, b, c')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAI8AAAAwBAMAAADa0TQAAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIpmJdu8QRM1mu90y\nVKvMIHo8AAAACXBIWXMAAA7EAAAOxAGVKw4bAAACa0lEQVRIDe2WsWtTURTGv74kNzV5aR79AzRo\nEAxqY3GwuASJilADXUQLxYdgF8FkcXCx2Xyg1iDioEsHBd0Uqi4qcRAEh0ToJEgDZsgiWCpRQYn3\n9Z13kt48mkLvINg75J7zO9/5ct5NcgmwtkKZvV6w1ddDaG3Vwut/hpqlxekldpW0GAHLtmJ0oXBT\nIRDpVlVlffmiQsQrs60gXKrW7PVMPHq6HiCUUoCRMlUNduODosKw2neHFIkcBZF6uKGyGRQIYYmC\nZN0n3h7NRqtrERsVrdg92yv6TKzgyayH2GiONITx/vMnj/hNiFi1q1RlNmX+qBDzJzrqOwBDe9Jn\ncL7T8Qg3RZtL+1Sja6ePqUbz+QNAKD8ppVes4W9dWzbqIgQxmkj8tIvW0Gs8BsQ5GAvdrqCmIEZG\niTaSuXgWXwGjjXiOjEKOc+Os4zTctOMuufewpIvc6Y84znPHmZeRUUYxO2bLCJEFFKtypxX07kGM\nJpJfo7n69FpvMYtl30XuQU3Mog4ryShZwdjsqmdURythsYCbmPSajzP1jUryjH9JCRDL7XgT4vrG\nE+EWC8lopBJL4SDEfvmpNSd3nuT6AKMVFpKRSE/Iz2PiLnMOeh7tcJ4oM/N7wSZGRtzXFwhfiXjp\nHVWZhV+EU8T83xylG20ZmGpZnmdZZYPzmX5JpGQ0+ukg0j1YVibtSJ2TTQfXYajauH1fRZvIR0+d\nUFXml6yK/uXcvRo0LPd22V7bJ/B/nsDo+HFbx5NHp3Bbhw8uVpDRYiT/IixqMZqG+K3DSKwioeWy\nEX8wUv6oY6SHeNDQcudfzr9tlgZP9BfpTNFAskm9tgAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\frac{a^{2} + \\frac{a}{c} + \\frac{a}{b} + b c}{a}$$"
      ],
      "text/plain": [
       " 2   a   a      \n",
       "a  + ─ + ─ + b⋅c\n",
       "     c   b      \n",
       "────────────────\n",
       "       a        "
      ]
     },
     "execution_count": 153,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = (a/c + c*b + a**2 + a/b)/a\n",
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAIsAAAArBAMAAAC6K2YiAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIpmJdu8QRM1mu90y\nVKvMIHo8AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB9klEQVRIDc1VPUsDQRAdL97lQ6LpBRsttBFB\nCysJKtgIdkGx8AhoYeFV9pJCFgRJa2XwFwhiK/kJKbROwAhaGVGiFkF37269zc0kWdkmU9ztvjf7\ndnaPmwdgEoe7fVdnCwT94GKwhKEIOVppR5Nw5Dy+ugiEDoYUJI1lAC6xTJLKi3R0ZRLX0RpipCuT\naq7WAJbWq4QGh3RlvFPnDSZrmRMzmboLH3AD47wkKnSrmQXn3ep9zboyJUh27ApViI/pynyD1fYW\njGU+Yb88UQbocTej1Hm3XLTtC1yB1YBiFTECsJ6+5hAxv1fi+3ZHcY1Dixf5bnSoZlmquHuiRAqL\n0oZBZmR6phBUZFTNcS7VMpdxdsCqmMvwH3Qsz2USjJ1tM9YIFMPnMmO3jJ0PxADsCnjVIE/ezcSP\niAAD+XF9LDy9xIJEzrSA/6D1cIWUCafBSy5RQQLzavCczflJJjKZfPouEWxlIuM0N6c2zGWUM5tU\no8g4rjKRwwM5UGz/D5Pcf959bV9fqL/t6+oMsH1dmQG2T8oQ7h7Yfjw7ajNxhs8pd/dtH+VGbQZR\nQLq7b/vxXKXNxCnuU5TbCdtHqbLNIEIAdoU/4iFsP46BHbUZxInmgUPYPkKVNoM4IN1d2D5KVdoM\n4mh3F7aPQmkziKPd3bf9eK5sM7+LNKpLhG5sJwAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$a + \\frac{1}{c} + \\frac{1}{b} + \\frac{b c}{a}$$"
      ],
      "text/plain": [
       "    1   1   b⋅c\n",
       "a + ─ + ─ + ───\n",
       "    c   b    a "
      ]
     },
     "execution_count": 154,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d.simplify()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to expand an expression? <a class=\"anchor\" id=\"expand\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = sp.Symbol('x')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEYAAAAbBAMAAAAzEOSeAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAImYQu82Z3XZU70SJ\nqzJu81j5AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABdElEQVQoFYWSPUvDUBSG3zStaW0aLy4dXOo/\nCChYBMEvXNUhg4O0KHR2VBc7iYOiLqK/QKhLNxfRLBYHBzfH5h9Y6eBQIZ6bc5PYUrhnuPc973nu\nR3IuoInOhqshYIvSlo6xhPOtZdrGQMcAhb6esZp6pkOIUaFhbFxLN1OnYV6q0TAb6wFKguwnPAPb\no3WZL8EewKQ/4+zcrfFeKXbLch9oAW/AZBj2YMkN01DMPdAVWFR+Oa1LpZiai26AXJuLpzRVL2bO\nm5wqhpITF3adzVXA9DOHFt1PRsIUf+m7lXkE2K7dL6prJYz1QW044IUPtA+yy1Hy6nnHnrcb6QaN\nTi+SIAaYanKSnpWvkxMzdBbwFchRRnzWDQyBojqL7lxwL5F3hxjHR14kd6a2vlxtYpqReJ/ye+cT\nmPDZfaTmnFX3KpzFTC0Mf4BcwO74XnBtQS2M3ofSNM2lMuoppyv/3SEt3wbH2DcWlbIiZoxKrEbn\nWWX8ASO+RkhG3/rDAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left(x + 2\\right)^{2}$$"
      ],
      "text/plain": [
       "       2\n",
       "(x + 2) "
      ]
     },
     "execution_count": 156,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = (x+2)**2\n",
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = y.expand()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to concatenate vectors and matrices? <a class=\"anchor\" id=\"concat\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 158,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAK0AAAAyBAMAAADcsUbmAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAiUR2q1TvELuZ3WYi\nMs0DCV8EAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADsUlEQVRYCbWYTWgTQRSAX9Ikm2ySJh6rh65X\nQRopCJ4a6NGDvVhBConSQ/EHciiipxQEpZ4ComgPdqWCWAR7FA82Bz0UeuhRQegeFOnJ2lp6aDW+\nn5mJG5I0YdcHOzNvfr5982beZDYAKBEHINFo5LEoEmk0yrrcbz7bHHAMi4mp9YqpsdY/lo3SZyHq\n6QEDRSwlNrTKebbsU/tR3uvOk1QIj5tU/rSuhssVHkCyFi4XeP4AJV6v8PwAtjjiFZkbon8hfkjA\nNKfCXRs6y8YDBNgPAGypPUd05kZvwA9EUkUg7ioZt+lgItxbK/AEsk9dVANxqwUkPMYHhdZtsQJL\nAFEX1UDcQQ8J0/igEHcGrN9dubHl19K7fRpdfs4NA7hk2QPpg1zrJ8S3u3Lt9rxm7QcuZpBJbBLi\n7kHMm+rmhx655INkmbHsh7vwrpgPg/sA7ZxrcmdHv4w7R3Cte64M+Ce9fU0r4gcYBqjWpI7WTaTL\nfiA/DKoBujvlW1pR3NUN2CxIXZMbd7Gm/T4jbm4CkxbZ07riIrSkuhluZuEXvqozd6SiISaP7uui\n4qIT0GQWwxW1M/e4ZjTziKvLipsrwlhd6nrmfh19pCk6Hxw/p2atuXMwrKbVK9f6U6nW4ZNGcl79\nbh3C0DySFDfh0ZnA0is3vg+5wucFH7dUgd1IPeY1uS5cUD165aY8qObhlI/7DI8Au57FyFX22uW+\nubh9RyZauFsQ3bOdzM6/3H79kFsh1/ntPYAU7jT0kLHXheG6TKlXP+Qc6zq0cHcAfxHALhgurtvY\nRhdu1ZNGnWK8xVboXuC39zzMY48hfPR+KMKqI4Pa2mu/lEadItd6eAI1P/fOGTQ3ja/T3FwNSo4M\nasuFS9KoU+SK+LlcdxJOGy7umE18FUl7bl4adWq4l3WNybPfLt43XDx30GSWtlyrYMZxQXPX3oz7\nG9CuRmPbcPEwsz3pwdzWe0m6ZbTmtlQ3VbVuuMlS+BYS4sq9hAO983km3TukiotBnFZnJ3H5XiKB\nHow7gwe4OuuJi4G0BBLoHbhH3R9e8Dwyu5hNy5SIy/cSCfT23A6zb63mu8Oi4ap7CQd6IG7SReaI\nw2C0V91LONADcXMFRNo1zQW5l3CgB+KOVRCpNgT5V+4lHOiBuLJkV4y9XAAO9CBc+Q5o/W6RQA/C\nVTciycgPYjgHehDuJLkXIHOTUsMlpdN9R9qOSPV3IfChFx43VlMvThWxEB73rZkPHab/4X8CSDnI\nDe1/DV61v6MLEVbYxqeHAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left ( \\left[\\begin{matrix}a_{1}\\\\a_{2}\\end{matrix}\\right], \\quad \\left[\\begin{matrix}b_{1} & b_{2}\\end{matrix}\\right]\\right )$$"
      ],
      "text/plain": [
       "⎛⎡a₁⎤          ⎞\n",
       "⎜⎢  ⎥, [b₁  b₂]⎟\n",
       "⎝⎣a₂⎦          ⎠"
      ]
     },
     "execution_count": 158,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a1, a2, b1, b2 = sp.symbols('a1, a2, b1, b2')\n",
    "a = sp.Matrix([[a1], [a2]]) # column vector\n",
    "b = sp.Matrix([[b1 ,b2]]) # row vector\n",
    "a, b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Concatenate two *column* vectors columnwise:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 159,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEkAAAAyBAMAAADiuOvtAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABsUlEQVQ4EWOQ//+JAS9g+v9fgEHYxRWvIgZW\nF2cBBjH8akCybMNBFUtRhSiGV93VGwMgglA/TnTg+sDAkIOikFOEYT0wEA4ABSGqWKUZ2A8wpNcC\nBRAgcANDDQNb+QWgCEQV+1cG3gYGhrkIJUBWfQDDDQYGToQqxgMM8QnoqmQYWL+hqIpXYLAH6kYx\ni/UTAzPQrUhmxRswvGJ2QFP1mYFvgQmyKp4G7ntMaGYxnGDY+0ABWRXriza/TnRVcR0pLyYgq4L6\nDcVdUDEkd0FFbKE0MsWMCAmIsPv9F8jyYDZL7b8GWKhiSKIJDIu0iuYndO4I8iMJuZapphQ5oCC5\nVv14ACzlQHKtCsMrZFXgXMvkwLcApgqSa68w5DsgKQPnWl4Hti8wVZBce5PBfwKSKnCu5Z3A8hOm\nCpprGeyBboABaK5lYP4KVwXJtaByAQ5YIbkWXIBAYhuaa5kK4GqADEiuZVAHMiGqoLl2O7IiBkiu\n5QbpRE45nAqcCSjqQJxJDNNQVWUZ2yC5HqKebbHxUVRV8v//YxjF+P//B1RVGErgAsjuggtiMIhW\nRVzNR1QtCgDbd3Z53aZMsAAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1} & a_{1}\\\\a_{2} & a_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁  a₁⎤\n",
       "⎢      ⎥\n",
       "⎣a₂  a₂⎦"
      ]
     },
     "execution_count": 159,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = a.row_join(a)\n",
    "c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Concatenate two *column* in one column:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACQAAABkCAMAAADZhmLGAAAAPFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo1xBWAAAAE3RSTlMA\nMquZdlQiEEAw7USJ781mu91sBSdjbwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAYhJREFUSA3tV9uS\ngzAIJTfTrVpN8///upDUCK101oeuOzvyUEk4Jkg40IDJRSxsSKo2AJOdRwkbGJjIYjOBui37Ohf+\nCahzg/NjXD+saPLr+hGDccMPRjFzedCPAMVxwilHVuNcInsRAXKZNkq+WHoFNNIaMZt3oJgHNNPa\nJMpKMdMZ2xsEOksFBDN6MyULtKAKitZ701nfvwORrYm2XQOQEpQQMFDnUrY1YE8RZyChiogLCxuc\nIJm+LDRCPTZOO8k5uNktTBaOM3IOyAWkRBUBYuRMCGoVkECX/FXfYORMSIYuF0YA3Fk5lOSkrH04\nxbeT5GxF4SnHBTlhcMvZ8JVAkHNqGP2Ae+R6X+uLCjK3EMK84fjiAj3H0lMeM8InjuL6AaDol5zg\njjC9w/LSTpvNC/UAx/+4TzvJ+bnOebm+klO0svt1PWBJTqVLSXIqoLNzCoKIwckWtbD+Tpx2kvNz\nnbMVMa1z8lSR5Dw7J88VHic+L/QdoB/cFCPdBn390y+2wUG5KXoP3zMGI0YO+8ldAAAAAElFTkSu\nQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1}\\\\a_{2}\\\\a_{1}\\\\a_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁⎤\n",
       "⎢  ⎥\n",
       "⎢a₂⎥\n",
       "⎢  ⎥\n",
       "⎢a₁⎥\n",
       "⎢  ⎥\n",
       "⎣a₂⎦"
      ]
     },
     "execution_count": 160,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = a.col_join(a)\n",
    "d"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Concatenate two *row* vectors in one row:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 161,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJEAAAAZBAMAAADDFdGlAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAq90iELvvzZlURIl2\nZjKb4wewAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABZUlEQVQ4Ec2TPUvDUBSGX2mkbQJNcXFRCHET\nB/+BWRS3OImzu6jg0LGIooJgFwcnS/9Ag85CR0GHjI5ujiIGpH5Q056Y3J5rDpQ6eKebl+d9OPdy\ngyl3EeOvlhvAGV/TNxSqf2ta3tTmMtYdLROxZKaa1kKxrmcSlpi6estu6JmEkcmM9Fbb0zIRI5Pl\naC1c6ZGIkak4c6udZff+hLtEjEz+nvHKasab5/MXK2JkuvTwicqaKitHsDvW4YGaiRiZjmB8VI4d\ntVXagR9cY1rNRIxMNZhdmEOm+Dm1G3N4Vk8oYmT6QiliJjvEmTePpaYylIiR6R0rITc1ja1YEl9N\ntkSMTLPYADNNhJP12LGQeQARI9PqXchNxulNLLH6tnSJGJkG7PCNU/0htaSbPEw2mYH5mCqSzS+m\nAaaYyg4v4eni3ONhHpaZCvsvHd7a7vV4lItlJl4Z9fufmlxX/bdGPdQP33Kr3xzScL6a4i75AAAA\nAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}b_{1} & b_{2} & b_{1} & b_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "[b₁  b₂  b₁  b₂]"
      ]
     },
     "execution_count": 161,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "e = b.row_join(b)\n",
    "e"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Concatenate two *row* vectors rowwise:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEUAAAAyBAMAAAD4hAtjAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAyu93NmUSr\ndmazgYEmAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABQ0lEQVQ4EWOQ//+JAQ9g+v9fgEHYxRWPEgZW\nF2cBBjF8KkBybGA1rIUNGArDJWBCEDUMnAtgAgh6FowJVcNvABNA0J9hTKia/QEwATjN/RXGhKrR\ngPERNFMDjA1VM+fuYpgIjOY8ewvqAIga1p8B8Q4M6TBpMB0/lfULg1YV0BEQNcxfGfgvZK1AUWMf\nwPCXyYFnAkwN1wSGeAWGHShqVjKwfuJwYPsCUwMMnv0GaGpmMXB/5tjA8humhv8Bw/oANDX/GLiA\nvge6Auoe/g2scgxoan4zBD5gYOC4AFPD84B9AbqacwxVQPdpATHU72v1gGxUN0ddesDAwLcArgbI\nAAJUNWChTQzbYOaA+QwWEAqJZJtsXIqixqv/LJI0mMn4//8HFDXoCuB8aJzC+dgYw1vNaB4czYMo\nqX4o50Fi6iYi6jgAy2WGV6pCuVAAAAAASUVORK5CYII=\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}b_{1} & b_{2}\\\\b_{1} & b_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡b₁  b₂⎤\n",
       "⎢      ⎥\n",
       "⎣b₁  b₂⎦"
      ]
     },
     "execution_count": 162,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f = b.col_join(b)\n",
    "f"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 163,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAE0AAABkCAMAAAD0dE18AAAAPFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo1xBWAAAAE3RSTlMA\nMquZdlQiEEAw7USJ781mu91sBSdjbwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAtZJREFUWAntmdua\noyAQhFFQZsdDdHj/d90GEu0CGk2yezEzckVI8X9Ngyk6qsaF1qp32hohSjVOG2rdOzB184jWeVr/\nFmif3F20PRlP9P5r3no9ajPZ43DKQoxtmOiszLTN1JqlwhSEQLPTjQjaYxqtV5kmCYGmnV/jagJm\nqNAkIdAmH5V1zSFNEnKadSNx/IhvldhEIdL8g9/OqvPPbZUmCDlNLZSx29oqH2KNJgqBZltjmr41\nwxFNEgLNQ7ZWWemmCR0mlGld5YQAjgklWq9X18aDB1OzDyCUaNmsUwMX7VSaMtGVtywlpwauvJ1K\nUyZK8lY23WyWUmUh0pjpjnrRsucLQqAx0x3JaMhvhCYJgcZMdyWafOeUhJ724f7EGJjpruQ0vQt2\nU4hPEn6xmyqarvdpIXGikK/UOm6624Ukj00Uchqarhp1zrmPgI0zIdDAdG8yTElCoPFYBro+DPG2\nxIfzPhdKtGbuum4RdoEjQSjRplA28WlCH4QSTZh7MPy7aNac2LuDjMWve7pVyb8VpxBM9H12wS7T\nufupIExXOleedZYgqu1KwpQWfuJgmvChKExog/RzmzLLwoQ2nkubUmVhQpupmtFn/mYpC5Fm3Wyp\npPRFW7V0Js1DCC6OtOhSzhyUzg87IyG6ONK0d/fob6x6SneAPm9CdHFP+/i8u3M8REPY/DotnDYv\nRBf/+uRPvQv/EoRTUqcx4WPZfgW4Un9ViDeWarGrFBNyF0daS7Et8ZGpx8aEzJyT2Kw2o18stTqN\nCbmLY2wRdIK2C7k5J7HtIsUqYjaadcGcJRpUxBmCDYA5SzSmf6Yr5u0ZyKa9aFsqnup8n7wJppuv\nVhCmKy2abk673JlVbZSesukW8lYW4i7spvsz3Xm/RW+me+QymxDdGfPGTLfuWUx4uTMc0nredunl\nznsuXu7h6X0Zc58Yaf/y3a71r2VNfH/ycnTh3a4x6i9pIjNQI/+CsAAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1} & a_{1}\\\\a_{2} & a_{2}\\\\b_{1} & b_{2}\\\\b_{1} & b_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁  a₁⎤\n",
       "⎢      ⎥\n",
       "⎢a₂  a₂⎥\n",
       "⎢      ⎥\n",
       "⎢b₁  b₂⎥\n",
       "⎢      ⎥\n",
       "⎣b₁  b₂⎦"
      ]
     },
     "execution_count": 163,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g = c.col_join(f)\n",
    "g"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to substitute variables by other variables? <a class=\"anchor\" id=\"subs\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 164,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACAAAAAyBAMAAADPSsRXAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA4klEQVQoFWOQ//+JAQ70/39kEHZxhfMZQlwM\nGcQQXBArkXYCLEUVolDLILZMdOD6wMCQA7eWVZqB/QBDei1cgP0rA28DA8NcuADjAYb4BGSBeAUG\ne6AsQkW8AcMrZgckAZ4G7ntMyCpYX7T5dSILgEwHAoQZED6DLYhGCg/3+y9QBSDqkFQMEwHsEcVU\nUwrzPiSiVBhewQQgEXWFId8BGmKQiLrJ4D8BKgCNKAb7AJgAJKIYbsDMgEYUUwFMABpR24F85Gjg\nVOBMQBHIMraBGQpSysAg//8/kCQrXjCyB3oGAgBVlU4HDjvicwAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1}\\\\a_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁⎤\n",
       "⎢  ⎥\n",
       "⎣a₂⎦"
      ]
     },
     "execution_count": 164,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a1, a2, b1, b2 = sp.symbols('a1, a2, b1, b2')\n",
    "a = sp.Matrix([[a1], [a2]]) # column vector\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAB4AAAAyBAMAAAC5cHbcAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAyu93NmUSr\ndmazgYEmAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA9UlEQVQoFWOQ//+JAQb0/39kEHZxhXEZQlwM\nGcTgPBAjEcRnLWyACYL5DJwLUPn8Bqj8/QGofA0YF2Iew5y7i6EiEPN/BsQ7MKSDhMB85q8M/Bey\nVsD5XBMY4hUYdsD5QOv3GyDx+R8wrA9A5m9glWNA4vM8YF+AzGddqwc0C2EeyGBMvgVIEOJfEMur\n/ywKHySGLE9HPl3ig2n5Upj/wPGhwnASxgfHRwtDvgPU/+D46Gbw3wDlQ+KDwR6YCsDhxw+OD4Ze\nmH5IfDAtgPEh8fEKyEUKb24F7gRkfqaxOcw8kEIG+f//gSQifsCCRPDR0ztafgAA94hWMvfBmrcA\nAAAASUVORK5CYII=\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}b_{1}\\\\b_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡b₁⎤\n",
       "⎢  ⎥\n",
       "⎣b₂⎦"
      ]
     },
     "execution_count": 165,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = a.subs(([a1, b1], [a2, b2]))\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACAAAAAyBAMAAADPSsRXAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABNklEQVQoFWOQ//+JAQ70/39kEHZxhfMZQlwM\nGcQQXBArkXYCLEUVolDLILZMdOD6wMBUUwqzllWagf0AgwrDK5gA+1cG3gaGKwz5DlCHMR5giE9g\nuMngPwEqEK/AYA8y0z4AJmDA8IoZqPwGUBBsC08D9z0mBgamApgA64s2v04Ghu1APrJvORU4E1AE\nsoxtYIaClDIwyP//DyRpGEBgWyAEsbbEyMI1QbUsRxf4jCbA+RVNgOkCmgDXi3YDqBDE0PilrF8Y\n1I8DgwPqfWBw/2By4FsAF6hiYP3E68D2BS6wnIHzM+8Elp9wgd8MwNhkYAZZDjH0J0PgBgZQ/MIE\nXjMcB7LVgRiqIrwJqIC7ACEAYjFMYpgGJBEBxLbY+CiKAOP//x9QBIAcEEBogfCxCWBkD/QMBAA6\nKVlm4A3ZoAAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{2}\\\\b_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₂⎤\n",
       "⎢  ⎥\n",
       "⎣b₂⎦"
      ]
     },
     "execution_count": 166,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = b.subs(b1, a2)\n",
    "c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to find all symbols in an expression? <a class=\"anchor\" id=\"free_symbols\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 167,
   "metadata": {},
   "outputs": [],
   "source": [
    "a1, a2 = sp.symbols('a1, a2')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 168,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACAAAAAyBAMAAADPSsRXAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA6klEQVQoFWOQ//+JAQ70/39kEHZxhfMZQlwM\nGcQQXBArkXYCLEUVolDLILZMdOD6wMCQA7eWVZqB/QBDei1cgP0rA28DA8NcuADjAYb4BGSBeAUG\ne6AsQkW8AcMrZgckAZ4G7ntMyCpYX7T5dSILgEwHAoQZED6DLYhGCg/3+y9QBSDqkFSQIcBUU4pq\nqArDK1SBKwz5DijuuMngPwFFgIHBPgBN4AaqGQxMBWgC24F8ZM9xKnAmwATAEZVlbAM3FBxR8v//\nw7RAIgpkAlQLNKIQUQmJqPRauApaRhRGzGEIEB2VGNkDPQMBABQdVe1mvkM6AAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1}\\\\a_{1}^{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁ ⎤\n",
       "⎢   ⎥\n",
       "⎢  2⎥\n",
       "⎣a₁ ⎦"
      ]
     },
     "execution_count": 168,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = sp.Matrix([[a1], [a1**2]]) # column vector\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 169,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACcAAAAVBAMAAAA3P+qgAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAZpkQzYndq1TvMrsi\nRHaZuvfyAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAyklEQVQYGWNgYGBUZEAALj0DEIfZFSEEZPHO\nAnEZP6AIMqiAuKwJqIJh1BLkUdWbDDU6EkSzOwCJmwdYgI5YDeLLg4jOBUC3TmRg2sCwSA3EZ1EA\nyuYAGUyfGdgeMDBcAzIZGMqArJsLGBg4NzDYAymwIEsBUIJ9AwODfQBDP5AJFgSbCfKRfQNDCccB\niCDYdpAg9wPGdFaoSrg3meteHX+LLgg0DwTAZkJUToCIAMk2EAssiAjPQ/l1QEFweDKghfxckHIG\nDow4AgAUFCzVXtmdbwAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left\\{a_{1}\\right\\}$$"
      ],
      "text/plain": [
       "{a₁}"
      ]
     },
     "execution_count": 169,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.free_symbols"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 170,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAADUAAAAyBAMAAAAOzY77AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABeklEQVQ4Ec2UP0vDUBTFT/Ov1JpS8M+iYLeu\ngq5iwEo3qV/AOgguDuKig8W6iG7VwU0o+AH0CwhZREdHJ3UMTlKt4GJ8ufe90JCXbopvyAv3x809\neefwMBP2oFlGGJYxVlvWINi1pTImdSSqOf+PWTt7E1JuvXrY4Fep89QbeQO2RK0wjiugeic4M3sK\neR+bLcFWr7EPwyt1Fcv34baBC8EOGniE6zkfiuV8NNeZTcP+hNuxvhRrVrAoekSf3YMpJsPsx2wW\nr6ZH7B2l7jxoBGsZbRefDP7mPW5eKkKo6JU6g6OVE2ZrxxtBB8XtmImXaEU6eZ3hXPXJyoJCzuXc\nbZLVnwMJc2EoxMozUw2J/W8Y2UNzU/PYHj1jezIY2aNnbE8WixKQxSJ7MhjZk8HInjSLYsv2pBjF\nlu1JMYotVfkxeGYUWzg+k6S3FFtn90HDZGwLWsax1TJwbPWMY6tnrOE3mKn7Bx5ntb7b8ucHz0yW\n4k2wYXfkkLv1B5IXasoWRH0pAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1} a_{2}\\\\a_{1}^{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁⋅a₂⎤\n",
       "⎢     ⎥\n",
       "⎢   2 ⎥\n",
       "⎣ a₁  ⎦"
      ]
     },
     "execution_count": 170,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = sp.Matrix([[a1*a2], [a1**2]]) # column vector\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 171,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEUAAAAVBAMAAADiLT7tAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAZpkQzYndq1TvMrsi\nRHaZuvfyAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABU0lEQVQoFcWSO0jDUBSG/zSPprGBTq5WUBeh\nZhMX41Jws3QQ3Jx0Ee0gjsFJFAQVNx9QXOtQdJfQxbWLgk5dFZRCFUSU+p8b0+rQOvoPN+fx3XvO\nubkAtGH0lJPzJKfnexJMuEeS1Zr9GIxI1lzsy8z/C5MezR3+aKtWfFAzM7Qg4eQMl7vQ4HgV8Sn3\nBHNA8UK4IQnslHlHB0hUcTYmPjWVwTjMUO02sty7wmCiBasB3NIUTXhYhRU6H+JsNFimDKSq8PmJ\nmWPo77Dq6U8iRolLsgr4BezR/Gb0V9jsDnaLi+pH7tnfxLoddpg3DrILVT6aS5iBhrZsqnP0F+69\nwmCpwMFoovMv9ODx+imqteQBk8/nQR1alkiXEYeSfmwykW5wTyM6Zz8OYosWS0ZyZrcvaSmm+35q\nawEwHTOpdrtJW70f5OOo+mZ+eXBPlW//9Z6/ADY3S84OrWq3AAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left\\{a_{1}, a_{2}\\right\\}$$"
      ],
      "text/plain": [
       "{a₁, a₂}"
      ]
     },
     "execution_count": 171,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.free_symbols"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Computation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to solve an algebraic equation for a symbol? <a class=\"anchor\" id=\"solve\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "metadata": {},
   "outputs": [],
   "source": [
    "a1, a2, b1, b2 = sp.symbols('a1, a2, b1, b2')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 173,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = a1/a2 + b2 # a = 0 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 174,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAADUAAAAyBAMAAAAOzY77AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAyzZl2RGa7\n3avWqQ/vAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABDElEQVQ4EWOQ//+JAQtg+v9fgEHYxRWLFAOr\ni7MAgxg2GZAY20DLeWhMDIA6Dt0tXCIM9UAXHgBJo8sFbmDoYWDruIBNrj+A4SYDAxdWORkG1m84\n5Fg/MTB/wCX3mYGvwASHmScZ9j5QwCEXNzPl5QIcciC347APIsXAjNUPYEmW3n8TgAz0cIFqBFMD\nI8daDgYJDPz/4WAwuhM5pBDsgQkzhP0MBPODxokAoHJ0d4LzA5MDXwEWOXB+4HVg+4JFDpwfeBew\n/MKUg+YHBuavWOQg+YGBF1sahOQHBg2gNgx3QvIDdwM2OZAYA8MihmVAEt1/YCm2YuOjuOQY////\ngEsOrBlsJr4yEk/ZCgCd4lZLywjdhgAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left [ - \\frac{a_{1}}{a_{2}}\\right ]$$"
      ],
      "text/plain": [
       "⎡-a₁ ⎤\n",
       "⎢────⎥\n",
       "⎣ a₂ ⎦"
      ]
     },
     "execution_count": 174,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = sp.solve(a, b2)\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to differentiate an expression? <a class=\"anchor\" id=\"diff\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 175,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nSADcswAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left ( \\left[\\begin{matrix}x{\\left (t \\right )}\\\\y{\\left (t \\right )}\\end{matrix}\\right], \\quad \\left[\\begin{matrix}a_{1} & b_{1}\\\\a_{2} & a_{1} b_{2}\\end{matrix}\\right]\\right )$$"
      ],
      "text/plain": [
       "⎛⎡x(t)⎤  ⎡a₁   b₁  ⎤⎞\n",
       "⎜⎢    ⎥, ⎢         ⎥⎟\n",
       "⎝⎣y(t)⎦  ⎣a₂  a₁⋅b₂⎦⎠"
      ]
     },
     "execution_count": 175,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Symbols do not depend on anything\n",
    "a1, a2, b1, b2 = sp.symbols('a1, a2, b1, b2')\n",
    "t = sp.Symbol('t')\n",
    "\n",
    "# Functions depend on something, here t\n",
    "x = sp.Function('x')(t)\n",
    "y = sp.Function('y')(t)\n",
    "\n",
    "# More complex expressions consisting of symbols and functions\n",
    "f = sp.Matrix([x, y])\n",
    "g = sp.Matrix([[a1, b1], [a2, a1*b2]])\n",
    "f, g"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 176,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAADYAAAArBAMAAADBI2arAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAMrvvmVREEIndzSJ2\nZqtw62vAAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABkUlEQVQ4EXWTP0sDMRjGn15r07MtfoQWHV38\nAkJxKiJSJ3Gy4CQKvVFcroMgimBHURAFcS7uyhXELg4dXBT8ArZDFUoXQd+8udrYJC/k3/vLJbk8\neQAZibkSt9ZqpmJNc7IWuNmRG+HGxbLl1sDFtpre0MHEIlJXDpYawq87WLKIsOpgYR2bDoSwgo+p\npp16Uf4yY0cQvdbDk87u5cC+kijyxC7XE9U07e03sT+R5uEL1XTwTGSBF5RbBsSCybINyp1RudWZ\neO7uniBXQnrpawU40NkeXqNzeB36gT7l33R2iNNgB34FSpcNnQWYpWGySr9QB1DAzyjkMt9UklUo\nXQo0GEfik/pyzRoEsD0GwHqujzaf5Rhr/8+SHnj9bAeZErAqIqCsfSd67cd3IN0A7qjFtcZGXXln\nFILmGE6Rd00R3zU5hUQZhae6sUbkFO01xdrOq7nkFBLlL/hN5OOFyClSFDOkU5QoJmOnsCgGU06x\nm0U5xW4W5RS7WZRTWBRjP+UUFsVgyiksisGUU1iUSfYLAohsDfNYsEoAAAAASUVORK5CYII=\n",
      "text/latex": [
       "$$\\frac{d}{d t} x{\\left (t \\right )}$$"
      ],
      "text/plain": [
       "d       \n",
       "──(x(t))\n",
       "dt      "
      ]
     },
     "execution_count": 176,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.diff(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 177,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAOBAMAAADkjZCYAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAiXZmMs1UEN0i77ur\nRJlR0qN3AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAUUlEQVQIHWNgYFQWYWBgCGOomMDAvICBMYCB\n+wAD23cG/gMMvN8Y6h8w8H5imC/AwAIkHzCwfISKAGXZvjFwb2Bg/g7VxdDGUOXAwFCodIQBAG3H\nFgUteuAKAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$0$$"
      ],
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 177,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a1.diff(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 178,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEMAAAA0BAMAAAAjw5g5AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymc123au7\nZkS/6sRXAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAC2UlEQVQ4EZVVQWsTQRT+sskkTZpsAxWPmpt6\ny0FEe3GlFUFUVlC0VUj8AZLiQVtq6YLiURY91NJDgxbRWw5eeutB8KCle1D0IvQm6CFB2oIgxvdm\ndiazSSv4YOa9nffx3tuZ980AWhbq2urXh7s/1VKt38PfTrdbxujEWeU7uRdETIyXcVB7jmgjqbMG\ncm3pgeXKRPxxnCcDES+zO7wQy02phz1SBpKbJrMnD8lchQhIGUiqmm/1EKVpIN0BjtmQmlf85BtM\nwQNyAXDZhqS8xm2DwHkyCxVgaMtK5K6dmmfI5PKlJyEWgW+b70I4lNDUwm4SUSm9LgTYIPM0jVIw\nCHF8Z8f18ILcMzTSTQMZ6SqBQHGdXIdoPKeRpb/qTwSMhAoi/gxAcru0RNKo00SJ3A58uE07iuhg\nqI60v4K8z+U6QbreV246ADVMu7qJiwAdeq41SVPFjkJbMAbcWJqcj4DvQGaDNMU15YrZZ9Vzr+4i\nFj4Alika+o+m6g0fvYbhY2Sxj/EebgHbap3nt9JMNMMoljmiEdVSRY8W4kRiGxtX860rBqIa8yN/\n61oOZHejXFgxEMvQkB9PF6PsWt3yGFNDeGEfNtqQPdnYq4Wj7MnGJOQ/2UhHST3n8WxqSbJRrLMT\nb3gykCQbhzwiiYfrCUiSjZ/JRwxwQjtKko2r5CIGCD41kyjBxkyTXMyAxzYkZqNYDHHGz0/Dvf97\nVjZoLwrBWRy3jBUUI3Ux4AstmUQSAIznAnxAoaouBu5mDTFs9FMhfiG1pS4GNHqQOAaptp/dlZAa\nwfogMRtnkC/LRG3iN5NFJyJLsRHvUWzJco/iBPrKVWzEHNqRvHnmBG3tnUQUxUai44In2X7hK7kf\nWRCLjbTxdJ9KEU1Sel80G4cDea/wMZIkjlGzsRAVqQRIjiHZDJqN7pKkftxSkraUiB+bATbKxix5\ntBf82Mgna182yieL68I/2Aj8BbOIwLwbaLzpAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}\\frac{d}{d t} x{\\left (t \\right )}\\\\\\frac{d}{d t} y{\\left (t \\right )}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡d       ⎤\n",
       "⎢──(x(t))⎥\n",
       "⎢dt      ⎥\n",
       "⎢        ⎥\n",
       "⎢d       ⎥\n",
       "⎢──(y(t))⎥\n",
       "⎣dt      ⎦"
      ]
     },
     "execution_count": 178,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f.diff(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 179,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAADUAAAAyBAMAAAAOzY77AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAydmbN3bur\nRJnDVIseAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA50lEQVQ4EWOQ//+JAQtg+v9fgEHYxRWLFAOr\ni7MAgxg2GZAYG0SOqUINRYV6UwJcbjJDlAOSJKcB6xKYHIcAA9MEJLlGBgZNmBz3AQbmr0hyexgY\n7AOg9vEfYOD9jCT3h4HhvgFULv4BA+93hBzrP6BcAVTOX4GBDUmOBRgY+XC5BwxsSIHDAtSXD1QO\n9h8+M4FuYUZziz3MLdwbGDiQ/bCbgaE/AGomPr8zLGYITED4gYHLgBUYA9CwDio/hiTFwKpeA1QK\nlUOWgLNH5eBBgcKAhsto2oWHCjAfjaZdfGUdvjIST9kKAP49YvMx8GztAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}0 & 0\\\\0 & 0\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡0  0⎤\n",
       "⎢    ⎥\n",
       "⎣0  0⎦"
      ]
     },
     "execution_count": 179,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g.diff(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 180,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAD0AAAAyBAMAAAAdGs4PAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAyq2Z2mc3d\nu0T2XE1VAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABnklEQVQ4Ee2VvUoDQRDH/16yZzCXGBCshKQS\nEpuID5CAsTaxFCV5gwQL0croCxhs/GhMZ2EjBJurBH0AGxECgljYKjGiscg5m71N1tO9iLUDx+zM\nb2d2dm5vD3GnBY0YjhPDRG5Bg8Fy8zFM6ij3mzqe3CmpfDbPrYGE0+yKWyKerW15+DYwM+DAroff\nAhnukut7+RvwlNZz9kG8pudBalnZj1N8OaGPH5YfVF/Gpz7cuVvW7c/bn+M8FaOIlWa99+bGn8Tt\nqkIBltwvcYfM/wUqxj//4/l3e+j2zziYVpqK1SlpubyBlax0cW1LQ/BQDMaZdHH9Ig3BIxUEXqWL\ndLRvCD5eQbQfQty4kJMFL9YR7UgX6fDmET+cJIIvJmCqvHjO2kg16cy5vA5TvWTo0+wY2VEq+ef8\np2AtK2u2Jaf6Amp9NpVr3Qe7kkeuEepviap6xxiZfMsiv7c/XRSqgFWTHJcolChOygaaNEzRI+Kx\ndLguGdfLe1UgVKeRy2n0TR7w6MfNxtyNHx9xnGc/LtbzWb834Rd82P0+5P/wCZfZaFCUT9RoAAAA\nAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}1 & 0\\\\0 & b_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡1  0 ⎤\n",
       "⎢     ⎥\n",
       "⎣0  b₂⎦"
      ]
     },
     "execution_count": 180,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g.diff(a1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 181,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGAAAAAWBAMAAADNzYTXAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAiXZmMs1UEN0i77ur\nRJlR0qN3AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB00lEQVQ4EXWSu2sUURTGf8POzmMf4wqmC3HR\nKk0QUwhW6z8QRmRTWYiIraNNxMJsCgXFYloRsmksrAwoxCoOPlpZwdqM4qNIIFGiyyJhPHdmEmfj\n3FPcOff7zjf3vKDcptaDckKDGmHD11DlsBOao3JGgzoDd09D6WBrqGM0uNPWEBgnj6XU7c3ncCGY\nu5QFTh2Kr54xv2XQPDdD8eyI4wOeJj/EvweVOGMPzlqStMAJqaxgqA56AbUVzr8SsbUD7/mQx17O\nvtXJaXGuQT0ira/WozEiUqznY85fXVOuWC5opJevcCSi+Vsu1SGN3UzgtJAE5JnUxgRLsBjT/JlR\nzpDXp7/w8eV6OwPGBLMznebmn8/0W5i5YKPFGv2BSrRg+Qv1QEapquvHmKozYg/UUe8hiRYsFwjy\nQlVXSMmLVZg3QhLdt4lu9363ezG7bodSnSraUkXDDMiKGnv2+BblL7xF5rQ4kBRWqaRrY8U8rPl4\nw+YOQfbL9MwFj2E72MA+GBznYNqTWfqGb3X+F8RwhwmuwF1udexfuEtHt3puzNnQi24U4vcHt0zl\nCVt2G66feKMaVE2SpMfy5HfcZ6dKBO6ndwGPZouMxv/XVk3AYXhhHPgLviF64I10eqQAAAAASUVO\nRK5CYII=\n",
      "text/latex": [
       "$$0.25 t^{2} + 5 t$$"
      ],
      "text/plain": [
       "      2      \n",
       "0.25⋅t  + 5⋅t"
      ]
     },
     "execution_count": 181,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = 1/4*t**2 + 5*t\n",
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 182,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEUAAAAQBAMAAACy4K9eAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAiXZmMs1UEN0i77ur\nRJlR0qN3AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABQklEQVQoFV2Qv0rDUBTGv5A0MU0TMzgWDDq5\niOggOOUJJFIijr6B0Ulc1EFBcMgTtC4dnBQcdNKLf9bSJ5AI/hmtghaHEs+5oUnTO3z5zpdfzj0n\ngDI7BT6NaHVTmlGpLGvvVK9jN+b4Iv0iPWFbnGqauoB6BiXgcO2eUL2Xvde97Fmpz5GxBPQ+B4LF\nkTixHldATeqkgP3LTrBMuKzjzH4C+5vjh8VXPN/deuyLPkvzPtByoUnmGq0utiRRMFZkDohJoPFC\ndKwDvGUu70PlDZDfRQP/4ZAZJQw32mEo2AOfMWhmnWeuBVAGBjWWZ7jXEzDdhXUJlXevBnD6dg9R\niWlTnyj/hw4tHiiB7peYBDii4Bh7vvEDM8FK7IgdieQzN6GeU7I98wicAs36B8yrhTJjvnSyy7O4\npMOZS+FYYYx+/Q88U0wiKv+tPAAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$0.5 t + 5$$"
      ],
      "text/plain": [
       "0.5⋅t + 5"
      ]
     },
     "execution_count": 182,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "v = s.diff(t) # = s.diff(t, 1)\n",
    "v"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2.nd derivative"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABoAAAAOBAMAAADDIxFwAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAiXZmMs1UEN0i77ur\nRJlR0qN3AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAn0lEQVQIHWNgYFQWYQCB4AK/BAaGMIaKCSDe\n+v8fGRiYFzAwBoB4gYeAgtwHGNi+g3gHQAT/AQbebyDGARBR/4CB9xOIcdjoCQPDfAEGFjBvO8P8\nCwzzHzCwAA0DAe4GhEoGBr6fIFPYQKbwBDAw/mXg3sDADLKBK4CB7zvcdj4GBg6gK9oYqhzYvzJw\nPmCwAjqmUOkIA0MPA8M8mecMAOzlKsSBHKoQAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$0.5$$"
      ],
      "text/plain": [
       "0.500000000000000"
      ]
     },
     "execution_count": 183,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = s.diff(t, 2)\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to compute the jacobian of a function? <a class=\"anchor\" id=\"jacbobian\"></a>\n",
    "\n",
    "Given a vector-valued function $f : \\mathbb{R}^2 \\to \\mathbb{R}^2$ with $f(x) = \\left(f_1, f_2\\right)^T = \\left(x_1 x_2, x_2^2\\right)^T$ and $x = \\left(x_1, x_2\\right)^T$ we want to calculate the Jacobian\n",
    "\n",
    "$$\n",
    "\\begin{pmatrix}\n",
    "\\frac{\\partial f_1}{x_1} & \\frac{\\partial f_1}{x_2}\\\\\n",
    "\\frac{\\partial f_2}{x_1} & \\frac{\\partial f_2}{x_2}\n",
    "\\end{pmatrix}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define the independent variables and hold them in a vector:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {},
   "outputs": [],
   "source": [
    "x1, x2 = sp.symbols('x_1, x_2')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 185,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACEAAAAyBAMAAAAgiK9pAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAydqtEZt3N\nu5nxBet/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA60lEQVQoFWOQ//+JAQ6Y/v8XYBB2cYULMLC6\nOAswiCH4IBYbrUXCKzyLCiB2QuxiVeDazn2Age0C3HamAKavnA5s7zbARVgZeEHSnAgRBgb+AnSR\n/ARUEeaAegb2AGRd8w3uM3ihmBNRHv5qAYoI0AwQQLELLMKMbDtIhOX1D6AbaB5iYMshxKCwC1cM\n6t0LgIUGJAaZHDgOwEQgMcjtwPYFJgKJQe4JLD8RIuAYZGD+ChOBxiADNzycoTHIoAcMEEhoQGOQ\n6wFcBMgAgUkM02BqIAJsh42vooow/v//AVUEqpK4XICZmzByHACAOEVeiljkPAAAAABJRU5ErkJg\ngg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}x_{1}\\\\x_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡x₁⎤\n",
       "⎢  ⎥\n",
       "⎣x₂⎦"
      ]
     },
     "execution_count": 185,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = sp.Matrix([[x1], [x2]])\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define the vector valued function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 186,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAADYAAAAyBAMAAADl+jX4AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAydqtEZt3N\nu5nxBet/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABe0lEQVQ4EWOQ//+JARvQ//+RQdjFFZsUQ4iL\nIYMYVhmQYOKgkwuv8CwqALuXtbxlujrU5WB3sipwbec+wMB2gYEhiGF1wR4GprdPYX5gCmD6yunA\n9m4DA4Mqg37AFAYVhh6YHCsDL1ALAydQLoDhLpC1hSHfAe53/gKoHAPDdyBrJ4P/BLhcfgJMju0b\nkMXAYB8AlWMOqGdgDwCbacr+gaEUKLcdiMHunG9wn8ELbB/nZ94PLAsYGJgewOQiysNfAQWAbmFt\nL61bBRReB8Qo8QByJwRwKnAmoMoxw+VyjG1hboEoZnn9owCqT/7/fyBrwONW7x7QhRCA7hYmB44D\nuOS4Hdi+4JSbwPITlxwDA/NX3HLcsMDBEi56MG2YclwPcMtNYpgGk0TyHzgBsx02voopB0nAjP//\nf8CUgyRgmDiIRpgJTcA4whOUgHGFJygBYw9PSALmxhqe0ASMNTyhCZiBbuEJCgoG7OEJlmLAHp4Q\nOWQyEW8ZiadsBQAsuHvczbC/RwAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}x_{1} x_{2}\\\\x_{2}^{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡x₁⋅x₂⎤\n",
       "⎢     ⎥\n",
       "⎢   2 ⎥\n",
       "⎣ x₂  ⎦"
      ]
     },
     "execution_count": 186,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f = sp.Matrix([[x1*x2], [x2**2]])\n",
    "f"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Calculate the Jacobian:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 187,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAFUAAAAyBAMAAADfKoqLAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAydqtEZt3N\nu5nxBet/AAAACXBIWXMAAA7EAAAOxAGVKw4bAAACCElEQVRIDe2WsUtbQRzHv0neJTEvakDI2iBI\nlhIDpVOHBIyDHcrDxU4S3G2CNMTJdihkDaXo4BB11MEghXYoGPAfcGnpUs0oihBsU3Xp610ud/4u\necOz0KX0hrv7fe/D7/3u93hfHh64V/Axgq6bwERh1gcKVphJIOmHFEz432cXVudWysP9YNU3G2kt\nyz6wVOyD3ULmxNEHvc089sqfgGWpSjboBLsj+WA+2pKqmqcw7bzDiwsZ9/Ni9Biw8+EfipKrg29i\nsykj9S7GebV23bqV6t18LbYDbKkoxFBXzGSEf4rAYEPOK0T4vWyenY7HkQ4qA2wje4qnHMpQEBj5\nPtqxtgbY59WFc67F2ibLapW1XS4ZNfSRt1g34X7kwYaPHn32ZJ9IVfVMRAHX7Xixzw5rPZmyXhzV\n/rOyG3/Wh/ROkTaT7xcvvxiKzhvPsvfGCdhrTNeppNlt4CE9AMYcBBJU0uxXIOfQEwSaiBrfn2Zv\ngEbWYONdRHufkFIVy35xtqxUtdpdEJdRrMW9vTTENlLUZTTL85ZSKp9aP4K6jGI9axhrgxGXUSz4\n3XLm3YA1kf/OZTTLzWjfUc+Wa6iNAq+sKCLhMpodfhdYAl5Sl9GsnWVJmU7N1sHkWZO6jGZZerWo\nKLnGXddtUpfRrMkNRj2X8cdKl/HHSpfxx8qS/iJ7n3+Ce/xr/AYxm4WPkXwu/gAAAABJRU5ErkJg\ngg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}x_{2} & x_{1}\\\\0 & 2 x_{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡x₂   x₁ ⎤\n",
       "⎢        ⎥\n",
       "⎣0   2⋅x₂⎦"
      ]
     },
     "execution_count": 187,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f.jacobian(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to compute the rank of a matrix? <a class=\"anchor\" id=\"rank\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 188,
   "metadata": {},
   "outputs": [],
   "source": [
    "a1, a2, b1, b2 = sp.symbols('a1, a2, b1, b2')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 189,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAFsAAAAyBAMAAADB47o4AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACeUlEQVRIDc2Wv2uTQRjHv33TNyFtkxT8sSg0\ng5BBhEAdLX3BSjeN/4BvB0EQwaIIHSrGRdotOrhJA+6azUmog+jo4KCLOoZOoVpBl9e757n3vefu\n0pJuHiR3+d7nfXN3z/f98mIh28dkLcqyeZxYuTIZjXjl8jxOTwhrrOzh8btPwdVC83HMrAe40AK8\n0Q5xqwX4TifErRbgF0IaVjP49L2NU8y92rofXGA1gz9NZkbAHSD+20mTaPOBvERojMdnUNnFrYdA\n6QCN7jnsSVxojFcOUOsCL4BKH2nzM+4mghca41O7SNcIV8e+0/6Kaz2BC43xtIllNa/u3hjgkTrK\nZXmcQjN4G3ulhPCe2gfwRdwcDasxPted/RbR3euDuXUgUh/bhMZ4PHxydZvweOO84t5YVo2ExriZ\nVWunVm1W18yw6Fhz8CUzeXvxktwqqaxJfPX7kPmFLCvumg9Yk3g+c0T//+OegXkvrQ/qtMau3TMw\n4VFS7x+CewYmvJaUfx2CewZmvDf9J8RNBDkGJpwetHDtHEuOgQ2un7dgqxRBroEN3lJ9gFMEuQZm\nfFY/AwGuI2icgfEMzwvcjSXfwKutx53yy8X3BU6xpItJEeQZuHoSrzGVZaMc51jSxaQI4sUW39cH\n2DQ/eO0cS7qYFEE6/URTSaIOVniGY0kXkyJIp59oZxH/hvSMiSWVRhxB+TNO18T7KI0gPZNyLKn/\n5Ahy8Z+o9y/WhGdMLKlicgQ5OD7i7Y+m9IyJJVVMjiAXv7F1c9gDZbSsqi2mi5td+56xxRyHB56x\nxRyHS8+Y/8u7pXxge8czVtajIv2ELD0j5KOH6mSO+YJyvNeff1UiwYnx16JSAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1} b_{2} & b_{2}\\\\a_{2} b_{1}^{2} & a_{2}^{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁⋅b₂   b₂ ⎤\n",
       "⎢           ⎥\n",
       "⎢     2    2⎥\n",
       "⎣a₂⋅b₁   a₂ ⎦"
      ]
     },
     "execution_count": 189,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = sp.Matrix([[a1*b2, b2], [a2*b1**2, a2**2]])\n",
    "A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 190,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAAkAAAAOBAMAAAAPuiubAAAALVBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMAEJm7MquJRO/dIs12VHWs\nM+wAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABRSURBVAgdY2BUMnZgYBBlYHvOwKDIwNDBwNDJwBC3\ngGGfAEMcUIKBYZ4AkGB/BmJyBoBIJRDBowAiLzFwLWBgSWDgWcCwMi0pkoFh37t3LxkABZYPUKJR\n+4UAAAAASUVORK5CYII=\n",
      "text/latex": [
       "$$2$$"
      ],
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 190,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r = A.rank()\n",
    "r"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 191,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAFkAAAAyBAMAAADFFmoFAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACe0lEQVRIDb2WPWhTURTH/3ntS0jaNAXRRaQZ\nhA4iBLoqfWDFTePkIrxugggWRSiiGBz82KKDm6Qg0k2yudZBujo46KJrqEtpG2h1eN5zP94991yE\ndPFCuPe983s3511++RMsFHuYaCRFMY8TK5cngpGuXJrHqclYoqqCTj99iR6+ecbdkjQaa67k5023\njOhWx5X8vO+WET3oulI518duGdHnXcXPSfkqlp6+t37SlD+8uO85s2qMntv2LP0qa+wCd4D0dzfP\nkkcP+BP5+/QAi9uqRUOnp1Hbwq3HwNQYrd5Z7HB6uYvDJJvbcHRtjGYPeAvUNpC3v+JuxvCHSPea\nWfXA0ZUt5KuaVsc96HzHtT6jN1Hfb/anjxydt7Gsymrv1hBPVIPqy/34A/Xd1KPtO+9gZyrTdF+9\nA/DNs8ARrg+hWzVvOdub+ZHoveeGs2tAoj5+/MK2ulhUH3smo2dXX2o6XT+n7n70qFrdeKq2nqEN\n7Hmbqupbj3q7vmqX5fQabwR90dZuL13olphZVN8tfQ7pKz9HprRQFAJGpSh2Q1oS8XXQd1wWd/47\nLYzV7TBjRXvCWKpyYwUtjKUqN1bQwlhNM2M9bdMnMNakjzfW0zZ9AmOh04d+XNF56/QJjYVOH28s\n23tAPoXG6vSJjaWHKH2EsTp9uLFh+ghjKX0CY8P0EcZS+nBjRfpQR2yo4zw0l+ZMRPoITyh9eLJV\nwvQRnlD6cE9E+ghPKH24JyJ9hCeUPjzZZPqEyWbSx3uSivQJk02nD0s2e1wufUSymWrkiUsf4Ymm\nI0/K9BGeaJp7Yluxk/CE7gaehLTwhIrckxD+95Xy5Hj/OI71b+Yv5o/K++H0o8QAAAAASUVORK5C\nYII=\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1} b_{2} & b_{2}\\\\a_{1} b_{2}^{2} & b_{2}^{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁⋅b₂   b₂ ⎤\n",
       "⎢           ⎥\n",
       "⎢     2    2⎥\n",
       "⎣a₁⋅b₂   b₂ ⎦"
      ]
     },
     "execution_count": 191,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B = sp.Matrix([[a1*b2, b2], [a1*b2**2, b2**2]])\n",
    "B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 192,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAPBAMAAAArJJMAAAAAIVBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAADdcGRXAAAACnRSTlMAVO8Qq4lmdpnNpXqjvAAAAAlwSFlzAAAOxAAA\nDsQBlSsOGwAAACBJREFUCB1jYAADRmUGBpOQxUA2GykEO1Axh9PKNrAZAEESCWTnoGnkAAAAAElF\nTkSuQmCC\n",
      "text/latex": [
       "$$1$$"
      ],
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 192,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r = B.rank()\n",
    "r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### How to compute the inverse of a matrix? <a class=\"anchor\" id=\"inverse\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 193,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAF4AAAAyBAMAAAAnynF8AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACcElEQVRIDeVWPWtUQRQ9ebtvwxo3jR+NQrYQ\ntnQllkpeEUnnrmLtJiIIIhgWBMGIq+BntVrYCQF/gCsINorbiP6AFLFRC4Ul1RqNYuPzztyZeXfe\nhGVTWTjNnLnnzDBv7uHwMJNuYtxxOP2GPfMnxpXjzPwR7B9brYRL/6W+2L66j58pQ+LZFmo3m2bJ\n7/Mw2TUELlFNo+juV6FGeS+eAbV3ao/Wxwcw2ceF6wCja1iR+lM9WkfJ9KrVT26h0gGeAIzaeEOU\nGzeaWEclKf2gij5/oo/WotYb5J9/EPFPVLrF31bfqmKOMJ1vUCxNEm+iQF+HwpbT17FRSLSe0YMO\nUXbE3zG9ehT6ynyf3Z2pj5E+3yD/Pu/x+nOVHkgdwO8zuHPyvtbHjNCo29NpPnvv/KCLqWWnNxzd\nXw+6faNncDY9wmNacL+4etySa3jetNjOpaezbwkL/cKngSHP3fpiZW6eSNOhr3fUKCDOHyVz3D/R\nRytX3AUcEH52NQMOYSNfgvRznlzD5SRfk37Ocx/Q6OZr0s95DpgL+iv9HOrXw5Lwc0BGy0FJ+jkg\nXwYVbONnJypXy4tuYYH0c5ZSGl2cPeZ9r8orz8+cUqqrGs2kqT1VzTqvpJ85pVRXGUkxYZ1Xpqb9\nySmlumqSC325ReeVzENOKdVVk1c6b9wWnVfSPyalqKsGnR46MWWqzivpnxanFKWkQbc9vc4r6R+T\nUtRVRqW61MPkVZaHJqWoq4wieHrOq8A/WVdf+HrzLVkecsF1Ne5spw/y0HW10K796okHYij9kyeL\nKur94fnHp4BXf+r5kvRPnhuxXtrx/8wO/5f+AqF+0rPbrPGpAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1} a_{3} & a_{2}\\\\a_{2} a_{4}^{2} & a_{2}^{2}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁⋅a₃   a₂ ⎤\n",
       "⎢           ⎥\n",
       "⎢     2    2⎥\n",
       "⎣a₂⋅a₄   a₂ ⎦"
      ]
     },
     "execution_count": 193,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a1, a2, a3, a4 = sp.symbols('a_1, a_2, a_3, a_4')\n",
    "A = sp.Matrix([[a1*a3, a2], [a2*a4**2, a2**2]])\n",
    "A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}\\frac{a_{2}^{2}}{a_{1} a_{2}^{2} a_{3} - a_{2}^{2} a_{4}^{2}} & - \\frac{a_{2}}{a_{1} a_{2}^{2} a_{3} - a_{2}^{2} a_{4}^{2}}\\\\- \\frac{a_{2} a_{4}^{2}}{a_{1} a_{2}^{2} a_{3} - a_{2}^{2} a_{4}^{2}} & \\frac{a_{1} a_{3}}{a_{1} a_{2}^{2} a_{3} - a_{2}^{2} a_{4}^{2}}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡          2                             ⎤\n",
       "⎢        a₂                   -a₂        ⎥\n",
       "⎢───────────────────  ───────────────────⎥\n",
       "⎢     2        2   2       2        2   2⎥\n",
       "⎢a₁⋅a₂ ⋅a₃ - a₂ ⋅a₄   a₁⋅a₂ ⋅a₃ - a₂ ⋅a₄ ⎥\n",
       "⎢                                        ⎥\n",
       "⎢            2                           ⎥\n",
       "⎢      -a₂⋅a₄                a₁⋅a₃       ⎥\n",
       "⎢───────────────────  ───────────────────⎥\n",
       "⎢     2        2   2       2        2   2⎥\n",
       "⎣a₁⋅a₂ ⋅a₃ - a₂ ⋅a₄   a₁⋅a₂ ⋅a₃ - a₂ ⋅a₄ ⎦"
      ]
     },
     "execution_count": 194,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A.inv()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to compute the transpose of a matrix? <a class=\"anchor\" id=\"transpose\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 195,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAI8AAABLCAMAAAB+xCQDAAAAPFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo1xBWAAAAE3RSTlMA\nMquZdlQiEEDpMESJ781mu91sQ2thggAAAAlwSFlzAAAOxAAADsQBlSsOGwAAA5NJREFUaAXtml2b\noyAMhVH82Nlqrev//69LwCNEQwbnop0LuDAKOXKM2Po+rWk231rz2bYGG8Y0m+1c6z9rxyxkot3I\nz/BhK3H6vvqJxRD2an2EoiRdv7w+g51sN4+J4W92bwuMruD1eczuyX+6R8615hWsIIaj01YQTPZl\nlQuSFJ1toWB+xnlx81ky0li70tyItH9tgmByV9Q+r6l7j6CwblI/J6UwP3Yjm2vntQ/vxxhE33na\nCILV+VE+YAWFnYxZwj05+ZmpMuPWFPsRBOvDmGFzG7kJCkoU6zNuzqmvGKWgLojUd2qygE6B5XAS\nuIuVpjDjHGrA6zNu9JXqbn5P32fwgXg+tTuWBccdL1Z0z7BEnICtn5frXtbW0DWU+DGiwExWcLJ3\nyQr5fpmx7bpmaDt/91EXRGkOUbAoduQpaMXtbzusPmxK+EBkg9LBnvhw1X1gOUh5sc8r/NoZNvqk\ncS3vp9+fd8SQr2xDYvPs+/6VW89cHhT0CbHgOyHnZ7Dr1rrlhMhPJBwhcfZvnULCpQuKZuqmlp4g\najk/YfT92+pHr3mtT62PXgF9tK6fWh+9AvpoXT+36qPDmnCq24Kf8uCBdaU8CAGiYJ66Eh5E5lTA\ng8C6Yh6EADFjJ+FBZBbxYMQ67X01oTsIEDN+BMWFB/98/Q3qBNYi1ml+BEEUio4EBeUdPPjvK+It\nhzV6d6TXYMWPLIBQ8pNRlPAgsE71kwIkBDFeHXGCRGYRDwLrFD+cByE44tWOySji/WKfzwzvgHWa\nH1EAoWSH82DM/J4HD6zT/KRTQoCYjsn7IbOMByPWFfIgBIiyhbQXmUU8CKwDtKUnEvchQBSTWCcy\nKw+ysugH7PnSU98yWv3oZa71qfXRK6CP1vVT66NXQB89rZ/beHdb8GMeBKQV8+AuAOVl6pDyIBSY\nyklYfRJYA6QV8yAEoLyMHWEKKL2C+UlgLUKa9r4qCMp5EFMgXv0ksEaDAdI0P4KgnAfjFJjK9aT1\nOcHaDmmKH1lwgwfBgYhnPyneAdJUP5IAlEfXf26cBzEFostO63OCtYL7xX7tO6pe/PvgoSjhQfxo\np9SH0x0EkfLO1XHHjCChiJHXJ+oTSNP8SIJSHsQUiOFc7H7F05sIaYU8CAEoLzlXZhcKRJ+W8wNI\nK+ZBCEB5GRNJNxSIqp9E99bdXH3eaiKZ7Hf6+V3/hxzpj4hd+FdCUrp37/r/Q3ad+Q/GJT024ic2\njAAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{11} & a_{12} & a_{13}\\\\a_{21} & a_{22} & a_{23}\\\\a_{31} & a_{32} & a_{33}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a_{11}  a_{12}  a_{13}⎤\n",
       "⎢                      ⎥\n",
       "⎢a_{21}  a_{22}  a_{23}⎥\n",
       "⎢                      ⎥\n",
       "⎣a_{31}  a_{32}  a_{33}⎦"
      ]
     },
     "execution_count": 195,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a11, a12, a13, a21, a22, a23, a31, a32, a33 = sp.symbols('a_{11}, a_{12}, a_{13}, a_{21}, a_{22}, a_{23}, a_{31}, a_{32}, a_{33}')\n",
    "A = sp.Matrix([[a11, a12, a13], [a21, a22, a23], [a31, a32, a33]])\n",
    "A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 196,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAI8AAABLCAMAAAB+xCQDAAAAPFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo1xBWAAAAE3RSTlMA\nMquZdlQiEEDpMESJ781mu91sQ2thggAAAAlwSFlzAAAOxAAADsQBlSsOGwAAA+NJREFUaAXtmluX\noyAQhPEWdzZXx///X5cGS7qkJXrm7Mw84EM6Ah9dtiSxDnHNHI7W/ewxRRnONXPX+2P4WTnuKSLa\nWfRcflhKSj9UPakYxrtaH6MoqumX1+fS3br+PirBb96eBlyZ4Ppc7/6T//AfOX80rygFMZ5tXhVw\n615duJAi4DTRd+2WID3j/enzdSKk6bpJciPK+/xQwM1fSft4BzhFdD6Z5KIUpKebRe7Uh8TXoMc5\nxFyNny4Bk9cTv1hLgCa6m3PPcC8UQXruUplxbg7rUcB0de4y+5fiBThFSJZwLzSh9YyzV+ykRQ6I\nRoyt9MqAoFLfAuAvVqfwdy9cuyJYj/yk+kUwyO8ZBiGSkngyzhrAnS4AXo8m+gcvDT+r1uNevvs5\ntU6u4YgeBtytCzJLejZE+X65se375tL2sgoO6SHgGeWsYBC3fSFCVpzUS10B1YdgDEKkTuPk6qt6\nleVwEAhr5zLLN4wi9vUMy+cd0ZCgm5rHMAwvWc8HASffEM/wW6CIPT2Xbppbv5wQdWrz/T08bZ4A\nXHPrb63XRCn29Jg5v6Gx6ikXudan1qdcgXJvXT+1PuUKlHvr+jlVn7JZM6Y6DXzVD642zxDjn6SS\ngcRARHM8E4sf1AStH2XWYNJg8+zZFYCBiDZg+UEiSI+yd3iITDbPSqAADES0hvs2RcAPEiF6/nz8\njTSZtfhQm2yelUABGIhoDfdtipAR4geJ+PyAzRVnqs1aesiONs9IwAD8YIo5siEWP6gIfb/YrCU9\ni6G3ZtfuDn4wxXcE/KAitB42a6uexeblkzsG4AfX+J5Y/KAiSA+ZNeiBzbNmJwADES2ALSf8oCJI\nD82w6FltHnUaJxiIaAyhpuQHNbGvJ5q0ZPNosvwEAxHzEdsW+ZyLHyRiTw9MGmzedrLsHAMRswFZ\nA/wgEXt6MvqbGqqecqFrfWp9yhUo99b1U+tTrkC5t66fU/U5be9OA1/2g9jEM6/L8oNFgBwk/KAi\naP0oewc/iE08U412d3B1ZUATGIkYUpAeZdbgB2HabD0KgKsrA5YfJIL0kFnD8zw28SxFCtCuLu76\nWYDlB2XcSmg9bNZWPatpyxIwsLq6fWBjObE/uEaZQvtTbe+gJ5k2Q48G4OoKwM7+oCK0HrZ30KOK\nmQmiDcXk6tbqZwCnSFOvBOkhe5f0xE28fG7v+PWGYnJ1+wAT8IMp0v3ijEFPMm3caZxFV3ccwEjE\nOCXVh7JEPwjTRl3WCVzdYWDdHyRiTw/8IEybJYHa4OoOA+v+IBF7eijXN55UPeVix/r8rv9DjvJH\nxD7+K6Gs/r/2hv9D9r37B8YlPTZ1jlthAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{11} & a_{21} & a_{31}\\\\a_{12} & a_{22} & a_{32}\\\\a_{13} & a_{23} & a_{33}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a_{11}  a_{21}  a_{31}⎤\n",
       "⎢                      ⎥\n",
       "⎢a_{12}  a_{22}  a_{32}⎥\n",
       "⎢                      ⎥\n",
       "⎣a_{13}  a_{23}  a_{33}⎦"
      ]
     },
     "execution_count": 196,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A.T"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to compute the eigenvalues and eigenvectors of a matrix? <a class=\"anchor\" id=\"eigen\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 197,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAFoAAAAyBAMAAAAuIdEGAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAB0klEQVRIDe2Wv0tCURTHv/7GTJd+LAU6BI4V\nNhY6GG5l0JwGQRBBEUQNSrZEbdbQFgj9AbU1BS5Ro0NDLdUoTmUZtPQ6515/PN+9gzYFduDw3j3v\n4+F63nsfHoJGFZ3FuPGGgfhsZzAW45MY7pBlbLmHaOfW7pB2NInwftJ0Qc7kONb3CqxTnbMV3kFc\nAO4iEL7lXwnaNQJPEatZiKRqIxYukYF7pwR7LFCgoqA9NfhzwBmtOVuxl8QD4C3BH3N/UFnQtiJS\naR09CtenpPPOrwadCiFK50pvVxUO+j/UG3DUmvQEKo6Yhn5HoDAlad6q3El/zvdk1/TGHa5fQpIO\nE1yfSflg7khHLx2ulPOC9m02aT6hUPYty4I+wSmt5N2R5Rk6cFrDUYL7PHJDZROdeC6D0xrO7HfO\nZhg0HDNtpTRrU2/NVWvpn7ZOpLfm/Qv72DPbevuweRT7jKGitQ+bR7XPPTbke9+6K8I+bB7VPo+Y\nz1tcJezjJ/NwUhPxfNftg2iyna7bR5hHsQ87j9/7ZrikfYQkFfvYyRltdN0+YPMo9rmiYjst7cPm\nUezjDXnTFlruic2j2GctMp3U2YfNo9onaBha+7B5/qB9uvvi6Opr5gcWOq4TBT1rdgAAAABJRU5E\nrkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{11} & a_{12}\\\\a_{21} & a_{22}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a_{11}  a_{12}⎤\n",
       "⎢              ⎥\n",
       "⎣a_{21}  a_{22}⎦"
      ]
     },
     "execution_count": 197,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a11, a12, a21, a22 = sp.symbols('a_{11}, a_{12}, a_{21}, a_{22}')\n",
    "A = sp.Matrix([[a11, a12], [a21, a22]])\n",
    "A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 198,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/latex": [
       "$$\\left \\{ \\frac{a_{11}}{2} + \\frac{a_{22}}{2} - \\frac{\\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2} : 1, \\quad \\frac{a_{11}}{2} + \\frac{a_{22}}{2} + \\frac{\\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2} : 1\\right \\}$$"
      ],
      "text/plain": [
       "⎧                     _______________________________________________________ \n",
       "⎪                    ╱       2                                             2  \n",
       "⎨a_{11}   a_{22}   ╲╱  a_{11}  - 2⋅a_{11}⋅a_{22} + 4⋅a_{12}⋅a_{21} + a_{22}   \n",
       "⎪────── + ────── - ──────────────────────────────────────────────────────────:\n",
       "⎩  2        2                                  2                              \n",
       "\n",
       "                         _____________________________________________________\n",
       "                        ╱       2                                             \n",
       "    a_{11}   a_{22}   ╲╱  a_{11}  - 2⋅a_{11}⋅a_{22} + 4⋅a_{12}⋅a_{21} + a_{22}\n",
       " 1, ────── + ────── + ────────────────────────────────────────────────────────\n",
       "      2        2                                  2                           \n",
       "\n",
       "__   ⎫\n",
       "2    ⎪\n",
       "     ⎬\n",
       "──: 1⎪\n",
       "     ⎭"
      ]
     },
     "execution_count": 198,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A.eigenvals()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is a dictionary. Each entry consists of the eigenvalue as key and its algebraic multiplicity as value. Use ``list(A.eigenvals().keys())`` to access the eigenvalues only:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 199,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nxXYAAAAASUVORK5CYII=\n",
      "text/latex": [
       "$$\\left [ \\frac{a_{11}}{2} + \\frac{a_{22}}{2} - \\frac{\\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2}, \\quad \\frac{a_{11}}{2} + \\frac{a_{22}}{2} + \\frac{\\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2}\\right ]$$"
      ],
      "text/plain": [
       "⎡                     _______________________________________________________ \n",
       "⎢                    ╱       2                                             2  \n",
       "⎢a_{11}   a_{22}   ╲╱  a_{11}  - 2⋅a_{11}⋅a_{22} + 4⋅a_{12}⋅a_{21} + a_{22}   \n",
       "⎢────── + ────── - ──────────────────────────────────────────────────────────,\n",
       "⎣  2        2                                  2                              \n",
       "\n",
       "                      _______________________________________________________⎤\n",
       "                     ╱       2                                             2 ⎥\n",
       " a_{11}   a_{22}   ╲╱  a_{11}  - 2⋅a_{11}⋅a_{22} + 4⋅a_{12}⋅a_{21} + a_{22}  ⎥\n",
       " ────── + ────── + ──────────────────────────────────────────────────────────⎥\n",
       "   2        2                                  2                             ⎦"
      ]
     },
     "execution_count": 199,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "EV=A.eigenvals()\n",
    "list(EV.keys())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 200,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n/j8Ge9voilTNegAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left [ \\left ( \\frac{a_{11}}{2} + \\frac{a_{22}}{2} - \\frac{\\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2}, \\quad 1, \\quad \\left [ \\left[\\begin{matrix}- \\frac{a_{12}}{\\frac{a_{11}}{2} - \\frac{a_{22}}{2} + \\frac{\\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2}}\\\\1\\end{matrix}\\right]\\right ]\\right ), \\quad \\left ( \\frac{a_{11}}{2} + \\frac{a_{22}}{2} + \\frac{\\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2}, \\quad 1, \\quad \\left [ \\left[\\begin{matrix}- \\frac{a_{12}}{\\frac{a_{11}}{2} - \\frac{a_{22}}{2} - \\frac{\\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2}}\\\\1\\end{matrix}\\right]\\right ]\\right )\\right ]$$"
      ],
      "text/plain": [
       "⎡⎛                                                                            \n",
       "⎢⎜                     _______________________________________________________\n",
       "⎢⎜                    ╱       2                                             2 \n",
       "⎢⎜a_{11}   a_{22}   ╲╱  a_{11}  - 2⋅a_{11}⋅a_{22} + 4⋅a_{12}⋅a_{21} + a_{22}  \n",
       "⎢⎜────── + ────── - ──────────────────────────────────────────────────────────\n",
       "⎢⎜  2        2                                  2                             \n",
       "⎢⎜                                                                            \n",
       "⎢⎜                                                                            \n",
       "⎣⎝                                                                            \n",
       "\n",
       "     ⎡⎡                                  -a_{12}                              \n",
       "     ⎢⎢───────────────────────────────────────────────────────────────────────\n",
       "     ⎢⎢                     __________________________________________________\n",
       "     ⎢⎢                    ╱       2                                          \n",
       ", 1, ⎢⎢a_{11}   a_{22}   ╲╱  a_{11}  - 2⋅a_{11}⋅a_{22} + 4⋅a_{12}⋅a_{21} + a_{\n",
       "     ⎢⎢────── - ────── + ─────────────────────────────────────────────────────\n",
       "     ⎢⎢  2        2                                  2                        \n",
       "     ⎢⎢                                                                       \n",
       "     ⎣⎣                                     1                                 \n",
       "\n",
       "     ⎤⎤⎞  ⎛                                                                   \n",
       "─────⎥⎥⎟  ⎜                     ______________________________________________\n",
       "_____⎥⎥⎟  ⎜                    ╱       2                                      \n",
       "   2 ⎥⎥⎟  ⎜a_{11}   a_{22}   ╲╱  a_{11}  - 2⋅a_{11}⋅a_{22} + 4⋅a_{12}⋅a_{21} +\n",
       "22}  ⎥⎥⎟, ⎜────── + ────── + ─────────────────────────────────────────────────\n",
       "─────⎥⎥⎟  ⎜  2        2                                  2                    \n",
       "     ⎥⎥⎟  ⎜                                                                   \n",
       "     ⎥⎥⎟  ⎜                                                                   \n",
       "     ⎦⎦⎠  ⎝                                                                   \n",
       "\n",
       "              ⎡⎡                                  -a_{12}                     \n",
       "_________     ⎢⎢──────────────────────────────────────────────────────────────\n",
       "       2      ⎢⎢                     _________________________________________\n",
       " a_{22}       ⎢⎢                    ╱       2                                 \n",
       "─────────, 1, ⎢⎢a_{11}   a_{22}   ╲╱  a_{11}  - 2⋅a_{11}⋅a_{22} + 4⋅a_{12}⋅a_{\n",
       "              ⎢⎢────── - ────── - ────────────────────────────────────────────\n",
       "              ⎢⎢  2        2                                  2               \n",
       "              ⎢⎢                                                              \n",
       "              ⎣⎣                                     1                        \n",
       "\n",
       "              ⎤⎤⎞⎤\n",
       "──────────────⎥⎥⎟⎥\n",
       "______________⎥⎥⎟⎥\n",
       "            2 ⎥⎥⎟⎥\n",
       "21} + a_{22}  ⎥⎥⎟⎥\n",
       "──────────────⎥⎥⎟⎥\n",
       "              ⎥⎥⎟⎥\n",
       "              ⎥⎥⎟⎥\n",
       "              ⎦⎦⎠⎦"
      ]
     },
     "execution_count": 200,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A.eigenvects()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For each eigenvalue this command returns a tuple containing the eigenvalue, its algebraic multiplicity and the corresponding eigenvector(s). See https://docs.sympy.org/latest/tutorial/matrices.html#eigenvalues-eigenvectors-and-diagonalization for more details."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to compute the observability matrix? <a class=\"anchor\" id=\"obs\"></a>\n",
    "\n",
    "We want to calculate the observability matrix\n",
    "\n",
    "\\begin{pmatrix}\n",
    "c\\\\\n",
    "c\\cdot A\\\\\n",
    "c\\cdot A^2\n",
    "\\end{pmatrix}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 201,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAI8AAABLCAMAAAB+xCQDAAAAPFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo1xBWAAAAE3RSTlMA\nMquZdlQiEEDpMESJ781mu91sQ2thggAAAAlwSFlzAAAOxAAADsQBlSsOGwAAA5NJREFUaAXtml2b\noyAMhVH82Nlqrev//69LwCNEQwbnop0LuDAKOXKM2Po+rWk231rz2bYGG8Y0m+1c6z9rxyxkot3I\nz/BhK3H6vvqJxRD2an2EoiRdv7w+g51sN4+J4W92bwuMruD1eczuyX+6R8615hWsIIaj01YQTPZl\nlQuSFJ1toWB+xnlx81ky0li70tyItH9tgmByV9Q+r6l7j6CwblI/J6UwP3Yjm2vntQ/vxxhE33na\nCILV+VE+YAWFnYxZwj05+ZmpMuPWFPsRBOvDmGFzG7kJCkoU6zNuzqmvGKWgLojUd2qygE6B5XAS\nuIuVpjDjHGrA6zNu9JXqbn5P32fwgXg+tTuWBccdL1Z0z7BEnICtn5frXtbW0DWU+DGiwExWcLJ3\nyQr5fpmx7bpmaDt/91EXRGkOUbAoduQpaMXtbzusPmxK+EBkg9LBnvhw1X1gOUh5sc8r/NoZNvqk\ncS3vp9+fd8SQr2xDYvPs+/6VW89cHhT0CbHgOyHnZ7Dr1rrlhMhPJBwhcfZvnULCpQuKZuqmlp4g\najk/YfT92+pHr3mtT62PXgF9tK6fWh+9AvpoXT+36qPDmnCq24Kf8uCBdaU8CAGiYJ66Eh5E5lTA\ng8C6Yh6EADFjJ+FBZBbxYMQ67X01oTsIEDN+BMWFB/98/Q3qBNYi1ml+BEEUio4EBeUdPPjvK+It\nhzV6d6TXYMWPLIBQ8pNRlPAgsE71kwIkBDFeHXGCRGYRDwLrFD+cByE44tWOySji/WKfzwzvgHWa\nH1EAoWSH82DM/J4HD6zT/KRTQoCYjsn7IbOMByPWFfIgBIiyhbQXmUU8CKwDtKUnEvchQBSTWCcy\nKw+ysugH7PnSU98yWv3oZa71qfXRK6CP1vVT66NXQB89rZ/beHdb8GMeBKQV8+AuAOVl6pDyIBSY\nyklYfRJYA6QV8yAEoLyMHWEKKL2C+UlgLUKa9r4qCMp5EFMgXv0ksEaDAdI0P4KgnAfjFJjK9aT1\nOcHaDmmKH1lwgwfBgYhnPyneAdJUP5IAlEfXf26cBzEFostO63OCtYL7xX7tO6pe/PvgoSjhQfxo\np9SH0x0EkfLO1XHHjCChiJHXJ+oTSNP8SIJSHsQUiOFc7H7F05sIaYU8CAEoLzlXZhcKRJ+W8wNI\nK+ZBCEB5GRNJNxSIqp9E99bdXH3eaiKZ7Hf6+V3/hxzpj4hd+FdCUrp37/r/Q3ad+Q/GJT024ic2\njAAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{11} & a_{12} & a_{13}\\\\a_{21} & a_{22} & a_{23}\\\\a_{31} & a_{32} & a_{33}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a_{11}  a_{12}  a_{13}⎤\n",
       "⎢                      ⎥\n",
       "⎢a_{21}  a_{22}  a_{23}⎥\n",
       "⎢                      ⎥\n",
       "⎣a_{31}  a_{32}  a_{33}⎦"
      ]
     },
     "execution_count": 201,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a11, a12, a13, a21, a22, a23, a31, a32, a33 = sp.symbols('a_{11}, a_{12}, a_{13}, a_{21}, a_{22}, a_{23}, a_{31}, a_{32}, a_{33}')\n",
    "A = sp.Matrix([[a11, a12, a13], [a21, a22, a23], [a31, a32, a33]])\n",
    "A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 202,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGoAAAAZBAMAAAAruabLAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAq90iiXYyVLvNmRDv\nZkT5vWlKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABSklEQVQ4EWMQUjJgIA3wKakwKJCmBazacFQX\nUqhREhosoWFIJkGYrqEJ6GJwZWC7mNUZOtFVGBVwTEATQygD62JyYBBnYGtAUaTCwFjAsmI1shhY\nmevCDQwMYF3rgQy2VQrIKrh+A3nODJLIYiBlXBe4GqC6ToDk+BRAJAzwNABZygz5BjABIA1SxuXA\n+wGii/sLSApV134HoJAeg/0DIAUFEGUMcLv+MjCwo+niv8DAUMDAUL8BpgdIg5Ux7EmAunAhA/cy\nNF1cAgy7gNKqSJoYwMpYpwKFwKHB4nsV3YUMLncDGBhYFiDrAitDuBAsheoviOpbyJqgbObvULtw\n6eJz4EtA07cngRnoPbALwTLsCmgKGBgyyyuQQwMkz2TAexpJF/Oij0CPoILz//+jCgATg6ujAZIu\ndGm8fIQL8SpDkyRXlxIZ5aEiANTBP33bI6EAAAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}c_{1} & c_{2} & c_{3}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "[c₁  c₂  c₃]"
      ]
     },
     "execution_count": 202,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c1, c2, c3 = sp.symbols('c_1, c_2, c_3')\n",
    "c = sp.Matrix([[c1, c2, c3]])\n",
    "c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Since $c$, $c \\cdot A$, $\\ldots$ are row vectors, it is straightforward how to build the matrix:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 203,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\ncEv7s+F/pKa39BsBTDYAAAAASUVORK5CYII=\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}c_{1} & c_{2} & c_{3}\\\\a_{11} c_{1} + a_{21} c_{2} + a_{31} c_{3} & a_{12} c_{1} + a_{22} c_{2} + a_{32} c_{3} & a_{13} c_{1} + a_{23} c_{2} + a_{33} c_{3}\\\\c_{1} \\left(a_{11}^{2} + a_{12} a_{21} + a_{13} a_{31}\\right) + c_{2} \\left(a_{11} a_{21} + a_{21} a_{22} + a_{23} a_{31}\\right) + c_{3} \\left(a_{11} a_{31} + a_{21} a_{32} + a_{31} a_{33}\\right) & c_{1} \\left(a_{11} a_{12} + a_{12} a_{22} + a_{13} a_{32}\\right) + c_{2} \\left(a_{12} a_{21} + a_{22}^{2} + a_{23} a_{32}\\right) + c_{3} \\left(a_{12} a_{31} + a_{22} a_{32} + a_{32} a_{33}\\right) & c_{1} \\left(a_{11} a_{13} + a_{12} a_{23} + a_{13} a_{33}\\right) + c_{2} \\left(a_{13} a_{21} + a_{22} a_{23} + a_{23} a_{33}\\right) + c_{3} \\left(a_{13} a_{31} + a_{23} a_{32} + a_{33}^{2}\\right)\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡                                                                          c₁ \n",
       "⎢                                                                             \n",
       "⎢                                                          a_{11}⋅c₁ + a_{21}⋅\n",
       "⎢                                                                             \n",
       "⎢   ⎛      2                                ⎞                                 \n",
       "⎣c₁⋅⎝a_{11}  + a_{12}⋅a_{21} + a_{13}⋅a_{31}⎠ + c₂⋅(a_{11}⋅a_{21} + a_{21}⋅a_{\n",
       "\n",
       "                                                                              \n",
       "                                                                              \n",
       "c₂ + a_{31}⋅c₃                                                                \n",
       "                                                                              \n",
       "                                                                              \n",
       "22} + a_{23}⋅a_{31}) + c₃⋅(a_{11}⋅a_{31} + a_{21}⋅a_{32} + a_{31}⋅a_{33})  c₁⋅\n",
       "\n",
       "                                                                       c₂     \n",
       "                                                                              \n",
       "                                                       a_{12}⋅c₁ + a_{22}⋅c₂ +\n",
       "                                                                              \n",
       "                                                     ⎛                      2 \n",
       "(a_{11}⋅a_{12} + a_{12}⋅a_{22} + a_{13}⋅a_{32}) + c₂⋅⎝a_{12}⋅a_{21} + a_{22}  \n",
       "\n",
       "                                                                              \n",
       "                                                                              \n",
       " a_{32}⋅c₃                                                                    \n",
       "                                                                              \n",
       "               ⎞                                                              \n",
       "+ a_{23}⋅a_{32}⎠ + c₃⋅(a_{12}⋅a_{31} + a_{22}⋅a_{32} + a_{32}⋅a_{33})  c₁⋅(a_{\n",
       "\n",
       "                                                                   c₃         \n",
       "                                                                              \n",
       "                                                   a_{13}⋅c₁ + a_{23}⋅c₂ + a_{\n",
       "                                                                              \n",
       "                                                                              \n",
       "11}⋅a_{13} + a_{12}⋅a_{23} + a_{13}⋅a_{33}) + c₂⋅(a_{13}⋅a_{21} + a_{22}⋅a_{23\n",
       "\n",
       "                                                                 ⎤\n",
       "                                                                 ⎥\n",
       "33}⋅c₃                                                           ⎥\n",
       "                                                                 ⎥\n",
       "                        ⎛                                      2⎞⎥\n",
       "} + a_{23}⋅a_{33}) + c₃⋅⎝a_{13}⋅a_{31} + a_{23}⋅a_{32} + a_{33} ⎠⎦"
      ]
     },
     "execution_count": 203,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.Matrix([c, c*A, c*A**2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to compute the controllability matrix? <a class=\"anchor\" id=\"control\"></a>\n",
    "\n",
    "The controllability matrix reads\n",
    "\n",
    "\\begin{pmatrix}\n",
    "b, A\\cdot b, A^2 b\n",
    "\\end{pmatrix}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 204,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAACIAAABLCAMAAAAiYqViAAAAPFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo1xBWAAAAE3RSTlMA\nMquZdlQiEEDpMES7793NiWZspsOa8gAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAYxJREFUSA3tls12\nhCAMhQMB6dQ/LO//rk0QIhlhuulqzmShKB9JUG4ATMpm4Wbb2QNgEjoyfyPg4Pc2MTLde683vkXC\nsm5XV20pBGDH2nHdn5DUSUgjcwrX6NrSSOykAhrZrXP4HEshIe0BQv4EZqlxtBefU0kODOIVUnnB\nnYaGFOk6D5D8VeY88RGSDhqPOdoQmSnOytwwkKXe5fwFIy8BXcw+xl44QrGRl9pPdz+YtCATbsm6\n8qg+nSCq8UHeWWoRF6zyVn9apBapJlkWFZtCRGobIVK7GPl6fJ+8SG0jtUyJLmw/j4ZvpMb+SzIq\nEI8rUgPYumu3kRpEqXrKSyO1Qwg9ozM9vs5UQGZzPisvgpjde7/00hVkzbW/PPa9CMuND/LWUnNo\nX0sNaSfAuvWpxSBSQ1qXByksm0JEatzV99JKLaxldetV10jN7VVpGmmlNgjUSI1lX7Z9le45A9Y1\n5THlzOhVFwGuL8f6Umomumjr6anvpUbM9/9E/jz6BT7gOVeqX5tHPvo5B7+lKByNevF9DwAAAABJ\nRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}b_{1}\\\\b_{2}\\\\b_{3}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡b₁⎤\n",
       "⎢  ⎥\n",
       "⎢b₂⎥\n",
       "⎢  ⎥\n",
       "⎣b₃⎦"
      ]
     },
     "execution_count": 204,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b1, b2, b3 = sp.symbols('b_1, b_2, b_3')\n",
    "b = sp.Matrix([b1, b2, b3])\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Since $b$, $A \\cdot b$, $\\ldots$ are column vectors the construction is a little bit spooky:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 205,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nAYQAAAAASUVORK5CYII=\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}b_{1} & a_{11} b_{1} + a_{12} b_{2} + a_{13} b_{3} & b_{1} \\left(a_{11}^{2} + a_{12} a_{21} + a_{13} a_{31}\\right) + b_{2} \\left(a_{11} a_{12} + a_{12} a_{22} + a_{13} a_{32}\\right) + b_{3} \\left(a_{11} a_{13} + a_{12} a_{23} + a_{13} a_{33}\\right)\\\\b_{2} & a_{21} b_{1} + a_{22} b_{2} + a_{23} b_{3} & b_{1} \\left(a_{11} a_{21} + a_{21} a_{22} + a_{23} a_{31}\\right) + b_{2} \\left(a_{12} a_{21} + a_{22}^{2} + a_{23} a_{32}\\right) + b_{3} \\left(a_{13} a_{21} + a_{22} a_{23} + a_{23} a_{33}\\right)\\\\b_{3} & a_{31} b_{1} + a_{32} b_{2} + a_{33} b_{3} & b_{1} \\left(a_{11} a_{31} + a_{21} a_{32} + a_{31} a_{33}\\right) + b_{2} \\left(a_{12} a_{31} + a_{22} a_{32} + a_{32} a_{33}\\right) + b_{3} \\left(a_{13} a_{31} + a_{23} a_{32} + a_{33}^{2}\\right)\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡                                          ⎛      2                           \n",
       "⎢b₁  a_{11}⋅b₁ + a_{12}⋅b₂ + a_{13}⋅b₃  b₁⋅⎝a_{11}  + a_{12}⋅a_{21} + a_{13}⋅a\n",
       "⎢                                                                             \n",
       "⎢                                                                             \n",
       "⎢b₂  a_{21}⋅b₁ + a_{22}⋅b₂ + a_{23}⋅b₃  b₁⋅(a_{11}⋅a_{21} + a_{21}⋅a_{22} + a_\n",
       "⎢                                                                             \n",
       "⎢                                                                             \n",
       "⎣b₃  a_{31}⋅b₁ + a_{32}⋅b₂ + a_{33}⋅b₃  b₁⋅(a_{11}⋅a_{31} + a_{21}⋅a_{32} + a_\n",
       "\n",
       "     ⎞                                                                        \n",
       "_{31}⎠ + b₂⋅(a_{11}⋅a_{12} + a_{12}⋅a_{22} + a_{13}⋅a_{32}) + b₃⋅(a_{11}⋅a_{13\n",
       "                                                                              \n",
       "                  ⎛                      2                ⎞                   \n",
       "{23}⋅a_{31}) + b₂⋅⎝a_{12}⋅a_{21} + a_{22}  + a_{23}⋅a_{32}⎠ + b₃⋅(a_{13}⋅a_{21\n",
       "                                                                              \n",
       "                                                                       ⎛      \n",
       "{31}⋅a_{33}) + b₂⋅(a_{12}⋅a_{31} + a_{22}⋅a_{32} + a_{32}⋅a_{33}) + b₃⋅⎝a_{13}\n",
       "\n",
       "                                  ⎤\n",
       "} + a_{12}⋅a_{23} + a_{13}⋅a_{33})⎥\n",
       "                                  ⎥\n",
       "                                  ⎥\n",
       "} + a_{22}⋅a_{23} + a_{23}⋅a_{33})⎥\n",
       "                                  ⎥\n",
       "                                2⎞⎥\n",
       "⋅a_{31} + a_{23}⋅a_{32} + a_{33} ⎠⎦"
      ]
     },
     "execution_count": 205,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.Matrix([b.T, (A*b).T, (A**2*b).T]).T"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Export"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to create a callable function from an expression? <a class=\"anchor\" id=\"callable\"></a>\n",
    "\n",
    "This is interesting when having done all the symbolic calculations and one wants to to some numerical simulations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 206,
   "metadata": {},
   "outputs": [],
   "source": [
    "a1, a2, b1, b2 = sp.symbols('a1, a2, b1, b2')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 207,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJEAAAARBAMAAAAvRlPIAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIpmJdu8QRM1mu90y\nVKvMIHo8AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABp0lEQVQ4EY2SMUvDQBiG3xpMam1N8Ado0SJi\nEeumuAQVXJwFcbAIiriki5NDpYNkkBL8BUVwV1DctDiJix2cFOnSoW6KUnWo9XL5krtAoL0lb773\nuaeXo0DvSz07j4D3NiKG3UbxdBRRihp2mek1GXiil7Y87DEX8zJIJq0lD3vMCyGOTEpwebHxzJpH\niBTaIcbl5WmpIVO8sUgfvW/E34EHhvCkTE1ItBsDQP3JW4boyWQdqR9IVgB1HX0V3GX9NItm2CSA\nVAu6KXoy1fP4So6xT+xrYdAEDvx0gUeDqXZtdx2zJAGHsHLUz9n2lW2XWT8J9RMaM/VXYFW5yUvX\nGC1AXt7Y/Sn2dyrWRE9nKkFrc5OVQ51tZCAlsOPKSwC6gxnW+T2Zft1Tu2eyamimDG7yEi5ljwzo\nBXZnCHoyfWPb4aaEOXCj8DNRUtJhkwCGnATrgp5MbzgFN6mN1ZEVbqJ0EhZBAjLzrAt6Mm0tOZ6J\n9rF78paW06p+lp8+IHoycci9J1ovfrh/fc77WX76gOh3pDoVmIZvGzTf7HQkIogBENnHsn/mPzjK\nioo5xBc8AAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$a_{1} a_{2} - a_{1} b_{2} + b_{1}$$"
      ],
      "text/plain": [
       "a₁⋅a₂ - a₁⋅b₂ + b₁"
      ]
     },
     "execution_count": 207,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = a1*a2 + b1 - b2*a1\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 208,
   "metadata": {},
   "outputs": [],
   "source": [
    "args = (a1, a2, b1, b2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 209,
   "metadata": {},
   "outputs": [],
   "source": [
    "a_fnc = sp.lambdify(args, a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 210,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAPBAMAAAArJJMAAAAAIVBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAADdcGRXAAAACnRSTlMAVO8Qq4lmdpnNpXqjvAAAAAlwSFlzAAAOxAAA\nDsQBlSsOGwAAACBJREFUCB1jYAADRmUGBpOQxUA2GykEO1Axh9PKNrAZAEESCWTnoGnkAAAAAElF\nTkSuQmCC\n",
      "text/latex": [
       "$$1$$"
      ],
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 210,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res = a_fnc(1, 0, 3, 2) # 1*0 - 1*2 + 3 = 1\n",
    "res"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to export an expression to C-code? <a class=\"anchor\" id=\"ccode\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 211,
   "metadata": {},
   "outputs": [],
   "source": [
    "a1, a2, b1, b2 = sp.symbols('a1, a2, b1, b2')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 212,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAJEAAAARBAMAAAAvRlPIAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIpmJdu8QRM1mu90y\nVKvMIHo8AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABp0lEQVQ4EY2SMUvDQBiG3xpMam1N8Ado0SJi\nEeumuAQVXJwFcbAIiriki5NDpYNkkBL8BUVwV1DctDiJix2cFOnSoW6KUnWo9XL5krtAoL0lb773\nuaeXo0DvSz07j4D3NiKG3UbxdBRRihp2mek1GXiil7Y87DEX8zJIJq0lD3vMCyGOTEpwebHxzJpH\niBTaIcbl5WmpIVO8sUgfvW/E34EHhvCkTE1ItBsDQP3JW4boyWQdqR9IVgB1HX0V3GX9NItm2CSA\nVAu6KXoy1fP4So6xT+xrYdAEDvx0gUeDqXZtdx2zJAGHsHLUz9n2lW2XWT8J9RMaM/VXYFW5yUvX\nGC1AXt7Y/Sn2dyrWRE9nKkFrc5OVQ51tZCAlsOPKSwC6gxnW+T2Zft1Tu2eyamimDG7yEi5ljwzo\nBXZnCHoyfWPb4aaEOXCj8DNRUtJhkwCGnATrgp5MbzgFN6mN1ZEVbqJ0EhZBAjLzrAt6Mm0tOZ6J\n9rF78paW06p+lp8+IHoycci9J1ovfrh/fc77WX76gOh3pDoVmIZvGzTf7HQkIogBENnHsn/mPzjK\nioo5xBc8AAAAAElFTkSuQmCC\n",
      "text/latex": [
       "$$a_{1} a_{2} - a_{1} b_{2} + b_{1}$$"
      ],
      "text/plain": [
       "a₁⋅a₂ - a₁⋅b₂ + b₁"
      ]
     },
     "execution_count": 212,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = a1*a2 + b1 - b2*a1\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 213,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'a1*a2 - a1*b2 + b1'"
      ]
     },
     "execution_count": 213,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.ccode(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 214,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAFsAAAAyBAMAAADB47o4AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMA74lUIhAymXZEzWa7\n3asHaVBoAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACFElEQVRIDe2Wvy9DURTHv9q+J0VF4seCsFkl\nrKKJik1qsogaJBaDWIgQZfBjw2CTSESM/AOSLsJoNGFsWERb0Ug899d75/ao5L3dWe6953ze6b23\nL5889HnvCBcxz2tDe2Y8HA0nM9aGrpCwxNww+Eyv3zEUjotoeCkSnqxEwmP3DE8sr3b6qWCcGNjK\nqkVTcXdQZ81RD9NNb8BiQMpJsgOXwMBtFrlzpwy3IHIad7rRWMDChkhQTF1hHbF06ylGs/h0V+SO\nNN5YQSoPnBArZptZPCCVdstYg/OOJOENBeTmON4D5wOpg0RVXHuyZOO5foyKfjXdRcO4OA/iFXxB\n/LzVPTeIl3ia4SW0ng5D7rIKcQ4Lb8k3P8ZYd9zh+rlfXA3wiltxUbR3p7gzuc/x2b354gGal4Dp\n7asaXGxRRs3edQpHONYzq7spjZjRGtyzoRu9jNNmdGLiqWiBetrgeW9qltj4zvt/0y/qr4R5Z/4q\n8/w/zm/EX5ubIfH4BTOygn+RgXgYTkZSBR8PxMPx2oLBSTwMZwWDk3gYzgoGJ/EwnBUMrsQjDcSD\njKQqBpfiUQbiOBnJxqV4lIE4TkaycSkeZSCOk5FsXIlHGogHGcnGlXiUJxlPRrJxJR5pIB5kJBtX\n4pEG4kFGsnE1DwzEn1FG4jgZiOPKSBwPDMRpbSSOc6re2rwE9Ur1ctHxiB8o0T5/fgCHPaA9xEVW\nuQAAAABJRU5ErkJggg==\n",
      "text/latex": [
       "$$\\left[\\begin{matrix}a_{1} & a_{2} b_{1}\\\\b_{2} & b_{1}\\end{matrix}\\right]$$"
      ],
      "text/plain": [
       "⎡a₁  a₂⋅b₁⎤\n",
       "⎢         ⎥\n",
       "⎣b₂   b₁  ⎦"
      ]
     },
     "execution_count": 214,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = sp.Matrix([[a1, a2*b1],[b2, b1]])\n",
    "A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For expressions with matrices, one has to provide a matrix symbol to assign values to. Hence, the following statement fails:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 215,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'// Not supported in C:\\n// ImmutableDenseMatrix\\nMatrix([\\n[a1, a2*b1],\\n[b2,    b1]])'"
      ]
     },
     "execution_count": 215,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.ccode(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Instead, one has to proceed as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 216,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAOBAMAAADUAYG5AAAALVBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMAZquZu0TvMnYiEN1UzbeU\nUHkAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABvSURBVAgdY2BgEHqnbOQSwAAEKQwMzM+BNPtDBgbW\nx0AGx0sGBsYXQAZLAgPDsl1ABp8CA/umBUBGnaKE9wEgzdA3gYErCcRwA3EOAIlHIEYDxBgGPaDJ\nIGPYnwBFeRMYGMK8GBiY7j0yVvFhYAAAty4XsUrydikAAAAASUVORK5CYII=\n",
      "text/latex": [
       "$$B$$"
      ],
      "text/plain": [
       "B"
      ]
     },
     "execution_count": 216,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "AC = sp.MatrixSymbol('B', 2, 2)\n",
    "AC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 219,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'B[0] = a1;\\nB[1] = a2*b1;\\nB[2] = b2;\\nB[3] = b1;'"
      ]
     },
     "execution_count": 219,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.ccode(A, AC)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
