├── environment.yml ├── notebooks ├── README.txt ├── qubits.ipynb ├── fidelity.ipynb ├── trace.ipynb ├── IntegrationOverPolytopes.ipynb └── sho1d_example.ipynb ├── beginner ├── basic.py ├── expansion.py ├── plotting_nice_plot.py ├── functions.py ├── precision.py ├── series.py ├── differentiation.py ├── substitution.py ├── limits_examples.py ├── print_pretty.py ├── plot_gallery.ipynb ├── plot_examples.py ├── plot_discont.ipynb ├── plot_advanced.ipynb ├── plot_colors.ipynb └── plot_intro.ipynb ├── intermediate ├── print_gtk.py ├── differential_equations.py ├── trees.py ├── mplot2d.py ├── mplot3d.py ├── partial_differential_eqs.py ├── infinite_1d_box.py ├── sample.py ├── coupled_cluster.py └── vandermonde.py ├── README.md ├── advanced ├── hydrogen.py ├── dense_coding_example.py ├── grover_example.py ├── autowrap_ufuncify.py ├── pidigits.py ├── qft.py ├── curvilinear_coordinates.py ├── gibbs_phenomenon.py ├── relativity.py ├── identitysearch_example.ipynb ├── fem.py ├── pyglet_plotting.py └── autowrap_integrators.py ├── .gitignore ├── LICENSE └── styles └── sympy.css /environment.yml: -------------------------------------------------------------------------------- 1 | name: sympy-notebooks 2 | channels: 3 | - default 4 | dependencies: 5 | - python>=3.6 6 | - sympy>=1.3 7 | - matplotlib>=3 8 | - numpy 9 | - jupyter 10 | -------------------------------------------------------------------------------- /notebooks/README.txt: -------------------------------------------------------------------------------- 1 | This directory contains `IPython`_ Notebooks. To open them, run ``ipython 2 | notebook`` in this directory. This command will start IPython `notebook`_ 3 | server, and let your default browser connect to it. 4 | 5 | 6 | .. _ipython: https://ipython.org/ 7 | .. _notebook: https://ipython.org/notebook.html 8 | -------------------------------------------------------------------------------- /beginner/basic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Basic example 4 | 5 | Demonstrates how to create symbols and print some algebra operations. 6 | """ 7 | 8 | from sympy import Symbol, pprint 9 | 10 | 11 | def main(): 12 | a = Symbol('a') 13 | b = Symbol('b') 14 | c = Symbol('c') 15 | e = ( a*b*b + 2*b*a*b )**c 16 | 17 | print('') 18 | pprint(e) 19 | print('') 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /beginner/expansion.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Expansion Example 4 | 5 | Demonstrates how to expand expressions. 6 | """ 7 | 8 | from sympy import pprint, Symbol 9 | 10 | def main(): 11 | a = Symbol('a') 12 | b = Symbol('b') 13 | e = (a + b)**5 14 | 15 | print("\nExpression:") 16 | pprint(e) 17 | print('\nExpansion of the above expression:') 18 | pprint(e.expand()) 19 | print() 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /intermediate/print_gtk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """print_gtk example 4 | 5 | Demonstrates printing with gtkmathview using mathml 6 | """ 7 | 8 | from sympy import Integral, Limit, print_gtk, sin, Symbol 9 | 10 | 11 | def main(): 12 | x = Symbol('x') 13 | 14 | example_limit = Limit(sin(x)/x, x, 0) 15 | print_gtk(example_limit) 16 | 17 | example_integral = Integral(x, (x, 0, 1)) 18 | print_gtk(example_integral) 19 | 20 | if __name__ == "__main__": 21 | main() 22 | -------------------------------------------------------------------------------- /beginner/plotting_nice_plot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Plotting example 4 | 5 | Demonstrates simple plotting. 6 | """ 7 | 8 | from sympy import Symbol, cos, sin, log, tan 9 | from sympy.plotting import PygletPlot 10 | from sympy.abc import x, y 11 | 12 | 13 | def main(): 14 | fun1 = cos(x)*sin(y) 15 | fun2 = sin(x)*sin(y) 16 | fun3 = cos(y) + log(tan(y/2)) + 0.2*x 17 | 18 | PygletPlot(fun1, fun2, fun3, [x, -0.00, 12.4, 40], [y, 0.1, 2, 40]) 19 | 20 | if __name__ == "__main__": 21 | main() 22 | -------------------------------------------------------------------------------- /beginner/functions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Functions example 4 | 5 | Demonstrates functions defined in SymPy. 6 | """ 7 | 8 | from sympy import pprint, Symbol, log, exp 9 | 10 | def main(): 11 | a = Symbol('a') 12 | b = Symbol('b') 13 | e = log((a + b)**5) 14 | print() 15 | pprint(e) 16 | print('\n') 17 | 18 | e = exp(e) 19 | pprint(e) 20 | print('\n') 21 | 22 | e = log(exp((a + b)**5)) 23 | pprint(e) 24 | print() 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /beginner/precision.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Precision Example 4 | 5 | Demonstrates SymPy's arbitrary integer precision abilities 6 | """ 7 | 8 | import sympy 9 | from sympy import Mul, Pow, S 10 | 11 | 12 | def main(): 13 | x = Pow(2, 50, evaluate=False) 14 | y = Pow(10, -50, evaluate=False) 15 | # A large, unevaluated expression 16 | m = Mul(x, y, evaluate=False) 17 | # Evaluating the expression 18 | e = S(2)**50/S(10)**50 19 | print("{} == {}".format(m, e)) 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /beginner/series.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Series example 4 | 5 | Demonstrates series. 6 | """ 7 | 8 | from sympy import Symbol, cos, sin, pprint 9 | 10 | 11 | def main(): 12 | x = Symbol('x') 13 | 14 | e = 1/cos(x) 15 | print('') 16 | print("Series for sec(x):") 17 | print('') 18 | pprint(e.series(x, 0, 10)) 19 | print("\n") 20 | 21 | e = 1/sin(x) 22 | print("Series for csc(x):") 23 | print('') 24 | pprint(e.series(x, 0, 4)) 25 | print('') 26 | 27 | if __name__ == "__main__": 28 | main() 29 | -------------------------------------------------------------------------------- /intermediate/differential_equations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Differential equations example 4 | 5 | Demonstrates solving 1st and 2nd degree linear ordinary differential 6 | equations. 7 | """ 8 | 9 | from sympy import dsolve, Eq, Function, sin, Symbol 10 | 11 | 12 | def main(): 13 | x = Symbol("x") 14 | f = Function("f") 15 | 16 | eq = Eq(f(x).diff(x), f(x)) 17 | print("Solution for ", eq, " : ", dsolve(eq, f(x))) 18 | 19 | eq = Eq(f(x).diff(x, 2), -f(x)) 20 | print("Solution for ", eq, " : ", dsolve(eq, f(x))) 21 | 22 | eq = Eq(x**2*f(x).diff(x), -3*x*f(x) + sin(x)/x) 23 | print("Solution for ", eq, " : ", dsolve(eq, f(x))) 24 | 25 | 26 | if __name__ == "__main__": 27 | main() 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SymPy Notebooks 2 | 3 | This repository contains examples of using SymPy within Jupyter Notebooks. 4 | 5 | 6 | The examples are broken up into three categories based on difficulty of 7 | both the mathematics and programming concepts. They roughly follow the 8 | following guide: 9 | 10 | beginner : 11 | Simple examples appropriate for first steps in using SymPy, for someone 12 | with little or no programming experience. 13 | 14 | ## Download and installation 15 | 16 | You can downloading the repository content with 17 | 18 | $ git clone git://github.com/sympy/sympy-notebooks.git 19 | 20 | You can install an Anaconda environment for using the content in 21 | the repository with 22 | 23 | conda env create -f environment.yml 24 | -------------------------------------------------------------------------------- /advanced/hydrogen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | This example shows how to work with the Hydrogen radial wavefunctions. 5 | """ 6 | 7 | from sympy import Eq, Integral, oo, pprint, symbols 8 | from sympy.physics.hydrogen import R_nl 9 | 10 | 11 | def main(): 12 | print("Hydrogen radial wavefunctions:") 13 | a, r = symbols("a r") 14 | print("R_{21}:") 15 | pprint(R_nl(2, 1, a, r)) 16 | print("R_{60}:") 17 | pprint(R_nl(6, 0, a, r)) 18 | 19 | print("Normalization:") 20 | i = Integral(R_nl(1, 0, 1, r)**2 * r**2, (r, 0, oo)) 21 | pprint(Eq(i, i.doit())) 22 | i = Integral(R_nl(2, 0, 1, r)**2 * r**2, (r, 0, oo)) 23 | pprint(Eq(i, i.doit())) 24 | i = Integral(R_nl(2, 1, 1, r)**2 * r**2, (r, 0, oo)) 25 | pprint(Eq(i, i.doit())) 26 | 27 | if __name__ == '__main__': 28 | main() 29 | -------------------------------------------------------------------------------- /beginner/differentiation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Differentiation example 4 | 5 | Demonstrates some differentiation operations. 6 | """ 7 | 8 | from sympy import pprint, Symbol 9 | 10 | def main(): 11 | a = Symbol('a') 12 | b = Symbol('b') 13 | e = (a + 2*b)**5 14 | 15 | print("\nExpression : ") 16 | print() 17 | pprint(e) 18 | print("\n\nDifferentiating w.r.t. a:") 19 | print() 20 | pprint(e.diff(a)) 21 | print("\n\nDifferentiating w.r.t. b:") 22 | print() 23 | pprint(e.diff(b)) 24 | print("\n\nSecond derivative of the above result w.r.t. a:") 25 | print() 26 | pprint(e.diff(b).diff(a, 2)) 27 | print("\n\nExpanding the above result:") 28 | print() 29 | pprint(e.expand().diff(b).diff(a, 2)) 30 | print() 31 | 32 | if __name__ == "__main__": 33 | main() 34 | -------------------------------------------------------------------------------- /intermediate/trees.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Calculates the Sloane's A000055 integer sequence, i.e. the "Number of 5 | trees with n unlabeled nodes." 6 | 7 | You can also google for "The On-Line Encyclopedia of Integer Sequences" 8 | and paste in the sequence returned by this script: 9 | 10 | 1, 1, 1, 1, 2, 3, 6, 11, 23, 47, 106 11 | 12 | and it will show you the A000055 13 | """ 14 | 15 | from sympy import Symbol, Poly 16 | 17 | 18 | def T(x): 19 | return x + x**2 + 2*x**3 + 4*x**4 + 9*x**5 + 20*x**6 + 48 * x**7 + \ 20 | 115*x**8 + 286*x**9 + 719*x**10 21 | 22 | 23 | def A(x): 24 | return 1 + T(x) - T(x)**2/2 + T(x**2)/2 25 | 26 | 27 | def main(): 28 | x = Symbol("x") 29 | s = Poly(A(x), x) 30 | num = list(reversed(s.coeffs()))[:11] 31 | 32 | print(s.as_expr()) 33 | print(num) 34 | 35 | if __name__ == "__main__": 36 | main() 37 | -------------------------------------------------------------------------------- /beginner/substitution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Substitution example 4 | 5 | Demonstrates substitution. 6 | """ 7 | 8 | import sympy 9 | from sympy import pprint 10 | 11 | 12 | def main(): 13 | x = sympy.Symbol('x') 14 | y = sympy.Symbol('y') 15 | 16 | e = 1/sympy.cos(x) 17 | print() 18 | pprint(e) 19 | print('\n') 20 | pprint(e.subs(sympy.cos(x), y)) 21 | print('\n') 22 | pprint(e.subs(sympy.cos(x), y).subs(y, x**2)) 23 | 24 | e = 1/sympy.log(x) 25 | e = e.subs(x, sympy.Float("2.71828")) 26 | print('\n') 27 | pprint(e) 28 | print('\n') 29 | pprint(e.evalf()) 30 | print() 31 | 32 | a = sympy.Symbol('a') 33 | b = sympy.Symbol('b') 34 | e = a*2 + a**b/a 35 | print('\n') 36 | pprint(e) 37 | a = 2 38 | print('\n') 39 | pprint(e.subs(a,8)) 40 | print() 41 | 42 | 43 | if __name__ == "__main__": 44 | main() 45 | -------------------------------------------------------------------------------- /beginner/limits_examples.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Limits Example 4 | 5 | Demonstrates limits. 6 | """ 7 | 8 | from sympy import exp, log, Symbol, Rational, sin, limit, sqrt, oo 9 | 10 | 11 | def sqrt3(x): 12 | return x**Rational(1, 3) 13 | 14 | 15 | def show(computed, correct): 16 | print("computed:", computed, "correct:", correct) 17 | 18 | 19 | def main(): 20 | x = Symbol("x") 21 | 22 | show( limit(sqrt(x**2 - 5*x + 6) - x, x, oo), -Rational(5)/2 ) 23 | 24 | show( limit(x*(sqrt(x**2 + 1) - x), x, oo), Rational(1)/2 ) 25 | 26 | show( limit(x - sqrt3(x**3 - 1), x, oo), Rational(0) ) 27 | 28 | show( limit(log(1 + exp(x))/x, x, -oo), Rational(0) ) 29 | 30 | show( limit(log(1 + exp(x))/x, x, oo), Rational(1) ) 31 | 32 | show( limit(sin(3*x)/x, x, 0), Rational(3) ) 33 | 34 | show( limit(sin(5*x)/sin(2*x), x, 0), Rational(5)/2 ) 35 | 36 | show( limit(((x - 1)/(x + 1))**x, x, oo), exp(-2)) 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /beginner/print_pretty.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Pretty print example 4 | 5 | Demonstrates pretty printing. 6 | """ 7 | 8 | from sympy import Symbol, pprint, sin, cos, exp, sqrt, MatrixSymbol, KroneckerProduct 9 | 10 | 11 | def main(): 12 | x = Symbol("x") 13 | y = Symbol("y") 14 | 15 | a = MatrixSymbol("a", 1, 1) 16 | b = MatrixSymbol("b", 1, 1) 17 | c = MatrixSymbol("c", 1, 1) 18 | 19 | pprint( x**x ) 20 | print('\n') # separate with two blank lines 21 | 22 | pprint(x**2 + y + x) 23 | print('\n') 24 | 25 | pprint(sin(x)**x) 26 | print('\n') 27 | 28 | pprint( sin(x)**cos(x) ) 29 | print('\n') 30 | 31 | pprint( sin(x)/(cos(x)**2 * x**x + (2*y)) ) 32 | print('\n') 33 | 34 | pprint( sin(x**2 + exp(x)) ) 35 | print('\n') 36 | 37 | pprint( sqrt(exp(x)) ) 38 | print('\n') 39 | 40 | pprint( sqrt(sqrt(exp(x))) ) 41 | print('\n') 42 | 43 | pprint( (1/cos(x)).series(x, 0, 10) ) 44 | print('\n') 45 | 46 | pprint(a*(KroneckerProduct(b, c))) 47 | print('\n') 48 | 49 | if __name__ == "__main__": 50 | main() 51 | -------------------------------------------------------------------------------- /beginner/plot_gallery.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "plot_gallery" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [ 7 | { 8 | "cells": [ 9 | { 10 | "cell_type": "markdown", 11 | "source": [ 12 | "### Beach ball" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "collapsed": true, 18 | "input": [ 19 | "from sympy.plotting import plot3d_parametric_surface" 20 | ], 21 | "language": "python", 22 | "outputs": [], 23 | "prompt_number": 1 24 | }, 25 | { 26 | "cell_type": "code", 27 | "collapsed": false, 28 | "input": [ 29 | "p = plot3d_parametric_surface(sin(x)*sin(y), sin(x)*cos(y), cos(x), (x, 0, pi), (y, 0, 2*pi))" 30 | ], 31 | "language": "python", 32 | "outputs": [], 33 | "prompt_number": 2 34 | }, 35 | { 36 | "cell_type": "code", 37 | "collapsed": false, 38 | "input": [ 39 | "p[0].surface_color = lambda a, b : cos(4*a)*sin(2*b)", 40 | "", 41 | "p.show()" 42 | ], 43 | "language": "python", 44 | "outputs": [], 45 | "prompt_number": 3 46 | } 47 | ] 48 | } 49 | ] 50 | } -------------------------------------------------------------------------------- /intermediate/mplot2d.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Matplotlib 2D plotting example 4 | 5 | Demonstrates plotting with matplotlib. 6 | """ 7 | 8 | import sys 9 | 10 | from sample import sample 11 | 12 | from sympy import sqrt, Symbol 13 | from sympy.utilities.iterables import is_sequence 14 | from sympy.external import import_module 15 | 16 | 17 | def mplot2d(f, var, *, show=True): 18 | """ 19 | Plot a 2d function using matplotlib/Tk. 20 | """ 21 | 22 | import warnings 23 | warnings.filterwarnings("ignore", r"Could not match \S") 24 | 25 | p = import_module('pylab') 26 | if not p: 27 | sys.exit("Matplotlib is required to use mplot2d.") 28 | 29 | if not is_sequence(f): 30 | f = [f, ] 31 | 32 | for f_i in f: 33 | x, y = sample(f_i, var) 34 | p.plot(x, y) 35 | 36 | p.draw() 37 | if show: 38 | p.show() 39 | 40 | 41 | def main(): 42 | x = Symbol('x') 43 | 44 | # mplot2d(log(x), (x, 0, 2, 100)) 45 | # mplot2d([sin(x), -sin(x)], (x, float(-2*pi), float(2*pi), 50)) 46 | mplot2d([sqrt(x), -sqrt(x), sqrt(-x), -sqrt(-x)], (x, -40.0, 40.0, 80)) 47 | 48 | if __name__ == "__main__": 49 | main() 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /intermediate/mplot3d.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Matplotlib 3D plotting example 4 | 5 | Demonstrates plotting with matplotlib. 6 | """ 7 | 8 | import sys 9 | 10 | from sample import sample 11 | 12 | from sympy import Symbol 13 | from sympy.external import import_module 14 | 15 | 16 | def mplot3d(f, var1, var2, *, show=True): 17 | """ 18 | Plot a 3d function using matplotlib/Tk. 19 | """ 20 | 21 | import warnings 22 | warnings.filterwarnings("ignore", r"Could not match \S") 23 | 24 | p = import_module('pylab') 25 | # Try newer version first 26 | p3 = import_module('mpl_toolkits.mplot3d', 27 | import_kwargs={'fromlist': ['something']}) or import_module('matplotlib.axes3d') 28 | if not p or not p3: 29 | sys.exit("Matplotlib is required to use mplot3d.") 30 | 31 | x, y, z = sample(f, var1, var2) 32 | 33 | fig = p.figure() 34 | ax = p3.Axes3D(fig) 35 | 36 | # ax.plot_surface(x, y, z, rstride=2, cstride=2) 37 | ax.plot_wireframe(x, y, z) 38 | 39 | ax.set_xlabel('X') 40 | ax.set_ylabel('Y') 41 | ax.set_zlabel('Z') 42 | 43 | if show: 44 | p.show() 45 | 46 | 47 | def main(): 48 | x = Symbol('x') 49 | y = Symbol('y') 50 | 51 | mplot3d(x**2 - y**2, (x, -10.0, 10.0, 20), (y, -10.0, 10.0, 20)) 52 | # mplot3d(x**2+y**2, (x, -10.0, 10.0, 20), (y, -10.0, 10.0, 20)) 53 | # mplot3d(sin(x)+sin(y), (x, -3.14, 3.14, 10), (y, -3.14, 3.14, 10)) 54 | 55 | if __name__ == "__main__": 56 | main() 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 SymPy Development Team 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | a. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | b. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | c. Neither the name of SymPy nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 28 | DAMAGE. 29 | -------------------------------------------------------------------------------- /advanced/dense_coding_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Demonstration of quantum dense coding.""" 4 | 5 | from sympy import pprint 6 | from sympy.physics.quantum import qapply 7 | from sympy.physics.quantum.gate import H, X, Z, CNOT 8 | from sympy.physics.quantum.grover import superposition_basis 9 | 10 | 11 | def main(): 12 | psi = superposition_basis(2) 13 | psi 14 | 15 | # Dense coding demo: 16 | 17 | # Assume Alice has the left QBit in psi 18 | print("An even superposition of 2 qubits. Assume Alice has the left QBit.") 19 | pprint(psi) 20 | 21 | # The corresponding gates applied to Alice's QBit are: 22 | # Identity Gate (1), Not Gate (X), Z Gate (Z), Z Gate and Not Gate (ZX) 23 | # Then there's the controlled not gate (with Alice's as control):CNOT(1, 0) 24 | # And the Hadamard gate applied to Alice's Qbit: H(1) 25 | 26 | # To Send Bob the message |0>|0> 27 | print("To Send Bob the message |00>.") 28 | circuit = H(1)*CNOT(1, 0) 29 | result = qapply(circuit*psi) 30 | result 31 | pprint(result) 32 | 33 | # To send Bob the message |0>|1> 34 | print("To Send Bob the message |01>.") 35 | circuit = H(1)*CNOT(1, 0)*X(1) 36 | result = qapply(circuit*psi) 37 | result 38 | pprint(result) 39 | 40 | # To send Bob the message |1>|0> 41 | print("To Send Bob the message |10>.") 42 | circuit = H(1)*CNOT(1, 0)*Z(1) 43 | result = qapply(circuit*psi) 44 | result 45 | pprint(result) 46 | 47 | # To send Bob the message |1>|1> 48 | print("To Send Bob the message |11>.") 49 | circuit = H(1)*CNOT(1, 0)*Z(1)*X(1) 50 | result = qapply(circuit*psi) 51 | result 52 | pprint(result) 53 | 54 | if __name__ == "__main__": 55 | main() 56 | -------------------------------------------------------------------------------- /beginner/plot_examples.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # Check the plot docstring 3 | 4 | from sympy import Symbol, exp, sin, cos 5 | from sympy.plotting import (plot, plot_parametric, 6 | plot3d_parametric_surface, plot3d_parametric_line, 7 | plot3d) 8 | 9 | lx = range(5) 10 | ly = [i**2 for i in lx] 11 | 12 | x = Symbol('x') 13 | y = Symbol('y') 14 | u = Symbol('u') 15 | v = Symbol('v') 16 | expr = x**2 - 1 17 | 18 | b = plot(expr, (x, 2, 4), show=False) # cartesian plot 19 | e = plot(exp(-x), (x, 0, 4), show=False) # cartesian plot (and coloring, see below) 20 | f = plot3d_parametric_line(sin(x), cos(x), x, (x, 0, 10), show=False) # 3d parametric line plot 21 | g = plot3d(sin(x)*cos(y), (x, -5, 5), (y, -10, 10), show=False) # 3d surface cartesian plot 22 | h = plot3d_parametric_surface(cos(u)*v, sin(u)*v, u, (u, 0, 10), (v, -2, 2), show=False) # 3d parametric surface plot 23 | 24 | # Some aesthetics 25 | e[0].line_color = lambda x: x / 4 26 | f[0].line_color = lambda x, y, z: z / 10 27 | g[0].surface_color = lambda x, y: sin(x) 28 | 29 | # Some more stuff on aesthetics - coloring wrt coordinates or parameters 30 | param_line_2d = plot_parametric((x*cos(x), x*sin(x), (x, 0, 15)), (1.1*x*cos(x), 1.1*x*sin(x), (x, 0, 15)), show=False) 31 | param_line_2d[0].line_color = lambda u: sin(u) # parametric 32 | param_line_2d[1].line_color = lambda u, v: u**2 + v**2 # coordinates 33 | param_line_2d.title = 'The inner one is colored by parameter and the outer one by coordinates' 34 | 35 | param_line_3d = plot3d_parametric_line((x*cos(x), x*sin(x), x, (x, 0, 15)), 36 | (1.5*x*cos(x), 1.5*x*sin(x), x, (x, 0, 15)), 37 | (2*x*cos(x), 2*x*sin(x), x, (x, 0, 15)), show=False) 38 | param_line_3d[0].line_color = lambda u: u # parametric 39 | param_line_3d[1].line_color = lambda u, v: u*v # first and second coordinates 40 | param_line_3d[2].line_color = lambda u, v, w: u*v*w # all coordinates 41 | 42 | 43 | if __name__ == '__main__': 44 | for p in [b, e, f, g, h, param_line_2d, param_line_3d]: 45 | p.show() 46 | -------------------------------------------------------------------------------- /beginner/plot_discont.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "plot_discont" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [ 7 | { 8 | "cells": [ 9 | { 10 | "cell_type": "markdown", 11 | "source": [ 12 | "The module does not cope well with discontinuities." 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "collapsed": true, 18 | "input": [ 19 | "from sympy.plotting import plot" 20 | ], 21 | "language": "python", 22 | "outputs": [], 23 | "prompt_number": 2 24 | }, 25 | { 26 | "cell_type": "code", 27 | "collapsed": false, 28 | "input": [ 29 | "plot(1/x)" 30 | ], 31 | "language": "python", 32 | "outputs": [], 33 | "prompt_number": 1 34 | }, 35 | { 36 | "cell_type": "code", 37 | "collapsed": false, 38 | "input": [ 39 | "plot(1/x,(x, 0, 3))" 40 | ], 41 | "language": "python", 42 | "outputs": [], 43 | "prompt_number": 4 44 | }, 45 | { 46 | "cell_type": "code", 47 | "collapsed": false, 48 | "input": [ 49 | "plot(Heaviside(x))" 50 | ], 51 | "language": "python", 52 | "outputs": [], 53 | "prompt_number": 6 54 | }, 55 | { 56 | "cell_type": "code", 57 | "collapsed": false, 58 | "input": [ 59 | "plot(sqrt(x))" 60 | ], 61 | "language": "python", 62 | "outputs": [], 63 | "prompt_number": 7 64 | }, 65 | { 66 | "cell_type": "code", 67 | "collapsed": false, 68 | "input": [ 69 | "plot(-sqrt(sqrt(x)),sqrt(sqrt(x)))" 70 | ], 71 | "language": "python", 72 | "outputs": [], 73 | "prompt_number": 8 74 | }, 75 | { 76 | "cell_type": "code", 77 | "collapsed": false, 78 | "input": [ 79 | "plot(LambertW(x))" 80 | ], 81 | "language": "python", 82 | "outputs": [], 83 | "prompt_number": 9 84 | }, 85 | { 86 | "cell_type": "code", 87 | "collapsed": false, 88 | "input": [ 89 | "plot(LambertW(x), sqrt(LambertW(x)), (x, -2, 1))" 90 | ], 91 | "language": "python", 92 | "outputs": [], 93 | "prompt_number": 10 94 | } 95 | ] 96 | } 97 | ] 98 | } -------------------------------------------------------------------------------- /intermediate/partial_differential_eqs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Partial Differential Equations example 4 | 5 | Demonstrates various ways to solve partial differential equations 6 | """ 7 | 8 | from sympy import symbols, Eq, Function, pde_separate, pprint, sin, cos 9 | from sympy import Derivative as D 10 | 11 | 12 | def main(): 13 | r, phi, theta = symbols("r,phi,theta") 14 | Xi = Function('Xi') 15 | R, Phi, Theta, u = map(Function, ['R', 'Phi', 'Theta', 'u']) 16 | C1, C2 = symbols('C1,C2') 17 | 18 | pprint("Separation of variables in Laplace equation in spherical coordinates") 19 | pprint("Laplace equation in spherical coordinates:") 20 | eq = Eq(D(Xi(r, phi, theta), r, 2) + 2/r * D(Xi(r, phi, theta), r) + 21 | 1/(r**2 * sin(phi)**2) * D(Xi(r, phi, theta), theta, 2) + 22 | cos(phi)/(r**2 * sin(phi)) * D(Xi(r, phi, theta), phi) + 23 | 1/r**2 * D(Xi(r, phi, theta), phi, 2), 0) 24 | pprint(eq) 25 | 26 | pprint("We can either separate this equation in regards with variable r:") 27 | res_r = pde_separate(eq, Xi(r, phi, theta), [R(r), u(phi, theta)]) 28 | pprint(res_r) 29 | 30 | pprint("Or separate it in regards of theta:") 31 | res_theta = pde_separate(eq, Xi(r, phi, theta), [Theta(theta), u(r, phi)]) 32 | pprint(res_theta) 33 | 34 | res_phi = pde_separate(eq, Xi(r, phi, theta), [Phi(phi), u(r, theta)]) 35 | pprint("But we cannot separate it in regards of variable phi: ") 36 | pprint("Result: %s" % res_phi) 37 | 38 | pprint("\n\nSo let's make theta dependent part equal with -C1:") 39 | eq_theta = Eq(res_theta[0], -C1) 40 | 41 | pprint(eq_theta) 42 | pprint("\nThis also means that second part is also equal to -C1:") 43 | eq_left = Eq(res_theta[1], -C1) 44 | pprint(eq_left) 45 | 46 | pprint("\nLets try to separate phi again :)") 47 | res_theta = pde_separate(eq_left, u(r, phi), [Phi(phi), R(r)]) 48 | pprint("\nThis time it is successful:") 49 | pprint(res_theta) 50 | 51 | pprint("\n\nSo our final equations with separated variables are:") 52 | pprint(eq_theta) 53 | pprint(Eq(res_theta[0], C2)) 54 | pprint(Eq(res_theta[1], C2)) 55 | 56 | 57 | if __name__ == "__main__": 58 | main() 59 | -------------------------------------------------------------------------------- /advanced/grover_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Grover's quantum search algorithm example.""" 4 | 5 | from sympy import pprint 6 | from sympy.physics.quantum import qapply 7 | from sympy.physics.quantum.qubit import IntQubit 8 | from sympy.physics.quantum.grover import (OracleGate, superposition_basis, 9 | WGate, grover_iteration) 10 | 11 | 12 | def demo_vgate_app(v): 13 | for i in range(2**v.nqubits): 14 | print('qapply(v*IntQubit(%i, %r))' % (i, v.nqubits)) 15 | pprint(qapply(v*IntQubit(i, nqubits=v.nqubits))) 16 | qapply(v*IntQubit(i, nqubits=v.nqubits)) 17 | 18 | 19 | def black_box(qubits): 20 | return True if qubits == IntQubit(1, nqubits=qubits.nqubits) else False 21 | 22 | 23 | def main(): 24 | print() 25 | print('Demonstration of Grover\'s Algorithm') 26 | print('The OracleGate or V Gate carries the unknown function f(x)') 27 | print('> V|x> = ((-1)^f(x))|x> where f(x) = 1 when x = a (True in our case)') 28 | print('> and 0 (False in our case) otherwise') 29 | print() 30 | 31 | nqubits = 2 32 | print('nqubits = ', nqubits) 33 | 34 | v = OracleGate(nqubits, black_box) 35 | print('Oracle or v = OracleGate(%r, black_box)' % nqubits) 36 | print() 37 | 38 | psi = superposition_basis(nqubits) 39 | print('psi:') 40 | pprint(psi) 41 | demo_vgate_app(v) 42 | print('qapply(v*psi)') 43 | pprint(qapply(v*psi)) 44 | print() 45 | 46 | w = WGate(nqubits) 47 | print('WGate or w = WGate(%r)' % nqubits) 48 | print('On a 2 Qubit system like psi, 1 iteration is enough to yield |1>') 49 | print('qapply(w*v*psi)') 50 | pprint(qapply(w*v*psi)) 51 | print() 52 | 53 | nqubits = 3 54 | print('On a 3 Qubit system, it requires 2 iterations to achieve') 55 | print('|1> with high enough probability') 56 | psi = superposition_basis(nqubits) 57 | print('psi:') 58 | pprint(psi) 59 | 60 | v = OracleGate(nqubits, black_box) 61 | print('Oracle or v = OracleGate(%r, black_box)' % nqubits) 62 | print() 63 | 64 | print('iter1 = grover.grover_iteration(psi, v)') 65 | iter1 = qapply(grover_iteration(psi, v)) 66 | pprint(iter1) 67 | print() 68 | 69 | print('iter2 = grover.grover_iteration(iter1, v)') 70 | iter2 = qapply(grover_iteration(iter1, v)) 71 | pprint(iter2) 72 | print() 73 | 74 | if __name__ == "__main__": 75 | main() 76 | -------------------------------------------------------------------------------- /advanced/autowrap_ufuncify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Setup ufuncs for the legendre polynomials 4 | ----------------------------------------- 5 | 6 | This example demonstrates how you can use the ufuncify utility in SymPy 7 | to create fast, customized universal functions for use with numpy 8 | arrays. An autowrapped sympy expression can be significantly faster than 9 | what you would get by applying a sequence of the ufuncs shipped with 10 | numpy. [0] 11 | 12 | You need to have numpy installed to run this example, as well as a 13 | working fortran compiler. 14 | 15 | 16 | [0]: 17 | http://ojensen.wordpress.com/2010/08/10/fast-ufunc-ish-hydrogen-solutions/ 18 | """ 19 | 20 | import sys 21 | 22 | from sympy.external import import_module 23 | 24 | np = import_module('numpy') 25 | if not np: 26 | sys.exit("Cannot import numpy. Exiting.") 27 | plt = import_module('matplotlib.pyplot') 28 | if not plt: 29 | sys.exit("Cannot import matplotlib.pyplot. Exiting.") 30 | 31 | import mpmath 32 | from sympy.utilities.autowrap import ufuncify 33 | from sympy import symbols, legendre, pprint 34 | 35 | 36 | def main(): 37 | 38 | print(__doc__) 39 | 40 | x = symbols('x') 41 | 42 | # a numpy array we can apply the ufuncs to 43 | grid = np.linspace(-1, 1, 1000) 44 | 45 | # set mpmath precision to 20 significant numbers for verification 46 | mpmath.mp.dps = 20 47 | 48 | print("Compiling legendre ufuncs and checking results:") 49 | 50 | # Let's also plot the ufunc's we generate 51 | for n in range(6): 52 | 53 | # Setup the SymPy expression to ufuncify 54 | expr = legendre(n, x) 55 | print("The polynomial of degree %i is" % n) 56 | pprint(expr) 57 | 58 | # This is where the magic happens: 59 | binary_poly = ufuncify(x, expr) 60 | 61 | # It's now ready for use with numpy arrays 62 | polyvector = binary_poly(grid) 63 | 64 | # let's check the values against mpmath's legendre function 65 | maxdiff = 0 66 | for j in range(len(grid)): 67 | precise_val = mpmath.legendre(n, grid[j]) 68 | diff = abs(polyvector[j] - precise_val) 69 | if diff > maxdiff: 70 | maxdiff = diff 71 | print("The largest error in applied ufunc was %e" % maxdiff) 72 | assert maxdiff < 1e-14 73 | 74 | # We can also attach the autowrapped legendre polynomial to a sympy 75 | # function and plot values as they are calculated by the binary function 76 | plot1 = plt.pyplot.plot(grid, polyvector, hold=True) 77 | 78 | 79 | print("Here's a plot with values calculated by the wrapped binary functions") 80 | plt.pyplot.show() 81 | 82 | if __name__ == '__main__': 83 | main() 84 | -------------------------------------------------------------------------------- /advanced/pidigits.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Pi digits example 4 | 5 | Example shows arbitrary precision using mpmath with the 6 | computation of the digits of pi. 7 | """ 8 | 9 | from mpmath import libmp, pi 10 | 11 | import math 12 | import sys 13 | from time import perf_counter 14 | 15 | 16 | def display_fraction(digits, *, skip=0, colwidth=10, columns=5): 17 | """Pretty printer for first n digits of a fraction""" 18 | perline = colwidth * columns 19 | printed = 0 20 | for linecount in range((len(digits) - skip) // (colwidth * columns)): 21 | line = digits[skip + linecount*perline:skip + (linecount + 1)*perline] 22 | for i in range(columns): 23 | print(line[i*colwidth: (i + 1)*colwidth],) 24 | print(":", (linecount + 1)*perline) 25 | if (linecount + 1) % 10 == 0: 26 | print() 27 | printed += colwidth*columns 28 | rem = (len(digits) - skip) % (colwidth * columns) 29 | if rem: 30 | buf = digits[-rem:] 31 | s = "" 32 | for i in range(columns): 33 | s += buf[:colwidth].ljust(colwidth + 1, " ") 34 | buf = buf[colwidth:] 35 | print(s + ":", printed + colwidth*columns) 36 | 37 | 38 | def calculateit(func, base, n, tofile): 39 | """Writes first n base-digits of a mpmath function to file""" 40 | prec = 100 41 | intpart = libmp.numeral(3, base) 42 | if intpart == 0: 43 | skip = 0 44 | else: 45 | skip = len(intpart) 46 | print("Step 1 of 2: calculating binary value...") 47 | prec = int(n*math.log2(base)) + 10 48 | t = perf_counter() 49 | a = func(prec) 50 | step1_time = perf_counter() - t 51 | print("Step 2 of 2: converting to specified base...") 52 | t = perf_counter() 53 | d = libmp.bin_to_radix(a.man, -a.exp, base, n) 54 | d = libmp.numeral(d, base, n) 55 | step2_time = perf_counter() - t 56 | print("\nWriting output...\n") 57 | if tofile: 58 | out_ = sys.stdout 59 | sys.stdout = tofile 60 | print("%i base-%i digits of pi:\n" % (n, base)) 61 | print(intpart, ".\n") 62 | display_fraction(d, skip=skip, colwidth=10, columns=5) 63 | if tofile: 64 | sys.stdout = out_ 65 | print("\nFinished in %f seconds (%f calc, %f convert)" % \ 66 | ((step1_time + step2_time), step1_time, step2_time)) 67 | 68 | 69 | def interactive(): 70 | """Simple function to interact with user""" 71 | print("Compute digits of pi with SymPy\n") 72 | base = int(input("Which base? (2-36, 10 for decimal) \n> ")) 73 | digits = int(input("How many digits? (enter a big number, say, 10000)\n> ")) 74 | tofile = input("Output to file? (enter a filename, or just press enter\nto print directly to the screen) \n> ") 75 | if tofile: 76 | tofile = open(tofile, "w") 77 | calculateit(pi, base, digits, tofile) 78 | 79 | 80 | def main(): 81 | """A non-interactive runner""" 82 | base = 16 83 | digits = 500 84 | tofile = None 85 | calculateit(pi, base, digits, tofile) 86 | 87 | if __name__ == "__main__": 88 | interactive() 89 | -------------------------------------------------------------------------------- /beginner/plot_advanced.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "plot_advanced" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [ 7 | { 8 | "cells": [ 9 | { 10 | "cell_type": "markdown", 11 | "source": [ 12 | "## Unevaluated Integrals" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "collapsed": true, 18 | "input": [ 19 | "from sympy.plotting import plot" 20 | ], 21 | "language": "python", 22 | "outputs": [], 23 | "prompt_number": 1 24 | }, 25 | { 26 | "cell_type": "code", 27 | "collapsed": true, 28 | "input": [ 29 | "i = Integral(log((sin(x)**2+1)*sqrt(x**2+1)),(x,0,y))" 30 | ], 31 | "language": "python", 32 | "outputs": [], 33 | "prompt_number": 2 34 | }, 35 | { 36 | "cell_type": "code", 37 | "collapsed": false, 38 | "input": [ 39 | "i" 40 | ], 41 | "language": "python", 42 | "outputs": [], 43 | "prompt_number": 3 44 | }, 45 | { 46 | "cell_type": "code", 47 | "collapsed": false, 48 | "input": [ 49 | "i.evalf(subs={y:1})" 50 | ], 51 | "language": "python", 52 | "outputs": [], 53 | "prompt_number": 4 54 | }, 55 | { 56 | "cell_type": "code", 57 | "collapsed": false, 58 | "input": [ 59 | "plot(i,(y, 1, 5))" 60 | ], 61 | "language": "python", 62 | "outputs": [], 63 | "prompt_number": 5 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "source": [ 68 | "## Infinite Sums" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "collapsed": true, 74 | "input": [ 75 | "s = summation(1/x**y,(x,1,oo))" 76 | ], 77 | "language": "python", 78 | "outputs": [], 79 | "prompt_number": 6 80 | }, 81 | { 82 | "cell_type": "code", 83 | "collapsed": false, 84 | "input": [ 85 | "s" 86 | ], 87 | "language": "python", 88 | "outputs": [], 89 | "prompt_number": 7 90 | }, 91 | { 92 | "cell_type": "code", 93 | "collapsed": false, 94 | "input": [ 95 | "plot(s, (y, 2, 10))" 96 | ], 97 | "language": "python", 98 | "outputs": [], 99 | "prompt_number": 9 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "source": [ 104 | "## Finite sums" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "collapsed": false, 110 | "input": [ 111 | "p = plot(summation(1/x,(x,1,y)), (y, 2, 10))" 112 | ], 113 | "language": "python", 114 | "outputs": [], 115 | "prompt_number": 10 116 | }, 117 | { 118 | "cell_type": "code", 119 | "collapsed": false, 120 | "input": [ 121 | "p[0].only_integers = True", 122 | "", 123 | "p[0].steps = True", 124 | "", 125 | "p.show()" 126 | ], 127 | "language": "python", 128 | "outputs": [], 129 | "prompt_number": 11 130 | } 131 | ] 132 | } 133 | ] 134 | } -------------------------------------------------------------------------------- /notebooks/qubits.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "qubits" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "code", 12 | "collapsed": false, 13 | "input": [ 14 | "from sympy import symbols\n", 15 | "from sympy.physics.quantum.trace import Tr\n", 16 | "from sympy.matrices.matrices import Matrix\n", 17 | "from IPython.core.display import display_pretty\n", 18 | "from sympy.printing.latex import *\n", 19 | "from sympy.physics.quantum.cartesian import *\n", 20 | "from sympy.physics.quantum.qubit import *\n", 21 | "from sympy.physics.quantum.density import *\n", 22 | "\n", 23 | "%load_ext sympyprinting\n", 24 | "\n", 25 | "#TODO: Add examples of simple qubit usage " 26 | ], 27 | "language": "python", 28 | "metadata": {}, 29 | "outputs": [], 30 | "prompt_number": 4 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "## Examples of Tr operations on Qubits" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "collapsed": false, 42 | "input": [ 43 | "q1 = Qubit('10110')\n", 44 | "q2 = Qubit('01010')\n", 45 | "d = Density( [q1, 0.6], [q2, 0.4] )\n", 46 | "\n", 47 | "# Trace one bit \n", 48 | "t = Tr(d,[0])\n", 49 | "\n", 50 | "display_pretty(t.doit())\n", 51 | "\n", 52 | "\n", 53 | "# Partial trace of 3 qubits\n", 54 | "# the 0th bit is the right-most bit\n", 55 | "t = Tr(d,[2, 1, 3])\n", 56 | "display_pretty(t.doit())" 57 | ], 58 | "language": "python", 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "output_type": "display_data", 63 | "text": [ 64 | "0.4\u22c5(\u27580101\u27e9, 1) + 0.6\u22c5(\u27581011\u27e9, 1)" 65 | ] 66 | }, 67 | { 68 | "output_type": "display_data", 69 | "text": [ 70 | "0.4\u22c5(\u275800\u27e9, 1) + 0.6\u22c5(\u275810\u27e9, 1)" 71 | ] 72 | } 73 | ], 74 | "prompt_number": 2 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "## Partial Tr of mixed state" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "collapsed": false, 86 | "input": [ 87 | "from sympy import *\n", 88 | "q = (1/sqrt(2)) * (Qubit('00') + Qubit('11'))\n", 89 | "\n", 90 | "d = Density ( [q, 1.0] )\n", 91 | "t = Tr(d, [0])\n", 92 | "display_pretty(t.doit())" 93 | ], 94 | "language": "python", 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "output_type": "display_data", 99 | "text": [ 100 | "0.5\u22c5(\u27580\u27e9, 1) + 0.5\u22c5(\u27581\u27e9, 1)" 101 | ] 102 | } 103 | ], 104 | "prompt_number": 3 105 | }, 106 | { 107 | "cell_type": "code", 108 | "collapsed": true, 109 | "input": [], 110 | "language": "python", 111 | "metadata": {}, 112 | "outputs": [], 113 | "prompt_number": 3 114 | } 115 | ], 116 | "metadata": {} 117 | } 118 | ] 119 | } -------------------------------------------------------------------------------- /intermediate/infinite_1d_box.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Applying perturbation theory to calculate the ground state energy 5 | of the infinite 1D box of width ``a`` with a perturbation 6 | which is linear in ``x``, up to second order in perturbation 7 | """ 8 | 9 | from sympy.core import pi 10 | from sympy import Integral, var, S 11 | from sympy.functions import sin, sqrt 12 | 13 | 14 | def X_n(n, a, x): 15 | """ 16 | Returns the wavefunction X_{n} for an infinite 1D box 17 | 18 | ``n`` 19 | the "principal" quantum number. Corresponds to the number of nodes in 20 | the wavefunction. n >= 0 21 | ``a`` 22 | width of the well. a > 0 23 | ``x`` 24 | x coordinate. 25 | """ 26 | n, a, x = map(S, [n, a, x]) 27 | C = sqrt(2 / a) 28 | return C * sin(pi * n * x / a) 29 | 30 | 31 | def E_n(n, a, mass): 32 | """ 33 | Returns the Energy psi_{n} for a 1d potential hole with infinity borders 34 | 35 | ``n`` 36 | the "principal" quantum number. Corresponds to the number of nodes in 37 | the wavefunction. n >= 0 38 | ``a`` 39 | width of the well. a > 0 40 | ``mass`` 41 | mass. 42 | """ 43 | return ((n * pi / a)**2) / mass 44 | 45 | 46 | def energy_corrections(perturbation, n, *, a=10, mass=0.5): 47 | """ 48 | Calculating first two order corrections due to perturbation theory and 49 | returns tuple where zero element is unperturbated energy, and two second 50 | is corrections 51 | 52 | ``n`` 53 | the "nodal" quantum number. Corresponds to the number of nodes in the 54 | wavefunction. n >= 0 55 | ``a`` 56 | width of the well. a > 0 57 | ``mass`` 58 | mass. 59 | 60 | """ 61 | x, _a = var("x _a") 62 | 63 | Vnm = lambda n, m, a: Integral(X_n(n, a, x) * X_n(m, a, x) 64 | * perturbation.subs({_a: a}), (x, 0, a)).n() 65 | 66 | # As we know from theory for V0*r/a we will just V(n, n-1) and V(n, n+1) 67 | # wouldn't equals zero 68 | 69 | return (E_n(n, a, mass).evalf(), 70 | 71 | Vnm(n, n, a).evalf(), 72 | 73 | (Vnm(n, n - 1, a)**2/(E_n(n, a, mass) - E_n(n - 1, a, mass)) 74 | + Vnm(n, n + 1, a)**2/(E_n(n, a, mass) - E_n(n + 1, a, mass))).evalf()) 75 | 76 | 77 | def main(): 78 | print() 79 | print("Applying perturbation theory to calculate the ground state energy") 80 | print("of the infinite 1D box of width ``a`` with a perturbation") 81 | print("which is linear in ``x``, up to second order in perturbation.") 82 | print() 83 | 84 | x, _a = var("x _a") 85 | perturbation = .1 * x / _a 86 | 87 | E1 = energy_corrections(perturbation, 1) 88 | print("Energy for first term (n=1):") 89 | print("E_1^{(0)} = ", E1[0]) 90 | print("E_1^{(1)} = ", E1[1]) 91 | print("E_1^{(2)} = ", E1[2]) 92 | print() 93 | 94 | E2 = energy_corrections(perturbation, 2) 95 | print("Energy for second term (n=2):") 96 | print("E_2^{(0)} = ", E2[0]) 97 | print("E_2^{(1)} = ", E2[1]) 98 | print("E_2^{(2)} = ", E2[2]) 99 | print() 100 | 101 | E3 = energy_corrections(perturbation, 3) 102 | print("Energy for third term (n=3):") 103 | print("E_3^{(0)} = ", E3[0]) 104 | print("E_3^{(1)} = ", E3[1]) 105 | print("E_3^{(2)} = ", E3[2]) 106 | print() 107 | 108 | 109 | if __name__ == "__main__": 110 | main() 111 | -------------------------------------------------------------------------------- /intermediate/sample.py: -------------------------------------------------------------------------------- 1 | r""" 2 | Utility functions for plotting sympy functions. 3 | 4 | See examples\mplot2d.py and examples\mplot3d.py for usable 2d and 3d 5 | graphing functions using matplotlib. 6 | """ 7 | 8 | from sympy.core.sympify import sympify, SympifyError 9 | from sympy.external import import_module 10 | np = import_module('numpy') 11 | 12 | def sample2d(f, x_args): 13 | r""" 14 | Samples a 2d function f over specified intervals and returns two 15 | arrays (X, Y) suitable for plotting with matlab (matplotlib) 16 | syntax. See examples\mplot2d.py. 17 | 18 | f is a function of one variable, such as x**2. 19 | x_args is an interval given in the form (var, min, max, n) 20 | """ 21 | try: 22 | f = sympify(f) 23 | except SympifyError: 24 | raise ValueError("f could not be interpreted as a SymPy function") 25 | try: 26 | x, x_min, x_max, x_n = x_args 27 | except (TypeError, IndexError): 28 | raise ValueError("x_args must be a tuple of the form (var, min, max, n)") 29 | 30 | x_l = float(x_max - x_min) 31 | x_d = x_l/float(x_n) 32 | X = np.arange(float(x_min), float(x_max) + x_d, x_d) 33 | 34 | Y = np.empty(len(X)) 35 | for i in range(len(X)): 36 | try: 37 | Y[i] = float(f.subs(x, X[i])) 38 | except TypeError: 39 | Y[i] = None 40 | return X, Y 41 | 42 | 43 | def sample3d(f, x_args, y_args): 44 | r""" 45 | Samples a 3d function f over specified intervals and returns three 46 | 2d arrays (X, Y, Z) suitable for plotting with matlab (matplotlib) 47 | syntax. See examples\mplot3d.py. 48 | 49 | f is a function of two variables, such as x**2 + y**2. 50 | x_args and y_args are intervals given in the form (var, min, max, n) 51 | """ 52 | x, x_min, x_max, x_n = None, None, None, None 53 | y, y_min, y_max, y_n = None, None, None, None 54 | try: 55 | f = sympify(f) 56 | except SympifyError: 57 | raise ValueError("f could not be interpreted as a SymPy function") 58 | try: 59 | x, x_min, x_max, x_n = x_args 60 | y, y_min, y_max, y_n = y_args 61 | except (TypeError, IndexError): 62 | raise ValueError("x_args and y_args must be tuples of the form (var, min, max, intervals)") 63 | 64 | x_l = float(x_max - x_min) 65 | x_d = x_l/float(x_n) 66 | x_a = np.arange(float(x_min), float(x_max) + x_d, x_d) 67 | 68 | y_l = float(y_max - y_min) 69 | y_d = y_l/float(y_n) 70 | y_a = np.arange(float(y_min), float(y_max) + y_d, y_d) 71 | 72 | def meshgrid(x, y): 73 | """ 74 | Taken from matplotlib.mlab.meshgrid. 75 | """ 76 | x = np.array(x) 77 | y = np.array(y) 78 | numRows, numCols = len(y), len(x) 79 | x.shape = 1, numCols 80 | X = np.repeat(x, numRows, 0) 81 | 82 | y.shape = numRows, 1 83 | Y = np.repeat(y, numCols, 1) 84 | return X, Y 85 | 86 | X, Y = np.meshgrid(x_a, y_a) 87 | 88 | Z = np.ndarray((len(X), len(X[0]))) 89 | for j in range(len(X)): 90 | for k in range(len(X[0])): 91 | try: 92 | Z[j][k] = float(f.subs(x, X[j][k]).subs(y, Y[j][k])) 93 | except (TypeError, NotImplementedError): 94 | Z[j][k] = 0 95 | return X, Y, Z 96 | 97 | 98 | def sample(f, *var_args): 99 | """ 100 | Samples a 2d or 3d function over specified intervals and returns 101 | a dataset suitable for plotting with matlab (matplotlib) syntax. 102 | Wrapper for sample2d and sample3d. 103 | 104 | f is a function of one or two variables, such as x**2. 105 | var_args are intervals for each variable given in the form (var, min, max, n) 106 | """ 107 | if len(var_args) == 1: 108 | return sample2d(f, var_args[0]) 109 | elif len(var_args) == 2: 110 | return sample3d(f, var_args[0], var_args[1]) 111 | else: 112 | raise ValueError("Only 2d and 3d sampling are supported at this time.") 113 | -------------------------------------------------------------------------------- /advanced/qft.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Quantum field theory example 4 | 5 | * https://en.wikipedia.org/wiki/Quantum_field_theory 6 | 7 | This particular example is a work in progress. Currently it calculates the 8 | scattering amplitude of the process: 9 | 10 | electron + positron -> photon -> electron + positron 11 | 12 | in QED (https://en.wikipedia.org/wiki/Quantum_electrodynamics). The aim 13 | is to be able to do any kind of calculations in QED or standard model in 14 | SymPy, but that's a long journey. 15 | 16 | """ 17 | 18 | from sympy import Basic, Symbol, Matrix, \ 19 | ones, sqrt, pprint, Eq, sympify 20 | 21 | from sympy.physics import msigma, mgamma 22 | 23 | # gamma^mu 24 | gamma0 = mgamma(0) 25 | gamma1 = mgamma(1) 26 | gamma2 = mgamma(2) 27 | gamma3 = mgamma(3) 28 | gamma5 = mgamma(5) 29 | 30 | # sigma_i 31 | sigma1 = msigma(1) 32 | sigma2 = msigma(2) 33 | sigma3 = msigma(3) 34 | 35 | E = Symbol("E", real=True) 36 | m = Symbol("m", real=True) 37 | 38 | 39 | def u(p, r): 40 | """ p = (p1, p2, p3); r = 0,1 """ 41 | if r not in [1, 2]: 42 | raise ValueError("Value of r should lie between 1 and 2") 43 | p1, p2, p3 = p 44 | if r == 1: 45 | ksi = Matrix([[1], [0]]) 46 | else: 47 | ksi = Matrix([[0], [1]]) 48 | a = (sigma1*p1 + sigma2*p2 + sigma3*p3) / (E + m)*ksi 49 | if a == 0: 50 | a = zeros(2, 1) 51 | return sqrt(E + m) *\ 52 | Matrix([[ksi[0, 0]], [ksi[1, 0]], [a[0, 0]], [a[1, 0]]]) 53 | 54 | 55 | def v(p, r): 56 | """ p = (p1, p2, p3); r = 0,1 """ 57 | if r not in [1, 2]: 58 | raise ValueError("Value of r should lie between 1 and 2") 59 | p1, p2, p3 = p 60 | if r == 1: 61 | ksi = Matrix([[1], [0]]) 62 | else: 63 | ksi = -Matrix([[0], [1]]) 64 | a = (sigma1*p1 + sigma2*p2 + sigma3*p3) / (E + m)*ksi 65 | if a == 0: 66 | a = zeros(2, 1) 67 | return sqrt(E + m) *\ 68 | Matrix([[a[0, 0]], [a[1, 0]], [ksi[0, 0]], [ksi[1, 0]]]) 69 | 70 | 71 | def pslash(p): 72 | p1, p2, p3 = p 73 | p0 = sqrt(m**2 + p1**2 + p2**2 + p3**2) 74 | return gamma0*p0 - gamma1*p1 - gamma2*p2 - gamma3*p3 75 | 76 | 77 | def Tr(M): 78 | return M.trace() 79 | 80 | 81 | def xprint(lhs, rhs): 82 | pprint(Eq(sympify(lhs), rhs)) 83 | 84 | 85 | def main(): 86 | a = Symbol("a", real=True) 87 | b = Symbol("b", real=True) 88 | c = Symbol("c", real=True) 89 | 90 | p = (a, b, c) 91 | 92 | assert u(p, 1).D*u(p, 2) == Matrix(1, 1, [0]) 93 | assert u(p, 2).D*u(p, 1) == Matrix(1, 1, [0]) 94 | 95 | p1, p2, p3 = [Symbol(x, real=True) for x in ["p1", "p2", "p3"]] 96 | pp1, pp2, pp3 = [Symbol(x, real=True) for x in ["pp1", "pp2", "pp3"]] 97 | k1, k2, k3 = [Symbol(x, real=True) for x in ["k1", "k2", "k3"]] 98 | kp1, kp2, kp3 = [Symbol(x, real=True) for x in ["kp1", "kp2", "kp3"]] 99 | 100 | p = (p1, p2, p3) 101 | pp = (pp1, pp2, pp3) 102 | 103 | k = (k1, k2, k3) 104 | kp = (kp1, kp2, kp3) 105 | 106 | mu = Symbol("mu") 107 | 108 | e = (pslash(p) + m*ones(4))*(pslash(k) - m*ones(4)) 109 | f = pslash(p) + m*ones(4) 110 | g = pslash(p) - m*ones(4) 111 | 112 | xprint('Tr(f*g)', Tr(f*g)) 113 | 114 | M0 = [(v(pp, 1).D*mgamma(mu)*u(p, 1))*(u(k, 1).D*mgamma(mu, True) * 115 | v(kp, 1)) for mu in range(4)] 116 | M = M0[0] + M0[1] + M0[2] + M0[3] 117 | M = M[0] 118 | if not isinstance(M, Basic): 119 | raise TypeError("Invalid type of variable") 120 | 121 | d = Symbol("d", real=True) # d=E+m 122 | 123 | xprint('M', M) 124 | print("-"*40) 125 | M = ((M.subs(E, d - m)).expand()*d**2).expand() 126 | xprint('M2', 1 / (E + m)**2*M) 127 | print("-"*40) 128 | x, y = M.as_real_imag() 129 | xprint('Re(M)', x) 130 | xprint('Im(M)', y) 131 | e = x**2 + y**2 132 | xprint('abs(M)**2', e) 133 | print("-"*40) 134 | xprint('Expand(abs(M)**2)', e.expand()) 135 | 136 | if __name__ == "__main__": 137 | main() 138 | -------------------------------------------------------------------------------- /advanced/curvilinear_coordinates.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | This example shows how to work with coordinate transformations, curvilinear 5 | coordinates and a little bit with differential geometry. 6 | 7 | It takes polar, cylindrical, spherical, rotating disk coordinates and others 8 | and calculates all kinds of interesting properties, like Jacobian, metric 9 | tensor, Laplace operator, ... 10 | """ 11 | 12 | from sympy import var, sin, cos, pprint, Matrix, eye, trigsimp, Eq, \ 13 | Function, simplify, sinh, cosh, expand, symbols 14 | 15 | 16 | def laplace(f, g_inv, g_det, X): 17 | """ 18 | Calculates Laplace(f), using the inverse metric g_inv, the determinant of 19 | the metric g_det, all in variables X. 20 | """ 21 | r = 0 22 | for i in range(len(X)): 23 | for j in range(len(X)): 24 | r += g_inv[i, j]*f.diff(X[i]).diff(X[j]) 25 | for sigma in range(len(X)): 26 | for alpha in range(len(X)): 27 | r += g_det.diff(X[sigma]) * g_inv[sigma, alpha] * \ 28 | f.diff(X[alpha]) / (2*g_det) 29 | return r 30 | 31 | 32 | def transform(name, X, Y, *, g_correct=None, recursive=False): 33 | """ 34 | Transforms from cartesian coordinates X to any curvilinear coordinates Y. 35 | 36 | It printing useful information, like Jacobian, metric tensor, determinant 37 | of metric, Laplace operator in the new coordinates, ... 38 | 39 | g_correct ... if not None, it will be taken as the metric --- this is 40 | useful if sympy's trigsimp() is not powerful enough to 41 | simplify the metric so that it is usable for later 42 | calculation. Leave it as None, only if the metric that 43 | transform() prints is not simplified, you can help it by 44 | specifying the correct one. 45 | 46 | recursive ... apply recursive trigonometric simplification (use only when 47 | needed, as it is an expensive operation) 48 | """ 49 | print("_"*80) 50 | print("Transformation:", name) 51 | for x, y in zip(X, Y): 52 | pprint(Eq(y, x)) 53 | J = X.jacobian(Y) 54 | print("Jacobian:") 55 | pprint(J) 56 | g = J.T*eye(J.shape[0])*J 57 | 58 | g = g.applyfunc(expand) 59 | print("metric tensor g_{ij}:") 60 | pprint(g) 61 | if g_correct is not None: 62 | g = g_correct 63 | print("metric tensor g_{ij} specified by hand:") 64 | pprint(g) 65 | print("inverse metric tensor g^{ij}:") 66 | g_inv = g.inv(method="ADJ") 67 | g_inv = g_inv.applyfunc(simplify) 68 | pprint(g_inv) 69 | print("det g_{ij}:") 70 | g_det = g.det() 71 | pprint(g_det) 72 | f = Function("f")(*list(Y)) 73 | print("Laplace:") 74 | pprint(laplace(f, g_inv, g_det, Y)) 75 | 76 | 77 | def main(): 78 | mu, nu, rho, theta, phi, sigma, tau, a, t, x, y, z, w = symbols( 79 | "mu, nu, rho, theta, phi, sigma, tau, a, t, x, y, z, w") 80 | 81 | transform("polar", Matrix([rho*cos(phi), rho*sin(phi)]), [rho, phi]) 82 | 83 | transform("cylindrical", Matrix([rho*cos(phi), rho*sin(phi), z]), 84 | [rho, phi, z]) 85 | 86 | transform("spherical", 87 | Matrix([rho*sin(theta)*cos(phi), rho*sin(theta)*sin(phi), 88 | rho*cos(theta)]), 89 | [rho, theta, phi], 90 | recursive=True 91 | ) 92 | 93 | transform("rotating disk", 94 | Matrix([t, 95 | x*cos(w*t) - y*sin(w*t), 96 | x*sin(w*t) + y*cos(w*t), 97 | z]), 98 | [t, x, y, z]) 99 | 100 | transform("parabolic", 101 | Matrix([sigma*tau, (tau**2 - sigma**2) / 2]), 102 | [sigma, tau]) 103 | 104 | transform("bipolar", 105 | Matrix([a*sinh(tau)/(cosh(tau)-cos(sigma)), 106 | a*sin(sigma)/(cosh(tau)-cos(sigma))]), 107 | [sigma, tau] 108 | ) 109 | 110 | transform("elliptic", 111 | Matrix([a*cosh(mu)*cos(nu), a*sinh(mu)*sin(nu)]), 112 | [mu, nu] 113 | ) 114 | 115 | if __name__ == "__main__": 116 | main() 117 | -------------------------------------------------------------------------------- /intermediate/coupled_cluster.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Calculates the Coupled-Cluster energy- and amplitude equations 5 | See 'An Introduction to Coupled Cluster Theory' by 6 | T. Daniel Crawford and Henry F. Schaefer III. 7 | 8 | Other Resource : http://vergil.chemistry.gatech.edu/notes/sahan-cc-2010.pdf 9 | """ 10 | 11 | from sympy.physics.secondquant import (AntiSymmetricTensor, wicks, 12 | F, Fd, NO, evaluate_deltas, substitute_dummies, Commutator, 13 | simplify_index_permutations, PermutationOperator) 14 | from sympy import ( 15 | symbols, Rational, latex, Dummy 16 | ) 17 | 18 | pretty_dummies_dict = { 19 | 'above': 'cdefgh', 20 | 'below': 'klmno', 21 | 'general': 'pqrstu' 22 | } 23 | 24 | 25 | def get_CC_operators(): 26 | """ 27 | Returns a tuple (T1,T2) of unique operators. 28 | """ 29 | i = symbols('i', below_fermi=True, cls=Dummy) 30 | a = symbols('a', above_fermi=True, cls=Dummy) 31 | t_ai = AntiSymmetricTensor('t', (a,), (i,)) 32 | ai = NO(Fd(a)*F(i)) 33 | i, j = symbols('i,j', below_fermi=True, cls=Dummy) 34 | a, b = symbols('a,b', above_fermi=True, cls=Dummy) 35 | t_abij = AntiSymmetricTensor('t', (a, b), (i, j)) 36 | abji = NO(Fd(a)*Fd(b)*F(j)*F(i)) 37 | 38 | T1 = t_ai*ai 39 | T2 = Rational(1, 4)*t_abij*abji 40 | return (T1, T2) 41 | 42 | 43 | def main(): 44 | print() 45 | print("Calculates the Coupled-Cluster energy- and amplitude equations") 46 | print("See 'An Introduction to Coupled Cluster Theory' by") 47 | print("T. Daniel Crawford and Henry F. Schaefer III") 48 | print("Reference to a Lecture Series: http://vergil.chemistry.gatech.edu/notes/sahan-cc-2010.pdf") 49 | print() 50 | 51 | # setup hamiltonian 52 | p, q, r, s = symbols('p,q,r,s', cls=Dummy) 53 | f = AntiSymmetricTensor('f', (p,), (q,)) 54 | pr = NO(Fd(p)*F(q)) 55 | v = AntiSymmetricTensor('v', (p, q), (r, s)) 56 | pqsr = NO(Fd(p)*Fd(q)*F(s)*F(r)) 57 | 58 | H = f*pr + Rational(1, 4)*v*pqsr 59 | print("Using the hamiltonian:", latex(H)) 60 | 61 | print("Calculating 4 nested commutators") 62 | C = Commutator 63 | 64 | T1, T2 = get_CC_operators() 65 | T = T1 + T2 66 | print("commutator 1...") 67 | comm1 = wicks(C(H, T)) 68 | comm1 = evaluate_deltas(comm1) 69 | comm1 = substitute_dummies(comm1) 70 | 71 | T1, T2 = get_CC_operators() 72 | T = T1 + T2 73 | print("commutator 2...") 74 | comm2 = wicks(C(comm1, T)) 75 | comm2 = evaluate_deltas(comm2) 76 | comm2 = substitute_dummies(comm2) 77 | 78 | T1, T2 = get_CC_operators() 79 | T = T1 + T2 80 | print("commutator 3...") 81 | comm3 = wicks(C(comm2, T)) 82 | comm3 = evaluate_deltas(comm3) 83 | comm3 = substitute_dummies(comm3) 84 | 85 | T1, T2 = get_CC_operators() 86 | T = T1 + T2 87 | print("commutator 4...") 88 | comm4 = wicks(C(comm3, T)) 89 | comm4 = evaluate_deltas(comm4) 90 | comm4 = substitute_dummies(comm4) 91 | 92 | print("construct Hausdorff expansion...") 93 | eq = H + comm1 + comm2/2 + comm3/6 + comm4/24 94 | eq = eq.expand() 95 | eq = evaluate_deltas(eq) 96 | eq = substitute_dummies(eq, new_indices=True, 97 | pretty_indices=pretty_dummies_dict) 98 | print("*********************") 99 | print() 100 | 101 | print("extracting CC equations from full Hbar") 102 | i, j, k, l = symbols('i,j,k,l', below_fermi=True) 103 | a, b, c, d = symbols('a,b,c,d', above_fermi=True) 104 | print() 105 | print("CC Energy:") 106 | print(latex(wicks(eq, simplify_dummies=True, 107 | keep_only_fully_contracted=True))) 108 | print() 109 | print("CC T1:") 110 | eqT1 = wicks(NO(Fd(i)*F(a))*eq, simplify_kronecker_deltas=True, keep_only_fully_contracted=True) 111 | eqT1 = substitute_dummies(eqT1) 112 | print(latex(eqT1)) 113 | print() 114 | print("CC T2:") 115 | eqT2 = wicks(NO(Fd(i)*Fd(j)*F(b)*F(a))*eq, simplify_dummies=True, keep_only_fully_contracted=True, simplify_kronecker_deltas=True) 116 | P = PermutationOperator 117 | eqT2 = simplify_index_permutations(eqT2, [P(a, b), P(i, j)]) 118 | print(latex(eqT2)) 119 | 120 | if __name__ == "__main__": 121 | main() 122 | -------------------------------------------------------------------------------- /advanced/gibbs_phenomenon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | This example illustrates the Gibbs phenomenon. 5 | 6 | It also calculates the Wilbraham-Gibbs constant by two approaches: 7 | 8 | 1) calculating the fourier series of the step function and determining the 9 | first maximum. 10 | 2) evaluating the integral for si(pi). 11 | 12 | See: 13 | * https://en.wikipedia.org/wiki/Gibbs_phenomena 14 | """ 15 | 16 | from sympy import var, sqrt, integrate, conjugate, seterr, Abs, pprint, I, pi,\ 17 | sin, cos, sign, lambdify, Integral, S 18 | 19 | x = var("x", real=True) 20 | 21 | 22 | def l2_norm(f, lim): 23 | """ 24 | Calculates L2 norm of the function "f", over the domain lim=(x, a, b). 25 | 26 | x ...... the independent variable in f over which to integrate 27 | a, b ... the limits of the interval 28 | 29 | Examples 30 | ======== 31 | 32 | >>> from sympy import Symbol 33 | >>> from gibbs_phenomenon import l2_norm 34 | >>> x = Symbol('x', real=True) 35 | >>> l2_norm(1, (x, -1, 1)) 36 | sqrt(2) 37 | >>> l2_norm(x, (x, -1, 1)) 38 | sqrt(6)/3 39 | 40 | """ 41 | return sqrt(integrate(Abs(f)**2, lim)) 42 | 43 | 44 | def l2_inner_product(a, b, lim): 45 | """ 46 | Calculates the L2 inner product (a, b) over the domain lim. 47 | """ 48 | return integrate(conjugate(a)*b, lim) 49 | 50 | 51 | def l2_projection(f, basis, lim): 52 | """ 53 | L2 projects the function f on the basis over the domain lim. 54 | """ 55 | r = 0 56 | for b in basis: 57 | r += l2_inner_product(f, b, lim) * b 58 | return r 59 | 60 | 61 | def l2_gram_schmidt(list, lim): 62 | """ 63 | Orthonormalizes the "list" of functions using the Gram-Schmidt process. 64 | 65 | Examples 66 | ======== 67 | 68 | >>> from sympy import Symbol 69 | >>> from gibbs_phenomenon import l2_gram_schmidt 70 | 71 | >>> x = Symbol('x', real=True) # perform computations over reals to save time 72 | >>> l2_gram_schmidt([1, x, x**2], (x, -1, 1)) 73 | [sqrt(2)/2, sqrt(6)*x/2, 3*sqrt(10)*(x**2 - 1/3)/4] 74 | 75 | """ 76 | r = [] 77 | for a in list: 78 | if r == []: 79 | v = a 80 | else: 81 | v = a - l2_projection(a, r, lim) 82 | v_norm = l2_norm(v, lim) 83 | if v_norm == 0: 84 | raise ValueError("The sequence is not linearly independent.") 85 | r.append(v/v_norm) 86 | return r 87 | 88 | 89 | def integ(f): 90 | return integrate(f, (x, -pi, 0)) + integrate(-f, (x, 0, pi)) 91 | 92 | 93 | def series(L): 94 | """ 95 | Normalizes the series. 96 | """ 97 | r = 0 98 | for b in L: 99 | r += integ(b)*b 100 | return r 101 | 102 | 103 | def msolve(f, x): 104 | """ 105 | Finds the first root of f(x) to the left of 0. 106 | 107 | The x0 and dx below are tailored to get the correct result for our 108 | particular function --- the general solver often overshoots the first 109 | solution. 110 | """ 111 | f = lambdify(x, f) 112 | x0 = -0.001 113 | dx = 0.001 114 | while f(x0 - dx) * f(x0) > 0: 115 | x0 = x0 - dx 116 | x_max = x0 - dx 117 | x_min = x0 118 | assert f(x_max) > 0 119 | assert f(x_min) < 0 120 | for n in range(100): 121 | x0 = (x_max + x_min)/2 122 | if f(x0) > 0: 123 | x_max = x0 124 | else: 125 | x_min = x0 126 | return x0 127 | 128 | 129 | def main(): 130 | L = [1] 131 | for i in range(1, 100): 132 | L.append(cos(i*x)) 133 | L.append(sin(i*x)) 134 | # next 2 lines equivalent to L = l2_gram_schmidt(L, (x, -pi, pi)), but faster: 135 | L[0] /= sqrt(2) 136 | L = [f/sqrt(pi) for f in L] 137 | 138 | f = series(L) 139 | print("Fourier series of the step function") 140 | pprint(f) 141 | x0 = msolve(f.diff(x), x) 142 | 143 | print("x-value of the maximum:", x0) 144 | max = f.subs(x, x0).evalf() 145 | print("y-value of the maximum:", max) 146 | g = max*pi/2 147 | print("Wilbraham-Gibbs constant :", g.evalf()) 148 | print("Wilbraham-Gibbs constant (exact):", \ 149 | Integral(sin(x)/x, (x, 0, pi)).evalf()) 150 | 151 | if __name__ == "__main__": 152 | main() 153 | -------------------------------------------------------------------------------- /notebooks/fidelity.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "fidelity" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "code", 12 | "collapsed": false, 13 | "input": [ 14 | "from sympy import *\n", 15 | "from sympy.physics.quantum import *\n", 16 | "from sympy.physics.quantum.density import *\n", 17 | "from sympy.physics.quantum.spin import (\n", 18 | " Jx, Jy, Jz, Jplus, Jminus, J2,\n", 19 | " JxBra, JyBra, JzBra,\n", 20 | " JxKet, JyKet, JzKet,\n", 21 | ")\n", 22 | "from IPython.core.display import display_pretty\n", 23 | "from sympy.physics.quantum.operator import *\n", 24 | "\n", 25 | "%load_ext sympyprinting" 26 | ], 27 | "language": "python", 28 | "metadata": {}, 29 | "outputs": [], 30 | "prompt_number": 2 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "##Fidelity using some kets" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "collapsed": false, 42 | "input": [ 43 | "up = JzKet(S(1)/2,S(1)/2)\n", 44 | "down = JzKet(S(1)/2,-S(1)/2)\n", 45 | "amp = 1/sqrt(2)\n", 46 | "updown = (amp * up ) + (amp * down)\n", 47 | "\n", 48 | "# represent turns Kets into matrices\n", 49 | "up_dm = represent(up * Dagger(up))\n", 50 | "down_dm = represent(down * Dagger(down)) \n", 51 | "updown_dm = represent(updown * Dagger(updown))\n", 52 | "updown2 = (sqrt(3)/2 )* up + (1/2)*down\n", 53 | "\n", 54 | "\n", 55 | "display_pretty(fidelity(up_dm, up_dm))\n", 56 | "display_pretty(fidelity(up_dm, down_dm)) #orthogonal states\n", 57 | "display_pretty(fidelity(up_dm, updown_dm).evalf())\n", 58 | "\n", 59 | "\n", 60 | "# alternatively, puts Kets into Density object and compute fidelity\n", 61 | "d1 = Density( [updown, 0.25], [updown2, 0.75])\n", 62 | "d2 = Density( [updown, 0.75], [updown2, 0.25])\n", 63 | "display_pretty(fidelity(d1, d2))" 64 | ], 65 | "language": "python", 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "output_type": "display_data", 70 | "text": [ 71 | "1" 72 | ] 73 | }, 74 | { 75 | "output_type": "display_data", 76 | "text": [ 77 | "0" 78 | ] 79 | }, 80 | { 81 | "output_type": "display_data", 82 | "text": [ 83 | "0.707106781186548" 84 | ] 85 | }, 86 | { 87 | "output_type": "display_data", 88 | "text": [ 89 | "0.817293551913876" 90 | ] 91 | } 92 | ], 93 | "prompt_number": 7 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": {}, 98 | "source": [ 99 | "## Fidelity on states as Qubits" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "collapsed": false, 105 | "input": [ 106 | "\n", 107 | "from sympy.physics.quantum.qubit import Qubit\n", 108 | "state1 = Qubit('0')\n", 109 | "state2 = Qubit('1')\n", 110 | "state3 = (1/sqrt(2))*state1 + (1/sqrt(2))*state2\n", 111 | "state4 = (sqrt(S(2)/3))*state1 + (1/sqrt(3))*state2\n", 112 | "\n", 113 | "state1_dm = Density([state1, 1])\n", 114 | "state2_dm = Density([state2, 1])\n", 115 | "state3_dm = Density([state3, 1])\n", 116 | "\n", 117 | "# mixed qubit states in density\n", 118 | "d1 = Density([state3, 0.70], [state4, 0.30])\n", 119 | "d2 = Density([state3, 0.20], [state4, 0.80])\n", 120 | "\n", 121 | "\n", 122 | "display_pretty(fidelity(d1, d2))\n", 123 | "\n" 124 | ], 125 | "language": "python", 126 | "metadata": {}, 127 | "outputs": [ 128 | { 129 | "output_type": "display_data", 130 | "text": [ 131 | "0.996370452558227" 132 | ] 133 | } 134 | ], 135 | "prompt_number": 9 136 | }, 137 | { 138 | "cell_type": "code", 139 | "collapsed": true, 140 | "input": [], 141 | "language": "python", 142 | "metadata": {}, 143 | "outputs": [] 144 | } 145 | ], 146 | "metadata": {} 147 | } 148 | ] 149 | } -------------------------------------------------------------------------------- /styles/sympy.css: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 9 | 10 | 11 | 12 | 152 | 168 | -------------------------------------------------------------------------------- /advanced/relativity.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | This example calculates the Ricci tensor from the metric and does this 5 | on the example of Schwarzschild solution. 6 | 7 | If you want to derive this by hand, follow the wiki page here: 8 | 9 | https://en.wikipedia.org/wiki/Deriving_the_Schwarzschild_solution 10 | 11 | Also read the above wiki and follow the references from there if 12 | something is not clear, like what the Ricci tensor is, etc. 13 | 14 | """ 15 | 16 | from sympy import (exp, Symbol, sin, dsolve, Function, 17 | Matrix, Eq, pprint, solve) 18 | 19 | 20 | def grad(f, X): 21 | a = [] 22 | for x in X: 23 | a.append(f.diff(x)) 24 | return a 25 | 26 | 27 | def d(m, x): 28 | return grad(m[0, 0], x) 29 | 30 | 31 | class MT: 32 | def __init__(self, m): 33 | self.gdd = m 34 | self.guu = m.inv() 35 | 36 | def __str__(self): 37 | return "g_dd =\n" + str(self.gdd) 38 | 39 | def dd(self, i, j): 40 | return self.gdd[i, j] 41 | 42 | def uu(self, i, j): 43 | return self.guu[i, j] 44 | 45 | 46 | class G: 47 | def __init__(self, g, x): 48 | self.g = g 49 | self.x = x 50 | 51 | def udd(self, i, k, l): 52 | g = self.g 53 | x = self.x 54 | r = 0 55 | for m in [0, 1, 2, 3]: 56 | r += g.uu(i, m)/2 * (g.dd(m, k).diff(x[l]) + g.dd(m, l).diff(x[k]) 57 | - g.dd(k, l).diff(x[m])) 58 | return r 59 | 60 | 61 | class Riemann: 62 | def __init__(self, G, x): 63 | self.G = G 64 | self.x = x 65 | 66 | def uddd(self, rho, sigma, mu, nu): 67 | G = self.G 68 | x = self.x 69 | r = G.udd(rho, nu, sigma).diff(x[mu]) - G.udd(rho, mu, sigma).diff(x[nu]) 70 | for lam in [0, 1, 2, 3]: 71 | r += G.udd(rho, mu, lam)*G.udd(lam, nu, sigma) \ 72 | - G.udd(rho, nu, lam)*G.udd(lam, mu, sigma) 73 | return r 74 | 75 | 76 | class Ricci: 77 | def __init__(self, R, x): 78 | self.R = R 79 | self.x = x 80 | self.g = R.G.g 81 | 82 | def dd(self, mu, nu): 83 | R = self.R 84 | x = self.x 85 | r = 0 86 | for lam in [0, 1, 2, 3]: 87 | r += R.uddd(lam, mu, lam, nu) 88 | return r 89 | 90 | def ud(self, mu, nu): 91 | r = 0 92 | for lam in [0, 1, 2, 3]: 93 | r += self.g.uu(mu, lam)*self.dd(lam, nu) 94 | return r.expand() 95 | 96 | 97 | def curvature(Rmn): 98 | return Rmn.ud(0, 0) + Rmn.ud(1, 1) + Rmn.ud(2, 2) + Rmn.ud(3, 3) 99 | 100 | nu = Function("nu") 101 | lam = Function("lambda") 102 | 103 | t = Symbol("t") 104 | r = Symbol("r") 105 | theta = Symbol(r"theta") 106 | phi = Symbol(r"phi") 107 | 108 | # general, spherically symmetric metric 109 | gdd = Matrix(( 110 | (-exp(nu(r)), 0, 0, 0), 111 | (0, exp(lam(r)), 0, 0), 112 | (0, 0, r**2, 0), 113 | (0, 0, 0, r**2*sin(theta)**2) 114 | )) 115 | g = MT(gdd) 116 | X = (t, r, theta, phi) 117 | Gamma = G(g, X) 118 | Rmn = Ricci(Riemann(Gamma, X), X) 119 | 120 | 121 | def pprint_Gamma_udd(i, k, l): 122 | pprint(Eq(Symbol('Gamma^%i_%i%i' % (i, k, l)), Gamma.udd(i, k, l))) 123 | 124 | 125 | def pprint_Rmn_dd(i, j): 126 | pprint(Eq(Symbol('R_%i%i' % (i, j)), Rmn.dd(i, j))) 127 | 128 | 129 | # from Differential Equations example 130 | def eq1(): 131 | r = Symbol("r") 132 | e = Rmn.dd(0, 0) 133 | e = e.subs(nu(r), -lam(r)) 134 | pprint(dsolve(e, lam(r))) 135 | 136 | 137 | def eq2(): 138 | r = Symbol("r") 139 | e = Rmn.dd(1, 1) 140 | C = Symbol("CC") 141 | e = e.subs(nu(r), -lam(r)) 142 | pprint(dsolve(e, lam(r))) 143 | 144 | 145 | def eq3(): 146 | r = Symbol("r") 147 | e = Rmn.dd(2, 2) 148 | e = e.subs(nu(r), -lam(r)) 149 | pprint(dsolve(e, lam(r))) 150 | 151 | 152 | def eq4(): 153 | r = Symbol("r") 154 | e = Rmn.dd(3, 3) 155 | e = e.subs(nu(r), -lam(r)) 156 | pprint(dsolve(e, lam(r))) 157 | pprint(dsolve(e, lam(r), 'best')) 158 | 159 | 160 | def main(): 161 | 162 | print("Initial metric:") 163 | pprint(gdd) 164 | print("-"*40) 165 | print("Christoffel symbols:") 166 | pprint_Gamma_udd(0, 1, 0) 167 | pprint_Gamma_udd(0, 0, 1) 168 | print() 169 | pprint_Gamma_udd(1, 0, 0) 170 | pprint_Gamma_udd(1, 1, 1) 171 | pprint_Gamma_udd(1, 2, 2) 172 | pprint_Gamma_udd(1, 3, 3) 173 | print() 174 | pprint_Gamma_udd(2, 2, 1) 175 | pprint_Gamma_udd(2, 1, 2) 176 | pprint_Gamma_udd(2, 3, 3) 177 | print() 178 | pprint_Gamma_udd(3, 2, 3) 179 | pprint_Gamma_udd(3, 3, 2) 180 | pprint_Gamma_udd(3, 1, 3) 181 | pprint_Gamma_udd(3, 3, 1) 182 | print("-"*40) 183 | print("Ricci tensor:") 184 | pprint_Rmn_dd(0, 0) 185 | e = Rmn.dd(1, 1) 186 | pprint_Rmn_dd(1, 1) 187 | pprint_Rmn_dd(2, 2) 188 | pprint_Rmn_dd(3, 3) 189 | print("-"*40) 190 | print("Solve Einstein's equations:") 191 | e = e.subs(nu(r), -lam(r)).doit() 192 | l = dsolve(e, lam(r)) 193 | pprint(l) 194 | lamsol = solve(l, lam(r))[0] 195 | metric = gdd.subs(lam(r), lamsol).subs(nu(r), -lamsol) # .combine() 196 | print("metric:") 197 | pprint(metric) 198 | 199 | if __name__ == "__main__": 200 | main() 201 | -------------------------------------------------------------------------------- /intermediate/vandermonde.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Vandermonde matrix example 4 | 5 | Demonstrates matrix computations using the Vandermonde matrix. 6 | * https://en.wikipedia.org/wiki/Vandermonde_matrix 7 | """ 8 | 9 | from sympy import Matrix, pprint, Rational, symbols, Symbol, zeros 10 | 11 | 12 | def symbol_gen(sym_str): 13 | """Symbol generator 14 | 15 | Generates sym_str_n where n is the number of times the generator 16 | has been called. 17 | """ 18 | n = 0 19 | while True: 20 | yield Symbol("%s_%d" % (sym_str, n)) 21 | n += 1 22 | 23 | 24 | def comb_w_rep(n, k): 25 | """Combinations with repetition 26 | 27 | Returns the list of k combinations with repetition from n objects. 28 | """ 29 | if k == 0: 30 | return [[]] 31 | combs = [[i] for i in range(n)] 32 | for i in range(k - 1): 33 | curr = [] 34 | for p in combs: 35 | for m in range(p[-1], n): 36 | curr.append(p + [m]) 37 | combs = curr 38 | return combs 39 | 40 | 41 | def vandermonde(order, dim=1, syms='a b c d'): 42 | """Computes a Vandermonde matrix of given order and dimension. 43 | 44 | Define syms to give beginning strings for temporary variables. 45 | 46 | Returns the Matrix, the temporary variables, and the terms for the 47 | polynomials. 48 | """ 49 | syms = syms.split() 50 | n = len(syms) 51 | if n < dim: 52 | new_syms = [] 53 | for i in range(dim - n): 54 | j, rem = divmod(i, n) 55 | new_syms.append(syms[rem] + str(j)) 56 | syms.extend(new_syms) 57 | terms = [] 58 | for i in range(order + 1): 59 | terms.extend(comb_w_rep(dim, i)) 60 | rank = len(terms) 61 | V = zeros(rank) 62 | generators = [symbol_gen(syms[i]) for i in range(dim)] 63 | all_syms = [] 64 | for i in range(rank): 65 | row_syms = [next(g) for g in generators] 66 | all_syms.append(row_syms) 67 | for j, term in enumerate(terms): 68 | v_entry = 1 69 | for k in term: 70 | v_entry *= row_syms[k] 71 | V[i*rank + j] = v_entry 72 | return V, all_syms, terms 73 | 74 | 75 | def gen_poly(points, order, syms): 76 | """Generates a polynomial using a Vandermonde system""" 77 | num_pts = len(points) 78 | if num_pts == 0: 79 | raise ValueError("Must provide points") 80 | dim = len(points[0]) - 1 81 | if dim > len(syms): 82 | raise ValueError("Must provide at least %d symbols for the polynomial" % dim) 83 | V, tmp_syms, terms = vandermonde(order, dim) 84 | if num_pts < V.shape[0]: 85 | raise ValueError( 86 | "Must provide %d points for order %d, dimension " 87 | "%d polynomial, given %d points" % 88 | (V.shape[0], order, dim, num_pts)) 89 | elif num_pts > V.shape[0]: 90 | print("gen_poly given %d points but only requires %d, "\ 91 | "continuing using the first %d points" % \ 92 | (num_pts, V.shape[0], V.shape[0])) 93 | num_pts = V.shape[0] 94 | 95 | subs_dict = {} 96 | for j in range(dim): 97 | for i in range(num_pts): 98 | subs_dict[tmp_syms[i][j]] = points[i][j] 99 | V_pts = V.subs(subs_dict) 100 | V_inv = V_pts.inv() 101 | 102 | coeffs = V_inv.multiply(Matrix([points[i][-1] for i in range(num_pts)])) 103 | 104 | f = 0 105 | for j, term in enumerate(terms): 106 | t = 1 107 | for k in term: 108 | t *= syms[k] 109 | f += coeffs[j]*t 110 | return f 111 | 112 | 113 | def main(): 114 | order = 2 115 | V, tmp_syms, _ = vandermonde(order) 116 | print("Vandermonde matrix of order 2 in 1 dimension") 117 | pprint(V) 118 | 119 | print('-'*79) 120 | print(r"Computing the determinant and comparing to \sum_{0 3: 51 | raise RuntimeError("Bernstein only implemented in 1D, 2D, and 3D") 52 | sum = 0 53 | basis = [] 54 | coeff = [] 55 | 56 | if nsd == 1: 57 | b1, b2 = x, 1 - x 58 | for o1 in range(0, order + 1): 59 | for o2 in range(0, order + 1): 60 | if o1 + o2 == order: 61 | aij = Symbol("a_%d_%d" % (o1, o2)) 62 | sum += aij*binomial(order, o1)*pow(b1, o1)*pow(b2, o2) 63 | basis.append(binomial(order, o1)*pow(b1, o1)*pow(b2, o2)) 64 | coeff.append(aij) 65 | 66 | if nsd == 2: 67 | b1, b2, b3 = x, y, 1 - x - y 68 | for o1 in range(0, order + 1): 69 | for o2 in range(0, order + 1): 70 | for o3 in range(0, order + 1): 71 | if o1 + o2 + o3 == order: 72 | aij = Symbol("a_%d_%d_%d" % (o1, o2, o3)) 73 | fac = factorial(order) / (factorial(o1)*factorial(o2)*factorial(o3)) 74 | sum += aij*fac*pow(b1, o1)*pow(b2, o2)*pow(b3, o3) 75 | basis.append(fac*pow(b1, o1)*pow(b2, o2)*pow(b3, o3)) 76 | coeff.append(aij) 77 | 78 | if nsd == 3: 79 | b1, b2, b3, b4 = x, y, z, 1 - x - y - z 80 | for o1 in range(0, order + 1): 81 | for o2 in range(0, order + 1): 82 | for o3 in range(0, order + 1): 83 | for o4 in range(0, order + 1): 84 | if o1 + o2 + o3 + o4 == order: 85 | aij = Symbol("a_%d_%d_%d_%d" % (o1, o2, o3, o4)) 86 | fac = factorial(order)/(factorial(o1)*factorial(o2)*factorial(o3)*factorial(o4)) 87 | sum += aij*fac*pow(b1, o1)*pow(b2, o2)*pow(b3, o3)*pow(b4, o4) 88 | basis.append(fac*pow(b1, o1)*pow(b2, o2)*pow(b3, o3)*pow(b4, o4)) 89 | coeff.append(aij) 90 | 91 | return sum, coeff, basis 92 | 93 | 94 | def create_point_set(order, nsd): 95 | h = Rational(1, order) 96 | set = [] 97 | 98 | if nsd == 1: 99 | for i in range(0, order + 1): 100 | x = i*h 101 | if x <= 1: 102 | set.append((x, y)) 103 | 104 | if nsd == 2: 105 | for i in range(0, order + 1): 106 | x = i*h 107 | for j in range(0, order + 1): 108 | y = j*h 109 | if x + y <= 1: 110 | set.append((x, y)) 111 | 112 | if nsd == 3: 113 | for i in range(0, order + 1): 114 | x = i*h 115 | for j in range(0, order + 1): 116 | y = j*h 117 | for k in range(0, order + 1): 118 | z = k*h 119 | if x + y + z <= 1: 120 | set.append((x, y, z)) 121 | 122 | return set 123 | 124 | 125 | def create_matrix(equations, coeffs): 126 | A = zeros(len(equations)) 127 | i = 0 128 | j = 0 129 | for j in range(0, len(coeffs)): 130 | c = coeffs[j] 131 | for i in range(0, len(equations)): 132 | e = equations[i] 133 | d, _ = reduced(e, [c]) 134 | A[i, j] = d[0] 135 | return A 136 | 137 | 138 | class Lagrange: 139 | def __init__(self, nsd, order): 140 | self.nsd = nsd 141 | self.order = order 142 | self.compute_basis() 143 | 144 | def nbf(self): 145 | return len(self.N) 146 | 147 | def compute_basis(self): 148 | order = self.order 149 | nsd = self.nsd 150 | N = [] 151 | pol, coeffs, basis = bernstein_space(order, nsd) 152 | points = create_point_set(order, nsd) 153 | 154 | equations = [] 155 | for p in points: 156 | ex = pol.subs(x, p[0]) 157 | if nsd > 1: 158 | ex = ex.subs(y, p[1]) 159 | if nsd > 2: 160 | ex = ex.subs(z, p[2]) 161 | equations.append(ex) 162 | 163 | A = create_matrix(equations, coeffs) 164 | Ainv = A.inv() 165 | 166 | b = eye(len(equations)) 167 | 168 | xx = Ainv*b 169 | 170 | for i in range(0, len(equations)): 171 | Ni = pol 172 | for j in range(0, len(coeffs)): 173 | Ni = Ni.subs(coeffs[j], xx[j, i]) 174 | N.append(Ni) 175 | 176 | self.N = N 177 | 178 | 179 | def main(): 180 | t = ReferenceSimplex(2) 181 | fe = Lagrange(2, 2) 182 | 183 | u = 0 184 | # compute u = sum_i u_i N_i 185 | us = [] 186 | for i in range(0, fe.nbf()): 187 | ui = Symbol("u_%d" % i) 188 | us.append(ui) 189 | u += ui*fe.N[i] 190 | 191 | J = zeros(fe.nbf()) 192 | for i in range(0, fe.nbf()): 193 | Fi = u*fe.N[i] 194 | print(Fi) 195 | for j in range(0, fe.nbf()): 196 | uj = us[j] 197 | integrands = diff(Fi, uj) 198 | print(integrands) 199 | J[j, i] = t.integrate(integrands) 200 | 201 | pprint(J) 202 | 203 | 204 | if __name__ == "__main__": 205 | main() 206 | -------------------------------------------------------------------------------- /advanced/pyglet_plotting.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Plotting Examples 5 | 6 | Suggested Usage: python -i pyglet_plotting.py 7 | """ 8 | 9 | 10 | from sympy import symbols, sin, cos, pi, sqrt 11 | from sympy.plotting.pygletplot import PygletPlot 12 | 13 | from time import sleep, perf_counter 14 | 15 | 16 | def main(): 17 | x, y, z = symbols('x,y,z') 18 | 19 | # toggle axes visibility with F5, colors with F6 20 | axes_options = 'visible=false; colored=true; label_ticks=true; label_axes=true; overlay=true; stride=0.5' 21 | # axes_options = 'colored=false; overlay=false; stride=(1.0, 0.5, 0.5)' 22 | 23 | p = PygletPlot( 24 | width=600, 25 | height=500, 26 | ortho=False, 27 | invert_mouse_zoom=False, 28 | axes=axes_options, 29 | antialiasing=True) 30 | 31 | examples = [] 32 | 33 | def example_wrapper(f): 34 | examples.append(f) 35 | return f 36 | 37 | @example_wrapper 38 | def mirrored_saddles(): 39 | p[5] = x**2 - y**2, [20], [20] 40 | p[6] = y**2 - x**2, [20], [20] 41 | 42 | @example_wrapper 43 | def mirrored_saddles_saveimage(): 44 | p[5] = x**2 - y**2, [20], [20] 45 | p[6] = y**2 - x**2, [20], [20] 46 | p.wait_for_calculations() 47 | # although the calculation is complete, 48 | # we still need to wait for it to be 49 | # rendered, so we'll sleep to be sure. 50 | sleep(1) 51 | p.saveimage("plot_example.png") 52 | 53 | @example_wrapper 54 | def mirrored_ellipsoids(): 55 | p[2] = x**2 + y**2, [40], [40], 'color=zfade' 56 | p[3] = -x**2 - y**2, [40], [40], 'color=zfade' 57 | 58 | @example_wrapper 59 | def saddle_colored_by_derivative(): 60 | f = x**2 - y**2 61 | p[1] = f, 'style=solid' 62 | p[1].color = abs(f.diff(x)), abs(f.diff(x) + f.diff(y)), abs(f.diff(y)) 63 | 64 | @example_wrapper 65 | def ding_dong_surface(): 66 | f = sqrt(1.0 - y)*y 67 | p[1] = f, [x, 0, 2*pi, 68 | 40], [y, - 69 | 1, 4, 100], 'mode=cylindrical; style=solid; color=zfade4' 70 | 71 | @example_wrapper 72 | def polar_circle(): 73 | p[7] = 1, 'mode=polar' 74 | 75 | @example_wrapper 76 | def polar_flower(): 77 | p[8] = 1.5*sin(4*x), [160], 'mode=polar' 78 | p[8].color = z, x, y, (0.5, 0.5, 0.5), ( 79 | 0.8, 0.8, 0.8), (x, y, None, z) # z is used for t 80 | 81 | @example_wrapper 82 | def simple_cylinder(): 83 | p[9] = 1, 'mode=cylindrical' 84 | 85 | @example_wrapper 86 | def cylindrical_hyperbola(): 87 | # (note that polar is an alias for cylindrical) 88 | p[10] = 1/y, 'mode=polar', [x], [y, -2, 2, 20] 89 | 90 | @example_wrapper 91 | def extruded_hyperbolas(): 92 | p[11] = 1/x, [x, -10, 10, 100], [1], 'style=solid' 93 | p[12] = -1/x, [x, -10, 10, 100], [1], 'style=solid' 94 | 95 | @example_wrapper 96 | def torus(): 97 | a, b = 1, 0.5 # radius, thickness 98 | p[13] = (a + b*cos(x))*cos(y), (a + b*cos(x)) *\ 99 | sin(y), b*sin(x), [x, 0, pi*2, 40], [y, 0, pi*2, 40] 100 | 101 | @example_wrapper 102 | def warped_torus(): 103 | a, b = 2, 1 # radius, thickness 104 | p[13] = (a + b*cos(x))*cos(y), (a + b*cos(x))*sin(y), b *\ 105 | sin(x) + 0.5*sin(4*y), [x, 0, pi*2, 40], [y, 0, pi*2, 40] 106 | 107 | @example_wrapper 108 | def parametric_spiral(): 109 | p[14] = cos(y), sin(y), y / 10.0, [y, -4*pi, 4*pi, 100] 110 | p[14].color = x, (0.1, 0.9), y, (0.1, 0.9), z, (0.1, 0.9) 111 | 112 | @example_wrapper 113 | def multistep_gradient(): 114 | p[1] = 1, 'mode=spherical', 'style=both' 115 | # p[1] = exp(-x**2-y**2+(x*y)/4), [-1.7,1.7,100], [-1.7,1.7,100], 'style=solid' 116 | # p[1] = 5*x*y*exp(-x**2-y**2), [-2,2,100], [-2,2,100] 117 | gradient = [0.0, (0.3, 0.3, 1.0), 118 | 0.30, (0.3, 1.0, 0.3), 119 | 0.55, (0.95, 1.0, 0.2), 120 | 0.65, (1.0, 0.95, 0.2), 121 | 0.85, (1.0, 0.7, 0.2), 122 | 1.0, (1.0, 0.3, 0.2)] 123 | p[1].color = z, [None, None, z], gradient 124 | # p[1].color = 'zfade' 125 | # p[1].color = 'zfade3' 126 | 127 | @example_wrapper 128 | def lambda_vs_sympy_evaluation(): 129 | start = perf_counter() 130 | p[4] = x**2 + y**2, [100], [100], 'style=solid' 131 | p.wait_for_calculations() 132 | print("lambda-based calculation took %s seconds." % (perf_counter() - start)) 133 | 134 | start = perf_counter() 135 | p[4] = x**2 + y**2, [100], [100], 'style=solid; use_sympy_eval' 136 | p.wait_for_calculations() 137 | print( 138 | "sympy substitution-based calculation took %s seconds." % 139 | (perf_counter() - start)) 140 | 141 | @example_wrapper 142 | def gradient_vectors(): 143 | def gradient_vectors_inner(f, i): 144 | from sympy import lambdify 145 | from sympy.plotting.plot_interval import PlotInterval 146 | from pyglet.gl import glBegin, glColor3f 147 | from pyglet.gl import glVertex3f, glEnd, GL_LINES 148 | 149 | def draw_gradient_vectors(f, iu, iv): 150 | """ 151 | Create a function which draws vectors 152 | representing the gradient of f. 153 | """ 154 | dx, dy, dz = f.diff(x), f.diff(y), 0 155 | FF = lambdify([x, y], [x, y, f]) 156 | FG = lambdify([x, y], [dx, dy, dz]) 157 | iu.v_steps /= 5 158 | iv.v_steps /= 5 159 | Gvl = [[[FF(u, v), FG(u, v)] 160 | for v in iv.frange()] 161 | for u in iu.frange()] 162 | 163 | def draw_arrow(p1, p2): 164 | """ 165 | Draw a single vector. 166 | """ 167 | glColor3f(0.4, 0.4, 0.9) 168 | glVertex3f(*p1) 169 | 170 | glColor3f(0.9, 0.4, 0.4) 171 | glVertex3f(*p2) 172 | 173 | def draw(): 174 | """ 175 | Iterate through the calculated 176 | vectors and draw them. 177 | """ 178 | glBegin(GL_LINES) 179 | for u in Gvl: 180 | for v in u: 181 | point = [[v[0][0], v[0][1], v[0][2]], 182 | [v[0][0] + v[1][0], v[0][1] + v[1][1], v[0][2] + v[1][2]]] 183 | draw_arrow(point[0], point[1]) 184 | glEnd() 185 | 186 | return draw 187 | p[i] = f, [-0.5, 0.5, 25], [-0.5, 0.5, 25], 'style=solid' 188 | iu = PlotInterval(p[i].intervals[0]) 189 | iv = PlotInterval(p[i].intervals[1]) 190 | p[i].postdraw.append(draw_gradient_vectors(f, iu, iv)) 191 | 192 | gradient_vectors_inner(x**2 + y**2, 1) 193 | gradient_vectors_inner(-x**2 - y**2, 2) 194 | 195 | def help_str(): 196 | s = ("\nPlot p has been created. Useful commands: \n" 197 | " help(p), p[1] = x**2, print(p), p.clear() \n\n" 198 | "Available examples (see source in plotting.py):\n\n") 199 | for i in range(len(examples)): 200 | s += "(%i) %s\n" % (i, examples[i].__name__) 201 | s += "\n" 202 | s += "e.g. >>> example(2)\n" 203 | s += " >>> ding_dong_surface()\n" 204 | return s 205 | 206 | def example(i): 207 | if callable(i): 208 | p.clear() 209 | i() 210 | elif i >= 0 and i < len(examples): 211 | p.clear() 212 | examples[i]() 213 | else: 214 | print("Not a valid example.\n") 215 | print(p) 216 | 217 | example(0) # 0 - 15 are defined above 218 | print(help_str()) 219 | 220 | if __name__ == "__main__": 221 | main() 222 | -------------------------------------------------------------------------------- /notebooks/trace.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "trace" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "code", 12 | "collapsed": true, 13 | "input": [ 14 | "from sympy import symbols\n", 15 | "from sympy.physics.quantum.trace import Tr\n", 16 | "from sympy.matrices.matrices import Matrix\n", 17 | "from IPython.core.display import display_pretty\n", 18 | "from sympy.printing.latex import *\n", 19 | "\n", 20 | "%load_ext sympyprinting" 21 | ], 22 | "language": "python", 23 | "metadata": {}, 24 | "outputs": [], 25 | "prompt_number": 2 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "###Basic Examples" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "collapsed": true, 37 | "input": [ 38 | "a, b, c, d = symbols('a b c d'); \n", 39 | "A, B = symbols('A B', commutative=False)\n", 40 | "t = Tr(A*B)" 41 | ], 42 | "language": "python", 43 | "metadata": {}, 44 | "outputs": [], 45 | "prompt_number": 3 46 | }, 47 | { 48 | "cell_type": "code", 49 | "collapsed": false, 50 | "input": [ 51 | "t" 52 | ], 53 | "language": "python", 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "latex": [ 58 | "$$\\mbox{Tr}\\left(A B\\right)$$" 59 | ], 60 | "output_type": "pyout", 61 | "prompt_number": 4, 62 | "text": [ 63 | "Tr(A\u22c5B)" 64 | ] 65 | } 66 | ], 67 | "prompt_number": 4 68 | }, 69 | { 70 | "cell_type": "code", 71 | "collapsed": false, 72 | "input": [ 73 | "latex(t)" 74 | ], 75 | "language": "python", 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "output_type": "pyout", 80 | "prompt_number": 5, 81 | "text": [ 82 | "\\mbox{Tr}\\left(A B\\right)" 83 | ] 84 | } 85 | ], 86 | "prompt_number": 5 87 | }, 88 | { 89 | "cell_type": "code", 90 | "collapsed": false, 91 | "input": [ 92 | "display_pretty(t)" 93 | ], 94 | "language": "python", 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "output_type": "display_data", 99 | "text": [ 100 | "Tr(\u03c1((\u27581,1\u27e9, 0.5),(\u27581,-1\u27e9, 0.5)))" 101 | ] 102 | } 103 | ], 104 | "prompt_number": 14 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "### Using Matrices" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "collapsed": true, 116 | "input": [ 117 | "t = Tr ( Matrix([ [2,3], [3,4] ]))" 118 | ], 119 | "language": "python", 120 | "metadata": {}, 121 | "outputs": [], 122 | "prompt_number": 15 123 | }, 124 | { 125 | "cell_type": "code", 126 | "collapsed": false, 127 | "input": [ 128 | "t" 129 | ], 130 | "language": "python", 131 | "metadata": {}, 132 | "outputs": [ 133 | { 134 | "latex": [ 135 | "$$6$$" 136 | ], 137 | "output_type": "pyout", 138 | "png": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAASCAYAAABvqT8MAAAABHNCSVQICAgIfAhkiAAAAO5JREFU\nKJHN0r1KQ0EQhuHnhAgBhaiIFpLOxs5O8CIsFG/A1spCL0CwsUtnaat4C7aWNooiCAEJKBb+oMGg\nSCzOHlyWlWDnV+3M7vvN7O7wRxWZXAs7+MIL3rCHXs5gGh0shXgS19isDtQSYB9tnIa4jgZec+5r\n+MD4sHtUOsTlsEP1aL2AeyxiGbNoYgs3KTiqfJVzbET5FTxhLgVmMEAfY1G+FqoepcBIAC4ybZ8p\n/6KoHOATd6F8ql5oeSIG4ARTGaCBLh7TjVW8V05BBZ5xkDECx9j1M2PruIpN0uFrYhvzofcH5ajc\n/lbhH+gb6f4rZTpaz0QAAAAASUVORK5CYII=\n", 139 | "prompt_number": 16, 140 | "text": [ 141 | "6" 142 | ] 143 | } 144 | ], 145 | "prompt_number": 16 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "### Example using modules in physics.quantum" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "collapsed": true, 157 | "input": [ 158 | "from sympy.physics.quantum.density import Density\n", 159 | "from sympy.physics.quantum.spin import (\n", 160 | " Jx, Jy, Jz, Jplus, Jminus, J2,\n", 161 | " JxBra, JyBra, JzBra,\n", 162 | " JxKet, JyKet, JzKet,\n", 163 | ")" 164 | ], 165 | "language": "python", 166 | "metadata": {}, 167 | "outputs": [], 168 | "prompt_number": 7 169 | }, 170 | { 171 | "cell_type": "code", 172 | "collapsed": false, 173 | "input": [ 174 | "d = Density([JzKet(1,1),0.5],[JzKet(1,-1),0.5]); d" 175 | ], 176 | "language": "python", 177 | "metadata": {}, 178 | "outputs": [ 179 | { 180 | "latex": [ 181 | "$$\\rho\\left(\\begin{pmatrix}{\\left|1,1\\right\\rangle }, & 0.5\\end{pmatrix},\\begin{pmatrix}{\\left|1,-1\\right\\rangle }, & 0.5\\end{pmatrix}\\right)$$" 182 | ], 183 | "output_type": "pyout", 184 | "prompt_number": 8, 185 | "text": [ 186 | "\u03c1((\u27581,1\u27e9, 0.5),(\u27581,-1\u27e9, 0.5))" 187 | ] 188 | } 189 | ], 190 | "prompt_number": 8 191 | }, 192 | { 193 | "cell_type": "code", 194 | "collapsed": true, 195 | "input": [ 196 | "t = Tr(d)" 197 | ], 198 | "language": "python", 199 | "metadata": {}, 200 | "outputs": [], 201 | "prompt_number": 9 202 | }, 203 | { 204 | "cell_type": "code", 205 | "collapsed": false, 206 | "input": [ 207 | "t" 208 | ], 209 | "language": "python", 210 | "metadata": {}, 211 | "outputs": [ 212 | { 213 | "latex": [ 214 | "$$\\mbox{Tr}\\left(\\rho\\left(\\begin{pmatrix}{\\left|1,1\\right\\rangle }, & 0.5\\end{pmatrix},\\begin{pmatrix}{\\left|1,-1\\right\\rangle }, & 0.5\\end{pmatrix}\\right)\\right)$$" 215 | ], 216 | "output_type": "pyout", 217 | "prompt_number": 10, 218 | "text": [ 219 | "Tr(\u03c1((\u27581,1\u27e9, 0.5),(\u27581,-1\u27e9, 0.5)))" 220 | ] 221 | } 222 | ], 223 | "prompt_number": 10 224 | }, 225 | { 226 | "cell_type": "code", 227 | "collapsed": false, 228 | "input": [ 229 | "latex(t)" 230 | ], 231 | "language": "python", 232 | "metadata": {}, 233 | "outputs": [ 234 | { 235 | "output_type": "pyout", 236 | "prompt_number": 11, 237 | "text": [ 238 | "\n", 239 | "\\mbox{Tr}\\left(\\rho\\left(\\begin{pmatrix}{\\left|1,1\\right\\rangle }, & 0.5\\end{p\n", 240 | "matrix},\\begin{pmatrix}{\\left|1,-1\\right\\rangle }, & 0.5\\end{pmatrix}\\right)\\r\n", 241 | "ight)" 242 | ] 243 | } 244 | ], 245 | "prompt_number": 11 246 | }, 247 | { 248 | "cell_type": "code", 249 | "collapsed": false, 250 | "input": [ 251 | "t.doit()" 252 | ], 253 | "language": "python", 254 | "metadata": {}, 255 | "outputs": [ 256 | { 257 | "latex": [ 258 | "$$1.0$$" 259 | ], 260 | "output_type": "pyout", 261 | "png": "iVBORw0KGgoAAAANSUhEUgAAABsAAAASCAYAAACq26WdAAAABHNCSVQICAgIfAhkiAAAASNJREFU\nOI3t1EErBGEcx/HPimLXgUiU5eKinGxyc8KLkLeDK+WqpChcpJQjBxc33JALsgfFwYrEOsws0za7\nBpOT3+U/z/eZZ77PMzPPwx8mU4P3Yg8DCZ/TjDlkUQzbqziuNyiHSZyinFAEy1iLtMdxja5aAwax\nhVkcfEPWjxdMVPErrCSdaVLZPB4Fry6aJdyioQIa/D4FXOKpip+jA0NpyrrxEMNLYe1JW1aK4RXW\nlqbsGW8xvCmsH31pyE5q8FxYb9KUHaM9hreGtZi2LB/DR3Av+FN/JcujJbw+EqxsNNLfiDEsCr5p\n3WwLNnXccVPAK3bDdgab2PA5+SnBduisJejCPs5CURl3OMR05L4+XGAmwrKCk2QdC9jB8Fcr+s+P\n8g572TfbrLZhHwAAAABJRU5ErkJggg==\n", 262 | "prompt_number": 12, 263 | "text": [ 264 | "1.00000000000000" 265 | ] 266 | } 267 | ], 268 | "prompt_number": 12 269 | }, 270 | { 271 | "cell_type": "code", 272 | "collapsed": true, 273 | "input": [], 274 | "language": "python", 275 | "metadata": {}, 276 | "outputs": [], 277 | "prompt_number": 12 278 | } 279 | ], 280 | "metadata": {} 281 | } 282 | ] 283 | } -------------------------------------------------------------------------------- /beginner/plot_colors.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "plot_colors" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [ 7 | { 8 | "cells": [ 9 | { 10 | "cell_type": "markdown", 11 | "source": [ 12 | "#Coloring" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "source": [ 18 | "", 19 | "", 20 | "### Cartesian Line Plot" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "collapsed": true, 26 | "input": [ 27 | "from sympy.plotting import plot, plot_parametric, plot3d, plot3d_parametric_line, plot3d_parametric_surface" 28 | ], 29 | "language": "python", 30 | "outputs": [], 31 | "prompt_number": 1 32 | }, 33 | { 34 | "cell_type": "code", 35 | "collapsed": false, 36 | "input": [ 37 | "p = plot(sin(x))" 38 | ], 39 | "language": "python", 40 | "outputs": [], 41 | "prompt_number": 2 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "source": [ 46 | "", 47 | "", 48 | "If the `line_color` aesthetic is a function of arity 1 then the coloring is a function of the x value of a point." 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "collapsed": false, 54 | "input": [ 55 | "p[0].line_color = lambda a : a", 56 | "", 57 | "p.show()" 58 | ], 59 | "language": "python", 60 | "outputs": [], 61 | "prompt_number": 3 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "source": [ 66 | "", 67 | "", 68 | "If the arity is 2 then the coloring is a function of both coordinates." 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "collapsed": false, 74 | "input": [ 75 | "p[0].line_color = lambda a, b : b", 76 | "", 77 | "p.show()" 78 | ], 79 | "language": "python", 80 | "outputs": [], 81 | "prompt_number": 4 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "source": [ 86 | "### Parametric Lines" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "collapsed": false, 92 | "input": [ 93 | "p = plot_parametric(x*sin(x), x*cos(x), (x, 0, 10))" 94 | ], 95 | "language": "python", 96 | "outputs": [], 97 | "prompt_number": 5 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "source": [ 102 | "", 103 | "", 104 | "If the arity is 1 the coloring depends on the parameter." 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "collapsed": false, 110 | "input": [ 111 | "p[0].line_color = lambda a : a", 112 | "", 113 | "p.show()" 114 | ], 115 | "language": "python", 116 | "outputs": [], 117 | "prompt_number": 6 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "source": [ 122 | "", 123 | "", 124 | "For arity 2 the coloring depends on coordinates." 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "collapsed": false, 130 | "input": [ 131 | "p[0].line_color = lambda a, b : a", 132 | "", 133 | "p.show()" 134 | ], 135 | "language": "python", 136 | "outputs": [], 137 | "prompt_number": 7 138 | }, 139 | { 140 | "cell_type": "code", 141 | "collapsed": false, 142 | "input": [ 143 | "p[0].line_color = lambda a, b : b", 144 | "", 145 | "p.show()" 146 | ], 147 | "language": "python", 148 | "outputs": [], 149 | "prompt_number": 8 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "source": [ 154 | "### 3D Parametric line" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "source": [ 160 | "", 161 | "", 162 | "Arity 1 - the first parameter. Arity 2 or 3 - the first two coordinates or all coordinates." 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "collapsed": false, 168 | "input": [ 169 | "p = plot3d_parametric_line(sin(x)+0.1*sin(x)*cos(7*x),", 170 | "", 171 | " cos(x)+0.1*cos(x)*cos(7*x),", 172 | "", 173 | " 0.1*sin(7*x),", 174 | "", 175 | " (x, 0, 2*pi))" 176 | ], 177 | "language": "python", 178 | "outputs": [], 179 | "prompt_number": 9 180 | }, 181 | { 182 | "cell_type": "code", 183 | "collapsed": false, 184 | "input": [ 185 | "p[0].line_color = lambda a : sin(4*a)", 186 | "", 187 | "p.show()" 188 | ], 189 | "language": "python", 190 | "outputs": [], 191 | "prompt_number": 10 192 | }, 193 | { 194 | "cell_type": "code", 195 | "collapsed": false, 196 | "input": [ 197 | "p[0].line_color = lambda a, b : b", 198 | "", 199 | "p.show()" 200 | ], 201 | "language": "python", 202 | "outputs": [], 203 | "prompt_number": 11 204 | }, 205 | { 206 | "cell_type": "code", 207 | "collapsed": false, 208 | "input": [ 209 | "p[0].line_color = lambda a, b, c : c", 210 | "", 211 | "p.show()" 212 | ], 213 | "language": "python", 214 | "outputs": [], 215 | "prompt_number": 12 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "source": [ 220 | "### Cartesian Surface Plot" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "collapsed": false, 226 | "input": [ 227 | "p = plot3d(sin(x)*y, (x, 0, 6*pi), (y, -5, 5))" 228 | ], 229 | "language": "python", 230 | "outputs": [], 231 | "prompt_number": 14 232 | }, 233 | { 234 | "cell_type": "markdown", 235 | "source": [ 236 | "", 237 | "", 238 | "Arity 1, 2 or 3 for first, the two first or all coordinates." 239 | ] 240 | }, 241 | { 242 | "cell_type": "code", 243 | "collapsed": false, 244 | "input": [ 245 | "p[0].surface_color = lambda a : a", 246 | "", 247 | "p.show()" 248 | ], 249 | "language": "python", 250 | "outputs": [], 251 | "prompt_number": 15 252 | }, 253 | { 254 | "cell_type": "code", 255 | "collapsed": false, 256 | "input": [ 257 | "p[0].surface_color = lambda a, b : b", 258 | "", 259 | "p.show()" 260 | ], 261 | "language": "python", 262 | "outputs": [], 263 | "prompt_number": 16 264 | }, 265 | { 266 | "cell_type": "code", 267 | "collapsed": false, 268 | "input": [ 269 | "p[0].surface_color = lambda a, b, c : c", 270 | "", 271 | "p.show()" 272 | ], 273 | "language": "python", 274 | "outputs": [], 275 | "prompt_number": 17 276 | }, 277 | { 278 | "cell_type": "code", 279 | "collapsed": false, 280 | "input": [ 281 | "p[0].surface_color = lambda a, b, c : sqrt((a-3*pi)**2+b**2)", 282 | "", 283 | "p.show()" 284 | ], 285 | "language": "python", 286 | "outputs": [], 287 | "prompt_number": 18 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "source": [ 292 | "### Parametric surface plots" 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "source": [ 298 | "", 299 | "", 300 | "Arity 1 or 2 - first or both parameters." 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "collapsed": false, 306 | "input": [ 307 | "p = plot3d_parametric_surface(x*cos(4*y), x*sin(4*y), y,", 308 | "", 309 | " (x, -1, 1), (y, -1, 1))" 310 | ], 311 | "language": "python", 312 | "outputs": [], 313 | "prompt_number": 19 314 | }, 315 | { 316 | "cell_type": "code", 317 | "collapsed": false, 318 | "input": [ 319 | "p[0].surface_color = lambda a : a", 320 | "", 321 | "p.show()" 322 | ], 323 | "language": "python", 324 | "outputs": [], 325 | "prompt_number": 20 326 | }, 327 | { 328 | "cell_type": "code", 329 | "collapsed": false, 330 | "input": [ 331 | "p[0].surface_color = lambda a, b : a*b", 332 | "", 333 | "p.show()" 334 | ], 335 | "language": "python", 336 | "outputs": [], 337 | "prompt_number": 21 338 | }, 339 | { 340 | "cell_type": "markdown", 341 | "source": [ 342 | "Arrity of 3 will color by coordinates." 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "collapsed": false, 348 | "input": [ 349 | "p[0].surface_color = lambda a, b, c : sqrt(a**2+b**2+c**2)", 350 | "", 351 | "p.show()" 352 | ], 353 | "language": "python", 354 | "outputs": [], 355 | "prompt_number": 22 356 | } 357 | ] 358 | } 359 | ] 360 | } -------------------------------------------------------------------------------- /advanced/autowrap_integrators.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Numerical integration with autowrap 4 | ----------------------------------- 5 | 6 | This example demonstrates how you can use the autowrap module in SymPy 7 | to create fast, numerical integration routines callable from python. See 8 | in the code for detailed explanations of the various steps. An 9 | autowrapped sympy expression can be significantly faster than what you 10 | would get by applying a sequence of the ufuncs shipped with numpy. [0] 11 | 12 | We will find the coefficients needed to approximate a quantum mechanical 13 | Hydrogen wave function in terms of harmonic oscillator solutions. For 14 | the sake of demonstration, this will be done by setting up a simple 15 | numerical integration scheme as a SymPy expression, and obtain a binary 16 | implementation with autowrap. 17 | 18 | You need to have numpy installed to run this example, as well as a 19 | working fortran compiler. If you have pylab installed, you will be 20 | rewarded with a nice plot in the end. 21 | 22 | [0]: 23 | http://ojensen.wordpress.com/2010/08/10/fast-ufunc-ish-hydrogen-solutions/ 24 | 25 | ---- 26 | """ 27 | 28 | import sys 29 | from sympy.external import import_module 30 | 31 | np = import_module('numpy') 32 | if not np: 33 | sys.exit("Cannot import numpy. Exiting.") 34 | pylab = import_module('pylab', warn_not_installed=True) 35 | 36 | from sympy.utilities.lambdify import implemented_function 37 | from sympy.utilities.autowrap import autowrap, ufuncify 38 | from sympy import Idx, IndexedBase, Lambda, pprint, Symbol, oo, Integral,\ 39 | Function 40 | from sympy.physics.sho import R_nl 41 | from sympy.physics.hydrogen import R_nl as hydro_nl 42 | 43 | 44 | # *************************************************************************** 45 | # calculation parameters to play with 46 | # *************************************************************************** 47 | 48 | basis_dimension = 5 # Size of h.o. basis (n < basis_dimension) 49 | omega2 = 0.1 # in atomic units: twice the oscillator frequency 50 | orbital_momentum_l = 1 # the quantum number `l` for angular momentum 51 | hydrogen_n = 2 # the nodal quantum number for the Hydrogen wave 52 | rmax = 20 # cut off in the radial direction 53 | gridsize = 200 # number of points in the grid 54 | 55 | # *************************************************************************** 56 | 57 | 58 | def main(): 59 | 60 | print(__doc__) 61 | 62 | # arrays are represented with IndexedBase, indices with Idx 63 | m = Symbol('m', integer=True) 64 | i = Idx('i', m) 65 | A = IndexedBase('A') 66 | B = IndexedBase('B') 67 | x = Symbol('x') 68 | 69 | print("Compiling ufuncs for radial harmonic oscillator solutions") 70 | 71 | # setup a basis of ho-solutions (for l=0) 72 | basis_ho = {} 73 | for n in range(basis_dimension): 74 | 75 | # Setup the radial ho solution for this n 76 | expr = R_nl(n, orbital_momentum_l, omega2, x) 77 | 78 | # Reduce the number of operations in the expression by eval to float 79 | expr = expr.evalf(15) 80 | 81 | print("The h.o. wave function with l = %i and n = %i is" % ( 82 | orbital_momentum_l, n)) 83 | pprint(expr) 84 | 85 | # implement, compile and wrap it as a ufunc 86 | basis_ho[n] = ufuncify(x, expr) 87 | 88 | # now let's see if we can express a hydrogen radial wave in terms of 89 | # the ho basis. Here's the solution we will approximate: 90 | H_ufunc = ufuncify(x, hydro_nl(hydrogen_n, orbital_momentum_l, 1, x)) 91 | 92 | # The transformation to a different basis can be written like this, 93 | # 94 | # psi(r) = sum_i c(i) phi_i(r) 95 | # 96 | # where psi(r) is the hydrogen solution, phi_i(r) are the H.O. solutions 97 | # and c(i) are scalar coefficients. 98 | # 99 | # So in order to express a hydrogen solution in terms of the H.O. basis, we 100 | # need to determine the coefficients c(i). In position space, it means 101 | # that we need to evaluate an integral: 102 | # 103 | # psi(r) = sum_i Integral(R**2*conj(phi(R))*psi(R), (R, 0, oo)) phi_i(r) 104 | # 105 | # To calculate the integral with autowrap, we notice that it contains an 106 | # element-wise sum over all vectors. Using the Indexed class, it is 107 | # possible to generate autowrapped functions that perform summations in 108 | # the low-level code. (In fact, summations are very easy to create, and as 109 | # we will see it is often necessary to take extra steps in order to avoid 110 | # them.) 111 | # we need one integration ufunc for each wave function in the h.o. basis 112 | binary_integrator = {} 113 | for n in range(basis_dimension): 114 | 115 | # 116 | # setup basis wave functions 117 | # 118 | # To get inline expressions in the low level code, we attach the 119 | # wave function expressions to a regular SymPy function using the 120 | # implemented_function utility. This is an extra step needed to avoid 121 | # erroneous summations in the wave function expressions. 122 | # 123 | # Such function objects carry around the expression they represent, 124 | # but the expression is not exposed unless explicit measures are taken. 125 | # The benefit is that the routines that searches for repeated indices 126 | # in order to make contractions will not search through the wave 127 | # function expression. 128 | psi_ho = implemented_function('psi_ho', 129 | Lambda(x, R_nl(n, orbital_momentum_l, omega2, x))) 130 | 131 | # We represent the hydrogen function by an array which will be an input 132 | # argument to the binary routine. This will let the integrators find 133 | # h.o. basis coefficients for any wave function we throw at them. 134 | psi = IndexedBase('psi') 135 | 136 | # 137 | # setup expression for the integration 138 | # 139 | 140 | step = Symbol('step') # use symbolic stepsize for flexibility 141 | 142 | # let i represent an index of the grid array, and let A represent the 143 | # grid array. Then we can approximate the integral by a sum over the 144 | # following expression (simplified rectangular rule, ignoring end point 145 | # corrections): 146 | 147 | expr = A[i]**2*psi_ho(A[i])*psi[i]*step 148 | 149 | if n == 0: 150 | print("Setting up binary integrators for the integral:") 151 | pprint(Integral(x**2*psi_ho(x)*Function('psi')(x), (x, 0, oo))) 152 | 153 | # Autowrap it. For functions that take more than one argument, it is 154 | # a good idea to use the 'args' keyword so that you know the signature 155 | # of the wrapped function. (The dimension m will be an optional 156 | # argument, but it must be present in the args list.) 157 | binary_integrator[n] = autowrap(expr, args=[A.label, psi.label, step, m]) 158 | 159 | # Lets see how it converges with the grid dimension 160 | print("Checking convergence of integrator for n = %i" % n) 161 | for g in range(3, 8): 162 | grid, step = np.linspace(0, rmax, 2**g, retstep=True) 163 | print("grid dimension %5i, integral = %e" % (2**g, 164 | binary_integrator[n](grid, H_ufunc(grid), step))) 165 | 166 | print("A binary integrator has been set up for each basis state") 167 | print("We will now use them to reconstruct a hydrogen solution.") 168 | 169 | # Note: We didn't need to specify grid or use gridsize before now 170 | grid, stepsize = np.linspace(0, rmax, gridsize, retstep=True) 171 | 172 | print("Calculating coefficients with gridsize = %i and stepsize %f" % ( 173 | len(grid), stepsize)) 174 | 175 | coeffs = {} 176 | for n in range(basis_dimension): 177 | coeffs[n] = binary_integrator[n](grid, H_ufunc(grid), stepsize) 178 | print("c(%i) = %e" % (n, coeffs[n])) 179 | 180 | print("Constructing the approximate hydrogen wave") 181 | hydro_approx = 0 182 | all_steps = {} 183 | for n in range(basis_dimension): 184 | hydro_approx += basis_ho[n](grid)*coeffs[n] 185 | all_steps[n] = hydro_approx.copy() 186 | if pylab: 187 | line = pylab.plot(grid, all_steps[n], ':', label='max n = %i' % n) 188 | 189 | # check error numerically 190 | diff = np.max(np.abs(hydro_approx - H_ufunc(grid))) 191 | print("Error estimate: the element with largest deviation misses by %f" % diff) 192 | if diff > 0.01: 193 | print("This is much, try to increase the basis size or adjust omega") 194 | else: 195 | print("Ah, that's a pretty good approximation!") 196 | 197 | # Check visually 198 | if pylab: 199 | print("Here's a plot showing the contribution for each n") 200 | line[0].set_linestyle('-') 201 | pylab.plot(grid, H_ufunc(grid), 'r-', label='exact') 202 | pylab.legend() 203 | pylab.show() 204 | 205 | print("""Note: 206 | These binary integrators were specialized to find coefficients for a 207 | harmonic oscillator basis, but they can process any wave function as long 208 | as it is available as a vector and defined on a grid with equidistant 209 | points. That is, on any grid you get from numpy.linspace. 210 | 211 | To make the integrators even more flexible, you can setup the harmonic 212 | oscillator solutions with symbolic parameters omega and l. Then the 213 | autowrapped binary routine will take these scalar variables as arguments, 214 | so that the integrators can find coefficients for *any* isotropic harmonic 215 | oscillator basis. 216 | 217 | """) 218 | 219 | 220 | if __name__ == '__main__': 221 | main() 222 | -------------------------------------------------------------------------------- /beginner/plot_intro.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "plot_intro" 4 | }, 5 | "nbformat": 2, 6 | "worksheets": [ 7 | { 8 | "cells": [ 9 | { 10 | "cell_type": "markdown", 11 | "source": [ 12 | "#New Plotting Framework for SymPy" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "source": [ 18 | "", 19 | "", 20 | "## Structure of the Module", 21 | "", 22 | "", 23 | "", 24 | "This module implements a new plotting framework for SymPy. The central class of the module is the `Plot` class that connects the data representations (subclasses of `BaseSeries`) with different plotting backends. It's not imported by default for backward compatibility with the old module.", 25 | "", 26 | "", 27 | "", 28 | "Then there are the `plot_*()` functions for plotting different kinds of plots and is better suited for interactive work.", 29 | "", 30 | "", 31 | "", 32 | "* ``plot``: Plots line plots in 2D.", 33 | "", 34 | "* ``plot_parametric``: Plots parametric line plots in 2D.", 35 | "", 36 | "* ``plot_implicit`` : Plots implicit equations and region plots in 2D", 37 | "", 38 | "* ``plot3d`` : Plots functions of two variables in 3D", 39 | "", 40 | "* ``plot3d_parametric_line``: Plots line parametric plots in 3D", 41 | "", 42 | "* ``plot3d_parametric_surface`` : Plots surface parametric plots of functions with two variables in 3D." 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "source": [ 48 | "##General examples" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "collapsed": true, 54 | "input": [ 55 | "from sympy.plotting import plot, plot_parametric, plot3d, plot3d_parametric_line, plot3d_parametric_surface" 56 | ], 57 | "language": "python", 58 | "outputs": [], 59 | "prompt_number": 8 60 | }, 61 | { 62 | "cell_type": "code", 63 | "collapsed": false, 64 | "input": [ 65 | "p = plot(x)" 66 | ], 67 | "language": "python", 68 | "outputs": [], 69 | "prompt_number": 9 70 | }, 71 | { 72 | "cell_type": "code", 73 | "collapsed": false, 74 | "input": [ 75 | "p # the Plot object" 76 | ], 77 | "language": "python", 78 | "outputs": [], 79 | "prompt_number": 10 80 | }, 81 | { 82 | "cell_type": "code", 83 | "collapsed": false, 84 | "input": [ 85 | "p[0] # one of the data series objects" 86 | ], 87 | "language": "python", 88 | "outputs": [], 89 | "prompt_number": 11 90 | }, 91 | { 92 | "cell_type": "code", 93 | "collapsed": false, 94 | "input": [ 95 | "p[0].label # an option of the data series" 96 | ], 97 | "language": "python", 98 | "outputs": [], 99 | "prompt_number": 12 100 | }, 101 | { 102 | "cell_type": "code", 103 | "collapsed": false, 104 | "input": [ 105 | "p.legend # a global option of the plot" 106 | ], 107 | "language": "python", 108 | "outputs": [], 109 | "prompt_number": 13 110 | }, 111 | { 112 | "cell_type": "code", 113 | "collapsed": false, 114 | "input": [ 115 | "p.legend = True", 116 | "", 117 | "p.show()" 118 | ], 119 | "language": "python", 120 | "outputs": [], 121 | "prompt_number": 14 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "source": [ 126 | "You can plot 2D different functions in the same plot." 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "collapsed": false, 132 | "input": [ 133 | "p1 = plot_parametric(x*sin(x),x*cos(x), show=False)", 134 | "", 135 | "p1.extend(p) # Plot objects are just like lists.", 136 | "", 137 | "p1.show()" 138 | ], 139 | "language": "python", 140 | "outputs": [], 141 | "prompt_number": 15 142 | }, 143 | { 144 | "cell_type": "code", 145 | "collapsed": false, 146 | "input": [ 147 | "p1.legend = True", 148 | "", 149 | "p1.show()" 150 | ], 151 | "language": "python", 152 | "outputs": [], 153 | "prompt_number": 16 154 | }, 155 | { 156 | "cell_type": "code", 157 | "collapsed": false, 158 | "input": [ 159 | "p1[0].line_color='r'", 160 | "", 161 | "p1[1].line_color='b' # a constant color", 162 | "", 163 | "p1.show()" 164 | ], 165 | "language": "python", 166 | "outputs": [], 167 | "prompt_number": 17 168 | }, 169 | { 170 | "cell_type": "code", 171 | "collapsed": false, 172 | "input": [ 173 | "p1[0].line_color = lambda a : a # color dependent on the parameter", 174 | "", 175 | "p1.show()" 176 | ], 177 | "language": "python", 178 | "outputs": [], 179 | "prompt_number": 18 180 | }, 181 | { 182 | "cell_type": "code", 183 | "collapsed": false, 184 | "input": [ 185 | "p1.title = 'Big title'", 186 | "", 187 | "p1.xlabel = 'the x axis'", 188 | "", 189 | "p1[1].label = 'straight line'", 190 | "", 191 | "p1.show()" 192 | ], 193 | "language": "python", 194 | "outputs": [], 195 | "prompt_number": 19 196 | }, 197 | { 198 | "cell_type": "code", 199 | "collapsed": false, 200 | "input": [ 201 | "p1.aspect_ratio" 202 | ], 203 | "language": "python", 204 | "outputs": [], 205 | "prompt_number": 20 206 | }, 207 | { 208 | "cell_type": "code", 209 | "collapsed": false, 210 | "input": [ 211 | "p1.aspect_ratio = (1,1)", 212 | "", 213 | "p1.xlim = (-15,20)", 214 | "", 215 | "p1.show()" 216 | ], 217 | "language": "python", 218 | "outputs": [], 219 | "prompt_number": 21 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "source": [ 224 | "Hm, `xlim` does not work in the notebook. Hopefully it works in IPython." 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "collapsed": true, 230 | "input": [ 231 | "p1._backend.ax.get_xlim()" 232 | ], 233 | "language": "python", 234 | "outputs": [], 235 | "prompt_number": 17 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "source": [ 240 | "Yeah, the backend got the command, but the `inline` backend does not honour it." 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "source": [ 246 | "## Adding expressions to a plot" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "collapsed": false, 252 | "input": [ 253 | "p = plot(x)", 254 | "", 255 | "p" 256 | ], 257 | "language": "python", 258 | "outputs": [], 259 | "prompt_number": 23 260 | }, 261 | { 262 | "cell_type": "code", 263 | "collapsed": false, 264 | "input": [ 265 | "p.extend(plot(x+1, show=False))", 266 | "", 267 | "p.show()", 268 | "", 269 | "p" 270 | ], 271 | "language": "python", 272 | "outputs": [], 273 | "prompt_number": 24 274 | }, 275 | { 276 | "cell_type": "code", 277 | "collapsed": false, 278 | "input": [ 279 | "p.append(plot(x+3, x**2, show=False)[1])", 280 | "", 281 | "p.show()", 282 | "", 283 | "p" 284 | ], 285 | "language": "python", 286 | "outputs": [], 287 | "prompt_number": 25 288 | }, 289 | { 290 | "cell_type": "markdown", 291 | "source": [ 292 | "## Different types of plots" 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "source": [ 298 | "###``plot``", 299 | "", 300 | "The ``plot`` by default uses an recursive adaptive algorithm to plot line plots. The default depth of recursion is 12, which means the function will be sampled at a maximum of $2^{12}$ points." 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "collapsed": false, 306 | "input": [ 307 | "help(plot)" 308 | ], 309 | "language": "python", 310 | "outputs": [], 311 | "prompt_number": 26 312 | }, 313 | { 314 | "cell_type": "code", 315 | "collapsed": false, 316 | "input": [ 317 | "plot(sin(x**2)) # plots with adaptive sampling and default range of (-10, 10)" 318 | ], 319 | "language": "python", 320 | "outputs": [], 321 | "prompt_number": 28 322 | }, 323 | { 324 | "cell_type": "markdown", 325 | "source": [ 326 | "You can also specify the depth of the recursion. It is also possible to disable adaptive sampling and use uniform sampling with ``nb_of_points``." 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "collapsed": false, 332 | "input": [ 333 | "plot(sin(x**2), depth=7) #specifying the depth of recursion." 334 | ], 335 | "language": "python", 336 | "outputs": [], 337 | "prompt_number": 30 338 | }, 339 | { 340 | "cell_type": "code", 341 | "collapsed": false, 342 | "input": [ 343 | "plot(sin(x**2), adaptive=False, nb_of_points=500)" 344 | ], 345 | "language": "python", 346 | "outputs": [], 347 | "prompt_number": 31 348 | }, 349 | { 350 | "cell_type": "markdown", 351 | "source": [ 352 | "###``plot_parametric``", 353 | "", 354 | "``plot_parametric`` uses an recursive adaptive sampling algorithm to plot." 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "collapsed": false, 360 | "input": [ 361 | "help(plot_parametric)" 362 | ], 363 | "language": "python", 364 | "outputs": [], 365 | "prompt_number": 32 366 | }, 367 | { 368 | "cell_type": "code", 369 | "collapsed": false, 370 | "input": [ 371 | "plot_parametric(cos(x), sin(x))" 372 | ], 373 | "language": "python", 374 | "outputs": [], 375 | "prompt_number": 33 376 | }, 377 | { 378 | "cell_type": "markdown", 379 | "source": [ 380 | "Multiple plots." 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "collapsed": false, 386 | "input": [ 387 | "plot_parametric((cos(x), sin(x)), (x, cos(x)))" 388 | ], 389 | "language": "python", 390 | "outputs": [], 391 | "prompt_number": 34 392 | }, 393 | { 394 | "cell_type": "markdown", 395 | "source": [ 396 | "We can combine parametric and line plots into a single plot." 397 | ] 398 | }, 399 | { 400 | "cell_type": "code", 401 | "collapsed": false, 402 | "input": [ 403 | "p = plot(sin(x), show=False)", 404 | "", 405 | "", 406 | "", 407 | "p.extend(plot_parametric(cos(x), sin(x), show=False))", 408 | "", 409 | "p.show()" 410 | ], 411 | "language": "python", 412 | "outputs": [], 413 | "prompt_number": 35 414 | }, 415 | { 416 | "cell_type": "markdown", 417 | "source": [ 418 | "###``plot3d``" 419 | ] 420 | }, 421 | { 422 | "cell_type": "code", 423 | "collapsed": false, 424 | "input": [ 425 | "help(plot3d)" 426 | ], 427 | "language": "python", 428 | "outputs": [], 429 | "prompt_number": 36 430 | }, 431 | { 432 | "cell_type": "code", 433 | "collapsed": false, 434 | "input": [ 435 | "plot3d(x*y)" 436 | ], 437 | "language": "python", 438 | "outputs": [], 439 | "prompt_number": 37 440 | }, 441 | { 442 | "cell_type": "code", 443 | "collapsed": false, 444 | "input": [ 445 | "plot3d(x*y, nb_of_points_x=100, nb_of_points_y=50) " 446 | ], 447 | "language": "python", 448 | "outputs": [], 449 | "prompt_number": 38 450 | }, 451 | { 452 | "cell_type": "markdown", 453 | "source": [ 454 | "###``plot3_parametric_line``" 455 | ] 456 | }, 457 | { 458 | "cell_type": "code", 459 | "collapsed": false, 460 | "input": [ 461 | "help(plot3d_parametric_line)" 462 | ], 463 | "language": "python", 464 | "outputs": [], 465 | "prompt_number": 39 466 | }, 467 | { 468 | "cell_type": "code", 469 | "collapsed": false, 470 | "input": [ 471 | "plot3d_parametric_line(cos(x), sin(x), x)" 472 | ], 473 | "language": "python", 474 | "outputs": [], 475 | "prompt_number": 40 476 | }, 477 | { 478 | "cell_type": "markdown", 479 | "source": [ 480 | "###``plot3d_parametric_surface``" 481 | ] 482 | }, 483 | { 484 | "cell_type": "code", 485 | "collapsed": false, 486 | "input": [ 487 | "help(plot3d_parametric_surface)" 488 | ], 489 | "language": "python", 490 | "outputs": [], 491 | "prompt_number": 41 492 | }, 493 | { 494 | "cell_type": "code", 495 | "collapsed": false, 496 | "input": [ 497 | "plot3d_parametric_surface(cos(x + y), sin(x - y), x - y)" 498 | ], 499 | "language": "python", 500 | "outputs": [], 501 | "prompt_number": 42 502 | }, 503 | { 504 | "cell_type": "markdown", 505 | "source": [ 506 | "## Complex values", 507 | "", 508 | "If complex values are encountered, they are discarded while plotting." 509 | ] 510 | }, 511 | { 512 | "cell_type": "code", 513 | "collapsed": false, 514 | "input": [ 515 | "plot(sqrt(x), (x, -5, 5))" 516 | ], 517 | "language": "python", 518 | "outputs": [], 519 | "prompt_number": 43 520 | }, 521 | { 522 | "cell_type": "markdown", 523 | "source": [ 524 | "", 525 | "", 526 | "## Textplot", 527 | "", 528 | "", 529 | "", 530 | "There is also the textplot backend that permits plotting in the terminal." 531 | ] 532 | }, 533 | { 534 | "cell_type": "code", 535 | "collapsed": true, 536 | "input": [ 537 | "pt = plot(sin(x),show=False)" 538 | ], 539 | "language": "python", 540 | "outputs": [], 541 | "prompt_number": 44 542 | }, 543 | { 544 | "cell_type": "code", 545 | "collapsed": true, 546 | "input": [ 547 | "pt.backend = plot_backends['text']" 548 | ], 549 | "language": "python", 550 | "outputs": [], 551 | "prompt_number": 45 552 | }, 553 | { 554 | "cell_type": "code", 555 | "collapsed": false, 556 | "input": [ 557 | "pt.show()" 558 | ], 559 | "language": "python", 560 | "outputs": [], 561 | "prompt_number": 46 562 | } 563 | ] 564 | } 565 | ] 566 | } -------------------------------------------------------------------------------- /notebooks/IntegrationOverPolytopes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Integration over Polytopes" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": { 13 | "collapsed": true 14 | }, 15 | "source": [ 16 | "#### Extra dependencies : matplotlib (if using methods : plot_polytope and plot_polynomial) " 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "outputs": [], 26 | "source": [ 27 | "from sympy import sqrt\n", 28 | "from sympy.abc import x, y, z\n", 29 | "from sympy.geometry import *\n", 30 | "from sympy.integrals.intpoly import *\n" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "## Methods : " 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": { 43 | "collapsed": true 44 | }, 45 | "source": [ 46 | "### polytope_integrate(poly, expr, **kwargs)\n", 47 | " Integrates polynomials over 2/3-Polytopes.\n", 48 | "\n", 49 | " This function accepts the polytope in `poly` and the function in `expr` (uni/bi/trivariate polynomials are\n", 50 | " implemented) and returns the exact integral of `expr` over `poly`.\n", 51 | " \n", 52 | " Parameters\n", 53 | " ---------------------------------------\n", 54 | " 1. poly(Polygon) : 2/3-Polytope\n", 55 | " 2. expr(SymPy expression) : uni/bi-variate polynomial for 2-Polytope and uni/bi/tri-variate for 3-Polytope\n", 56 | " \n", 57 | " Optional Parameters\n", 58 | " ---------------------------------------\n", 59 | " 1. clockwise(Boolean) : If user is not sure about orientation of vertices of the 2-Polytope and wants\n", 60 | " to clockwise sort the points.\n", 61 | " 2. max_degree(Integer) : Maximum degree of any monomial of the input polynomial. This would require \n", 62 | " \n", 63 | " #### Examples :" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": {}, 70 | "outputs": [], 71 | "source": [ 72 | "triangle = Polygon(Point(0,0), Point(1,1), Point(1,0))\n", 73 | "plot_polytope(triangle)\n", 74 | "print(\"Area of Triangle with vertices : (0,0), (1,1), (1,0) : \", polytope_integrate(triangle, 1))\n", 75 | "print(\"x*y integrated over Triangle with vertices : (0,0), (1,1), (1,0) : \", polytope_integrate(triangle, x*y),\"\\n\")\n", 76 | "\n", 77 | "hexagon = Polygon(Point(0, 0), Point(-sqrt(3) / 2, 0.5),\n", 78 | " Point(-sqrt(3) / 2, 3 / 2), Point(0, 2),\n", 79 | " Point(sqrt(3) / 2, 3 / 2), Point(sqrt(3) / 2, 0.5))\n", 80 | "plot_polytope(hexagon)\n", 81 | "print(\"Area of regular hexagon with unit side length : \", polytope_integrate(hexagon, 1))\n", 82 | "print(\"x + y**2 integrated over regular hexagon with unit side length : \", polytope_integrate(hexagon, x + y**2))\n", 83 | "\n", 84 | "polys = [1, x, y, x*y]\n", 85 | "print(\"1, x, y, x*y integrated over hexagon : \", polytope_integrate(hexagon, polys, max_degree=2))" 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "### main_integrate3d(expr, facets, vertices, hp_params)\n", 93 | " Function to translate the problem of integrating uni/bi/tri-variate\n", 94 | " polynomials over a 3-Polytope to integrating over its faces.\n", 95 | " This is done using Generalized Stokes's Theorem and Euler's Theorem.\n", 96 | " \n", 97 | " Parameters\n", 98 | " ------------------\n", 99 | " 1. expr : The input polynomial\n", 100 | " 2. facets : Faces of the 3-Polytope(expressed as indices of `vertices`)\n", 101 | " 3. vertices : Vertices that constitute the Polytope\n", 102 | " 4. hp_params : Hyperplane Parameters of the facets\n", 103 | " \n", 104 | " #### Examples:" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": null, 110 | "metadata": {}, 111 | "outputs": [], 112 | "source": [ 113 | "cube = [[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)],\n", 114 | " [2, 6, 7, 3], [3, 7, 5, 1], [7, 6, 4, 5], [1, 5, 4, 0], [3, 1, 0, 2], [0, 4, 6, 2]]\n", 115 | "vertices = cube[0]\n", 116 | "faces = cube[1:]\n", 117 | "hp_params = hyperplane_parameters(faces, vertices)\n", 118 | "main_integrate3d(1, faces, vertices, hp_params)" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "### polygon_integrate(facet, index, facets, vertices, expr, degree)\n", 126 | " Helper function to integrate the input uni/bi/trivariate polynomial\n", 127 | " over a certain face of the 3-Polytope.\n", 128 | " \n", 129 | " Parameters\n", 130 | " ------------------\n", 131 | " facet : Particular face of the 3-Polytope over which `expr` is integrated\n", 132 | " index : The index of `facet` in `facets`\n", 133 | " facets : Faces of the 3-Polytope(expressed as indices of `vertices`)\n", 134 | " vertices : Vertices that constitute the facet\n", 135 | " expr : The input polynomial\n", 136 | " degree : Degree of `expr`\n", 137 | " \n", 138 | " #### Examples:" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": null, 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [ 147 | "cube = [[(0, 0, 0), (0, 0, 5), (0, 5, 0), (0, 5, 5), (5, 0, 0),\n", 148 | " (5, 0, 5), (5, 5, 0), (5, 5, 5)],\n", 149 | " [2, 6, 7, 3], [3, 7, 5, 1], [7, 6, 4, 5], [1, 5, 4, 0],\n", 150 | " [3, 1, 0, 2], [0, 4, 6, 2]]\n", 151 | "facet = cube[1]\n", 152 | "facets = cube[1:]\n", 153 | "vertices = cube[0]\n", 154 | "print(\"Area of polygon < [(0, 5, 0), (5, 5, 0), (5, 5, 5), (0, 5, 5)] > : \", polygon_integrate(facet, 0, facets, vertices, 1, 0))" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": {}, 160 | "source": [ 161 | "### distance_to_side(point, line_seg)\n", 162 | "\n", 163 | " Helper function to compute the distance between given 3D point and\n", 164 | " a line segment.\n", 165 | "\n", 166 | " Parameters\n", 167 | " -----------------\n", 168 | " point : 3D Point\n", 169 | " line_seg : Line Segment\n", 170 | " \n", 171 | "#### Examples:" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": {}, 178 | "outputs": [], 179 | "source": [ 180 | "point = (0, 0, 0)\n", 181 | "distance_to_side(point, [(0, 0, 1), (0, 1, 0)])" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "### lineseg_integrate(polygon, index, line_seg, expr, degree)\n", 189 | " Helper function to compute the line integral of `expr` over `line_seg`\n", 190 | "\n", 191 | " Parameters\n", 192 | " -------------\n", 193 | " polygon : Face of a 3-Polytope\n", 194 | " index : index of line_seg in polygon\n", 195 | " line_seg : Line Segment\n", 196 | "#### Examples :" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": null, 202 | "metadata": {}, 203 | "outputs": [], 204 | "source": [ 205 | "polygon = [(0, 5, 0), (5, 5, 0), (5, 5, 5), (0, 5, 5)]\n", 206 | "line_seg = [(0, 5, 0), (5, 5, 0)]\n", 207 | "print(lineseg_integrate(polygon, 0, line_seg, 1, 0))" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "### main_integrate(expr, facets, hp_params, max_degree=None)\n", 215 | "\n", 216 | " Function to translate the problem of integrating univariate/bivariate\n", 217 | " polynomials over a 2-Polytope to integrating over its boundary facets.\n", 218 | " This is done using Generalized Stokes's Theorem and Euler's Theorem.\n", 219 | "\n", 220 | " Parameters\n", 221 | " --------------------\n", 222 | " expr : The input polynomial\n", 223 | " facets : Facets(Line Segments) of the 2-Polytope\n", 224 | " hp_params : Hyperplane Parameters of the facets\n", 225 | "\n", 226 | " Optional Parameters:\n", 227 | " --------------------\n", 228 | " max_degree : The maximum degree of any monomial of the input polynomial.\n", 229 | " \n", 230 | "#### Examples:" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": null, 236 | "metadata": {}, 237 | "outputs": [], 238 | "source": [ 239 | "triangle = Polygon(Point(0, 3), Point(5, 3), Point(1, 1))\n", 240 | "facets = triangle.sides\n", 241 | "hp_params = hyperplane_parameters(triangle)\n", 242 | "print(main_integrate(x**2 + y**2, facets, hp_params))\n" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "### integration_reduction(facets, index, a, b, expr, dims, degree)\n", 250 | " This is a helper function for polytope_integrate. It relates the result of the integral of a polynomial over a\n", 251 | " d-dimensional entity to the result of the same integral of that polynomial over the (d - 1)-dimensional \n", 252 | " facet[index].\n", 253 | " \n", 254 | " For the 2D case, surface integral --> line integrals --> evaluation of polynomial at vertices of line segments\n", 255 | " For the 3D case, volume integral --> 2D use case\n", 256 | " \n", 257 | " The only minor limitation is that some lines of code are 2D specific, but that can be easily changed. Note that\n", 258 | " this function is a helper one and works for a facet which bounds the polytope(i.e. the intersection point with the\n", 259 | " other facets is required), not for an independent line.\n", 260 | " \n", 261 | " Parameters\n", 262 | " ------------------\n", 263 | " facets : List of facets that decide the region enclose by 2-Polytope.\n", 264 | " index : The index of the facet with respect to which the integral is supposed to be found.\n", 265 | " a, b : Hyperplane parameters corresponding to facets.\n", 266 | " expr : Uni/Bi-variate Polynomial\n", 267 | " dims : List of symbols denoting axes\n", 268 | " degree : Degree of the homogeneous polynoimal(expr)\n", 269 | " \n", 270 | " #### Examples:" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "metadata": {}, 277 | "outputs": [], 278 | "source": [ 279 | "facets = [Segment2D(Point(0, 0), Point(1, 1)), Segment2D(Point(1, 1), Point(1, 0)), Segment2D(Point(0, 0), Point(1, 0))]\n", 280 | "print(integration_reduction(facets, 0, (0, 1), 0, 1, [x, y], 0))\n", 281 | "print(integration_reduction(facets, 1, (0, 1), 0, 1, [x, y], 0))\n", 282 | "print(integration_reduction(facets, 2, (0, 1), 0, 1, [x, y], 0))" 283 | ] 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "metadata": {}, 288 | "source": [ 289 | "### hyperplane_parameters(poly) :\n", 290 | " poly : 2-Polytope\n", 291 | " \n", 292 | " Returns the list of hyperplane parameters for facets of the polygon.\n", 293 | " \n", 294 | " Limitation : 2D specific.\n", 295 | " #### Examples:" 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": null, 301 | "metadata": {}, 302 | "outputs": [], 303 | "source": [ 304 | "triangle = Polygon(Point(0,0), Point(1,1), Point(1,0))\n", 305 | "hyperplane_parameters(triangle)" 306 | ] 307 | }, 308 | { 309 | "cell_type": "markdown", 310 | "metadata": {}, 311 | "source": [ 312 | "### best_origin(a, b, lineseg, expr) :\n", 313 | " a, b : Line parameters of the line-segment\n", 314 | " expr : Uni/Bi-variate polynomial\n", 315 | " \n", 316 | " Returns a point on the lineseg whose vector inner product with the divergence of expr yields an expression with \n", 317 | " the least maximum total power. This is for reducing the number of computations in the integration reduction call.\n", 318 | " \n", 319 | " Limitation : 2D specific.\n", 320 | " \n", 321 | " #### Examples:" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": null, 327 | "metadata": {}, 328 | "outputs": [], 329 | "source": [ 330 | "print(\"Best origin for x**3*y on x + y = 3 : \", best_origin((1,1), 3, Segment2D(Point(0, 3), Point(3, 0)), x**3*y))\n", 331 | "print(\"Best origin for x*y**3 on x + y = 3 : \",best_origin((1,1), 3, Segment2D(Point(0, 3), Point(3, 0)), x*y**3))" 332 | ] 333 | }, 334 | { 335 | "cell_type": "markdown", 336 | "metadata": {}, 337 | "source": [ 338 | "### decompose(expr, separate=False) :\n", 339 | " expr : Uni/Bi-variate polynomial.\n", 340 | " separate(default : False) : If separate is True then return list of constituting monomials.\n", 341 | " \n", 342 | " Returns a dictionary of the terms having same total power. This is done to get homogeneous polynomials of\n", 343 | " different degrees from the expression.\n", 344 | " \n", 345 | " #### Examples:" 346 | ] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "execution_count": null, 351 | "metadata": {}, 352 | "outputs": [], 353 | "source": [ 354 | "print(decompose(1 + x + x**2 + x*y))\n", 355 | "print(decompose(x**2 + x + y + 1 + x**3 + x**2*y + y**4 + x**3*y + y**2*x**2))\n", 356 | "print(decompose(x**2 + x + y + 1 + x**3 + x**2*y + y**4 + x**3*y + y**2*x**2, 1))" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "metadata": {}, 362 | "source": [ 363 | "### norm(expr) :\n", 364 | " \n", 365 | " point : Tuple/SymPy Point object/Dictionary\n", 366 | " \n", 367 | " Returns Euclidean norm of the point object.\n", 368 | "\n", 369 | " #### Examples:" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": null, 375 | "metadata": {}, 376 | "outputs": [], 377 | "source": [ 378 | "print(norm((1, 2)))\n", 379 | "print(norm(Point(1, 2)))\n", 380 | "print(norm({x: 3, y: 3, z: 1}))" 381 | ] 382 | }, 383 | { 384 | "cell_type": "markdown", 385 | "metadata": {}, 386 | "source": [ 387 | "### intersection(lineseg_1, lineseg_2) :\n", 388 | " \n", 389 | " lineseg_1, lineseg_2 : The input line segments whose intersection is to be found.\n", 390 | " \n", 391 | " Returns intersection point of two lines of which lineseg_1, lineseg_2 are part of. This function is\n", 392 | " called for adjacent line segments so the intersection point is always present with line segment boundaries.\n", 393 | "\n", 394 | " #### Examples:" 395 | ] 396 | }, 397 | { 398 | "cell_type": "code", 399 | "execution_count": null, 400 | "metadata": {}, 401 | "outputs": [], 402 | "source": [ 403 | "print(intersection(Segment2D(Point(0, 0), Point(2, 2)), Segment2D(Point(1, 0), Point(0, 1))))\n", 404 | "print(intersection(Segment2D(Point(2, 0), Point(2, 2)), Segment2D(Point(0, 0), Point(4, 4))))" 405 | ] 406 | }, 407 | { 408 | "cell_type": "markdown", 409 | "metadata": {}, 410 | "source": [ 411 | "### is_vertex(ent) :\n", 412 | " \n", 413 | " ent : Geometrical entity to denote a vertex.\n", 414 | " \n", 415 | " Returns True if ent is a vertex. Currently tuples of length 2 or 3 and SymPy Point object are supported.\n", 416 | " #### Examples:" 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "execution_count": null, 422 | "metadata": { 423 | "collapsed": true 424 | }, 425 | "outputs": [], 426 | "source": [ 427 | "print(is_vertex(Point(2, 8)))\n", 428 | "print(is_vertex(Point(2, 8, 1)))\n", 429 | "print(is_vertex((1, 1)))\n", 430 | "print(is_vertex([2, 9]))\n", 431 | "print(is_vertex(Polygon(Point(0, 0), Point(1, 1), Point(1, 0))))" 432 | ] 433 | }, 434 | { 435 | "cell_type": "markdown", 436 | "metadata": {}, 437 | "source": [ 438 | "### plot_polytope(poly) :\n", 439 | " \n", 440 | " poly : 2-Polytope\n", 441 | " \n", 442 | " Plots the 2-Polytope. Currently just defers it to plotting module in SymPy which in turn uses matplotlib.\n", 443 | " \n", 444 | " #### Examples:" 445 | ] 446 | }, 447 | { 448 | "cell_type": "code", 449 | "execution_count": null, 450 | "metadata": {}, 451 | "outputs": [], 452 | "source": [ 453 | "hexagon = Polygon(Point(0, 0), Point(-sqrt(3) / 2, 0.5),\n", 454 | " Point(-sqrt(3) / 2, 3 / 2), Point(0, 2),\n", 455 | " Point(sqrt(3) / 2, 3 / 2), Point(sqrt(3) / 2, 0.5))\n", 456 | "plot_polytope(hexagon)\n", 457 | "\n", 458 | "twist = Polygon(Point(-1, 1), Point(0, 0), Point(1, 1), Point(1, -1),\n", 459 | " Point(0, 0), Point(-1, -1))\n", 460 | "plot_polytope(twist)\n" 461 | ] 462 | }, 463 | { 464 | "cell_type": "markdown", 465 | "metadata": {}, 466 | "source": [ 467 | "### plot_polynomial(expr) :\n", 468 | " \n", 469 | " expr : The uni/bi-variate polynomial to plot\n", 470 | " \n", 471 | " Plots the polynomial. Currently just defers it to plotting module in SymPy which in turn uses matplotlib.\n", 472 | " \n", 473 | " #### Examples:" 474 | ] 475 | }, 476 | { 477 | "cell_type": "code", 478 | "execution_count": null, 479 | "metadata": {}, 480 | "outputs": [], 481 | "source": [ 482 | "expr = x**2\n", 483 | "plot_polynomial(expr)\n", 484 | "\n", 485 | "expr = x*y\n", 486 | "plot_polynomial(expr)" 487 | ] 488 | }, 489 | { 490 | "cell_type": "code", 491 | "execution_count": null, 492 | "metadata": { 493 | "collapsed": true 494 | }, 495 | "outputs": [], 496 | "source": [] 497 | } 498 | ], 499 | "metadata": { 500 | "kernelspec": { 501 | "display_name": "Python 3", 502 | "language": "python", 503 | "name": "python3" 504 | }, 505 | "language_info": { 506 | "codemirror_mode": { 507 | "name": "ipython", 508 | "version": 3 509 | }, 510 | "file_extension": ".py", 511 | "mimetype": "text/x-python", 512 | "name": "python", 513 | "nbconvert_exporter": "python", 514 | "pygments_lexer": "ipython3", 515 | "version": "3.5.2" 516 | } 517 | }, 518 | "nbformat": 4, 519 | "nbformat_minor": 2 520 | } 521 | -------------------------------------------------------------------------------- /notebooks/sho1d_example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "sho1d_example" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "heading", 12 | "level": 1, 13 | "metadata": {}, 14 | "source": [ 15 | "Example Notebook for sho1d.py" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "Import the sho1d.py file as well as the test_sho1d.py file" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "collapsed": false, 28 | "input": [ 29 | "from sympy import *\n", 30 | "from IPython.display import display_pretty\n", 31 | "from sympy.physics.quantum import *\n", 32 | "from sympy.physics.quantum.sho1d import *\n", 33 | "from sympy.physics.quantum.tests.test_sho1d import *\n", 34 | "init_printing(pretty_print=False, use_latex=False)" 35 | ], 36 | "language": "python", 37 | "metadata": {}, 38 | "outputs": [ ], 39 | "prompt_number": 1 40 | }, 41 | { 42 | "cell_type": "heading", 43 | "level": 3, 44 | "metadata": {}, 45 | "source": [ 46 | "Printing Of Operators" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "Create a raising and lowering operator and make sure they print correctly" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "collapsed": false, 59 | "input": [ 60 | "ad = RaisingOp('a')\n", 61 | "a = LoweringOp('a')" 62 | ], 63 | "language": "python", 64 | "metadata": {}, 65 | "outputs": [], 66 | "prompt_number": 2 67 | }, 68 | { 69 | "cell_type": "code", 70 | "collapsed": false, 71 | "input": [ 72 | "ad" 73 | ], 74 | "language": "python", 75 | "metadata": {}, 76 | "outputs": [ 77 | { 78 | "output_type": "pyout", 79 | "prompt_number": 3, 80 | "text": [ 81 | "RaisingOp(a)" 82 | ] 83 | } 84 | ], 85 | "prompt_number": 3 86 | }, 87 | { 88 | "cell_type": "code", 89 | "collapsed": false, 90 | "input": [ 91 | "a" 92 | ], 93 | "language": "python", 94 | "metadata": {}, 95 | "outputs": [ 96 | { 97 | "output_type": "pyout", 98 | "prompt_number": 4, 99 | "text": [ 100 | "a" 101 | ] 102 | } 103 | ], 104 | "prompt_number": 4 105 | }, 106 | { 107 | "cell_type": "code", 108 | "collapsed": false, 109 | "input": [ 110 | "print(latex(ad))\n", 111 | "print(latex(a))" 112 | ], 113 | "language": "python", 114 | "metadata": {}, 115 | "outputs": [ 116 | { 117 | "output_type": "stream", 118 | "stream": "stdout", 119 | "text": [ 120 | "a^{\\dag}\n", 121 | "a\n" 122 | ] 123 | } 124 | ], 125 | "prompt_number": 5 126 | }, 127 | { 128 | "cell_type": "code", 129 | "collapsed": false, 130 | "input": [ 131 | "display_pretty(ad)\n", 132 | "display_pretty(a)" 133 | ], 134 | "language": "python", 135 | "metadata": {}, 136 | "outputs": [ 137 | { 138 | "output_type": "display_data", 139 | "text": [ 140 | "RaisingOp(a)" 141 | ] 142 | }, 143 | { 144 | "output_type": "display_data", 145 | "text": [ 146 | "a" 147 | ] 148 | } 149 | ], 150 | "prompt_number": 6 151 | }, 152 | { 153 | "cell_type": "code", 154 | "collapsed": false, 155 | "input": [ 156 | "print(srepr(ad))\n", 157 | "print(srepr(a))" 158 | ], 159 | "language": "python", 160 | "metadata": {}, 161 | "outputs": [ 162 | { 163 | "output_type": "stream", 164 | "stream": "stdout", 165 | "text": [ 166 | "RaisingOp(Symbol('a'))\n", 167 | "LoweringOp(Symbol('a'))\n" 168 | ] 169 | } 170 | ], 171 | "prompt_number": 7 172 | }, 173 | { 174 | "cell_type": "code", 175 | "collapsed": false, 176 | "input": [ 177 | "print(repr(ad))\n", 178 | "print(repr(a))" 179 | ], 180 | "language": "python", 181 | "metadata": {}, 182 | "outputs": [ 183 | { 184 | "output_type": "stream", 185 | "stream": "stdout", 186 | "text": [ 187 | "RaisingOp(a)\n", 188 | "a\n" 189 | ] 190 | } 191 | ], 192 | "prompt_number": 8 193 | }, 194 | { 195 | "cell_type": "heading", 196 | "level": 3, 197 | "metadata": {}, 198 | "source": [ 199 | "Printing of States" 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": {}, 205 | "source": [ 206 | "Create a simple harmonic state and check its printing" 207 | ] 208 | }, 209 | { 210 | "cell_type": "code", 211 | "collapsed": false, 212 | "input": [ 213 | "k = SHOKet('k')\n", 214 | "b = SHOBra('b')" 215 | ], 216 | "language": "python", 217 | "metadata": {}, 218 | "outputs": [], 219 | "prompt_number": 9 220 | }, 221 | { 222 | "cell_type": "code", 223 | "collapsed": false, 224 | "input": [ 225 | "k" 226 | ], 227 | "language": "python", 228 | "metadata": {}, 229 | "outputs": [ 230 | { 231 | "output_type": "pyout", 232 | "prompt_number": 10, 233 | "text": [ 234 | "|k>" 235 | ] 236 | } 237 | ], 238 | "prompt_number": 10 239 | }, 240 | { 241 | "cell_type": "code", 242 | "collapsed": false, 243 | "input": [ 244 | "b" 245 | ], 246 | "language": "python", 247 | "metadata": {}, 248 | "outputs": [ 249 | { 250 | "output_type": "pyout", 251 | "prompt_number": 11, 252 | "text": [ 253 | "" 460 | ] 461 | } 462 | ], 463 | "prompt_number": 20 464 | }, 465 | { 466 | "cell_type": "markdown", 467 | "metadata": {}, 468 | "source": [ 469 | "Taking the InnerProduct of the bra and ket will return the KroneckerDelta function" 470 | ] 471 | }, 472 | { 473 | "cell_type": "code", 474 | "collapsed": false, 475 | "input": [ 476 | "InnerProduct(b,k).doit()" 477 | ], 478 | "language": "python", 479 | "metadata": {}, 480 | "outputs": [ 481 | { 482 | "output_type": "pyout", 483 | "prompt_number": 21, 484 | "text": [ 485 | "KroneckerDelta(k, b)" 486 | ] 487 | } 488 | ], 489 | "prompt_number": 21 490 | }, 491 | { 492 | "cell_type": "markdown", 493 | "metadata": {}, 494 | "source": [ 495 | "Take a look at how the raising and lowering operators act on states. We use qapply to apply an operator to a state" 496 | ] 497 | }, 498 | { 499 | "cell_type": "code", 500 | "collapsed": false, 501 | "input": [ 502 | "qapply(ad*k)" 503 | ], 504 | "language": "python", 505 | "metadata": {}, 506 | "outputs": [ 507 | { 508 | "output_type": "pyout", 509 | "prompt_number": 22, 510 | "text": [ 511 | "sqrt(k + 1)*|k + 1>" 512 | ] 513 | } 514 | ], 515 | "prompt_number": 22 516 | }, 517 | { 518 | "cell_type": "code", 519 | "collapsed": false, 520 | "input": [ 521 | "qapply(a*k)" 522 | ], 523 | "language": "python", 524 | "metadata": {}, 525 | "outputs": [ 526 | { 527 | "output_type": "pyout", 528 | "prompt_number": 23, 529 | "text": [ 530 | "sqrt(k)*|k - 1>" 531 | ] 532 | } 533 | ], 534 | "prompt_number": 23 535 | }, 536 | { 537 | "cell_type": "markdown", 538 | "metadata": {}, 539 | "source": [ 540 | "But the states may have an explicit energy level. Let's look at the ground and first excited states" 541 | ] 542 | }, 543 | { 544 | "cell_type": "code", 545 | "collapsed": false, 546 | "input": [ 547 | "kg = SHOKet(0)\n", 548 | "kf = SHOKet(1)" 549 | ], 550 | "language": "python", 551 | "metadata": {}, 552 | "outputs": [], 553 | "prompt_number": 24 554 | }, 555 | { 556 | "cell_type": "code", 557 | "collapsed": false, 558 | "input": [ 559 | "qapply(ad*kg)" 560 | ], 561 | "language": "python", 562 | "metadata": {}, 563 | "outputs": [ 564 | { 565 | "output_type": "pyout", 566 | "prompt_number": 25, 567 | "text": [ 568 | "|1>" 569 | ] 570 | } 571 | ], 572 | "prompt_number": 25 573 | }, 574 | { 575 | "cell_type": "code", 576 | "collapsed": false, 577 | "input": [ 578 | "qapply(ad*kf)" 579 | ], 580 | "language": "python", 581 | "metadata": {}, 582 | "outputs": [ 583 | { 584 | "output_type": "pyout", 585 | "prompt_number": 26, 586 | "text": [ 587 | "sqrt(2)*|2>" 588 | ] 589 | } 590 | ], 591 | "prompt_number": 26 592 | }, 593 | { 594 | "cell_type": "code", 595 | "collapsed": false, 596 | "input": [ 597 | "qapply(a*kg)" 598 | ], 599 | "language": "python", 600 | "metadata": {}, 601 | "outputs": [ 602 | { 603 | "output_type": "pyout", 604 | "prompt_number": 27, 605 | "text": [ 606 | "0" 607 | ] 608 | } 609 | ], 610 | "prompt_number": 27 611 | }, 612 | { 613 | "cell_type": "code", 614 | "collapsed": false, 615 | "input": [ 616 | "qapply(a*kf)" 617 | ], 618 | "language": "python", 619 | "metadata": {}, 620 | "outputs": [ 621 | { 622 | "output_type": "pyout", 623 | "prompt_number": 28, 624 | "text": [ 625 | "|0>" 626 | ] 627 | } 628 | ], 629 | "prompt_number": 28 630 | }, 631 | { 632 | "cell_type": "markdown", 633 | "metadata": {}, 634 | "source": [ 635 | "Notice that a*kg is 0 and a*kf is the |0> the ground state." 636 | ] 637 | }, 638 | { 639 | "cell_type": "heading", 640 | "level": 3, 641 | "metadata": {}, 642 | "source": [ 643 | "NumberOp & Hamiltonian" 644 | ] 645 | }, 646 | { 647 | "cell_type": "markdown", 648 | "metadata": {}, 649 | "source": [ 650 | "Let's look at the Number Operator and Hamiltonian Operator" 651 | ] 652 | }, 653 | { 654 | "cell_type": "code", 655 | "collapsed": false, 656 | "input": [ 657 | "k = SHOKet('k')\n", 658 | "ad = RaisingOp('a')\n", 659 | "a = LoweringOp('a')\n", 660 | "N = NumberOp('N')\n", 661 | "H = Hamiltonian('H')" 662 | ], 663 | "language": "python", 664 | "metadata": {}, 665 | "outputs": [], 666 | "prompt_number": 29 667 | }, 668 | { 669 | "cell_type": "markdown", 670 | "metadata": {}, 671 | "source": [ 672 | "The number operator is simply expressed as ad*a" 673 | ] 674 | }, 675 | { 676 | "cell_type": "code", 677 | "collapsed": false, 678 | "input": [ 679 | "N().rewrite('a').doit()" 680 | ], 681 | "language": "python", 682 | "metadata": {}, 683 | "outputs": [ 684 | { 685 | "output_type": "pyout", 686 | "prompt_number": 30, 687 | "text": [ 688 | "RaisingOp(a)*a" 689 | ] 690 | } 691 | ], 692 | "prompt_number": 30 693 | }, 694 | { 695 | "cell_type": "markdown", 696 | "metadata": {}, 697 | "source": [ 698 | "The number operator expressed in terms of the position and momentum operators" 699 | ] 700 | }, 701 | { 702 | "cell_type": "code", 703 | "collapsed": false, 704 | "input": [ 705 | "N().rewrite('xp').doit()" 706 | ], 707 | "language": "python", 708 | "metadata": {}, 709 | "outputs": [ 710 | { 711 | "output_type": "pyout", 712 | "prompt_number": 31, 713 | "text": [ 714 | "-1/2 + (m**2*omega**2*X**2 + Px**2)/(2*hbar*m*omega)" 715 | ] 716 | } 717 | ], 718 | "prompt_number": 31 719 | }, 720 | { 721 | "cell_type": "markdown", 722 | "metadata": {}, 723 | "source": [ 724 | "It can also be expressed in terms of the Hamiltonian operator" 725 | ] 726 | }, 727 | { 728 | "cell_type": "code", 729 | "collapsed": false, 730 | "input": [ 731 | "N().rewrite('H').doit()" 732 | ], 733 | "language": "python", 734 | "metadata": {}, 735 | "outputs": [ 736 | { 737 | "output_type": "pyout", 738 | "prompt_number": 32, 739 | "text": [ 740 | "-1/2 + H/(hbar*omega)" 741 | ] 742 | } 743 | ], 744 | "prompt_number": 32 745 | }, 746 | { 747 | "cell_type": "markdown", 748 | "metadata": {}, 749 | "source": [ 750 | "The Hamiltonian operator can be expressed in terms of the raising and lowering operators, position and momentum operators, and the number operator" 751 | ] 752 | }, 753 | { 754 | "cell_type": "code", 755 | "collapsed": false, 756 | "input": [ 757 | "H().rewrite('a').doit()" 758 | ], 759 | "language": "python", 760 | "metadata": {}, 761 | "outputs": [ 762 | { 763 | "output_type": "pyout", 764 | "prompt_number": 33, 765 | "text": [ 766 | "hbar*omega*(1/2 + RaisingOp(a)*a)" 767 | ] 768 | } 769 | ], 770 | "prompt_number": 33 771 | }, 772 | { 773 | "cell_type": "code", 774 | "collapsed": false, 775 | "input": [ 776 | "H().rewrite('xp').doit()" 777 | ], 778 | "language": "python", 779 | "metadata": {}, 780 | "outputs": [ 781 | { 782 | "output_type": "pyout", 783 | "prompt_number": 34, 784 | "text": [ 785 | "(m**2*omega**2*X**2 + Px**2)/(2*m)" 786 | ] 787 | } 788 | ], 789 | "prompt_number": 34 790 | }, 791 | { 792 | "cell_type": "code", 793 | "collapsed": false, 794 | "input": [ 795 | "H().rewrite('N').doit()" 796 | ], 797 | "language": "python", 798 | "metadata": {}, 799 | "outputs": [ 800 | { 801 | "output_type": "pyout", 802 | "prompt_number": 35, 803 | "text": [ 804 | "hbar*omega*(1/2 + N)" 805 | ] 806 | } 807 | ], 808 | "prompt_number": 35 809 | }, 810 | { 811 | "cell_type": "markdown", 812 | "metadata": {}, 813 | "source": [ 814 | "The raising and lowering operators can also be expressed in terms of the position and momentum operators" 815 | ] 816 | }, 817 | { 818 | "cell_type": "code", 819 | "collapsed": false, 820 | "input": [ 821 | "ad().rewrite('xp').doit()" 822 | ], 823 | "language": "python", 824 | "metadata": {}, 825 | "outputs": [ 826 | { 827 | "output_type": "pyout", 828 | "prompt_number": 36, 829 | "text": [ 830 | "sqrt(2)*(m*omega*X - I*Px)/(2*sqrt(hbar)*sqrt(m*omega))" 831 | ] 832 | } 833 | ], 834 | "prompt_number": 36 835 | }, 836 | { 837 | "cell_type": "code", 838 | "collapsed": false, 839 | "input": [ 840 | "a().rewrite('xp').doit()" 841 | ], 842 | "language": "python", 843 | "metadata": {}, 844 | "outputs": [ 845 | { 846 | "output_type": "pyout", 847 | "prompt_number": 37, 848 | "text": [ 849 | "sqrt(2)*(m*omega*X + I*Px)/(2*sqrt(hbar)*sqrt(m*omega))" 850 | ] 851 | } 852 | ], 853 | "prompt_number": 37 854 | }, 855 | { 856 | "cell_type": "heading", 857 | "level": 3, 858 | "metadata": {}, 859 | "source": [ 860 | "Properties" 861 | ] 862 | }, 863 | { 864 | "cell_type": "markdown", 865 | "metadata": {}, 866 | "source": [ 867 | "Let's take a look at how the NumberOp and Hamiltonian act on states" 868 | ] 869 | }, 870 | { 871 | "cell_type": "code", 872 | "collapsed": false, 873 | "input": [ 874 | "qapply(N*k)" 875 | ], 876 | "language": "python", 877 | "metadata": {}, 878 | "outputs": [ 879 | { 880 | "output_type": "pyout", 881 | "prompt_number": 38, 882 | "text": [ 883 | "k*|k>" 884 | ] 885 | } 886 | ], 887 | "prompt_number": 38 888 | }, 889 | { 890 | "cell_type": "markdown", 891 | "metadata": {}, 892 | "source": [ 893 | "Apply the Number operator to a state returns the state times the ket" 894 | ] 895 | }, 896 | { 897 | "cell_type": "code", 898 | "collapsed": false, 899 | "input": [ 900 | "ks = SHOKet(2)\n", 901 | "qapply(N*ks)" 902 | ], 903 | "language": "python", 904 | "metadata": {}, 905 | "outputs": [ 906 | { 907 | "output_type": "pyout", 908 | "prompt_number": 39, 909 | "text": [ 910 | "2*|2>" 911 | ] 912 | } 913 | ], 914 | "prompt_number": 39 915 | }, 916 | { 917 | "cell_type": "code", 918 | "collapsed": false, 919 | "input": [ 920 | "qapply(H*k)" 921 | ], 922 | "language": "python", 923 | "metadata": {}, 924 | "outputs": [ 925 | { 926 | "output_type": "pyout", 927 | "prompt_number": 40, 928 | "text": [ 929 | "hbar*k*omega*|k> + hbar*omega*|k>/2" 930 | ] 931 | } 932 | ], 933 | "prompt_number": 40 934 | }, 935 | { 936 | "cell_type": "markdown", 937 | "metadata": {}, 938 | "source": [ 939 | "Let's see how the operators commute with each other" 940 | ] 941 | }, 942 | { 943 | "cell_type": "code", 944 | "collapsed": false, 945 | "input": [ 946 | "Commutator(N,ad).doit()" 947 | ], 948 | "language": "python", 949 | "metadata": {}, 950 | "outputs": [ 951 | { 952 | "output_type": "pyout", 953 | "prompt_number": 41, 954 | "text": [ 955 | "RaisingOp(a)" 956 | ] 957 | } 958 | ], 959 | "prompt_number": 41 960 | }, 961 | { 962 | "cell_type": "code", 963 | "collapsed": false, 964 | "input": [ 965 | "Commutator(N,a).doit()" 966 | ], 967 | "language": "python", 968 | "metadata": {}, 969 | "outputs": [ 970 | { 971 | "output_type": "pyout", 972 | "prompt_number": 42, 973 | "text": [ 974 | "-a" 975 | ] 976 | } 977 | ], 978 | "prompt_number": 42 979 | }, 980 | { 981 | "cell_type": "code", 982 | "collapsed": false, 983 | "input": [ 984 | "Commutator(N,H).doit()" 985 | ], 986 | "language": "python", 987 | "metadata": {}, 988 | "outputs": [ 989 | { 990 | "output_type": "pyout", 991 | "prompt_number": 43, 992 | "text": [ 993 | "0" 994 | ] 995 | } 996 | ], 997 | "prompt_number": 43 998 | }, 999 | { 1000 | "cell_type": "heading", 1001 | "level": 3, 1002 | "metadata": {}, 1003 | "source": [ 1004 | "Representation" 1005 | ] 1006 | }, 1007 | { 1008 | "cell_type": "markdown", 1009 | "metadata": {}, 1010 | "source": [ 1011 | "We can express the operators in NumberOp basis. There are different ways to create a matrix in Python, we will use 3 different ways." 1012 | ] 1013 | }, 1014 | { 1015 | "cell_type": "heading", 1016 | "level": 4, 1017 | "metadata": {}, 1018 | "source": [ 1019 | "Sympy" 1020 | ] 1021 | }, 1022 | { 1023 | "cell_type": "code", 1024 | "collapsed": false, 1025 | "input": [ 1026 | "represent(ad, basis=N, ndim=4, format='sympy')" 1027 | ], 1028 | "language": "python", 1029 | "metadata": {}, 1030 | "outputs": [ 1031 | { 1032 | "output_type": "pyout", 1033 | "prompt_number": 44, 1034 | "text": [ 1035 | "[0, 0, 0, 0]\n", 1036 | "[1, 0, 0, 0]\n", 1037 | "[0, sqrt(2), 0, 0]\n", 1038 | "[0, 0, sqrt(3), 0]" 1039 | ] 1040 | } 1041 | ], 1042 | "prompt_number": 44 1043 | }, 1044 | { 1045 | "cell_type": "heading", 1046 | "level": 4, 1047 | "metadata": {}, 1048 | "source": [ 1049 | "Numpy" 1050 | ] 1051 | }, 1052 | { 1053 | "cell_type": "code", 1054 | "collapsed": false, 1055 | "input": [ 1056 | "represent(ad, basis=N, ndim=5, format='numpy')" 1057 | ], 1058 | "language": "python", 1059 | "metadata": {}, 1060 | "outputs": [ 1061 | { 1062 | "output_type": "pyout", 1063 | "prompt_number": 45, 1064 | "text": [ 1065 | "array([[ 0. , 0. , 0. , 0. , 0. ],\n", 1066 | " [ 1. , 0. , 0. , 0. , 0. ],\n", 1067 | " [ 0. , 1.41421356, 0. , 0. , 0. ],\n", 1068 | " [ 0. , 0. , 1.73205081, 0. , 0. ],\n", 1069 | " [ 0. , 0. , 0. , 2. , 0. ]])" 1070 | ] 1071 | } 1072 | ], 1073 | "prompt_number": 45 1074 | }, 1075 | { 1076 | "cell_type": "heading", 1077 | "level": 4, 1078 | "metadata": {}, 1079 | "source": [ 1080 | "Scipy.Sparse" 1081 | ] 1082 | }, 1083 | { 1084 | "cell_type": "code", 1085 | "collapsed": false, 1086 | "input": [ 1087 | "represent(ad, basis=N, ndim=4, format='scipy.sparse', spmatrix='lil')" 1088 | ], 1089 | "language": "python", 1090 | "metadata": {}, 1091 | "outputs": [ 1092 | { 1093 | "output_type": "pyout", 1094 | "prompt_number": 46, 1095 | "text": [ 1096 | "<4x4 sparse matrix of type ''\n", 1097 | "\twith 3 stored elements in Compressed Sparse Row format>" 1098 | ] 1099 | } 1100 | ], 1101 | "prompt_number": 46 1102 | }, 1103 | { 1104 | "cell_type": "code", 1105 | "collapsed": false, 1106 | "input": [ 1107 | "print(represent(ad, basis=N, ndim=4, format='scipy.sparse', spmatrix='lil'))" 1108 | ], 1109 | "language": "python", 1110 | "metadata": {}, 1111 | "outputs": [ 1112 | { 1113 | "output_type": "stream", 1114 | "stream": "stdout", 1115 | "text": [ 1116 | " (1, 0)\t1.0\n", 1117 | " (2, 1)\t1.41421356237\n", 1118 | " (3, 2)\t1.73205080757\n" 1119 | ] 1120 | } 1121 | ], 1122 | "prompt_number": 47 1123 | }, 1124 | { 1125 | "cell_type": "markdown", 1126 | "metadata": {}, 1127 | "source": [ 1128 | "The same can be done for the other operators" 1129 | ] 1130 | }, 1131 | { 1132 | "cell_type": "code", 1133 | "collapsed": false, 1134 | "input": [ 1135 | "represent(a, basis=N, ndim=4, format='sympy')" 1136 | ], 1137 | "language": "python", 1138 | "metadata": {}, 1139 | "outputs": [ 1140 | { 1141 | "output_type": "pyout", 1142 | "prompt_number": 48, 1143 | "text": [ 1144 | "[0, 1, 0, 0]\n", 1145 | "[0, 0, sqrt(2), 0]\n", 1146 | "[0, 0, 0, sqrt(3)]\n", 1147 | "[0, 0, 0, 0]" 1148 | ] 1149 | } 1150 | ], 1151 | "prompt_number": 48 1152 | }, 1153 | { 1154 | "cell_type": "code", 1155 | "collapsed": false, 1156 | "input": [ 1157 | "represent(N, basis=N, ndim=4, format='sympy')" 1158 | ], 1159 | "language": "python", 1160 | "metadata": {}, 1161 | "outputs": [ 1162 | { 1163 | "output_type": "pyout", 1164 | "prompt_number": 49, 1165 | "text": [ 1166 | "[0, 0, 0, 0]\n", 1167 | "[0, 1, 0, 0]\n", 1168 | "[0, 0, 2, 0]\n", 1169 | "[0, 0, 0, 3]" 1170 | ] 1171 | } 1172 | ], 1173 | "prompt_number": 49 1174 | }, 1175 | { 1176 | "cell_type": "code", 1177 | "collapsed": false, 1178 | "input": [ 1179 | "represent(H, basis=N, ndim=4, format='sympy')" 1180 | ], 1181 | "language": "python", 1182 | "metadata": {}, 1183 | "outputs": [ 1184 | { 1185 | "output_type": "pyout", 1186 | "prompt_number": 50, 1187 | "text": [ 1188 | "[hbar*omega/2, 0, 0, 0]\n", 1189 | "[ 0, 3*hbar*omega/2, 0, 0]\n", 1190 | "[ 0, 0, 5*hbar*omega/2, 0]\n", 1191 | "[ 0, 0, 0, 7*hbar*omega/2]" 1192 | ] 1193 | } 1194 | ], 1195 | "prompt_number": 50 1196 | }, 1197 | { 1198 | "cell_type": "heading", 1199 | "level": 4, 1200 | "metadata": {}, 1201 | "source": [ 1202 | "Ket and Bra Representation" 1203 | ] 1204 | }, 1205 | { 1206 | "cell_type": "code", 1207 | "collapsed": false, 1208 | "input": [ 1209 | "k0 = SHOKet(0)\n", 1210 | "k1 = SHOKet(1)\n", 1211 | "b0 = SHOBra(0)\n", 1212 | "b1 = SHOBra(1)" 1213 | ], 1214 | "language": "python", 1215 | "metadata": {}, 1216 | "outputs": [], 1217 | "prompt_number": 51 1218 | }, 1219 | { 1220 | "cell_type": "code", 1221 | "collapsed": false, 1222 | "input": [ 1223 | "print(represent(k0, basis=N, ndim=5, format='sympy'))" 1224 | ], 1225 | "language": "python", 1226 | "metadata": {}, 1227 | "outputs": [ 1228 | { 1229 | "output_type": "stream", 1230 | "stream": "stdout", 1231 | "text": [ 1232 | "[1]\n", 1233 | "[0]\n", 1234 | "[0]\n", 1235 | "[0]\n", 1236 | "[0]\n" 1237 | ] 1238 | } 1239 | ], 1240 | "prompt_number": 52 1241 | }, 1242 | { 1243 | "cell_type": "code", 1244 | "collapsed": false, 1245 | "input": [ 1246 | "print(represent(k1, basis=N, ndim=5, format='sympy'))" 1247 | ], 1248 | "language": "python", 1249 | "metadata": {}, 1250 | "outputs": [ 1251 | { 1252 | "output_type": "stream", 1253 | "stream": "stdout", 1254 | "text": [ 1255 | "[0]\n", 1256 | "[1]\n", 1257 | "[0]\n", 1258 | "[0]\n", 1259 | "[0]\n" 1260 | ] 1261 | } 1262 | ], 1263 | "prompt_number": 53 1264 | }, 1265 | { 1266 | "cell_type": "code", 1267 | "collapsed": false, 1268 | "input": [ 1269 | "print(represent(b0, basis=N, ndim=5, format='sympy'))" 1270 | ], 1271 | "language": "python", 1272 | "metadata": {}, 1273 | "outputs": [ 1274 | { 1275 | "output_type": "stream", 1276 | "stream": "stdout", 1277 | "text": [ 1278 | "[1, 0, 0, 0, 0]\n" 1279 | ] 1280 | } 1281 | ], 1282 | "prompt_number": 54 1283 | }, 1284 | { 1285 | "cell_type": "code", 1286 | "collapsed": false, 1287 | "input": [ 1288 | "print(represent(b1, basis=N, ndim=5, format='sympy'))" 1289 | ], 1290 | "language": "python", 1291 | "metadata": {}, 1292 | "outputs": [ 1293 | { 1294 | "output_type": "stream", 1295 | "stream": "stdout", 1296 | "text": [ 1297 | "[0, 1, 0, 0, 0]\n" 1298 | ] 1299 | } 1300 | ], 1301 | "prompt_number": 55 1302 | }, 1303 | { 1304 | "cell_type": "code", 1305 | "collapsed": false, 1306 | "input": [], 1307 | "language": "python", 1308 | "metadata": {}, 1309 | "outputs": [] 1310 | } 1311 | ], 1312 | "metadata": {} 1313 | } 1314 | ] 1315 | } --------------------------------------------------------------------------------