{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "class Lie_algebra:\n",
    "    def __init__(self, ring, dimension):\n",
    "        \"\"\"\n",
    "        Constructor of a Lie algebra\n",
    "        \n",
    "        Parameters :\n",
    "           ring : The ring of all the coefficients for the bracket.\n",
    "           dimension : The dimension of the algebra. (integer)\n",
    "        \n",
    "        Examples:\n",
    "           sage: l = Lie_algebra( SR, 5 ); l\n",
    "           Lie Algebra of dimension 5\n",
    "           \n",
    "        \"\"\"\n",
    "        self._ring = ring\n",
    "        self._n = dimension #The dimension\n",
    "        self._e = []  #The canonical basis\n",
    "        self._zero = vector(self._ring, [0 for i in range(self._n)])\n",
    "        for i in range(dimension):\n",
    "            l = [ 0 for k in range(dimension)]\n",
    "            l[i] = 1\n",
    "            self._e.append( vector(self._ring,l) )\n",
    "        self._bracket_basis = {}\n",
    "        for j in range(0,dimension):\n",
    "            for i in range(0,j):\n",
    "                self._bracket_basis[ (i,j) ] = [\n",
    "                    0 for k in range(dimension)\n",
    "                ]  # [ C_[i,j}^k ]_{0 <= k <= dimension-1}\n",
    "        self._metric_matrix = [\n",
    "            [ 0 for j in range(self._n) ]\n",
    "            for i in range( self._n)\n",
    "        ]\n",
    "    def set_metric(self, metric_matrix, check_validity=True):\n",
    "        \"\"\"\n",
    "            Set the metric Matrix.\n",
    "            \n",
    "            If check_validity is set to True, the this function will\n",
    "            raise an error if the metric matrix is not symmetric or\n",
    "            is degenerate.\n",
    "            \n",
    "            Parameters :\n",
    "                metric_matrix : A matrix\n",
    "                check_validity : A boolean\n",
    "            \n",
    "            EXAMPLES:\n",
    "            \n",
    "            \n",
    "                sage: h = Lie_algebra(SR,3); h\n",
    "                sage: M = Matrix([[1,3,2],[1,4,3],[2,1,1]])\n",
    "                sage: M = M - M.transpose()\n",
    "                sage: h.set_metric( M, check_validity=False )\n",
    "                sage: h.set_metric( M )\n",
    "                Traceback (most recent call last):\n",
    "                ...\n",
    "                ValueError: The metric matrix is not symmetric.\n",
    "        \"\"\"\n",
    "        if check_validity:\n",
    "            if not metric_matrix.is_symmetric():\n",
    "                raise ValueError( \"The metric matrix is not symmetric.\" )\n",
    "            if metric_matrix.det() == 0:\n",
    "                raise ValueError( \"The metric matrix is degenerate.\" )\n",
    "        self._metric_matrix = map(lambda x: list(x),  metric_matrix)\n",
    "    def set_metric_coefficient(self, i, j, coefficient):\n",
    "        \"\"\"\n",
    "        \"\"\"\n",
    "        self._metric_matrix[i][j] = coefficient\n",
    "    def metric(self):\n",
    "        return Matrix(self._ring, self._metric_matrix)\n",
    "    def dimension(self):\n",
    "        \"\"\"\n",
    "        Return the dimension of the Lie algebra.\n",
    "        \n",
    "        Examples:\n",
    "            sage: l = Lie_algebra( SR, 5 );\n",
    "            sage: l.dimension()\n",
    "            5\n",
    "            \n",
    "        \"\"\"\n",
    "        return self._n\n",
    "    def __repr__(self):\n",
    "        return \"Lie Algebra of dimension \" + str(self._n)\n",
    "    def e(self, j):\n",
    "        if not( 0 <= j and j < self._n ):\n",
    "            raise ValueError(\n",
    "                \"The canonical basis are idexed from 0 to \" + \n",
    "                str(self._n) + \" excluded.\"\n",
    "            )            \n",
    "        return self._e[j]\n",
    "    def canonical_basis( self ):\n",
    "        return self._e\n",
    "    def set_braket( self, i, j, vect ):\n",
    "        if( j<i ):\n",
    "            vect = - vect\n",
    "            (i,j) = (j, i)\n",
    "        self._bracket_basis[ (i,j) ] = list( vect )\n",
    "    def bracket(self, vect1, vect2):\n",
    "        \"\"\"\n",
    "        Examples:\n",
    "            sage: l = Lie_algebra( SR, 5 )\n",
    "            sage: e0, e1, e2, e3, e4 = l.canonical_basis()\n",
    "            sage: l.set_braket(1,2, 3*e1+ 4*e4 )\n",
    "            sage: l.set_braket(3,2, e0+ e2 )\n",
    "            sage: l.bracket( e1+e3 , e2 )\n",
    "            (1, 3, 1, 0, 4)\n",
    "            \n",
    "        \"\"\"\n",
    "        res = self._zero\n",
    "        for j in range(self._n):\n",
    "            for i in range(j):\n",
    "                res = res + (\n",
    "                    ( vect1[i]*vect2[j]  -  vect1[j]*vect2[i] ) * \n",
    "                    vector(self._ring, self._bracket_basis[ (i,j) ] )\n",
    "                )\n",
    "        return res\n",
    "    def jacobi(self, u, v, w):\n",
    "        \"\"\"\n",
    "        Examples:\n",
    "            sage: g = Lie_algebra(SR,3)\n",
    "            sage: e = g.canonical_basis()\n",
    "            sage: g.set_braket(0, 1, e[2])\n",
    "            sage: g.set_braket(1, 2, e[0])\n",
    "            sage: g.set_braket(2, 0, e[1])\n",
    "            sage: g.jacobi( e[0], e[1], e[2] )\n",
    "            0\n",
    "        \"\"\"\n",
    "        return self.bracket(\n",
    "            u, self.bracket( v, w )\n",
    "        ) + self.bracket(\n",
    "            v, self.bracket( w, u )\n",
    "        ) + self.bracket(\n",
    "            w, self.bracket( u, v )\n",
    "        )\n",
    "    def test_lie_algebra(self):\n",
    "        \"\"\"\n",
    "        Return the list of all triplet\n",
    "        (i < j < k) that doesn't vanish with the Jacobi identity.\n",
    "        \n",
    "        Examples:\n",
    "            sage: g = Lie_algebra(SR,3)\n",
    "            sage: e = g.canonical_basis()\n",
    "            sage: g.set_braket(0, 1, e[2])\n",
    "            sage: g.set_braket(1, 2, e[0])\n",
    "            sage: g.set_braket(2, 0, e[1])\n",
    "            sage: g.is_lie_algebra()\n",
    "            {}\n",
    "            \n",
    "            sage: var('a, b')\n",
    "            sage: g = Lie_algebra(SR,3)\n",
    "            sage: e = g.canonical_basis()\n",
    "            sage: g.set_braket(0, 1, a*e[2]+b*e[1])\n",
    "            sage: g.set_braket(1, 2, b*e[0]+a*e[2])\n",
    "            sage: g.set_braket(2, 0, e[1])\n",
    "            sage: g.is_lie_algebra()\n",
    "            {(0, 1, 2):(b^2, a, a*b)}            \n",
    "        \"\"\"\n",
    "        res = {}\n",
    "        for i in range(self._n):\n",
    "            for j in range(i+1, self._n):\n",
    "                for k in range(j+1,self._n):\n",
    "                    jacobi = simplify(\n",
    "                        self.jacobi(self.e(i), self.e(j), self.e(k))\n",
    "                    )\n",
    "                    if jacobi != self._zero:\n",
    "                        res[(i,j,k)] = jacobi\n",
    "        return res\n",
    "    def is_lie_algebra(self):\n",
    "        \"\"\"\n",
    "        Return true if it is a Lie Algebra and False if not.\n",
    "        \"\"\"\n",
    "        return not( self.test_lie_algebra() )\n",
    "    def adjoint(self, vect):\n",
    "        \"\"\"\n",
    "        Return the adjoint matrix of 'vect'.\n",
    "        \n",
    "        Examples:\n",
    "            sage: var('a, b')\n",
    "            sage: h = Lie_algebra(SR,3)\n",
    "            sage: eh = h.canonical_basis()\n",
    "            sage: h.set_braket(0, 1, a*eh[2]+b*eh[1])\n",
    "            sage: h.set_braket(1, 2, b*eh[0]+a*eh[2])\n",
    "            sage: h.set_braket(2, 0, eh[1])\n",
    "            sage: h.adjoint(eh[0])\n",
    "            [ 0  0  0]\n",
    "            [ 0  b -1]\n",
    "            [ 0  a  0]\n",
    "            \n",
    "        \"\"\"\n",
    "        res = []\n",
    "        for i in range(self._n):\n",
    "            res.append( self.bracket(vect,self.e(i)) )\n",
    "        return Matrix( self._ring, res ).transpose()\n",
    "    \n",
    "    def modular_form( self ):\n",
    "        \"\"\"\n",
    "        Examples:\n",
    "            sage: var('a, b')\n",
    "            sage: h = Lie_algebra(SR,3)\n",
    "            sage: eh = h.canonical_basis()\n",
    "            sage: h.set_braket(0, 1, a*eh[2]+b*eh[1])\n",
    "            sage: h.set_braket(1, 2, b*eh[0]+a*eh[2])\n",
    "            sage: h.set_braket(2, 0, eh[1])\n",
    "            sage: h.modular_form()\n",
    "            (b, a, 0)\n",
    "        \"\"\"\n",
    "        res = []\n",
    "        for i in range(self._n):\n",
    "            res.append( self.adjoint(self.e(i)).trace() )\n",
    "        return vector( self._ring, res )\n",
    "    def killing(self, vect1, vect2):\n",
    "        \"\"\"\n",
    "            Examples:\n",
    "                sage: var('a, b')\n",
    "                sage: h = Lie_algebra(SR,3)\n",
    "                sage: eh = h.canonical_basis()\n",
    "                sage: h.set_braket(0, 1, a*eh[2]+b*eh[1])\n",
    "                sage: h.set_braket(1, 2, b*eh[0]+a*eh[2])\n",
    "                sage: h.set_braket(2, 0, eh[1])\n",
    "                sage: h.killing( eh[0], eh[0] )\n",
    "                b^2 - 2*a\n",
    "                \n",
    "        \"\"\"\n",
    "        return (self.adjoint(vect1)*self.adjoint(vect2)).trace()\n",
    "    def killing_matrix(self):\n",
    "        \"\"\"\n",
    "        Examples:\n",
    "            sage: var('a, b')\n",
    "            sage: h = Lie_algebra(SR,3)\n",
    "            sage: eh = h.canonical_basis()\n",
    "            sage: h.set_braket(0, 1, a*eh[2]+b*eh[1])\n",
    "            sage: h.set_braket(1, 2, b*eh[0]+a*eh[2])\n",
    "            sage: h.set_braket(2, 0, eh[1])\n",
    "            sage: h.killing_matrix().is_symmetric()\n",
    "            True\n",
    "            \n",
    "        \"\"\"\n",
    "        return Matrix(\n",
    "            self._ring, self._n,\n",
    "            lambda i, j: self.killing(self.e(i), self.e(j)) \n",
    "        )\n",
    "    def scalar_product( self, vect1, vect2 ):\n",
    "        \"\"\"\n",
    "        EXAMPLES:\n",
    "            sage: h = Lie_algebra(SR,3)\n",
    "            sage: h.set_metric( matrix.identity(SR,3) )\n",
    "            sage: h.scalar_product( vector(SR, [1,2,3]), vector(SR, [4,5,6] ))\n",
    "            32\n",
    "        \"\"\"\n",
    "        return vect1 * Matrix(self._ring, self._metric_matrix)* vect2\n",
    "    def levi_civita_product(self, vect1, vect2):\n",
    "        \"\"\"\n",
    "        Compute the levi-civita product of two vectors.\n",
    "\n",
    "        EXAMPLES:\n",
    "            sage: h = Lie_algebra(SR,4)\n",
    "            sage: e0, e1, e2, e3 = h.canonical_basis()\n",
    "            sage: h.set_braket( 0, 1, e1 )\n",
    "            sage: h.set_braket( 0, 2, e2 + e1 )\n",
    "            sage: h.set_metric(\n",
    "            ....:     Matrix(\n",
    "            ....:         SR, \n",
    "            ....:         [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "            ....:     )\n",
    "            ....: )\n",
    "            sage: all( [\n",
    "            ....:     (\n",
    "            ....:         h.levi_civita_product( h.e(i), h.e(j) ) - \n",
    "            ....:         h.levi_civita_product( h.e(j), h.e(i)) \n",
    "            ....:     ) == h.bracket( h.e(i), h.e(j) )\n",
    "            ....:     for i in range(h.dimension())\n",
    "            ....:     for j in range(i+1)\n",
    "            ....: ] )\n",
    "            True\n",
    "        \"\"\"\n",
    "        def levi( u, v, w):\n",
    "            return (1/2)*(\n",
    "                self.scalar_product(\n",
    "                    self.bracket(u,v), w\n",
    "                ) + self.scalar_product(\n",
    "                    self.bracket(w, u), v\n",
    "                ) + self.scalar_product(\n",
    "                    self.bracket(w,v), u\n",
    "                )\n",
    "            )\n",
    "                \n",
    "        return (\n",
    "            Matrix(\n",
    "                self._ring,\n",
    "                self._metric_matrix\n",
    "            )^(-1) * vector(\n",
    "                [\n",
    "                    levi(vect1, vect2, self.e(i))\n",
    "                    for i in range(self._n)\n",
    "                ]\n",
    "            )\n",
    "        ) \n",
    "    def left_levi(self, vect):\n",
    "        \"\"\"\n",
    "        Return the matrix of the left multiplication for Levi-Civita product\n",
    "        of vect.\n",
    "        \n",
    "        EXAMPLES:\n",
    "            sage: h = Lie_algebra(SR,4)\n",
    "            sage: e0, e1, e2, e3 = h.canonical_basis()\n",
    "            sage: h.set_braket( 0, 1, e1 )\n",
    "            sage: h.set_braket( 0, 2, e2 + e1 )\n",
    "            sage: h.set_metric(\n",
    "            ....:     Matrix(\n",
    "            ....:         SR, \n",
    "            ....:         [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "            ....:     )\n",
    "            ....: )\n",
    "            sage: all( [\n",
    "            ....:     h.left_levi(h.e(i)) - h.right_levi(h.e(i)) == h.adjoint(h.e(i))\n",
    "            ....:     for i in range(h.dimension())\n",
    "            ....: ] )\n",
    "            True        \n",
    "            \n",
    "        \"\"\"\n",
    "        res = []\n",
    "        for i in range(self._n):\n",
    "            res.append( self.levi_civita_product(vect,self.e(i)) )\n",
    "        return Matrix( self._ring, res ).transpose()    \n",
    "\n",
    "    def right_levi(self, vect):\n",
    "        \"\"\"\n",
    "        Return the matrix of the right multiplication for Levi-Civita product\n",
    "        of vect.\n",
    "        \n",
    "        EXAMPLES:\n",
    "            sage: h = Lie_algebra(SR,4)\n",
    "            sage: e0, e1, e2, e3 = h.canonical_basis()\n",
    "            sage: h.set_braket( 0, 1, e1 )\n",
    "            sage: h.set_braket( 0, 2, e2 + e1 )\n",
    "            sage: h.set_metric(\n",
    "            ....:     Matrix(\n",
    "            ....:         SR, \n",
    "            ....:         [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "            ....:     )\n",
    "            ....: )\n",
    "            sage: all( [\n",
    "            ....:     h.left_levi(h.e(i)) - h.right_levi(h.e(i)) == h.adjoint(h.e(i))\n",
    "            ....:     for i in range(h.dimension())\n",
    "            ....: ] )\n",
    "            True\n",
    "        \"\"\"\n",
    "        res = []\n",
    "        for i in range(self._n):\n",
    "            res.append( self.levi_civita_product(self.e(i), vect) )\n",
    "        return Matrix( self._ring, res ).transpose()    \n",
    "    def curvature( self, vect1, vect2):\n",
    "        \"\"\"\n",
    "        Compute the curvature of vact1 and vect2.\n",
    "        \n",
    "        Examples:\n",
    "        \n",
    "            sage: h = Lie_algebra(SR,4)\n",
    "            sage: e0, e1, e2, e3 = h.canonical_basis()\n",
    "            sage: h.set_braket( 0, 1, e1 )\n",
    "            sage: h.set_braket( 0, 2, e2 + e1 )\n",
    "            sage: h.set_metric(\n",
    "            ....:     Matrix(\n",
    "            ....:         SR, \n",
    "            ....:         [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "            ....:     )\n",
    "            ....: )        \n",
    "            sage: all( [\n",
    "            sage:     h.curvature( h.e(i), h.e(j) ) == matrix.zero(h.dimension())\n",
    "            sage:     for i in range(h.dimension())\n",
    "            sage:     for j in range(i+1)\n",
    "            sage: ] )\n",
    "            True\n",
    "        \"\"\"\n",
    "        return (\n",
    "            self.left_levi(vect1) * self.left_levi(vect2) -\n",
    "            self.left_levi(vect2) * self.left_levi(vect1) -\n",
    "            self.left_levi( self.bracket( vect1, vect2) )\n",
    "        )\n",
    "    def ricci_curvature(self, vect1, vect2):\n",
    "        \"\"\"\n",
    "        Return the RIcci Curvature of two vectors.\n",
    "        \n",
    "        Examples:\n",
    "            sage: h = Lie_algebra(SR,4)\n",
    "            sage: e0, e1, e2, e3 = h.canonical_basis()\n",
    "            sage: h.set_braket( 0, 1, e1 )\n",
    "            sage: h.set_braket( 0, 2, e2 + e1 )\n",
    "            sage: h.set_metric(\n",
    "            ....:     Matrix(\n",
    "            ....:         SR, \n",
    "            ....:         [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "            ....:     )\n",
    "            ....: )\n",
    "            sage: all( [\n",
    "            ....:     h.ricci_curvature( h.e(i), h.e(j) ) == 0\n",
    "            ....:    for i in range(h.dimension())\n",
    "            ....:    for j in range(i+1)\n",
    "            ....: ] )\n",
    "            True\n",
    "        \"\"\"\n",
    "        return (\n",
    "            - (self.right_levi(vect1)*self.right_levi(vect2)).trace() +\n",
    "            self.right_levi( self.levi_civita_product(vect1,vect2)  ).trace() \n",
    "        )\n",
    "    def ricci_matrix( self ):\n",
    "        \"\"\"\n",
    "        Examples:\n",
    "            sage: h = Lie_algebra(SR,4)\n",
    "            sage: e0, e1, e2, e3 = h.canonical_basis()\n",
    "            sage: h.set_braket( 0, 1, e1 )\n",
    "            sage: h.set_braket( 0, 2, e2 + e1 )\n",
    "            sage: h.set_metric(\n",
    "            ....:     Matrix(\n",
    "            ....:         SR, \n",
    "            ....:         [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "            ....:     )\n",
    "            ....: )\n",
    "            sage: h.ricci_matrix() \n",
    "            [0 0 0 0]\n",
    "            [0 0 0 0]\n",
    "            [0 0 0 0]\n",
    "            [0 0 0 0]\n",
    "        \"\"\"\n",
    "        return Matrix( \n",
    "            self._ring, self._n, \n",
    "            lambda i, j: self.ricci_curvature( self.e(i), self.e(j) )\n",
    "        )\n",
    "    def ricci_operator( self ):\n",
    "        \"\"\"\n",
    "        Return the Ricci operator.\n",
    "        \n",
    "        Examples:\n",
    "            sage: h = Lie_algebra(SR,4)\n",
    "            sage: e0, e1, e2, e3 = h.canonical_basis()\n",
    "            sage: h.set_braket( 0, 1, e1 )\n",
    "            sage: h.set_braket( 0, 2, e2 + e1 )\n",
    "            sage: h.set_metric(\n",
    "            ....:     Matrix(\n",
    "            ....:         SR, \n",
    "            ....:         [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "            ....:     )\n",
    "            ....: )\n",
    "            sage: h.ricci_operator() \n",
    "            [0 0 0 0]\n",
    "            [0 0 0 0]\n",
    "            [0 0 0 0]\n",
    "            [0 0 0 0]\n",
    "        \"\"\"\n",
    "        return (\n",
    "            Matrix( self._ring, self._metric_matrix)^(-1) * \n",
    "            self.ricci_matrix()\n",
    "        )\n",
    "    def scalar_curvature(self):\n",
    "        \"\"\"\n",
    "        Return the scalar curvature.\n",
    "        \n",
    "        Examples:\n",
    "            sage: h = Lie_algebra(SR,4)\n",
    "            sage: e0, e1, e2, e3 = h.canonical_basis()\n",
    "            sage: h.set_braket( 0, 1, e1 )\n",
    "            sage: h.set_braket( 0, 2, e2 + e1 )\n",
    "            sage: h.set_metric(\n",
    "            ....:     Matrix(\n",
    "            ....:         SR, \n",
    "            ....:         [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "            ....:     )\n",
    "            ....: )\n",
    "            sage: h.scalar_curvature()\n",
    "            0\n",
    "        \"\"\"\n",
    "        return self.ricci_operator().trace()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "        print( \"vect1 : \" + str(vect1) )\n",
    "        print( \"vect2 : \" + str(vect2) )\n",
    "        print( \"bracket : \" + self.bracket(vect1,vect2)  )\n",
    "        print( \"right levi vect1: \" + str(elf.right_levi(vect1)) )\n",
    "        print( \"right levi vect2: \" + str(elf.right_levi(vect2)) )\n",
    "        print( \"\" )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "Matrix?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "l = Lie_algebra( SR, 5 ); l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "e0, e1, e2, e3, e4 = l.canonical_basis()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "l.set_braket(1,2, 3*e1+ 4*e4 )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "l.set_braket(3,2, e0+ e2 )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "l._bracket_basis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "l.bracket( e1+e3 , e2 )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "l.dimension()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "g = Lie_algebra(SR,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "e = g.canonical_basis()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "g.set_braket(0, 1, e[2])\n",
    "g.set_braket(1, 2, e[0])\n",
    "g.set_braket(2, 0, e[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "g._bracket_basis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "g.jacobi( e[0], e[1], e[2] )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "g.is_lie_algebra()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "var('a, b')\n",
    "h = Lie_algebra(SR,3)\n",
    "eh = h.canonical_basis()\n",
    "h.set_braket(0, 1, a*eh[2]+b*eh[1])\n",
    "h.set_braket(1, 2, b*eh[0]+a*eh[2])\n",
    "h.set_braket(2, 0, eh[1])\n",
    "h.test_lie_algebra()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h.adjoint(eh[2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h.modular_form()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h._bracket_basis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h.killing( eh[0], eh[0] )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h.adjoint(eh[0])^2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "M = h.killing_matrix()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "M.is_symmetric()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "map( lambda x: list(x),  matrix.identity(4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h = Lie_algebra(SR,3); h"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h = Lie_algebra(SR,3); h\n",
    "M = Matrix([[1,3,2],[1,4,3],[2,1,1]])\n",
    "M = M - M.transpose()\n",
    "h.set_metric( M )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h._metric_matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "h.set_metric_coefficient(0,1, 42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h.metric()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h = Lie_algebra(SR,3)\n",
    "h.set_metric( matrix.identity(SR,3) )\n",
    "h.scalar_product( vector(SR, [1,2,3]), vector(SR, [4,5,6] ))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h = Lie_algebra(SR,4)\n",
    "e0, e1, e2, e3 = h.canonical_basis()\n",
    "h.set_braket( 0, 1, e1 )\n",
    "h.set_braket( 0, 2, e2 + e1 )\n",
    "h.set_metric(\n",
    "    Matrix(\n",
    "        SR, \n",
    "        [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "    )\n",
    ")\n",
    "\n",
    "all( [\n",
    "    (\n",
    "        h.levi_civita_product( h.e(i), h.e(j) ) - \n",
    "        h.levi_civita_product( h.e(j), h.e(i)) \n",
    "    ) == h.bracket( h.e(i), h.e(j) )\n",
    "    for i in range(h.dimension())\n",
    "    for j in range(i+1)\n",
    "] )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "h = Lie_algebra(SR,4)\n",
    "e0, e1, e2, e3 = h.canonical_basis()\n",
    "h.set_braket( 0, 1, e1 )\n",
    "h.set_braket( 0, 2, e2 + e1 )\n",
    "h.set_metric(\n",
    "    Matrix(\n",
    "        SR, \n",
    "        [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "    )\n",
    ")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h = Lie_algebra(SR,4)\n",
    "e0, e1, e2, e3 = h.canonical_basis()\n",
    "h.set_braket( 0, 1, e1 )\n",
    "h.set_braket( 0, 2, e2 + e1 )\n",
    "h.set_metric(\n",
    "    Matrix(\n",
    "        SR, \n",
    "        [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "    )\n",
    ")\n",
    "\n",
    "all( [\n",
    "    h.curvature( h.e(i), h.e(j) ) == matrix.zero(h.dimension())\n",
    "    for i in range(h.dimension())\n",
    "    for j in range(i+1)\n",
    "] )\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h = Lie_algebra(SR,4)\n",
    "e0, e1, e2, e3 = h.canonical_basis()\n",
    "h.set_braket( 0, 1, e1 )\n",
    "h.set_braket( 0, 2, e2 + e1 )\n",
    "h.set_metric(\n",
    "    Matrix(\n",
    "        SR, \n",
    "        [[0, 1, 0 , 0],[1, 0, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]] \n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "all( [\n",
    "    h.ricci_curvature( h.e(i), h.e(j) ) == 0\n",
    "    for i in range(h.dimension())\n",
    "    for j in range(i+1)\n",
    "] )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h.ricci_curvature( e0, e0 )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h.ricci_matrix()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h.ricci_operator()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "h.scalar_curvature()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exemple de l'article : "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "var('a')\n",
    "hflat = Lie_algebra(SR,6)\n",
    "e = hflat.canonical_basis()\n",
    "hflat.set_braket( 0, 2, e[3] )\n",
    "hflat.set_braket( 0, 3, -e[2] )\n",
    "hflat.set_braket( 0, 4, a*e[2]+e[5] )\n",
    "hflat.set_braket( 0, 5, a*e[3]-e[4] )\n",
    "hflat.set_braket( 2, 4, -a*e[1] )\n",
    "hflat.set_braket( 3, 5, -a*e[1] )\n",
    "hflat.set_braket( 4, 5, 2*a^2*e[1])\n",
    "hflat.set_metric(\n",
    "    Matrix(\n",
    "        SR,\n",
    "        [\n",
    "            [0, 1,   0,    0,     0,     0],\n",
    "            [1, 0,   0,    0,     0,     0],\n",
    "            [0, 0,   1,    0,     0,   2*a],\n",
    "            [0, 0,   0,    1,  -2*a,     0],\n",
    "            [0, 0,   0, -2*a, 1+a^2,     0],\n",
    "            [0, 0, 2*a,    0,     0, 1+a^2]\n",
    "        ]\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[      0       1       0       0       0       0]\n",
       "[      1       0       0       0       0       0]\n",
       "[      0       0       1       0       0     2*a]\n",
       "[      0       0       0       1    -2*a       0]\n",
       "[      0       0       0    -2*a a^2 + 1       0]\n",
       "[      0       0     2*a       0       0 a^2 + 1]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hflat.metric()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hflat.is_lie_algebra()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "hflat.levi_civita_product( e[1], e[0] )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "hflat.bracket( e[0], e[2] )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 0, 0, 1, 0, 0)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hflat.levi_civita_product( e[0], e[2] )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[                                                         0                                                          0                                                          0                                                          0                                                          0                                                          0]\n",
       "[                                                         0                                                          0                                                          0                                                          0                                                          0                                                          0]\n",
       "[                                                         0                                                          0                                                          0                                                         -1 -2*a*(4*a^2/(3*a^2 - 1) - 1) + 2*(2*a^2 + 1)*a/(3*a^2 - 1)                                                          0]\n",
       "[                                                         0                                                          0                                                          1                                                          0                                                          0 -2*a*(4*a^2/(3*a^2 - 1) - 1) + 2*(2*a^2 + 1)*a/(3*a^2 - 1)]\n",
       "[                                                         0                                                          0                                                          0                                                          0                                                          0               -4*a^2/(3*a^2 - 1) + (2*a^2 + 1)/(3*a^2 - 1)]\n",
       "[                                                         0                                                          0                                                          0                                                          0                4*a^2/(3*a^2 - 1) - (2*a^2 + 1)/(3*a^2 - 1)                                                          0]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hflat.left_levi( e[0] )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "erreur = {}\n",
    "for i in range(hflat.dimension()):\n",
    "    for j in range(i+1):\n",
    "        res = hflat.curvature(e[i], e[j])\n",
    "        if res != matrix.zero(SR, hflat.dimension()) :\n",
    "            erreur[(i,j)] = res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(5, 0), (4, 0)]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "erreur.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[                                                                                                                    0                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0]\n",
       "[                                                                                                                    0                                                                                                                     0                                                                                                                     0                                                                                                                     0 a^2*(4*a^2/(3*a^2 - 1) - (2*a^2 + 1)/(3*a^2 - 1)) - 2*(a*(4*a^2/(3*a^2 - 1) - 1) - (2*a^2 + 1)*a/(3*a^2 - 1))*a - a^2                                                                                                                     0]\n",
       "[                                                                                                                    0                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0]\n",
       "[                                           -2*(a*(4*a^2/(3*a^2 - 1) - 1) - (2*a^2 + 1)*a/(3*a^2 - 1))*a^2/(3*a^2 - 1)                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0]\n",
       "[                                     -a^2*(4*a^2/(3*a^2 - 1) - (2*a^2 + 1)/(3*a^2 - 1))/(3*a^2 - 1) + a^2/(3*a^2 - 1)                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0]\n",
       "[                                                                                                                    0                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0                                                                                                                     0]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "erreur[(4,0)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(x, y)"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var('x,y')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nRHNzczQ3N8ecOXPimWeeifvuuy8efvjhspfWMH+9B3v27ImIiOXLl8fBgwfj2WefjVWrVsWaNWum\n9DUY77cPEScv4l6zZk1kWRY//OEPS1zlxBptDzhdnudn7bU5RNx6663x0ksvxdatW8teSikWLVoU\nBw8ejOeeey6++tWvRmdnZxw6dKjsZTXMkSNH4vbbb4//+q//iunTpxd+/kkzu623tze6u7tP/fqR\nRx6Jb3/726d98xscHIxKpRIXXXRRHD58uIxlTqi/3oNqtRozZswY8bxLL700brnllrjrrrsaubyG\neb99GA6kV199NZ566qmYN29eiaucWKP9XXjttddiwYIFceDAgViyZElZS2y4/v7++MhHPhI/+9nP\nYvXq1aceX7duXRw7diy2bdtW4urKUalU4tFHHz1tP84mGzZsiJ///Oexe/fuuOiii8pezqSwYsWK\n+MQnPhE/+tGPyl5KQ2zfvj1uuummmDZtWgznzODgYGRZFtOmTYsTJ07U9T9Rk+bjtlmzZsUll1xy\n6tfr168f8S/+ypUro7OzM26++eZGL68h/noP3s/Q0FCcOHGiASsqR2ofhgPp8OHD8fTTT0/pQIr4\n238XzsZ3TqZPnx5XXHFF7Ny589T3hjzPY+fOnXHbbbeVvDoabcOGDbF9+/bYtWuXQHqPqf7fh792\n3XXXxf/+7/+e9ti6deti8eLFcffdd9f9vXLSRNJfmzdv3oj/EE6fPj3OP//8WLhwYUmraqy+vr74\n7ne/G6tXr46Pfexj0dPTEz/4wQ/i6NGjsWbNmrKX1zCDg4PxxS9+MQ4cOBCPPfZY9Pf3n3qXpbW1\ndULeYp2M3nrrrfjDH/4QtVot8jyPQ4cORZ7ncf7554+4TmequuOOO2Lt2rVxxRVXxJVXXhn33ntv\n9PX1xbp168peWsP09vbG73//+1P/13z48OE4ePBgtLa2RltbW8mra4xbb701urq6YseOHTFr1qxT\n3w9aWlpi5syZJa+ucb71rW/F9ddfH21tbXH8+PH4yU9+Ert27Yonnnii7KU1zKxZs0ZcizZr1qw4\n55xzivmBr0J+Rq5BFixYcFbdAuDdd9/Nb7rppvzCCy/MZ86cmVer1fyf/umf8v3795e9tIZ69dVX\n80qlcto/WZbllUol37VrV9nLa5h///d/P/X7fu8/GzduLHtpDbV58+b84x//eD5z5sz8qquuyvft\n21f2khrq17/+dfLvwc0331z20hom9fuvVCr5f/zHf5S9tIa65ZZb8gULFuQzZ87M58+fn69YsSLf\nuXNn2ct0NpYoAAAATUlEQVQq3bXXXlvYLQAmzTVJAACTyaT56TYAgMlEJAEAJIgkAIAEkQQAkCCS\nAAASRBIAQIJIAgBIEEkAAAkiCQAgQSQBACSIJACAhP8HNl+xOYiSfIAAAAAASUVORK5CYII=\n",
      "text/plain": [
       "Graphics object consisting of 1 graphics primitive"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "implicit_plot(5*x^2 + 4*x*y+3*y^2==0, (x,-4,4), (y,-4,4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "implicit_plot?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "SageMath 7.4",
   "language": "",
   "name": "sagemath"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
