{ "cells": [ { "cell_type": "raw", "metadata": {}, "source": [ "---\n", "title: Sympy\n", "file_title: Sympy\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`SymPy` is a symbolic mathematics library built on the Python programming language.\n", "\n", "In this post we'll look at how to use some of the basic functions of the library." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import sympy as sy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The equation that we want to solve is in the form of\n", "\\begin{equation}\n", "a x^2 + bx + c = 0\n", "\\end{equation}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Solving Algebraic Roots\n", "Let's solve for the roots of the quadratic equation. First we have to define the relevant variables as sympy symbols. We can accomplish this in one line by using the `symbols` function, providing a list of variables, and setting them to the associated variables that we want to use. The order does matter [^1]." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "a, b, c, x = sy.symbols('a, b, c, x')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, let's define the quadratic equation as a `sympy` equation using the `Eq` function. Note that the equation is assumed to be equal to zero." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/travis/build/BrianChevalier/gitMechanics/.snakemake/conda/ee189a0b/lib/python3.6/site-packages/sympy/core/relational.py:470: SymPyDeprecationWarning: \n", "\n", "Eq(expr) with rhs default to 0 has been deprecated since SymPy 1.5.\n", "Use Eq(expr, 0) instead. See\n", "https://github.com/sympy/sympy/issues/16587 for more info.\n", "\n", " deprecated_since_version=\"1.5\"\n" ] } ], "source": [ "eq = sy.Eq(a*x**2 + b*x + c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's make sure that our equation looks right by printing it:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Eq(a*x**2 + b*x + c, 0)\n" ] } ], "source": [ "print(eq)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is pretty ugly. Luckily, we can print a much better version using tools built into `sympy`." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle a x^{2} + b x + c = 0$" ], "text/plain": [ " 2 \n", "a⋅x + b⋅x + c = 0" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sy.init_printing(use_latex='mathjax')\n", "eq" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can even print out the $\\LaTeX{}$ used to display the equation we can be copied and pated into $\\LaTeX{}$ documents." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a x^{2} + b x + c = 0\n" ] } ], "source": [ "sy.print_latex(eq)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, let's go ahead and solve the equation for $x$. All we need to do is call the `sympy.solve` function with the equation and the variable we want to find." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\left[ \\frac{- b + \\sqrt{- 4 a c + b^{2}}}{2 a}, \\ - \\frac{b + \\sqrt{- 4 a c + b^{2}}}{2 a}\\right]$" ], "text/plain": [ "⎡ _____________ ⎛ _____________⎞ ⎤\n", "⎢ ╱ 2 ⎜ ╱ 2 ⎟ ⎥\n", "⎢-b + ╲╱ -4⋅a⋅c + b -⎝b + ╲╱ -4⋅a⋅c + b ⎠ ⎥\n", "⎢─────────────────────, ────────────────────────⎥\n", "⎣ 2⋅a 2⋅a ⎦" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "solutions = sy.solve(eq, x)\n", "solutions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function returned a list of solutions. The quadratic equation has two roots (which should come as no suprise). Using typical python syntax we can extract the first solution:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\frac{- b + \\sqrt{- 4 a c + b^{2}}}{2 a}$" ], "text/plain": [ " _____________\n", " ╱ 2 \n", "-b + ╲╱ -4⋅a⋅c + b \n", "─────────────────────\n", " 2⋅a " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "solutions[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can even substitute in values for the constant coefficients using the `subs` method on the first solution:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle -1 + \\sqrt{2}$" ], "text/plain": [ "-1 + √2" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "solutions[0].subs({a:1,b:2,c:-1})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Conclusion\n", "`SymPy` is a great stand-alone symbolic computing library. It has many features, and its integrations with Jupyter notebooks makes it great for interactive computational mathematics. Because Python is a free, open source langauge it can be extended for uses such as symbolic computations and retain the rich programming features that are built into the core of the language." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[^1]: NOTE: The list on the right side of the assignment does not have to match the left. I could have assigned `a` to be equal to the variable `x`, but this would be very confusing and bad practice. Don't do that!" ] } ], "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.10" }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }