{
 "metadata": {
  "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "GraviPy - tutorial"
     ]
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "_Coordinates_ and _MetricTensor_"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "To start working with the gravipy package you must load the package and to initialize a pretty-printing mode in IPython environment"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from gravipy import * # import SymPy and GraviPy package\n",
      "init_printing()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 1
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The next step is to choose coordinates and  to define a metric tensor of a particular space. Let's take, for example, the Schwarzschild metric - vacuum solution to the Einstein's field equations which describes the gravitational field of a spherical mass distribution."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "t, r, theta, phi, M = symbols('t, r, \\\\theta, \\phi, M') # define some symbolic variables\n",
      "x = Coordinates('\\chi', [t, r, theta, phi]) # create a four-vector of coordinates object instantiating the Coordinates class\n",
      "Metric = diag(-(1-2*M/r), 1/(1-2*M/r), r**2, r**2*sin(theta)**2) # define a matrix of a metric tensor components  \n",
      "g = MetricTensor('g', x, Metric) # create a metric tensor object instantiating the MetricTensor class"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 2
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Each component of any tensor object, can be computed by calling the appropriate instance of the _GeneralTensor_ subclass with indices as arguments. The covariant indices take positive integer values (1, 2, ..., dim). The contravariant indices take negative values (-dim, ..., -2, -1)."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "x(-1)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$t$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "iVBORw0KGgoAAAANSUhEUgAAAAkAAAARCAYAAAAPFIbmAAAABHNCSVQICAgIfAhkiAAAAJdJREFU\nKJG9zjELQQEUxfFfTMogZZTBaLZRLDYz38BA+SI+kJUsslhtJrIrRLHcV3q93mBwpnvu/XfP4Uc1\ncUIjWRQyoCGquORBXWxxz4M6WGf1GGEZH97YhJ9mwRM8UPpepuP62OGWB/WwyopI1Io+gzxohifK\n4Suop+O62OMafo5XGiriGHM7yp+TQ6IDxtGthkV0/Lc+9gIbF9gUSuQAAAAASUVORK5CYII=\n",
       "prompt_number": 3,
       "text": [
        "t"
       ]
      }
     ],
     "prompt_number": 3
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "g(1, 1)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\frac{2 M}{r} - 1$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "iVBORw0KGgoAAAANSUhEUgAAAEsAAAAZCAYAAAB5CNMWAAAABHNCSVQICAgIfAhkiAAAA0xJREFU\nWIXt2GuIVVUUwPGfZTpaORE19hoqmw8VJPQyM2fK6UMEQdgkpFEUFERFSVBfokgUekFgX4oeNEQU\nEUUUoRXSaApSUNIDBMEp6UNvK6aHZNmHtWWOx3v2udrcrsb9w+Xcvfbar7XXXmftQ4f/BVe1ewIH\nC6fj9XZPoswhpfIcvIZV+BTP4sRM++exCbvwF3prxpuHMfyJjXiuQm8JXqrpq1VMxyd1SufgHRyV\nykdgHb7FKZl2fVgvDHZpRu8wPCqM+njNXD7CtLoJt4Dz8aFYy14UPWs5bsVPqTyGO3EsHsoM0G/c\nQ2Zl9G7C5jTmmozeHHyO3zM6E80ZeAu3ic2sZQzb0FOSb8f3mXbPoFss7sEKnVNxAx7G3zg6099K\nXF4/3ZYxrAnPGsVMHF7S2SF/JLrxM75Q7VnXi/g2ILzmxwq9Q7EA72bGaxuTC//n4kh8XZCdIAw4\nUtH+JOGNsFVjYy3EG+jCuXg6M59BvI+dJfmQMGIvFmMRzkzjr8QHmT4njKJn/WpPQ8Ed4tjcW9H+\nYvESIDyzbKwZOA0f40IR5NepZgleLMmm4gLcLgz0itiYRzBfeG3b6RNxbEVG5wnj8ecucda7C/X3\nCG+FZan++Iq+ukQaMqkkv0x45xT8UZhPb9K/JL+MfWZYRcyqYqpw7cdq9F4u/F+YBjk7lc/DlYX6\n97Al09eQxi+IuWIDBlL/s2vm9G8ZVmGsyQ1kk0QqsBr3ZzqdiW8K5a3pOUskdVfggSSbIo5SLtFc\nXNAvsjE9B/GDSJYbcRaesrdnVrEJtzSpW8kK3FeSNYoLi3B1oTxD7MjdIqc6uVB3Uaqrii/d6oP0\nWrxaozMRDGsidYAbRUBfXpLPb9C2357B+hex8/0ikH9ZqBtIz6rgPiSuWVVME8dxJKPTcorHcFBc\nR1bjhZJO2dI94mqztCQfFQloOT1YgK9ELtaIa3BzZp7zxFEeyehMFF3pOR2/VSltF0Zp9NvtaceI\n4zCW5KPiirCbJ8XCCO9aJe55u0SGv1ZcoYocl+Q5rhPHtNl4tK/04G18ZnzN34mX0rUtGnO/WCru\npB2aYIPw2AOecoD/r+kTXzlyF/UDhnYbq50f+Q463hQfGTt06NChGf4BALaoxf7hO2UAAAAASUVO\nRK5CYII=\n",
       "prompt_number": 4,
       "text": [
        "2\u22c5M    \n",
        "\u2500\u2500\u2500 - 1\n",
        " r     "
       ]
      }
     ],
     "prompt_number": 4
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "x(1)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$t \\left(\\frac{2 M}{r} - 1\\right)$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "iVBORw0KGgoAAAANSUhEUgAAAGEAAAAZCAYAAAAhd0APAAAABHNCSVQICAgIfAhkiAAABJ5JREFU\naIHt2VuIVWUUB/Cfl3FGLZWpNLppZlRGZJZWkzM5ikVYRPpg0VUqigz0IXqIsMs8ZEUPhg9dUaIb\n3ehCZUVlqWUmKtmVwsmKoouaNSRRaQ9rH2afM/vsM+qZGQfmD8Pee31rr+/bZ631X+v7hj70agzs\n6QXkYFZPLyADNdU2OAtzq220SjgeL/b0IjJwG86qlrGzsbhENhkv4HVswqM4PMfGY9iI3fgPR1aY\nswFt+AdrsDRH907MqWCvqzAEn5QZq8FrGN8ZQ8fgR4zOGBuGtclkBUzEmxiRPB+A9/ELxuTMMw6r\nhCOm5+jV4F7hrPsrrp71GNwJvWpjEj4W31MOo7FOCTX1z1C8APX4OWPsFjyJv1KyFtyA35PnNszH\nIViUs6BG7RE9NkfvGnyZrPXtHD0iIz/Dzgp61cQJeBXzRKDkYQs+xVWVjD6P9zLkQ7ENB5XI2/Ad\nRpbIt+O3nHkewXDxg91VRudoseC7sUsERx4W47wKOl2JZfIzAU7FN2lBViZMEXRSipn4FltL5K0Y\nJZyUxt/yaWE4diQ2y2XCFaJ+NIkI35ZjbwCa8VaOzv6ADSKQJxYEBSfMwXJ8JCK6OXmel3p5Bj7I\nMHqG4LrWlOww4Zi1ZRZyhMge2CzbCRfhZdSJ6MkKjDSmYSX+LZHPxhK8JGrZlSKznhD01d3YJWrh\nueUUrlM+gtcl453BIsGPDWXGL8WFyf0SHbNrGG5K7qeLFK/U8SzVsQWsxT3J/deCuxtFJG5J5q4m\nlqlMR3Afni48lNJRs6jwWYVtjPbim4dxuFHwfFbmEJS3MrnfLLh+eGr8ejyY3Dcl17xMqMMpGfNN\nxYcYJNrgDcm8Q0TNei73S7oO20S9Q0cnTJVdlIkfqZITakX39BBuzdGr187vBRorUNJp+Ap/Js9N\nopD9lGNvptijlEbhDrwjKLMWzyTy7zEBK3JsdiW2SgVd+ujhRMHj5ZywW3YhL6CfoITlWJijN0px\n+7s5uY4VG53zcXsiG4TT8VSOPbgk9U4aa5LrNPHhm8q8f5IInH4V5ilgo8jWvUX/9FxpJzSLolZI\n6RE4UEQNkQV5LWILvkiuBRS6mzSaFFNLOhPmKt4NTxL1qVxgEBF1lOi/y6E5sVGOrzfhzJz3q416\nKVZJR3aj8HBb8jxfcafRqrwT5oqq31Iin5Kh26jYCX+IKG0UO8ktqbHO1IPZ4sikHAYLOlqRo9Pd\nqJfqJtOZMED07EQE7lTMw6tkn3tME8cKy/F4Sj5Qx8gbKbqdBSXyVlGoHi6RN+OH1LqycDGuzRlv\nELS2IkenWqhLrkMUnyqUYrwyu/+TsVq0TzfryP8zxIapFNvFj531V8iMgwUdtCXyVsV7kAe0t7M1\nosiuT3R3Ju/Oz5j7UPlUBZeL/Upn+X5PMRJvCDosfPeveFe04qUYKJqOCXszWa2gjbzT0e7GAnFu\n1ZvQgM/3xcAd2jc/+wNWiyzrTXgWV++LgaGik6h0kNYdGCd2wL0JxwlqHLCvhiaLk9a8PUN3YCEu\n6+E17AnqxOHisdUyeI7sQtmdeEX8A6m3oEXPHBj2oQ996ENn8T+yG/C9oH/95gAAAABJRU5ErkJg\ngg==\n",
       "prompt_number": 5,
       "text": [
        "  \u239b2\u22c5M    \u239e\n",
        "t\u22c5\u239c\u2500\u2500\u2500 - 1\u239f\n",
        "  \u239d r     \u23a0"
       ]
      }
     ],
     "prompt_number": 5
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Matrix representation of a tensor can be obtained in the following way"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "x(-All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}t & r & \\theta & \\phi\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 6,
       "text": [
        "[t  r  \\theta  \\phi]"
       ]
      }
     ],
     "prompt_number": 6
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "g(All, All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}\\frac{2 M}{r} - 1 & 0 & 0 & 0\\\\0 & \\frac{1}{- \\frac{2 M}{r} + 1} & 0 & 0\\\\0 & 0 & r^{2} & 0\\\\0 & 0 & 0 & r^{2} \\sin^{2}{\\left (\\theta \\right )}\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 7,
       "text": [
        "\u23a12\u22c5M                                    \u23a4\n",
        "\u23a2\u2500\u2500\u2500 - 1      0      0          0       \u23a5\n",
        "\u23a2 r                                     \u23a5\n",
        "\u23a2                                       \u23a5\n",
        "\u23a2             1                         \u23a5\n",
        "\u23a2   0     \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  0          0       \u23a5\n",
        "\u23a2           2\u22c5M                         \u23a5\n",
        "\u23a2         - \u2500\u2500\u2500 + 1                     \u23a5\n",
        "\u23a2            r                          \u23a5\n",
        "\u23a2                                       \u23a5\n",
        "\u23a2                     2                 \u23a5\n",
        "\u23a2   0         0      r          0       \u23a5\n",
        "\u23a2                                       \u23a5\n",
        "\u23a2                         2    2        \u23a5\n",
        "\u23a3   0         0      0   r \u22c5sin (\\theta)\u23a6"
       ]
      }
     ],
     "prompt_number": 7
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "g(All, 4)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}0 & 0 & 0 & r^{2} \\sin^{2}{\\left (\\theta \\right )}\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 8,
       "text": [
        "\u23a1          2    2        \u23a4\n",
        "\u23a30  0  0  r \u22c5sin (\\theta)\u23a6"
       ]
      }
     ],
     "prompt_number": 8
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Predefined _Tensor_ Classes"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The GraviPy package contains a number of the _Tensor_ subclasses that can be used to calculate a tensor components. The _Tensor_ subclasses available in the current version of GraviPy package are"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "print([cls.__name__ for cls in vars()['Tensor'].__subclasses__()])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "['Christoffel', 'Ricci', 'Riemann', 'Einstein', 'Geodesic']\n"
       ]
      }
     ],
     "prompt_number": 9
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "The _Christoffel_ symbols"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The first one is the _Christoffel_ class that represents Christoffel symbols of the first and second kind. (Note that the Christoffel symbols are not tensors) Components of the _Christoffel_ objects are computed from the below formula "
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "$$ \\Gamma_{\\rho \\mu \\nu} = g_{\\rho \\sigma}\\Gamma^{\\sigma}_{\\ \\mu \\nu} = \\frac{1}{2}(g_{\\rho \\mu, \\nu} + g_{\\rho \\nu, \\mu} - g_{\\mu \\nu, \\rho})$$\n"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Let's create an instance of the _Christoffel_ class for the Schwarzschild metric g and compute some components of the object"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Ga = Christoffel('Ga', g)\n",
      "Ga(1, 2, 1)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$- \\frac{M}{r^{2}}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "iVBORw0KGgoAAAANSUhEUgAAACEAAAAiCAYAAADRcLDBAAAABHNCSVQICAgIfAhkiAAAAaFJREFU\nWIXt1s1LVUEYx/HPvSUWpEJLMXpTIdBVKxeCmOAiQullka7cCYLQpp1uWgQtWyb+CRK0EekNRHdB\n4SKklDYuulQGEQhB1mJGOlzvkbA5Xoj73ZznzDwzz+/MmXnm4T/jFGZQwZMcn1vYxUMMFSWkDXN4\nV6PvLO5jvbqjnFjEAB7hHI5n2kvoRzOeJY65j7vxWUFnpn0UrVjDSPWg1Cuxx3t0RbsTn3ACl/Cy\nSBHt2KoSUUYfVoWN+ArfihQxiOcZEd24jsex7Qqe1hqYeiUq0d6IorbwPSOi5qY8liB4L+5hAk1Y\nET6uFfO4ijvC7/iCD9hOELdBMZQydq+Q7Uo5vtW8wWRqEYfl179qSCEijzKmcDK+PygwVi7XcCba\nC7ic51jU3QEXcTvamxlBR0ozWqK9JGTUmqTImHn8xA+hjtjFYoGxDqQNs/UKvseUcJ80KbCmPIgx\noXb4jK/oyXNMkSc6cBM38BFvMS1sxJ0E8/8Vw8JRf43xaJ8/quBZTgvLfqi8kypZDWJZOIp1EzHk\nT31ZN17gQr1FNGiQlN/ENT5ElFfAUwAAAABJRU5ErkJggg==\n",
       "prompt_number": 10,
       "text": [
        "-M \n",
        "\u2500\u2500\u2500\n",
        "  2\n",
        " r "
       ]
      }
     ],
     "prompt_number": 10
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Each component of the _Tensor_ object is computed only once due to memoization procedure implemented in the _Tensor_ class. Computed value of a tensor component is stored in _components_ dictionary (attribute of a _Tensor_ instance) and returned by the next call to the instance."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Ga.components"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\begin{Bmatrix}\\begin{pmatrix}1, & 1, & 2\\end{pmatrix} : - \\frac{M}{r^{2}}, & \\begin{pmatrix}1, & 2, & 1\\end{pmatrix} : - \\frac{M}{r^{2}}\\end{Bmatrix}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 11,
       "text": [
        "\u23a7           -M              -M \u23ab\n",
        "\u23aa(1, 1, 2): \u2500\u2500\u2500, (1, 2, 1): \u2500\u2500\u2500\u23aa\n",
        "\u23a8             2               2\u23ac\n",
        "\u23aa            r               r \u23aa\n",
        "\u23a9                              \u23ad"
       ]
      }
     ],
     "prompt_number": 11
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The above dictionary consists of two elements because the symmetry of the Christoffel symbols is implemented in the _Christoffel_ class. "
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "If necessary, you can clear the _components_ dictionary"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Ga.components = {}\n",
      "Ga.components"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\begin{Bmatrix}\\end{Bmatrix}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 12,
       "text": [
        "{}"
       ]
      }
     ],
     "prompt_number": 12
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The _Matrix_ representation of the Christoffel symbols is the following"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Ga(All, All, All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}\\left[\\begin{matrix}0 & - \\frac{M}{r^{2}} & 0 & 0\\\\- \\frac{M}{r^{2}} & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right] & \\left[\\begin{matrix}\\frac{M}{r^{2}} & 0 & 0 & 0\\\\0 & - \\frac{M}{\\left(2 M - r\\right)^{2}} & 0 & 0\\\\0 & 0 & - r & 0\\\\0 & 0 & 0 & - r \\sin^{2}{\\left (\\theta \\right )}\\end{matrix}\\right] & \\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & r & 0\\\\0 & r & 0 & 0\\\\0 & 0 & 0 & - \\frac{r^{2}}{2} \\sin{\\left (2 \\theta \\right )}\\end{matrix}\\right] & \\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & r \\sin^{2}{\\left (\\theta \\right )}\\\\0 & 0 & 0 & \\frac{r^{2}}{2} \\sin{\\left (2 \\theta \\right )}\\\\0 & r \\sin^{2}{\\left (\\theta \\right )} & \\frac{r^{2}}{2} \\sin{\\left (2 \\theta \\right )} & 0\\end{matrix}\\right]\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 13,
       "text": [
        "\u23a1\u23a1     -M       \u23a4  \u23a1M                                  \u23a4                      \n",
        "\u23a2\u23a2 0   \u2500\u2500\u2500  0  0\u23a5  \u23a2\u2500\u2500      0       0          0       \u23a5  \u23a10  0  0          0 \n",
        "\u23a2\u23a2       2      \u23a5  \u23a2 2                                 \u23a5  \u23a2                   \n",
        "\u23a2\u23a2      r       \u23a5  \u23a2r                                  \u23a5  \u23a20  0  r          0 \n",
        "\u23a2\u23a2              \u23a5  \u23a2                                   \u23a5  \u23a2                   \n",
        "\u23a2\u23a2-M            \u23a5  \u23a2       -M                          \u23a5  \u23a20  r  0          0 \n",
        "\u23a2\u23a2\u2500\u2500\u2500   0   0  0\u23a5  \u23a20   \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  0          0       \u23a5  \u23a2                   \n",
        "\u23a2\u23a2  2           \u23a5  \u23a2             2                     \u23a5  \u23a2           2       \n",
        "\u23a2\u23a2 r            \u23a5  \u23a2    (2\u22c5M - r)                      \u23a5  \u23a2         -r \u22c5sin(2\u22c5\n",
        "\u23a2\u23a2              \u23a5  \u23a2                                   \u23a5  \u23a20  0  0  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
        "\u23a2\u23a2 0    0   0  0\u23a5  \u23a20       0       -r         0       \u23a5  \u23a3                 2 \n",
        "\u23a2\u23a2              \u23a5  \u23a2                                   \u23a5                      \n",
        "\u23a2\u23a3 0    0   0  0\u23a6  \u23a2                          2        \u23a5                      \n",
        "\u23a2                  \u23a30       0       0   -r\u22c5sin (\\theta)\u23a6                      \n",
        "\u23a3                                                                             \n",
        "\n",
        "                                                                  \u23a4\n",
        "        \u23a4  \u23a10        0                0                 0        \u23a4\u23a5\n",
        "        \u23a5  \u23a2                                                     \u23a5\u23a5\n",
        "        \u23a5  \u23a2                                           2         \u23a5\u23a5\n",
        "        \u23a5  \u23a20        0                0           r\u22c5sin (\\theta) \u23a5\u23a5\n",
        "        \u23a5  \u23a2                                                     \u23a5\u23a5\n",
        "        \u23a5  \u23a2                                      2              \u23a5\u23a5\n",
        "        \u23a5  \u23a2                                     r \u22c5sin(2\u22c5\\theta)\u23a5\u23a5\n",
        "\\theta) \u23a5  \u23a20        0                0          \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u23a5\u23a5\n",
        "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u23a5  \u23a2                                            2        \u23a5\u23a5\n",
        "        \u23a6  \u23a2                                                     \u23a5\u23a5\n",
        "           \u23a2                    2                                \u23a5\u23a5\n",
        "           \u23a2        2          r \u22c5sin(2\u22c5\\theta)                  \u23a5\u23a5\n",
        "           \u23a20  r\u22c5sin (\\theta)  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500         0        \u23a5\u23a5\n",
        "           \u23a3                          2                          \u23a6\u23a6"
       ]
      }
     ],
     "prompt_number": 13
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "You can get help on any of classes mentioned before by running the command"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "help(Christoffel)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Help on class Christoffel in module gravipy.tensorial:\n",
        "\n",
        "class Christoffel(Tensor)\n",
        " |  Represents a class of Christoffel symbols of the first and second kind.\n",
        " |  \n",
        " |  Parameters\n",
        " |  ==========\n",
        " |  \n",
        " |  symbol : python string - name of the Christoffel symbol\n",
        " |  metric : GraviPy MtricTensor object\n",
        " |  \n",
        " |  Examples\n",
        " |  ========\n",
        " |  \n",
        " |  Define a Christoffel symbols for the Schwarzschild metric:\n",
        " |  \n",
        " |  >>> from gravipy import *\n",
        " |  >>> t, r, theta, phi = symbols('t, r, \\\\theta, \\phi')\n",
        " |  >>> chi = Coordinates('\\chi', [t, r, theta, phi])\n",
        " |  >>> M = Symbol('M')\n",
        " |  >>> Metric = diag(-(1 - 2 * M / r), 1 / (1 - 2 * M / r), r ** 2,\n",
        " |  ...                  r ** 2 * sin(theta) ** 2)\n",
        " |  >>> g = MetricTensor('g', chi, Metric)\n",
        " |  >>> Ga = Christoffel('Ga', g)\n",
        " |  >>> Ga(-1, 2, 1)\n",
        " |  -M/(r*(2*M - r))\n",
        " |  >>> Ga(2, All, All)\n",
        " |  Matrix([\n",
        " |  [M/r**2,               0,  0,                 0],\n",
        " |  [     0, -M/(2*M - r)**2,  0,                 0],\n",
        " |  [     0,               0, -r,                 0],\n",
        " |  [     0,               0,  0, -r*sin(\\theta)**2]])\n",
        " |  >>> Ga(1, -1, 2) # doctest: +IGNORE_EXCEPTION_DETAIL\n",
        " |  Traceback (most recent call last):\n",
        " |  GraviPyError: \"Tensor component Ga(1, -1, 2) doesn't  exist\"\n",
        " |  \n",
        " |  Method resolution order:\n",
        " |      Christoffel\n",
        " |      Tensor\n",
        " |      GeneralTensor\n",
        " |      __builtin__.object\n",
        " |  \n",
        " |  Methods defined here:\n",
        " |  \n",
        " |  __init__(self, symbol, metric, *args, **kwargs)\n",
        " |  \n",
        " |  ----------------------------------------------------------------------\n",
        " |  Data and other attributes inherited from Tensor:\n",
        " |  \n",
        " |  TensorObjects = [<gravipy.tensorial.Christoffel object>]\n",
        " |  \n",
        " |  ----------------------------------------------------------------------\n",
        " |  Methods inherited from GeneralTensor:\n",
        " |  \n",
        " |  __call__(self, *idxs)\n",
        " |  \n",
        " |  covariantD(self, *idxs)\n",
        " |  \n",
        " |  partialD(self, *idxs)\n",
        " |  \n",
        " |  ----------------------------------------------------------------------\n",
        " |  Static methods inherited from GeneralTensor:\n",
        " |  \n",
        " |  get_nmatrixel(M, idxs)\n",
        " |  \n",
        " |  ----------------------------------------------------------------------\n",
        " |  Data descriptors inherited from GeneralTensor:\n",
        " |  \n",
        " |  __dict__\n",
        " |      dictionary for instance variables (if defined)\n",
        " |  \n",
        " |  __weakref__\n",
        " |      list of weak references to the object (if defined)\n",
        " |  \n",
        " |  ----------------------------------------------------------------------\n",
        " |  Data and other attributes inherited from GeneralTensor:\n",
        " |  \n",
        " |  GeneralTensorObjects = [<gravipy.tensorial.Coordinates object>, <gravi...\n",
        "\n"
       ]
      }
     ],
     "prompt_number": 14
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Try also \"_Christoffel?_\" and  \"_Christoffel??_\""
     ]
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "The _Ricci_ tensor"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "$$ R_{\\mu \\nu} = \\frac{\\partial \\Gamma^{\\sigma}_{\\ \\mu \\nu}}{\\partial x^{\\sigma}} - \\frac{\\partial \\Gamma^{\\sigma}_{\\ \\mu \\sigma}}{\\partial x^{\\nu}} + \\Gamma^{\\sigma}_{\\ \\mu \\nu}\\Gamma^{\\rho}_{\\ \\sigma \\rho} - \\Gamma^{\\rho}_{\\ \\mu \\sigma}\\Gamma^{\\sigma}_{\\ \\nu \\rho} $$"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Ri = Ricci('Ri', g)\n",
      "Ri(All, All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 15,
       "text": [
        "\u23a10  0  0  0\u23a4\n",
        "\u23a2          \u23a5\n",
        "\u23a20  0  0  0\u23a5\n",
        "\u23a2          \u23a5\n",
        "\u23a20  0  0  0\u23a5\n",
        "\u23a2          \u23a5\n",
        "\u23a30  0  0  0\u23a6"
       ]
      }
     ],
     "prompt_number": 15
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Contraction of the _Ricci_ tensor $R = R_{\\mu}^{\\ \\mu} = g^{\\mu \\nu}R_{\\mu \\nu}$"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Ri.scalar()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$0$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAASCAYAAABvqT8MAAAABHNCSVQICAgIfAhkiAAAANtJREFU\nKJHN0r0uhEEUxvGf9VWItTYahSgQPYV2SxfBBbiAbfSidSE60e4trASNjghZGiHbEFnFzpscb84W\nOqd5cp6Z/5nJzMMfa6rWb+MU9xhhBV0MMngJjzgI3jFuMJcBJ3jBTPDa+MJRBtzhIvGv0auaRtFF\nbOEhAZ6wWwfWi74nwBBNzEegWfRzAgCtCHwXHSXAbNHpCLwmG6taKPoRgUGZvjwBeKsDQ/SxlgCb\nuKqaRli4xJ7fcdkoQ86zu66Wow+Dd4ZbIRoxBs/oGEdkx/gz29iXP/d/qR8UhCWn2ReXCwAAAABJ\nRU5ErkJggg==\n",
       "prompt_number": 16,
       "text": [
        "0"
       ]
      }
     ],
     "prompt_number": 16
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "The _Riemann_ tensor"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "$$ R_{\\mu \\nu \\rho \\sigma} = \\frac{\\partial \\Gamma_{\\mu \\nu \\sigma}}{\\partial x^{\\rho}} - \\frac{\\partial \\Gamma_{\\mu \\nu \\rho}}{\\partial x^{\\sigma}} + \\Gamma^{\\alpha}_{\\ \\nu \\sigma}\\Gamma_{\\mu \\rho \\alpha} - \\Gamma^{\\alpha}_{\\ \\nu \\rho}\\Gamma_{\\mu \\sigma \\alpha} - \\frac{\\partial g_{\\mu \\alpha}}{\\partial x^{\\rho}}\\Gamma^{\\alpha}_{\\ \\nu \\sigma} + \\frac{\\partial g_{\\mu \\alpha}}{\\partial x^{\\sigma}}\\Gamma^{\\alpha}_{\\ \\nu \\rho} $$"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Rm = Riemann('Rm', g)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 17
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Some nonzero components of the _Riemann_ tensor are"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from IPython.core.display import display, Math\n",
      "for i, j, k, l in list(variations(range(1, 5), 4, True)):\n",
      "    if Rm(i, j, k, l) != 0 and k<l and i<j:\n",
      "        display(Math('R_{'+str(i)+str(j)+str(k)+str(l)+'} = '+latex(Rm(i, j, k, l))))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$R_{1212} = - \\frac{2 M}{r^{3}}$$"
       ],
       "metadata": {},
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0xbd4bfac>"
       ]
      },
      {
       "latex": [
        "$$R_{1313} = \\frac{M}{r^{2}} \\left(- 2 M + r\\right)$$"
       ],
       "metadata": {},
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0xbd51cec>"
       ]
      },
      {
       "latex": [
        "$$R_{1414} = \\frac{M}{r^{2}} \\left(- 2 M + r\\right) \\sin^{2}{\\left (\\theta \\right )}$$"
       ],
       "metadata": {},
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0xc06960c>"
       ]
      },
      {
       "latex": [
        "$$R_{2323} = \\frac{M}{2 M - r}$$"
       ],
       "metadata": {},
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0xbd4bfac>"
       ]
      },
      {
       "latex": [
        "$$R_{2424} = \\frac{M \\sin^{2}{\\left (\\theta \\right )}}{2 M - r}$$"
       ],
       "metadata": {},
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0xbd538ec>"
       ]
      },
      {
       "latex": [
        "$$R_{3434} = 2 M r \\sin^{2}{\\left (\\theta \\right )}$$"
       ],
       "metadata": {},
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0xbd85acc>"
       ]
      }
     ],
     "prompt_number": 18
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "You can also display the matrix representation of the tensor"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# Rm(All, All, All, All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 19
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Contraction of the _Riemann_ tensor $R_{\\mu \\nu} = R^{\\rho}_{\\ \\mu \\rho \\nu} $"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "ricci = sum([Rm(i, All, k, All)*g(-i, -k) for i, k in list(variations(range(1, 5), 2, True))], zeros(4))\n",
      "ricci.simplify()\n",
      "ricci"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 20,
       "text": [
        "\u23a10  0  0  0\u23a4\n",
        "\u23a2          \u23a5\n",
        "\u23a20  0  0  0\u23a5\n",
        "\u23a2          \u23a5\n",
        "\u23a20  0  0  0\u23a5\n",
        "\u23a2          \u23a5\n",
        "\u23a30  0  0  0\u23a6"
       ]
      }
     ],
     "prompt_number": 20
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "The _Einstein_ tensor"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "$$ G_{\\mu \\nu} = R_{\\mu \\nu} - \\frac{1}{2}g_{\\mu \\nu}R $$"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "G = Einstein('G', Ri)\n",
      "G(All, All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 21,
       "text": [
        "\u23a10  0  0  0\u23a4\n",
        "\u23a2          \u23a5\n",
        "\u23a20  0  0  0\u23a5\n",
        "\u23a2          \u23a5\n",
        "\u23a20  0  0  0\u23a5\n",
        "\u23a2          \u23a5\n",
        "\u23a30  0  0  0\u23a6"
       ]
      }
     ],
     "prompt_number": 21
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "_Geodesics_"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "$$ w_{\\mu} = \\frac{Du_{\\mu}}{d\\tau} = \\frac{d^2x_{\\mu}}{d\\tau^2} - \\frac{1}{2}g_{\\rho \\sigma, \\mu} \\frac{dx^{\\rho}}{d\\tau}\\frac{dx^{\\sigma}}{d\\tau} $$"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "tau = Symbol('\\\\tau')\n",
      "w = Geodesic('w', g, tau)\n",
      "w(All).transpose()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}- \\frac{2 M \\frac{d}{d \\tau} r{\\left (\\tau \\right )}}{r^{2}{\\left (\\tau \\right )}} \\frac{d}{d \\tau} t{\\left (\\tau \\right )} + \\left(\\frac{2 M}{r{\\left (\\tau \\right )}} - 1\\right) \\frac{d^{2}}{d \\tau^{2}}  t{\\left (\\tau \\right )}\\\\\\frac{M \\left(\\frac{d}{d \\tau} t{\\left (\\tau \\right )}\\right)^{2}}{r^{2}{\\left (\\tau \\right )}} - \\frac{M \\left(\\frac{d}{d \\tau} r{\\left (\\tau \\right )}\\right)^{2}}{\\left(- \\frac{2 M}{r{\\left (\\tau \\right )}} + 1\\right)^{2} r^{2}{\\left (\\tau \\right )}} - r{\\left (\\tau \\right )} \\sin^{2}{\\left (\\theta{\\left (\\tau \\right )} \\right )} \\left(\\frac{d}{d \\tau} \\phi{\\left (\\tau \\right )}\\right)^{2} - r{\\left (\\tau \\right )} \\left(\\frac{d}{d \\tau} \\theta{\\left (\\tau \\right )}\\right)^{2} + \\frac{\\frac{d^{2}}{d \\tau^{2}}  r{\\left (\\tau \\right )}}{- \\frac{2 M}{r{\\left (\\tau \\right )}} + 1}\\\\- r^{2}{\\left (\\tau \\right )} \\sin{\\left (\\theta{\\left (\\tau \\right )} \\right )} \\cos{\\left (\\theta{\\left (\\tau \\right )} \\right )} \\left(\\frac{d}{d \\tau} \\phi{\\left (\\tau \\right )}\\right)^{2} + r^{2}{\\left (\\tau \\right )} \\frac{d^{2}}{d \\tau^{2}}  \\theta{\\left (\\tau \\right )} + 2 r{\\left (\\tau \\right )} \\frac{d}{d \\tau} \\theta{\\left (\\tau \\right )} \\frac{d}{d \\tau} r{\\left (\\tau \\right )}\\\\r^{2}{\\left (\\tau \\right )} \\sin^{2}{\\left (\\theta{\\left (\\tau \\right )} \\right )} \\frac{d^{2}}{d \\tau^{2}}  \\phi{\\left (\\tau \\right )} + 2 r^{2}{\\left (\\tau \\right )} \\sin{\\left (\\theta{\\left (\\tau \\right )} \\right )} \\cos{\\left (\\theta{\\left (\\tau \\right )} \\right )} \\frac{d}{d \\tau} \\phi{\\left (\\tau \\right )} \\frac{d}{d \\tau} \\theta{\\left (\\tau \\right )} + 2 r{\\left (\\tau \\right )} \\sin^{2}{\\left (\\theta{\\left (\\tau \\right )} \\right )} \\frac{d}{d \\tau} \\phi{\\left (\\tau \\right )} \\frac{d}{d \\tau} r{\\left (\\tau \\right )}\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 22,
       "text": [
        "\u23a1                                                                         d   \n",
        "\u23a2                                                                   2\u22c5M\u22c5\u2500\u2500\u2500\u2500\u2500(\n",
        "\u23a2                                                                       d\\tau \n",
        "\u23a2                                                                 - \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
        "\u23a2                                                                             \n",
        "\u23a2                                                                             \n",
        "\u23a2                                                                             \n",
        "\u23a2                                                                             \n",
        "\u23a2                                          2                        2         \n",
        "\u23a2                          \u239b  d           \u239e         \u239b  d           \u239e          \n",
        "\u23a2                        M\u22c5\u239c\u2500\u2500\u2500\u2500\u2500(t(\\tau))\u239f       M\u22c5\u239c\u2500\u2500\u2500\u2500\u2500(r(\\tau))\u239f          \n",
        "\u23a2                          \u239dd\\tau         \u23a0         \u239dd\\tau         \u23a0          \n",
        "\u23a2                        \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 - r(\\\n",
        "\u23a2                               2                             2               \n",
        "\u23a2                              r (\\tau)        \u239b    2\u22c5M      \u239e   2            \n",
        "\u23a2                                              \u239c- \u2500\u2500\u2500\u2500\u2500\u2500\u2500 + 1\u239f \u22c5r (\\tau)      \n",
        "\u23a2                                              \u239d  r(\\tau)    \u23a0                \n",
        "\u23a2                                                                             \n",
        "\u23a2                                                                             \n",
        "\u23a2                            2                                           \u239b  d \n",
        "\u23a2                         - r (\\tau)\u22c5sin(\\theta(\\tau))\u22c5cos(\\theta(\\tau))\u22c5\u239c\u2500\u2500\u2500\u2500\n",
        "\u23a2                                                                        \u239dd\\ta\n",
        "\u23a2                                                                             \n",
        "\u23a2                                                                             \n",
        "\u23a2                               2                                             \n",
        "\u23a2 2          2                 d                     2                        \n",
        "\u23a2r (\\tau)\u22c5sin (\\theta(\\tau))\u22c5\u2500\u2500\u2500\u2500\u2500\u2500(\\phi(\\tau)) + 2\u22c5r (\\tau)\u22c5sin(\\theta(\\tau))\n",
        "\u23a2                                 2                                           \n",
        "\u23a3                            d\\tau                                            \n",
        "\n",
        "           d                                                                  \n",
        "r(\\tau))\u22c5\u2500\u2500\u2500\u2500\u2500(t(\\tau))                    2                                  \n",
        "         d\\tau            \u239b  2\u22c5M      \u239e   d                                   \n",
        "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 + \u239c\u2500\u2500\u2500\u2500\u2500\u2500\u2500 - 1\u239f\u22c5\u2500\u2500\u2500\u2500\u2500\u2500(t(\\tau))                       \n",
        "    2                     \u239dr(\\tau)    \u23a0      2                                \n",
        "   r (\\tau)                             d\\tau                                 \n",
        "                                                                              \n",
        "                                                                              \n",
        "                                                                              \n",
        "                                                                              \n",
        "                                           2                                2 \n",
        "        2               \u239b  d              \u239e            \u239b  d                \u239e  \n",
        "tau)\u22c5sin (\\theta(\\tau))\u22c5\u239c\u2500\u2500\u2500\u2500\u2500(\\phi(\\tau))\u239f  - r(\\tau)\u22c5\u239c\u2500\u2500\u2500\u2500\u2500(\\theta(\\tau))\u239f  \n",
        "                        \u239dd\\tau            \u23a0            \u239dd\\tau              \u23a0  \n",
        "                                                                              \n",
        "                                                                              \n",
        "                                                                              \n",
        "                                                                              \n",
        "              2               2                                               \n",
        "             \u239e     2         d                                d               \n",
        "\u2500(\\phi(\\tau))\u239f  + r (\\tau)\u22c5\u2500\u2500\u2500\u2500\u2500\u2500(\\theta(\\tau)) + 2\u22c5r(\\tau)\u22c5\u2500\u2500\u2500\u2500\u2500(\\theta(\\tau)\n",
        "u            \u23a0                  2                           d\\tau             \n",
        "                           d\\tau                                              \n",
        "                                                                              \n",
        "                                                                              \n",
        "                     d                 d                                2     \n",
        "\u22c5cos(\\theta(\\tau))\u22c5\u2500\u2500\u2500\u2500\u2500(\\phi(\\tau))\u22c5\u2500\u2500\u2500\u2500\u2500(\\theta(\\tau)) + 2\u22c5r(\\tau)\u22c5sin (\\the\n",
        "                   d\\tau             d\\tau                                    \n",
        "                                                                              \n",
        "\n",
        "                                          \u23a4\n",
        "                                          \u23a5\n",
        "                                          \u23a5\n",
        "                                          \u23a5\n",
        "                                          \u23a5\n",
        "                                          \u23a5\n",
        "                                          \u23a5\n",
        "     2                                    \u23a5\n",
        "    d                                     \u23a5\n",
        "  \u2500\u2500\u2500\u2500\u2500\u2500(r(\\tau))                         \u23a5\n",
        "       2                                  \u23a5\n",
        "  d\\tau                                   \u23a5\n",
        "+ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500                         \u23a5\n",
        "       2\u22c5M                                \u23a5\n",
        "   - \u2500\u2500\u2500\u2500\u2500\u2500\u2500 + 1                          \u23a5\n",
        "     r(\\tau)                              \u23a5\n",
        "                                          \u23a5\n",
        "                                          \u23a5\n",
        "                                          \u23a5\n",
        "    d                                     \u23a5\n",
        ")\u22c5\u2500\u2500\u2500\u2500\u2500(r(\\tau))                          \u23a5\n",
        "  d\\tau                                   \u23a5\n",
        "                                          \u23a5\n",
        "                                          \u23a5\n",
        "                                          \u23a5\n",
        "            d                 d           \u23a5\n",
        "ta(\\tau))\u22c5\u2500\u2500\u2500\u2500\u2500(\\phi(\\tau))\u22c5\u2500\u2500\u2500\u2500\u2500(r(\\tau))\u23a5\n",
        "          d\\tau             d\\tau         \u23a5\n",
        "                                          \u23a6"
       ]
      }
     ],
     "prompt_number": 22
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Please note that instantiation of a _Geodesic_ class for the metric $g$ automatically turns on a _Parametrization_ mode for the metric $g$.  \n",
      "Then all coordinates are functions of a world line parameter $\\tau$"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Parametrization.info()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\begin{bmatrix}\\begin{bmatrix}\\chi, & \\tau\\end{bmatrix}\\end{bmatrix}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 23,
       "text": [
        "[[\\chi, \\tau]]"
       ]
      }
     ],
     "prompt_number": 23
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "x(-All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}t{\\left (\\tau \\right )} & r{\\left (\\tau \\right )} & \\theta{\\left (\\tau \\right )} & \\phi{\\left (\\tau \\right )}\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 24,
       "text": [
        "[t(\\tau)  r(\\tau)  \\theta(\\tau)  \\phi(\\tau)]"
       ]
      }
     ],
     "prompt_number": 24
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "g(All, All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}\\frac{2 M}{r{\\left (\\tau \\right )}} - 1 & 0 & 0 & 0\\\\0 & \\frac{1}{- \\frac{2 M}{r{\\left (\\tau \\right )}} + 1} & 0 & 0\\\\0 & 0 & r^{2}{\\left (\\tau \\right )} & 0\\\\0 & 0 & 0 & r^{2}{\\left (\\tau \\right )} \\sin^{2}{\\left (\\theta{\\left (\\tau \\right )} \\right )}\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 25,
       "text": [
        "\u23a1  2\u22c5M                                                            \u23a4\n",
        "\u23a2\u2500\u2500\u2500\u2500\u2500\u2500\u2500 - 1        0           0                   0             \u23a5\n",
        "\u23a2r(\\tau)                                                          \u23a5\n",
        "\u23a2                                                                 \u23a5\n",
        "\u23a2                   1                                             \u23a5\n",
        "\u23a2     0       \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500     0                   0             \u23a5\n",
        "\u23a2                 2\u22c5M                                             \u23a5\n",
        "\u23a2             - \u2500\u2500\u2500\u2500\u2500\u2500\u2500 + 1                                       \u23a5\n",
        "\u23a2               r(\\tau)                                           \u23a5\n",
        "\u23a2                                                                 \u23a5\n",
        "\u23a2                             2                                   \u23a5\n",
        "\u23a2     0             0        r (\\tau)               0             \u23a5\n",
        "\u23a2                                                                 \u23a5\n",
        "\u23a2                                       2          2              \u23a5\n",
        "\u23a3     0             0           0      r (\\tau)\u22c5sin (\\theta(\\tau))\u23a6"
       ]
      }
     ],
     "prompt_number": 25
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "_Parametrization_ mode can be deactivated by typing"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Parametrization.deactivate(x)\n",
      "Parametrization.info()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "No parametrization activated\n"
       ]
      }
     ],
     "prompt_number": 26
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "x(-All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}t & r & \\theta & \\phi\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 27,
       "text": [
        "[t  r  \\theta  \\phi]"
       ]
      }
     ],
     "prompt_number": 27
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "g(All, All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}\\frac{2 M}{r} - 1 & 0 & 0 & 0\\\\0 & \\frac{1}{- \\frac{2 M}{r} + 1} & 0 & 0\\\\0 & 0 & r^{2} & 0\\\\0 & 0 & 0 & r^{2} \\sin^{2}{\\left (\\theta \\right )}\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 28,
       "text": [
        "\u23a12\u22c5M                                    \u23a4\n",
        "\u23a2\u2500\u2500\u2500 - 1      0      0          0       \u23a5\n",
        "\u23a2 r                                     \u23a5\n",
        "\u23a2                                       \u23a5\n",
        "\u23a2             1                         \u23a5\n",
        "\u23a2   0     \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  0          0       \u23a5\n",
        "\u23a2           2\u22c5M                         \u23a5\n",
        "\u23a2         - \u2500\u2500\u2500 + 1                     \u23a5\n",
        "\u23a2            r                          \u23a5\n",
        "\u23a2                                       \u23a5\n",
        "\u23a2                     2                 \u23a5\n",
        "\u23a2   0         0      r          0       \u23a5\n",
        "\u23a2                                       \u23a5\n",
        "\u23a2                         2    2        \u23a5\n",
        "\u23a3   0         0      0   r \u22c5sin (\\theta)\u23a6"
       ]
      }
     ],
     "prompt_number": 28
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Derivatives"
     ]
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "Partial derivative"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "All instances of a _GeneralTensor_ subclasses inherits _partialD_ method which works exactly the same way as SymPy _diff_ method."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "T = Tensor('T', 2, g)\n",
      "T(1, 2)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\operatorname{T(1, 2)}{\\left (t,r,\\theta,\\phi \\right )}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "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\nghGMYFfE/wC9QUke1AjR9gAAAABJRU5ErkJggg==\n",
       "prompt_number": 29,
       "text": [
        "T(1, 2)(t, r, \\theta, \\phi)"
       ]
      }
     ],
     "prompt_number": 29
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "T.partialD(1, 2, 1, 3) # The first two indices belongs to second rank tensor T"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\frac{\\partial^{2}}{\\partial \\theta\\partial t}  \\operatorname{T(1, 2)}{\\left (t,r,\\theta,\\phi \\right )}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "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\n",
       "prompt_number": 30,
       "text": [
        "     2                                 \n",
        "    \u2202                                  \n",
        "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500(T(1, 2)(t, r, \\theta, \\phi))\n",
        "\u2202t \u2202\\theta                             "
       ]
      }
     ],
     "prompt_number": 30
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "T(1, 2).diff(x(-1), x(-3))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\frac{\\partial^{2}}{\\partial \\theta\\partial t}  \\operatorname{T(1, 2)}{\\left (t,r,\\theta,\\phi \\right )}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "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\n",
       "prompt_number": 31,
       "text": [
        "     2                                 \n",
        "    \u2202                                  \n",
        "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500(T(1, 2)(t, r, \\theta, \\phi))\n",
        "\u2202t \u2202\\theta                             "
       ]
      }
     ],
     "prompt_number": 31
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The only difference is that computed value of _partialD_ is saved in  \"_partial_derivative_components_\" dictionary an then returned by the next call to the _partialD_ method."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "T.partial_derivative_components"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\begin{Bmatrix}\\begin{pmatrix}1, & 2, & 1, & 3\\end{pmatrix} : \\frac{\\partial^{2}}{\\partial \\theta\\partial t}  \\operatorname{T(1, 2)}{\\left (t,r,\\theta,\\phi \\right )}\\end{Bmatrix}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 32,
       "text": [
        "\u23a7                   2                                 \u23ab\n",
        "\u23aa                  \u2202                                  \u23aa\n",
        "\u23a8(1, 2, 1, 3): \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500(T(1, 2)(t, r, \\theta, \\phi))\u23ac\n",
        "\u23aa              \u2202t \u2202\\theta                             \u23aa\n",
        "\u23a9                                                     \u23ad"
       ]
      }
     ],
     "prompt_number": 32
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "Covariant derivative"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Covariant derivative components of the tensor ___T___  can be computed by the covariantD method from the formula"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "$$ \\nabla_{\\sigma} T_{\\mu}^{\\ \\nu} = T_{\\mu \\ ;\\sigma}^{\\ \\nu} = \\frac{\\partial T_{\\mu}^{\\ \\nu}}{\\partial x^{\\sigma}} - \\Gamma^{\\rho}_{\\ \\mu \\sigma}T_{\\rho}^{\\ \\nu} + \\Gamma^{\\nu}_{\\ \\rho \\sigma}T_{\\mu}^{\\ \\rho}$$"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Let's compute some covariant derivatives of a scalar field C"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "C = Tensor('C', 0, g)\n",
      "C()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$C{\\left (t,r,\\theta,\\phi \\right )}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "iVBORw0KGgoAAAANSUhEUgAAAFQAAAAWCAYAAABe+7umAAAABHNCSVQICAgIfAhkiAAABDVJREFU\nWIXt2HmIV1UUB/CPjY4LtClmq0uSpWMaQRuMkfZH1D8h0gImWhQVuRSW/ZN/ZAsUtFlG0mpURFpg\nJBilrS4FWhGZJiXtpkRlkRWV/XHeT9/vznvzezOjA8F84fHePfeec+49996zPHrQrWjB3XgHr2Mp\nHsUI9MISHJkbPwzTunmORRiOxbgLy3BwF+Xdn7SbcLOwQSUcIgz3FS5D31zfYLyEJ7E5Rz8Mz6BP\nImskvhPG7g4Mx0YclbXnYmEX5I3BzAL62bi9ioAR2IS1GFQy5iTswUM52iM4tWDs9fgD/aoo7yKa\nsQFX5GgXiYPRWVyDsSV9C9HaHvNAbMFWHN5A0WZMzr5PxKqScS/irQay9hduErehOUe7Umx+enOq\n4gHlV/t4vJEnHJQMWIRRYld+aqBoZ07YbDxdMq4VbzeQtT/QT/i1x/FXjj46e6drrYo92VOELzK5\npxR1npExVl38Jbnvz4WvzPetxHuZzHez9nUV5E4RrmQ5BmC6CC7P4vR2+GZkuloS+nrsqqC3hj64\nCk+ImLBCBN/ZIhiluBMLigQtziY0vQPKiWDzY0nf1fgT/SvK6iuyCsLtrMAE4cu/VO+zUyzHbrFx\ntWcV/hFZShUMwzrMEifvWozP+hYJA6eYjNeKhG0VBj22ovIaJuDTkr7nxemsivPEBJtFIKtF0ePw\nIc4p4WvCz3guoV8g1lR4ghIMwjb1Ef1h+/znMZms8QlfK74pErgbv1VQDCfkvqeIa1WE7bijokw4\nE4eKlGQPxlXkG5qNn5XQH8zoJ1eQ8Rg+yrV7CYPW0D+TdWnC14Lfa428o96lmq9pVj/xJvxbMK4F\nQ3Qswq/HL5gk3MjHFfmGZO9NOVpvXCyueyM5fTBVfWAdi09y7Vpw+zrh/TvfyBt0vUjaBzRQPgdP\n5do7FadYEzNla7P2YeLqVsFEsRFl0TVFbVHbc7TzcQTmV+AfKLKELckcVufaU/GZ8LEp745aI2/Q\n+8Rpm9GO4gvF5DfmaN8qLgAmCL9XcyNzJLsp8tc04e8vrv6b7cwj5a0l7nn5c0W1V3RDUr078IP6\nEnW0fbFhHC7PnvQ2DhS5byFuxK+i3MwbezBu09ZHEb7mexyd0JeJ2h9Ow7ykf6I4gUsT+rka+70i\n3jViw4lKaZ3i6qxM7wxxS/uLtS/Kjf8gexfhFm1r/Tq0CmNswKuZ4nvUB6IUS9TnpUQ0XJPxztM2\nsR4j3MW2hD4N72v/x0MR7xi8IkrghcpL3TK9RIB9QZzs1SIozRfuqgwrlRu705ik7Y5Xxa1d0Hug\neGeLirERBotTvXfzO1uOpVgt/lCNbDSwAH0bD+l23lEiADXCTFEp7Q2e+8ugRP2/QAf+EdoXuDqD\nA8lbZQ2jxAF6uZNzqISzRLlZBb1xr45tQHfwDsUNDWQ0iTK4qz+ue9CDHvy/8R8CB9t6oms7hgAA\nAABJRU5ErkJggg==\n",
       "prompt_number": 33,
       "text": [
        "C(t, r, \\theta, \\phi)"
       ]
      }
     ],
     "prompt_number": 33
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "C.covariantD(1)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\frac{\\partial}{\\partial t} C{\\left (t,r,\\theta,\\phi \\right )}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "iVBORw0KGgoAAAANSUhEUgAAAGIAAAAfCAYAAAAcGRgRAAAABHNCSVQICAgIfAhkiAAABURJREFU\naIHt2WmoVVUUwPGf7zk3mfEaLStJS00jaAKNzCDsS4iUhUUWRUVqRdOHkmimaLSMpNGosLRAyLDJ\nZrWgiWgupWxUojmb7cM6R8+9757hPX3vQ94/HO7d++y1zj5n772GvVvl04aZGI8v8F1B2yZdyBYY\ngIOxUgxMky6iteDeX/hdrIY9MAivdkenNkdaKrb7AEO6siObO3kD0SL8wxLMxQT07oDeEbgOL+EZ\nzMedYmX1SHTumGk/GCd2pONdyO6Yg2uxAFtthK6b68qtuEh8g0rciCdt+PifiYEpY2vxwT/HCeiT\nudeGx3CvWGEpA/AAejXQNwRfiYHqDnbHG9gpKZ+HWZ3UNRzTGtQfiiurKBiMPzEsKbfgVxxWIrcH\n3sNSbJfTZm+sw22Zujuwf077c4Sf6lvW6U1Ab7yOUzJ1x4hJ1RnOwMice7MwpkzBZHyUKU/AJ+hZ\nIDMQH+JjbFui/wNMTP4Pw7MFbR/FCyX6NhUXiNWXNcGnionTaLWWcYt8E7QnnstWNPIR3+GX5P82\nuF7Ytb8LHjobQ8Us+L6kg2synZiB+wvajsGLJfo2BX3FO94trEHKPslv1aAmy7rkasSKROd+RQpa\nhHN9BE/guJIHHpQ8sOoHm5z5/6n20dhkLBah8jq8nJTPKtE7SZi8heiPk4TDfRAHlshOTZ41oq5+\nOX4qkU3phdNwj/B5i0RQMkPjNOFqXF5RdyXmiJc4qYNygxVn66fjD/SroKuPiNII87gIY4Wv+kyt\nT2rEQqwVA55ez+IfEfmVMRjLMF1M5DMxOrk3WwxMPRPxdAXdlflYDMSgDsqNxfsF9+eJ1VCFI8WL\n9RbOPY1KdsVbigONVvyAh+rqjxLvVTZrtxM7D9kI6XYb/MMuiZ7RdXJjRLK8yVhrg08pY6/M/0li\n6efxDa6qqPdg4c8OFS89qqIc7JbITK+rvzWp37dE/i68nSn3EAOR0i/RU2/iR+C3tNAZJ1TPT6rZ\n0d5qX7YV/+a0HYEdVI+YluNHHC7M3TsV5STPIULvlJ44VpilIl29MEVtwDES72bKqcNfVSdbE/yk\nA7GuE1fKcpGs9S/oMJyN+zLlNfJD3XFJR5cm5QHCzJQxTgxeXrTSiPSDfJOpm4DtlSexA0XE9WFd\nH5ZkylNEOrCsgezqtJAORI9OXCk3idk9taDDR4sXfiNT96X8xG+ssO2pyTtb7Qwapn2S10+YqOcL\n+tFINk3YsvrPEzsE9SuyXnY1vlW7DbKPDb5vFE5OrvrVP1DkLQ1pwzUitBqW16gB5+Nnsa2RNXdt\nuEJ7+0sM5tfYucG9BSKEhgNwYebeODHj59fJjFdu0/NkXxGThcisl2k/0HmyU4VV6CfefXam/ZvJ\nbyMu0X4vaj15ZxBDcUieUMIY8QFfF/tU83GDWgddz1y1eUXKaPFxbhCDkB3c4cKsrayTORGvKd5Q\ny5MdjsfFdsssjbdU8mSJwOMRsYqWCGc9U3zLPBbLH6QabhbJCJFxnlZFqIMcrv0Mq8plG/HcrpKd\nISZtGW1iFa2fNEVRU/YM4gg8VeEBHWWJ2LHtzFlHn/Im3S47VO0+XR7ThPlfH1RkN/JacLFYLqvE\nshqV1LfgeJFgVU2yqnKGSMBOUD3aSZ15Z+hK2SrnDEPFxLs0r0HeGcSpwnZ2JYeILY0q9BR9rXy4\n0k2yu+HcEh2tYrsl97Cp6Azifo0dapMuoOgMYoVIblrkx/1NNpLUWeedQQwQK2W1sOHdcVK2WZLa\nuxY8LJzllsIczRMrYp6IsVcpPk1r0qRJkyZNmjT5//IfYTEi9GXk4dUAAAAASUVORK5CYII=\n",
       "prompt_number": 34,
       "text": [
        "\u2202                        \n",
        "\u2500\u2500(C(t, r, \\theta, \\phi))\n",
        "\u2202t                       "
       ]
      }
     ],
     "prompt_number": 34
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "C.covariantD(2, 3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\frac{1}{r} \\left(r \\frac{\\partial^{2}}{\\partial \\theta\\partial r}  C{\\left (t,r,\\theta,\\phi \\right )} - \\frac{\\partial}{\\partial \\theta} C{\\left (t,r,\\theta,\\phi \\right )}\\right)$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "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\nSUVORK5CYII=\n",
       "prompt_number": 35,
       "text": [
        "       2                                                            \n",
        "      \u2202                                  \u2202                          \n",
        "r\u22c5\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500(C(t, r, \\theta, \\phi)) - \u2500\u2500\u2500\u2500\u2500\u2500\u2500(C(t, r, \\theta, \\phi))\n",
        "  \u2202r \u2202\\theta                          \u2202\\theta                       \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\n",
        "                                 r                                  "
       ]
      }
     ],
     "prompt_number": 35
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "All _covariantD_ components of every _Tensor_ object are also memoized"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "C.covariant_derivative_components"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\begin{Bmatrix}\\begin{pmatrix}1\\end{pmatrix} : \\frac{\\partial}{\\partial t} C{\\left (t,r,\\theta,\\phi \\right )}, & \\begin{pmatrix}2\\end{pmatrix} : \\frac{\\partial}{\\partial r} C{\\left (t,r,\\theta,\\phi \\right )}, & \\begin{pmatrix}3\\end{pmatrix} : \\frac{\\partial}{\\partial \\theta} C{\\left (t,r,\\theta,\\phi \\right )}, & \\begin{pmatrix}4\\end{pmatrix} : \\frac{\\partial}{\\partial \\phi} C{\\left (t,r,\\theta,\\phi \\right )}, & \\begin{pmatrix}2, & 3\\end{pmatrix} : \\frac{1}{r} \\left(r \\frac{\\partial^{2}}{\\partial \\theta\\partial r}  C{\\left (t,r,\\theta,\\phi \\right )} - \\frac{\\partial}{\\partial \\theta} C{\\left (t,r,\\theta,\\phi \\right )}\\right)\\end{Bmatrix}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 36,
       "text": [
        "\u23a7                                                                             \n",
        "\u23aa                                                                             \n",
        "\u23aa                                                                             \n",
        "\u23a8      \u2202                                \u2202                                   \u2202 \n",
        "\u23aa(1,): \u2500\u2500(C(t, r, \\theta, \\phi)), (2,): \u2500\u2500(C(t, r, \\theta, \\phi)), (3,): \u2500\u2500\u2500\u2500\u2500\n",
        "\u23aa      \u2202t                               \u2202r                               \u2202\\the\n",
        "\u23a9                                                                             \n",
        "\n",
        "                                                                              \n",
        "                                                                             \u2202\n",
        "                                                                       r\u22c5\u2500\u2500\u2500\u2500\u2500\n",
        "                                   \u2202                                     \u2202r \u2202\\\n",
        "\u2500\u2500(C(t, r, \\theta, \\phi)), (4,): \u2500\u2500\u2500\u2500\u2500(C(t, r, \\theta, \\phi)), (2, 3): \u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
        "ta                               \u2202\\phi                                        \n",
        "                                                                              \n",
        "\n",
        "2                                                            \u23ab\n",
        "                                  \u2202                          \u23aa\n",
        "\u2500\u2500\u2500\u2500\u2500(C(t, r, \\theta, \\phi)) - \u2500\u2500\u2500\u2500\u2500\u2500\u2500(C(t, r, \\theta, \\phi))\u23aa\n",
        "theta                          \u2202\\theta                       \u23ac\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\u23aa\n",
        "                          r                                  \u23aa\n",
        "                                                             \u23ad"
       ]
      }
     ],
     "prompt_number": 36
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "C.covariantD(1, 2, 3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\frac{1}{r \\left(2 M - r\\right)} \\left(M \\frac{\\partial^{2}}{\\partial \\theta\\partial t}  C{\\left (t,r,\\theta,\\phi \\right )} + r \\left(2 M - r\\right) \\frac{\\partial^{3}}{\\partial \\theta\\partial r\\partial t}  C{\\left (t,r,\\theta,\\phi \\right )} - \\left(2 M - r\\right) \\frac{\\partial^{2}}{\\partial \\theta\\partial t}  C{\\left (t,r,\\theta,\\phi \\right )}\\right)$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "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\n",
       "prompt_number": 37,
       "text": [
        "       2                                                 3                    \n",
        "      \u2202                                                 \u2202                     \n",
        "M\u22c5\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500(C(t, r, \\theta, \\phi)) + r\u22c5(2\u22c5M - r)\u22c5\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500(C(t, r, \\theta\n",
        "  \u2202t \u2202\\theta                                      \u2202t \u2202r \u2202\\theta               \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",
        "                                                            r\u22c5(2\u22c5M - r)       \n",
        "\n",
        "                          2                           \n",
        "                         \u2202                            \n",
        ", \\phi)) - (2\u22c5M - r)\u22c5\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500(C(t, r, \\theta, \\phi))\n",
        "                     \u2202t \u2202\\theta                       \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\n",
        "                                                      "
       ]
      }
     ],
     "prompt_number": 37
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Proof that the covariant derivative of the metric tensor $g$ is zero"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "not any([g.covariantD(i, j, k).simplify() for i, j, k in list(variations(range(1, 5), 3, True))])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 38,
       "text": [
        "True"
       ]
      }
     ],
     "prompt_number": 38
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Bianchi identity in the Schwarzschild spacetime"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "$$ R_{\\mu \\nu \\sigma \\rho ;\\gamma} + R_{\\mu \\nu \\gamma \\sigma ;\\rho} + R_{\\mu \\nu \\rho \\gamma ;\\sigma} = 0$$"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "not any([(Rm.covariantD(i, j, k, l, m) + Rm.covariantD(i, j, m, k, l) + Rm.covariantD(i, j, l, m, k)).simplify() \\\n",
      " for i, j, k, l, m in list(variations(range(1, 5), 5, True))])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 39,
       "text": [
        "True"
       ]
      }
     ],
     "prompt_number": 39
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "User-defined tensors"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "To define a new scalar/vector/tensor field in some space you should __extend__ the _Tensor_ class or __create an instance__ of the _Tensor_ class."
     ]
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "_Tensor_ class instantiation"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Let's create a third-rank tensor field living in the Schwarzshild spacetime as an instance of the _Tensor_ class"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "S = Tensor('S', 3, g)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 40
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Until you define (override) the _\\_compute\\_covariant\\_component_ method of the __S__ object, all of $4^3$ components are arbitrary functions of coordinates "
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "S(1, 2, 3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\operatorname{S(1, 2, 3)}{\\left (t,r,\\theta,\\phi \\right )}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "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\n",
       "prompt_number": 41,
       "text": [
        "S(1, 2, 3)(t, r, \\theta, \\phi)"
       ]
      }
     ],
     "prompt_number": 41
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "source(T._compute_covariant_component)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "In file: /usr/local/lib/python2.7/dist-packages/gravipy/tensorial.py\n",
        "    def _compute_covariant_component(self, idxs):\n",
        "        if len(idxs) == 0:\n",
        "            component = Function(str(self.symbol))(*self.coords.c)\n",
        "        elif len(idxs) == 1:\n",
        "            component = Function(str(self.symbol) +\n",
        "                                 '(' + str(idxs[0]) + ')')(*self.coords.c)\n",
        "        else:\n",
        "            component = Function(str(self.symbol) + str(idxs))(*self.coords.c)\n",
        "        return component\n",
        "\n"
       ]
      }
     ],
     "prompt_number": 42
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Let's assume that tensor __S__ is the commutator of the covariant derivatives of some arbitrary vector field __V__ and create a new _\\_compute\\_covariant\\_component_ method for the object __S__"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "V = Tensor('V', 1, g)\n",
      "V(All)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}\\operatorname{V(1)}{\\left (t,r,\\theta,\\phi \\right )} & \\operatorname{V(2)}{\\left (t,r,\\theta,\\phi \\right )} & \\operatorname{V(3)}{\\left (t,r,\\theta,\\phi \\right )} & \\operatorname{V(4)}{\\left (t,r,\\theta,\\phi \\right )}\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 43,
       "text": [
        "[V(1)(t, r, \\theta, \\phi)  V(2)(t, r, \\theta, \\phi)  V(3)(t, r, \\theta, \\phi) \n",
        " V(4)(t, r, \\theta, \\phi)]"
       ]
      }
     ],
     "prompt_number": 43
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def S_new_method(idxs):\n",
      "    component = (V.covariantD(idxs[0], idxs[1], idxs[2]) - V.covariantD(idxs[0], idxs[2], idxs[1])).simplify() # definition\n",
      "    S.components.update({idxs: component}) # memoization\n",
      "    return component\n",
      "S._compute_covariant_component = S_new_method # _compute_covariant_component method was overriden"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 44
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "S(1, 1, 3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\frac{M}{r^{4}} \\left(2 M - r\\right) \\operatorname{V(3)}{\\left (t,r,\\theta,\\phi \\right )}$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "png": "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\nLxtQBzZfSRrCAAAAAElFTkSuQmCC\n",
       "prompt_number": 45,
       "text": [
        "M\u22c5(2\u22c5M - r)\u22c5V(3)(t, r, \\theta, \\phi)\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\n",
        "                  4                 \n",
        "                 r                  "
       ]
      }
     ],
     "prompt_number": 45
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "One can check that the well known formula is correct"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "$$ V_{\\mu ;\\nu \\rho} - V_{\\mu ;\\rho \\nu} = R^{\\sigma}_{\\ \\mu \\nu \\rho}V_{\\sigma} $$"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "zeros = reduce(Matrix.add, [Rm(-i, All, All, All)*V(i) for i  in range(1, 5)]) - S(All, All, All)\n",
      "zeros.simplify()\n",
      "zeros"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$\\left[\\begin{matrix}\\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right] & \\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right] & \\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right] & \\left[\\begin{matrix}0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\\\0 & 0 & 0 & 0\\end{matrix}\\right]\\end{matrix}\\right]$$"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 46,
       "text": [
        "\u23a1\u23a10  0  0  0\u23a4  \u23a10  0  0  0\u23a4  \u23a10  0  0  0\u23a4  \u23a10  0  0  0\u23a4\u23a4\n",
        "\u23a2\u23a2          \u23a5  \u23a2          \u23a5  \u23a2          \u23a5  \u23a2          \u23a5\u23a5\n",
        "\u23a2\u23a20  0  0  0\u23a5  \u23a20  0  0  0\u23a5  \u23a20  0  0  0\u23a5  \u23a20  0  0  0\u23a5\u23a5\n",
        "\u23a2\u23a2          \u23a5  \u23a2          \u23a5  \u23a2          \u23a5  \u23a2          \u23a5\u23a5\n",
        "\u23a2\u23a20  0  0  0\u23a5  \u23a20  0  0  0\u23a5  \u23a20  0  0  0\u23a5  \u23a20  0  0  0\u23a5\u23a5\n",
        "\u23a2\u23a2          \u23a5  \u23a2          \u23a5  \u23a2          \u23a5  \u23a2          \u23a5\u23a5\n",
        "\u23a3\u23a30  0  0  0\u23a6  \u23a30  0  0  0\u23a6  \u23a30  0  0  0\u23a6  \u23a30  0  0  0\u23a6\u23a6"
       ]
      }
     ],
     "prompt_number": 46
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Another way of tensor creation is to make an instance of the _Tensor_ class with components option. Tensor components stored in _Matrix_ object are  writen to the _components_ dictionary of the instance by this method. "
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Z = Tensor('Z', 3, g, components=zeros, components_type=(1, 1, 1))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 47
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "not any(Z.components.values())"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 48,
       "text": [
        "True"
       ]
      }
     ],
     "prompt_number": 48
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "_Tensor_ class extension"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "As an example of the _Tensor_ class extension you can get the source code of any of the predefined _Tensor_ subclasses"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "print([cls.__name__ for cls in vars()['Tensor'].__subclasses__()])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "['Christoffel', 'Ricci', 'Riemann', 'Einstein', 'Geodesic']\n"
       ]
      }
     ],
     "prompt_number": 49
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "source(Christoffel)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "In file: /usr/local/lib/python2.7/dist-packages/gravipy/tensorial.py\n",
        "class Christoffel(Tensor):\n",
        "    r\"\"\"\n",
        "    Represents a class of Christoffel symbols of the first and second kind.\n",
        "\n",
        "    Parameters\n",
        "    ==========\n",
        "\n",
        "    symbol : python string - name of the Christoffel symbol\n",
        "    metric : GraviPy MtricTensor object\n",
        "\n",
        "    Examples\n",
        "    ========\n",
        "\n",
        "    Define a Christoffel symbols for the Schwarzschild metric:\n",
        "\n",
        "    >>> from gravipy import *\n",
        "    >>> t, r, theta, phi = symbols('t, r, \\\\theta, \\phi')\n",
        "    >>> chi = Coordinates('\\chi', [t, r, theta, phi])\n",
        "    >>> M = Symbol('M')\n",
        "    >>> Metric = diag(-(1 - 2 * M / r), 1 / (1 - 2 * M / r), r ** 2,\n",
        "    ...                  r ** 2 * sin(theta) ** 2)\n",
        "    >>> g = MetricTensor('g', chi, Metric)\n",
        "    >>> Ga = Christoffel('Ga', g)\n",
        "    >>> Ga(-1, 2, 1)\n",
        "    -M/(r*(2*M - r))\n",
        "    >>> Ga(2, All, All)\n",
        "    Matrix([\n",
        "    [M/r**2,               0,  0,                 0],\n",
        "    [     0, -M/(2*M - r)**2,  0,                 0],\n",
        "    [     0,               0, -r,                 0],\n",
        "    [     0,               0,  0, -r*sin(\\theta)**2]])\n",
        "    >>> Ga(1, -1, 2) # doctest: +IGNORE_EXCEPTION_DETAIL\n",
        "    Traceback (most recent call last):\n",
        "    GraviPyError: \"Tensor component Ga(1, -1, 2) doesn't  exist\"\n",
        "    \"\"\"\n",
        "\n",
        "    def __init__(self, symbol, metric, *args, **kwargs):\n",
        "        super(Christoffel, self).__init__(\n",
        "            symbol, 3, metric, index_types=(0, 1, 1), *args, **kwargs)\n",
        "        self.is_connection = True\n",
        "        self.conn = self\n",
        "        self.metric.conn = self\n",
        "\n",
        "    def _compute_covariant_component(self, idxs):\n",
        "        component = Rational(1, 2) * (\n",
        "            self.metric(idxs[0], idxs[1]).diff(self.coords(-idxs[2])) +\n",
        "            self.metric(idxs[0], idxs[2]).diff(self.coords(-idxs[1])) -\n",
        "            self.metric(idxs[1], idxs[2]).diff(self.coords(-idxs[0]))) \\\n",
        "            .together().simplify()\n",
        "        self.components.update({idxs: component})\n",
        "        if self.apply_tensor_symmetry:\n",
        "            self.components.update({(idxs[0], idxs[2], idxs[1]): component})\n",
        "        return component\n",
        "\n"
       ]
      }
     ],
     "prompt_number": 50
    }
   ],
   "metadata": {}
  }
 ]
}