{ "metadata": { "name": "commutators and sympy-Copy0" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": "#Commutator and expansion based computations with Python & Sympy" }, { "cell_type": "code", "collapsed": false, "input": "from sympy.physics.quantum import Commutator, Dagger, Operator\nfrom sympy import simplify, exp, series\ninit_printing()\nt = Symbol(\"t\")", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 229 }, { "cell_type": "markdown", "metadata": {}, "source": "Here's a quick demo on how to do computations with commutators and expansions involving operators with Python and Sympy. Let's define a couple of operators first." }, { "cell_type": "code", "collapsed": false, "input": "L1= Operator(\"L1\")\nL2= Operator(\"L2\")\nL = L1+L2;", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 226 }, { "cell_type": "markdown", "metadata": {}, "source": "Note that those operators by definition do **not** commute. " }, { "cell_type": "code", "collapsed": false, "input": "Commutator(L1,L2)==0", "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 234, "text": "False" } ], "prompt_number": 234 }, { "cell_type": "markdown", "metadata": {}, "source": "Now let's move on to an operator defined by an expansion, the exponential operator. This is a well-defined operator as long as L is bounded. Most often it's denoted by $e^{Lt}$ and is really nothing more than \n\n$$e^{Lt}=\\sum_{k=0}^{\\infty}\\frac{(Lt)^k}{k!}$$\n\nLet's define a function that approximates this operator, up to a certain order." }, { "cell_type": "code", "collapsed": false, "input": "def expseries(L,t,k):\n return series(exp(L*t),x=t,n=k);\n ", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 235 }, { "cell_type": "markdown", "metadata": {}, "source": "Now we can compute the expansions of those operators and combinations of them. For example, the first terms of $e^{(L_1+2L_2)t}$ are" }, { "cell_type": "code", "collapsed": false, "input": "expseries(L1+2*L2,t,3)\n\n\n\n", "language": "python", "metadata": {}, "outputs": [ { "latex": "$$1 + t \\left(L_{1} + 2 L_{2}\\right) + t^{2} \\left(L_{1} L_{2} + \\frac{\\left(L_{1}\\right)^{2}}{2} + L_{2} L_{1} + 2 \\left(L_{2}\\right)^{2}\\right) + \\mathcal{O}\\left(t^{3}\\right)$$", "metadata": {}, "output_type": "pyout", "prompt_number": 199, "text": " \u239b 2 \u239e \n 2 \u239c L\u2081 2\u239f \u239b 3\u239e\n1 + t\u22c5(L\u2081 + 2\u22c5L\u2082) + t \u22c5\u239cL\u2081\u22c5L\u2082 + \u2500\u2500\u2500 + L\u2082\u22c5L\u2081 + 2\u22c5L\u2082 \u239f + O\u239dt \u23a0\n \u239d 2 \u23a0 " } ], "prompt_number": 199 }, { "cell_type": "markdown", "metadata": {}, "source": "We can also compute the difference between different exponential operators. For example, it is a fact that we can approximate the operator $e^{Lt}=e^{(L_1+L_2)t}$ with $e^{L_1t}e^{L_2t}$ \n\nThis is called the Lie splitting and with Python & Sympy we can figure out the difference between those two, which is a new operator. " }, { "cell_type": "code", "collapsed": false, "input": "expseries(L1+L2,t,3)-expseries(L1,t,3)*expseries(L2,t,3)\n", "language": "python", "metadata": {}, "outputs": [ { "latex": "$$- \\left(1 + t L_{1} + \\frac{t^{2} \\left(L_{1}\\right)^{2}}{2} + \\mathcal{O}\\left(t^{3}\\right)\\right) \\left(1 + t L_{2} + \\frac{t^{2} \\left(L_{2}\\right)^{2}}{2} + \\mathcal{O}\\left(t^{3}\\right)\\right) + 1 + t \\left(L_{1} + L_{2}\\right) + t^{2} \\left(\\frac{L_{1} L_{2}}{2} + \\frac{\\left(L_{1}\\right)^{2}}{2} + \\frac{L_{2} L_{1}}{2} + \\frac{\\left(L_{2}\\right)^{2}}{2}\\right) + \\mathcal{O}\\left(t^{3}\\right)$$", "metadata": {}, "output_type": "pyout", "prompt_number": 214, "text": " \u239b 2 2 \u239e \u239b 2 2 \u239e \n \u239c t \u22c5L\u2081 \u239b 3\u239e\u239f \u239c t \u22c5L\u2082 \u239b 3\u239e\u239f \n- \u239c1 + t\u22c5L\u2081 + \u2500\u2500\u2500\u2500\u2500\u2500 + O\u239dt \u23a0\u239f\u22c5\u239c1 + t\u22c5L\u2082 + \u2500\u2500\u2500\u2500\u2500\u2500 + O\u239dt \u23a0\u239f + 1 + t\u22c5(L\u2081 + L\u2082) + \n \u239d 2 \u23a0 \u239d 2 \u23a0 \n\n \u239b 2 2\u239e \n 2 \u239cL\u2081\u22c5L\u2082 L\u2081 L\u2082\u22c5L\u2081 L\u2082 \u239f \u239b 3\u239e\nt \u22c5\u239c\u2500\u2500\u2500\u2500\u2500 + \u2500\u2500\u2500 + \u2500\u2500\u2500\u2500\u2500 + \u2500\u2500\u2500\u239f + O\u239dt \u23a0\n \u239d 2 2 2 2 \u23a0 " } ], "prompt_number": 214 }, { "cell_type": "markdown", "metadata": {}, "source": "Those are the error terms, but clearly we can have python do more simplifications for us. We use sympy's *simplify* for that." }, { "cell_type": "code", "collapsed": false, "input": "simplify(expseries(L1+L2,t,3)-expseries(L1,t,3)*expseries(L2,t,3))", "language": "python", "metadata": {}, "outputs": [ { "latex": "$$\\frac{1}{2} \\left(t^{2} L_{2} L_{1} - t^{2} L_{1} L_{2} + \\mathcal{O}\\left(t^{3}\\right)\\right)$$", "metadata": {}, "output_type": "pyout", "prompt_number": 236, "text": " 2 2 \u239b 3\u239e\nt \u22c5L\u2082\u22c5L\u2081 - t \u22c5L\u2081\u22c5L\u2082 + O\u239dt \u23a0\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n 2 " } ], "prompt_number": 236 }, { "cell_type": "markdown", "metadata": {}, "source": "Now things look a lot better! Note that the term in there is actually the commutator of $L_1$ and $L_2$. It's easy to isolate that term in python with an *expand* and *coeff*." }, { "cell_type": "code", "collapsed": false, "input": "expand(simplify(expseries(L1+L2,t,3)-expseries(L1,t,3)*expseries(L2,t,3))).coeff(t,2)\n", "language": "python", "metadata": {}, "outputs": [ { "latex": "$$- \\frac{L_{1} L_{2}}{2} + \\frac{L_{2} L_{1}}{2}$$", "metadata": {}, "output_type": "pyout", "prompt_number": 237, "text": " L\u2081\u22c5L\u2082 L\u2082\u22c5L\u2081\n- \u2500\u2500\u2500\u2500\u2500 + \u2500\u2500\u2500\u2500\u2500\n 2 2 " } ], "prompt_number": 237 }, { "cell_type": "markdown", "metadata": {}, "source": "We can use the same idea to compute the errors between arbitrarily complex splittings.\n\nFor example, we can also approximate $e^{Lt}$ with $e^{L_1t/2}e^{L_2t}e^{L_1t/2}$. This is called the Strang splitting. Again we try to compute the error term." }, { "cell_type": "code", "collapsed": false, "input": "simplify(expseries(L1+L2,t,3)-expseries(L1/2,t,3)*expseries(L2,t,3)*expseries(L1,t,3))", "language": "python", "metadata": {}, "outputs": [ { "latex": "$$\\frac{1}{8} \\left(- 4 t L_{1} - 4 t^{2} L_{2} L_{1} - 5 t^{2} \\left(L_{1}\\right)^{2} + \\mathcal{O}\\left(t^{3}\\right)\\right)$$", "metadata": {}, "output_type": "pyout", "prompt_number": 217, "text": " 2 2 2 \u239b 3\u239e\n-4\u22c5t\u22c5L\u2081 - 4\u22c5t \u22c5L\u2082\u22c5L\u2081 - 5\u22c5t \u22c5L\u2081 + O\u239dt \u23a0\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n 8 " } ], "prompt_number": 217 }, { "cell_type": "markdown", "metadata": {}, "source": "In this case, the error term contains first order terms. Since we *know* that Strang is more accurate than Lie, it must be the case that we don't have enough terms in the expansion. A lot of multiplications will be hidden under the following *simplify*." }, { "cell_type": "code", "collapsed": false, "input": "simplify(expseries(L1+L2,t,4)-expseries(L1/2,t,4)*expseries(L2,t,4)*expseries(L1/2,t,4))", "language": "python", "metadata": {}, "outputs": [ { "latex": "$$\\frac{1}{24} \\left(- 2 t^{3} \\left(L_{2}\\right)^{2} L_{1} + t^{3} L_{2} \\left(L_{1}\\right)^{2} + 4 t^{3} L_{2} L_{1} L_{2} + t^{3} \\left(L_{1}\\right)^{2} L_{2} - 2 t^{3} L_{1} \\left(L_{2}\\right)^{2} - 2 t^{3} L_{1} L_{2} L_{1} + \\mathcal{O}\\left(t^{4}\\right)\\right)$$", "metadata": {}, "output_type": "pyout", "prompt_number": 222, "text": " 3 2 3 2 3 3 2 3 2 3 \n- 2\u22c5t \u22c5L\u2082 \u22c5L\u2081 + t \u22c5L\u2082\u22c5L\u2081 + 4\u22c5t \u22c5L\u2082\u22c5L\u2081\u22c5L\u2082 + t \u22c5L\u2081 \u22c5L\u2082 - 2\u22c5t \u22c5L\u2081\u22c5L\u2082 - 2\u22c5t \u22c5L\u2081\u22c5\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n 24 \n\n \u239b 4\u239e\nL\u2082\u22c5L\u2081 + O\u239dt \u23a0\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n " } ], "prompt_number": 222 }, { "cell_type": "markdown", "metadata": {}, "source": "Once again, we can collect the important terms by *expand* and *coeff*." }, { "cell_type": "code", "collapsed": false, "input": "expand(Out[222]).coeff(t,3)", "language": "python", "metadata": {}, "outputs": [ { "latex": "$$- \\frac{L_{1} L_{2}}{12} L_{1} - \\frac{L_{1} \\left(L_{2}\\right)^{2}}{12} + \\frac{\\left(L_{1}\\right)^{2} L_{2}}{24} + \\frac{L_{2} L_{1}}{6} L_{2} + \\frac{L_{2} \\left(L_{1}\\right)^{2}}{24} - \\frac{\\left(L_{2}\\right)^{2} L_{1}}{12}$$", "metadata": {}, "output_type": "pyout", "prompt_number": 224, "text": " 2 2 2 2 \n L\u2081\u22c5L\u2082\u22c5L\u2081 L\u2081\u22c5L\u2082 L\u2081 \u22c5L\u2082 L\u2082\u22c5L\u2081\u22c5L\u2082 L\u2082\u22c5L\u2081 L\u2082 \u22c5L\u2081\n- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 - \u2500\u2500\u2500\u2500\u2500\u2500 + \u2500\u2500\u2500\u2500\u2500\u2500 + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 + \u2500\u2500\u2500\u2500\u2500\u2500 - \u2500\u2500\u2500\u2500\u2500\u2500\n 12 12 24 6 24 12 " } ], "prompt_number": 224 }, { "cell_type": "code", "collapsed": false, "input": "", "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }