{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "> This is one of the 100 recipes of the [IPython Cookbook](http://ipython-books.github.io/), the definitive guide to high-performance scientific computing and data science in Python.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 15.1. Diving into symbolic computing with SymPy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "SymPy is a pure Python package for symbolic mathematics." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, we import SymPy, and enable rich display LaTeX-based printing in the IPython notebook (using the MathJax Javascript library)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from sympy import *\n", "init_printing()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With NumPy and the other packages we have been using so far, we were dealing with numbers and numerical arrays. With SymPy, we deal with symbolic variables. It's a radically different shift of paradigm, which mathematicians may be more familiar with." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To deal with symbolic variables, we need to declare them." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "var('x y')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The var function creates symbols and injects them into the namespace. This function should only be used in interactive mode. In a Python module, it is better to use the symbol function which returns the symbols." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x, y = symbols('x y')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can create mathematical expressions with these symbols." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "expr1 = (x + 1)**2\n", "expr2 = x**2 + 2*x + 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Are these expressions equal?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "expr1 == expr2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These expressions are mathematically equal, but not syntactically identical. To test whether they are equal, we can ask SymPy to simplify the difference algebraically." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "simplify(expr1-expr2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A very common operation with symbolic expressions is substitution of a symbol by another symbol, expression, or a number." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "expr1.subs(x, expr1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "expr1.subs(x, pi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A rational number cannot be written simply as \"1/2\" as this Python expression evaluates to 0. A possibility is to use a SymPy object for 1, for example using the function S." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "expr1.subs(x, S(1)/2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Exactly-represented numbers can be evaluated numerically with evalf:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "_.evalf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can transform this *symbolic* function into an actual Python function that can be evaluated on NumPy arrays, using the `lambdify` function." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "f = lambdify(x, expr1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n", "f(np.linspace(-2., 2., 5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> You'll find all the explanations, figures, references, and much more in the book (to be released later this summer).\n", "\n", "> [IPython Cookbook](http://ipython-books.github.io/), by [Cyrille Rossant](http://cyrille.rossant.net), Packt Publishing, 2014 (500 pages)." ] } ], "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.4.2" } }, "nbformat": 4, "nbformat_minor": 0 }