{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "This is a brief introduction to sympy, a symbolic computer algebra system written in Python, based on the excellent tutorial, \"Taming math and physics using SymPy,\" by Ivan Savov. The tutorial can be found at https://minireference.com/static/tutorials/sympy_tutorial.pdf\n", "\n", "You should be viewing this notebook in browser connected to a Jupyter backend. This can be launched by opening a Terminal window and typing 'jupyter notebook' at the Unix shell prompt.\n", "\n", "The first step is to load (import) the sympy package. We'll also import some plotting functions. To execute a command line in jupyter, press Shift+Enter." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sympy import *\n", "from sympy.plotting import (plot, plot_parametric,plot3d_parametric_surface, plot3d_parametric_line,plot3d)\n", "init_printing()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here's some simple arithmetic and defining some symbols using the symbols() command. We'll then define some simple expressions to simplify, factor, expand, and solve. Finally, we'll substitute values into an expression, and show the builtins, pi and E." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 3 # an integer" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "a" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 3.0 # a float\n", "a # combine definition of a and output a" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t,u,v,w,x,y,z = symbols('t u v w x y z') # define t-z as symbols" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "expr = 2*x +3*x - sin(x)-4*x+9 # define an expression to be simplified" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "simplify(expr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "factor(x**2 - 2*x -8)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "expand((x-4)*(x+2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "solve(x**2 + 2*x - 8, x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a, b, c = symbols('a b c') # define some more symbols" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "solve(a*x**2 + b*x + c, x) # Solve quadratic equation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gen_soln = solve(a*x**2 + b*x + c, x) # store general solution above to gen_soln" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "[ gen_soln[0].subs({'a':1,'b':2,'c':-8}),\n", " gen_soln[1].subs({'a':1,'b':2,'c':-8}) ] # plug in values for a,b,c to general solution using subs()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r = 4.2 # define a radius\n", "a = pi*r**2 # define an area\n", "a # print the area" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = pi.evalf() * r**2 # evaluate pi\n", "a # print value of a" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b = a*E # constant E\n", "b" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b = a*E.evalf()\n", "b # value of b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course, sympy is well aware of trig functions and complex numbers." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sin(pi/6)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cos(pi/6)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tan(pi/6)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "atan(sqrt(3)/3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sin(x) == cos(x - pi/2) # test for identity" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "e = 2*sin(x)**2 + 2*cos(x)**2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "trigsimp(e)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "expand_trig(sin(2*x)) # use expand_trig() to expand trig functions; regular expand() won't touch trig" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "simplify((exp(x)+exp(-x))/2) # cosh" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "simplify((exp(x)-exp(-x))/2) # sinh" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "solve(x**2 + 1,x) # complex solutions" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "z = 4 + 3*I # define complex number" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print (\"Real = %d, Imaginary = %d\" % (re(z), im(z))) # use python's print function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = symbols('x', real=True) # define symbol x to be real" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print (\"Real = %s, Imaginary = %s\" % (re(exp(I*x)), im(exp(I*x))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Handling limits is a snap. The two letters 'o' together as 'oo' represents infinity in sympy." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "limit((1+1/x)**x,x,oo)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "limit(1/x, x, 0, dir=\"+\") # 1/x to zero from positive" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "limit(1/x, x, 0, dir='-') # 1/x to zero from negative" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "SymPy has a very powerful engine for calculus and differential equations. Notice that the output above is ASCII text. Let's make the following output prettier by calling init_printing()." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "init_printing()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "expr = 1 + sqrt(2/x) + sin(x/y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "expr" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "diff(x**3,x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "diff(x**2*sin(x),x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "diff(x**3, x, 2) # second derivative, same as diff(diff(x**3,x),x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f = symbols('f',cls=Function)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dsolve(f(x) - diff(f(x),x), f(x))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "integrate(x**3,x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "integrate(sin(x),x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "integrate(x**3,(x,0,2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f = x**2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "F = integrate(f,x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "F" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "diff(F,x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "SymPy can handle sequences too, and makes use of python's [item list] syntax." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "k,m,n = symbols('k m n', integer=True) # define some integer symbols" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a_n = 1/n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b_n = 1/factorial(n)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a_n.subs({n:5})" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "[ a_n.subs({n:i}) for i in range(0,8)] # make a list of 1/n for n = 0 .. 8" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "[ b_n.subs({n:i}) for i in range(0,8)] # make a list of 1/n! for n = 0 .. 8" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "limit(a_n, n, oo) # limit of 1/n as n->oo" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "summation(a_n, [n, 1, oo]) # summation 1/n, n=1 .. oo" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "summation(b_n, [n, 0, oo]) # summation 1/n!, n=0 .. oo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like any programming language, SymPy can handle matrices quite well." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A = Matrix([[2,-3,-8,7],\n", " [-2,-1,2,-7],\n", " [1,0,-3,6]])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A[0,1] # row 0, col 1 of A" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A[0:2,0:3] # top left of A" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "eye(2) # 2x2 identity matrix" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "zeros(2) # 2x2 zero matrix" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A.transpose() # transpose of A" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M = eye(3) # M = 3x3 identity matrix" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M[1,:] = M[1,:] + 3*M[0,:] # add 3*first row to second row" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M.det() # determinant" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M.inv() # inverse" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M.inv() * M # identity" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "M.inv() * M == eye(3) # should be true" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A = Matrix([[9,-2],\n", " [-2,6]])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A.eigenvals() # eigenvalues of A" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A.eigenvects() # eigenvectors of A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now for some plotting. SymPy has several plotting routines, and we've loaded some of those at the top of this notebook. The examples below are based on shows from github user jrioux at https://github.com/sympy/sympy/blob/master/examples/beginner/plot_examples.py\n", "The SymPy plotting docs are a good bookmark - http://docs.sympy.org/latest/modules/plotting.html\n", "\n", "First, we setup matplotlib for interactive graphics." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib notebook" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f = x**3-2*x**2+x" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = plot(f,(x,-4,4)) # plot the function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b = plot(diff(f,x),(x,-4,4)) # plot the derivative" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c = plot(diff(f,x,2),(x,-4,4)) # plot the second derivative\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a.extend(b) # combine b plot into a plot\n", "a.extend(c) # combine c into a\n", "a.show() # display a" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot3d(sin(2*x)*cos(3*y)*exp(x+y), (x, 0, 2), (y, 0, 2)) # 3D plot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plot3d_parametric_surface(cos(u)*v, sin(u)*v, u, (u, 0, 10), (v, -2, 2)) # 3D parametric plot" ] } ], "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.5.2" } }, "nbformat": 4, "nbformat_minor": 2 }