{
 "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')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Solveset\n",
    "\n",
    "Equation solving is both a common need also a common building block for more complicated symbolic algorithms.  \n",
    "\n",
    "Here we introduce the `solveset` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "solveset(x**2 - 4, x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solveset takes two arguments and one optional argument specifying the domain, an equation like $x^2 - 4$ and a variable on which we want to solve, like $x$ and an optional argument domain specifying the region in which we want to solve.\n",
    "\n",
    "Solveset returns the values of the variable, $x$, for which the equation, $x^2 - 4$ equals 0."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "What would the following code produce?  Are you sure?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "solveset(x**2 - 4 == 0, x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Infinite Solutions\n",
    "\n",
    "One of the major improvements of `solveset` over `solve` is that it also supports infinite solution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "solveset(sin(x), x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Domain argument"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "solveset(exp(x) - 1, x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`solveset` by default solves everything in the complex domain. In complex domain $exp(x) == cos(x) + i\\ sin(x)$ and solution is basically equal to solution to $cos(x) == 1$. If you want only real solution, you can specify the domain as `S.Reals`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "solveset(exp(x) - 1, x, domain=S.Reals)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Condition Set\n",
    "\n",
    "`solveset` isn't always able to solve a given equation, such cases it returns a `ConditionSet` object. `ConditionSet` represents a set satisfying a given condition."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "solveset(exp(x) + cos(x) + 1, x, domain=S.Reals)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`solveset` aims to return all the solutions of the equation. In cases where it able to find some solution but not all it returns a union of the known solutions and `ConditionSet`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "solveset((x - 1)*(exp(x) + cos(x) + 1), x, domain=S.Reals)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Symbolic use of `solveset`\n",
    "\n",
    "Results of `solveset` don't need to be numeric, like `{-2, 2}`.  We can use solveset to perform algebraic manipulations.  For example if we know a simple equation for the area of a square\n",
    "\n",
    "    area = height * width\n",
    "    \n",
    "we can solve this equation for any of the variables.  For example how would we solve this system for the `height`, given the `area` and `width`?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "height, width, area = symbols('height, width, area')\n",
    "solveset(area - height*width, height)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that we would have liked to have written\n",
    "\n",
    "    solveset(area == height * width, height)\n",
    "    \n",
    "But the `==` gotcha bites us.  Instead we remember that `solveset` expects an expression that is equal to zero, so we rewrite the equation\n",
    "\n",
    "    area = height * width\n",
    "    \n",
    "into the equation\n",
    "\n",
    "    0 = height * width - area\n",
    "    \n",
    "and that is what we give to solveset."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "Compute the radius of a sphere, given the volume.  Reminder, the volume of a sphere of radius `r` is given by\n",
    "\n",
    "$$ V = \\frac{4}{3}\\pi r^3 $$\n",
    "\n",
    "Assume r, V to be positive and domain to be Real."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%load_ext exercise"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use either the * ``%exercise`` * or * ``%load`` * magic to get the exercise / solution respecitvely (*i.e.* delete the whole contents of the cell except for the uncommented magic command). Replace **???** with the correct expression."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %load exercise_volume.py\n",
    "r, V = symbols(???)\n",
    "solveset(???)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Substitution\n",
    "\n",
    "We often want to substitute in one expression for another.  For this we use the subs method"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Replace x with y\n",
    "(x**2).subs({x: y})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "Subsitute $x$ for $sin(x)$ in the equation $x^2 + 2\\cdot x + 1$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Replace x with sin(x)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Subs + Solveset\n",
    "\n",
    "We can use subs and solveset together to plug the solution of one equation into another"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Solve for the height of a rectangle given area and width\n",
    "soln = list(solveset(area - height*width, height))[0]\n",
    "soln"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Define perimeter of rectangle in terms of height and width\n",
    "perimeter = 2*(height + width)\n",
    "perimeter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Substitute the solution for height into the expression for perimeter\n",
    "perimeter.subs({height: soln})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "In the last section you solved for the radius of a sphere given its volume"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "V, r = symbols('V, r', real=True)\n",
    "4*pi/3 * r**3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "r_v = list(solveset(V - 4*pi/3 * r**3, r))[0]\n",
    "r_v"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now lets compute the surface area of a sphere in terms of the volume.  Recall that the surface area of a sphere is given by\n",
    "\n",
    "$$ 4 \\pi r^2 $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %load exercise_surface.py\n",
    "(4*pi*r**2).subs(???)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Does the expression look right?  How would you expect the surface area to scale with respect to the volume?  What is the exponent on $V$?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plotting\n",
    "\n",
    "SymPy can plot expressions easily using the `plot` function.  By default this links against matplotlib."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "plot(x**2, (x, -100, 100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "In the last exercise you derived a relationship between the volume of a sphere and the surface area.  Plot this relationship using `plot`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %load exercise_plot_surface.py\n",
    "plot(???)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Low dependencies\n",
    "\n",
    "You may know that SymPy tries to be a very low-dependency project.  Our user base is very broad.  Some entertaining aspects result.  For example, `textplot`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "textplot(x**2, -3, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise\n",
    "\n",
    "Play with `textplot` and enjoy :)"
   ]
  }
 ],
 "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
}