{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sympy import *\n",
    "init_printing()\n",
    "x, y, z = symbols('x,y,z')\n",
    "r, theta = symbols('r,theta', positive=True)\n",
    "\n",
    "%load_ext exercise"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Matrices\n",
    "\n",
    "The SymPy `Matrix` object helps us with small problems in linear algebra."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot = Matrix([[r*cos(theta), -r*sin(theta)],\n",
    "              [r*sin(theta),  r*cos(theta)]])\n",
    "rot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Standard methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot.det()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot.inv()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot.singular_values()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "Find the inverse of the following Matrix:\n",
    "\n",
    "$$ \\left[\\begin{matrix}1 & x\\\\y & 1\\end{matrix}\\right] $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Create a matrix and use the `inv` method to find the inverse\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Operators\n",
    "\n",
    "The standard SymPy operators work on matrices."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot * 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "v = Matrix([[x], [y]])\n",
    "v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot * v"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "In the last exercise you found the inverse of the following matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "M = Matrix([[1, x], [y, 1]])\n",
    "M"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "M.inv()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now verify that this is the true inverse by multiplying the matrix times its inverse.  Do you get the identity matrix back?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Multiply `M` by its inverse.  Do you get back the identity matrix?\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "What are the eigenvectors and eigenvalues of `M`?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Find the methods to compute eigenvectors and eigenvalues. Use these methods on `M`\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### NumPy-like Item access"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot[0, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot[:, 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot[1, :]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Mutation\n",
    "\n",
    "We can change elements in the matrix."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot[0, 0] += 1\n",
    "rot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "simplify(rot.det())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rot.singular_values()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Matrix Constructors\n",
    "\n",
    "Matrix Constructors can be used for making special types of Matrices quickly and efficiently. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "eye(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "diag(1, 2, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "ones(3, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "zeros(3, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "diag(eye(2), 1) # eye(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use the matrix constructors to construct the following matrices.  There may be more than one correct answer."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\\left[\\begin{array}{ccc}4 & 0 & 0\\\\\\\\ \n",
    "0 & 4 & 0\\\\\\\\ \n",
    "0 & 0 & 4\\end{array}\\right]$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %exercise exercise_matrix1.py\n",
    "def matrix1():\n",
    "    \"\"\"\n",
    "    >>> matrix1()\n",
    "    [4, 0, 0]\n",
    "    [0, 4, 0]\n",
    "    [0, 0, 4]\n",
    "    \"\"\"\n",
    "    return diag(eye(2)*4, 4)\n",
    "matrix1()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\\left[\\begin{array}{}1 & 1 & 1 & 0\\\\\\\\1 & 1 & 1 & 0\\\\\\\\0 & 0 & 0 & 1\\end{array}\\right]$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %exercise exercise_matrix2.py\n",
    "def matrix2():\n",
    "    \"\"\"\n",
    "    >>> matrix2()\n",
    "    [1, 1, 1, 0]\n",
    "    [1, 1, 1, 0]\n",
    "    [0, 0, 0, 1]\n",
    "    \"\"\"\n",
    "    return ???\n",
    "matrix2()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$$\\left[\\begin{array}{}-1 & -1 & -1 & 0 & 0 & 0\\\\\\\\-1 & -1 & -1 & 0 & 0 & 0\\\\\\\\-1 & -1 & -1 & 0 & 0 & 0\\\\\\\\0 & 0 & 0 & 0 & 0 & 0\\\\\\\\0 & 0 & 0 & 0 & 0 & 0\\\\\\\\0 & 0 & 0 & 0 & 0 & 0\\end{array}\\right]$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %exercise exercise_matrix3.py\n",
    "def matrix3():\n",
    "    \"\"\"\n",
    "    >>> matrix3()\n",
    "    [-1, -1, -1, 0, 0, 0]\n",
    "    [-1, -1, -1, 0, 0, 0]\n",
    "    [-1, -1, -1, 0, 0, 0]\n",
    "    [ 0,  0,  0, 0, 0, 0]\n",
    "    [ 0,  0,  0, 0, 0, 0]\n",
    "    [ 0,  0,  0, 0, 0, 0]\n",
    "    \"\"\"\n",
    "    return ???\n",
    "matrix3()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "Play around with your matrix `M`, manipulating elements in a NumPy like way.  Then try the various methods that we've talked about (or others).  See what sort of answers you get."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Play with matrices\n"
   ]
  }
 ],
 "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.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}