{ "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 }