def hodge_star(self, metric):
        r"""
        Compute the Hodge dual of the differential form. 
        
        If ``self`` is a `p`-form `A`, its Hodge dual is the `(n-p)`-form
        `*A` defined by (`n` being the manifold's dimension)
        
        .. MATH::
            
            *A_{i_1\ldots i_{n-p}} = \frac{1}{p!} A_{k_1\ldots k_p}
                \epsilon^{k_1\ldots k_p}_{\qquad\ i_1\ldots i_{n-p}}
                
        where $\epsilon$ is the volume form associated with some 
        pseudo-Riemannian metric `g` on the manifold, and the indices 
        `k_1,\ldots, k_p` are raised with `g`. 
        
        INPUT:
        
        - ``metric``: the pseudo-Riemannian metric `g` defining the Hodge dual, 
          via the volume form `\epsilon`; must be an instance of :class:`Metric`
        
        OUTPUT:
        
        - the `(n-p)`-form `*A` 
        
        EXAMPLES:
        
        Hodge star of a 1-form in the Euclidean space `R^3`::
        
            sage: m = Manifold(3, 'M', start_index=1)
            sage: X.<x,y,z> = m.chart('x y z', 'xyz')
            sage: g = Metric(m, 'g')
            sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1
            sage: a = OneForm(m, 'A')
            sage: var('Ax Ay Az')
            (Ax, Ay, Az)
            sage: a[:] = (Ax, Ay, Az)
            sage: sa = a.hodge_star(g) ; sa
            2-form '*A' on the 3-dimensional manifold 'M'
            sage: sa.view()
            *A = Az dx/\dy - Ay dx/\dz + Ax dy/\dz
            sage: ssa = sa.hodge_star(g) ; ssa
            1-form '**A' on the 3-dimensional manifold 'M'
            sage: ssa.view()
            **A = Ax dx + Ay dy + Az dz
            sage: ssa == a  # must hold for a Riemannian metric in dimension 3
            True
        
        Hodge star of a 0-form (scalar field) in `R^3`::
        
            sage: f = ScalarField(m, function('F',x,y,z), name='f')
            sage: sf = f.hodge_star(g) ; sf
            3-form '*f' on the 3-dimensional manifold 'M'
            sage: sf.view()
            *f = F(x, y, z) dx/\dy/\dz
            sage: ssf = sf.hodge_star(g) ; ssf
            scalar field '**f' on the 3-dimensional manifold 'M'
            sage: ssf.view()
            **f: (x, y, z) |--> F(x, y, z)
            sage: ssf == f # must hold for a Riemannian metric
            True
            
        Hodge star of a 0-form in Minkowksi spacetime::
        
            sage: m = Manifold(4, 'M')
            sage: X = m.chart('t x y z', 'txyz')
            sage: g = Metric(m, 'g', signature=2)
            sage: g[0,0], g[1,1], g[2,2], g[3,3] = -1, 1, 1, 1
            sage: g.view()  # Minkowski metric
            g = -dt*dt + dx*dx + dy*dy + dz*dz
            sage: var('f0')
            f0
            sage: f = ScalarField(m, f0, name='f')
            sage: sf = f.hodge_star(g) ; sf 
            4-form '*f' on the 4-dimensional manifold 'M'
            sage: sf.view()
            *f = f0 dt/\dx/\dy/\dz
            sage: ssf = sf.hodge_star(g) ; ssf
            scalar field '**f' on the 4-dimensional manifold 'M'
            sage: ssf.view()
            **f: (t, x, y, z) |--> -f0
            sage: ssf == -f  # must hold for a Lorentzian metric             
            True

        Hodge star of a 1-form in Minkowksi spacetime::
        
            sage: a = OneForm(m, 'A')
            sage: var('At Ax Ay Az')
            (At, Ax, Ay, Az)
            sage: a[:] = (At, Ax, Ay, Az)
            sage: a.view()
            A = At dt + Ax dx + Ay dy + Az dz
            sage: sa = a.hodge_star(g) ; sa
            3-form '*A' on the 4-dimensional manifold 'M'
            sage: sa.view()
            *A = -Az dt/\dx/\dy + Ay dt/\dx/\dz - Ax dt/\dy/\dz - At dx/\dy/\dz
            sage: ssa = sa.hodge_star(g) ; ssa
            1-form '**A' on the 4-dimensional manifold 'M'
            sage: ssa.view()
            **A = At dt + Ax dx + Ay dy + Az dz
            sage: ssa == a  # must hold for a Lorentzian metric in dimension 4
            True

        Hodge star of a 2-form in Minkowksi spacetime::
        
            sage: F = DiffForm(m, 2, 'F')    
            sage: var('Ex Ey Ez Bx By Bz')
            (Ex, Ey, Ez, Bx, By, Bz)
            sage: F[0,1], F[0,2], F[0,3] = -Ex, -Ey, -Ez
            sage: F[1,2], F[1,3], F[2,3] = Bz, -By, Bx
            sage: F[:]
            [  0 -Ex -Ey -Ez]
            [ Ex   0  Bz -By]
            [ Ey -Bz   0  Bx]
            [ Ez  By -Bx   0]
            sage: sF = F.hodge_star(g) ; sF
            2-form '*F' on the 4-dimensional manifold 'M'
            sage: sF[:]
            [  0  Bx  By  Bz]
            [-Bx   0  Ez -Ey]
            [-By -Ez   0  Ex]
            [-Bz  Ey -Ex   0]
            sage: ssF = sF.hodge_star(g) ; ssF
            2-form '**F' on the 4-dimensional manifold 'M'
            sage: ssF[:]   
            [  0  Ex  Ey  Ez]
            [-Ex   0 -Bz  By]
            [-Ey  Bz   0 -Bx]
            [-Ez -By  Bx   0]
            sage: ssF.view()
            **F = Ex dt/\dx + Ey dt/\dy + Ez dt/\dz - Bz dx/\dy + By dx/\dz - Bx dy/\dz
            sage: F.view()
            F = -Ex dt/\dx - Ey dt/\dy - Ez dt/\dz + Bz dx/\dy - By dx/\dz + Bx dy/\dz
            sage: ssF == -F  # must hold for a Lorentzian metric in dimension 4
            True

        Test of the standard identity
        
        .. MATH::
            
            *(A\wedge B) = \epsilon(A^\sharp, B^\sharp, ., .)
            
        where `A` and `B` are any 1-forms and `A^\sharp` and `B^\sharp` the 
        vectors associated to them by the metric `g` (index raising)::

            sage: b = OneForm(m, 'B')
            sage: var('Bt Bx By Bz')
            (Bt, Bx, By, Bz)
            sage: b[:] = (Bt, Bx, By, Bz) ; b.view()
            B = Bt dt + Bx dx + By dy + Bz dz
            sage: epsilon = g.volume_form()
            sage: (a.wedge(b)).hodge_star(g) == epsilon.contract(0, a.up(g), 0).contract(0, b.up(g), 0)
            True

        """
        from sage.functions.other import factorial
        from utilities import format_unop_txt, format_unop_latex
        p = self.rank
        eps = metric.volume_form(p)
        if p == 0:
            resu = self * eps
        else:
            resu = self.contract(0, eps, 0)
            for j in range(1, p):
                resu = resu.self_contract(0, p-j)
            if p > 1:
                resu = resu / factorial(p)
        # Name and LaTeX name of the result:
        resu.name = format_unop_txt('*', self.name)
        resu.latex_name = format_unop_latex(r'\star ', self.latex_name)
        return resu
Beispiel #2
0
    def hodge_star(self, metric):
        r"""
        Compute the Hodge dual of the differential form. 
        
        If ``self`` is a `p`-form `A`, its Hodge dual is the `(n-p)`-form
        `*A` defined by (`n` being the manifold's dimension)
        
        .. MATH::
            
            *A_{i_1\ldots i_{n-p}} = \frac{1}{p!} A_{k_1\ldots k_p}
                \epsilon^{k_1\ldots k_p}_{\qquad\ i_1\ldots i_{n-p}}
                
        where $\epsilon$ is the volume form associated with some 
        pseudo-Riemannian metric `g` on the manifold, and the indices 
        `k_1,\ldots, k_p` are raised with `g`. 
        
        INPUT:
        
        - ``metric``: the pseudo-Riemannian metric `g` defining the Hodge dual, 
          via the volume form `\epsilon`; must be an instance of :class:`Metric`
        
        OUTPUT:
        
        - the `(n-p)`-form `*A` 
        
        EXAMPLES:
        
        Hodge star of a 1-form in the Euclidean space `R^3`::
        
            sage: m = Manifold(3, 'M', start_index=1)
            sage: X = Chart(m, 'x y z', 'xyz')
            sage: g = Metric(m, 'g')
            sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1
            sage: a = OneForm(m, 'A')
            sage: var('Ax Ay Az')
            (Ax, Ay, Az)
            sage: a[:] = (Ax, Ay, Az)
            sage: sa = a.hodge_star(g) ; sa
            2-form '*A' on the 3-dimensional manifold 'M'
            sage: sa.show()
            *A = Az dx/\dy - Ay dx/\dz + Ax dy/\dz
            sage: ssa = sa.hodge_star(g) ; ssa
            1-form '**A' on the 3-dimensional manifold 'M'
            sage: ssa.show()
            **A = Ax dx + Ay dy + Az dz
            sage: ssa == a  # must hold for a Riemannian metric in dimension 3
            True
        
        Hodge star of a 0-form (scalar field) in `R^3`::
        
            sage: f = ScalarField(m, function('F',x,y,z), name='f')
            sage: sf = f.hodge_star(g) ; sf
            3-form '*f' on the 3-dimensional manifold 'M'
            sage: sf.show()
            *f = F(x, y, z) dx/\dy/\dz
            sage: ssf = sf.hodge_star(g) ; ssf
            scalar field '**f' on the 3-dimensional manifold 'M'
            sage: ssf.show()
            **f: (x, y, z) |--> F(x, y, z)
            sage: ssf == f # must hold for a Riemannian metric
            True
            
        Hodge star of a 0-form in Minkowksi spacetime::
        
            sage: m = Manifold(4, 'M')
            sage: X = Chart(m, 't x y z', 'txyz')
            sage: g = Metric(m, 'g', signature=2)
            sage: g[0,0], g[1,1], g[2,2], g[3,3] = -1, 1, 1, 1
            sage: g.show()  # Minkowski metric
            g = -dt*dt + dx*dx + dy*dy + dz*dz
            sage: var('f0')
            f0
            sage: f = ScalarField(m, f0, name='f')
            sage: sf = f.hodge_star(g) ; sf 
            4-form '*f' on the 4-dimensional manifold 'M'
            sage: sf.show()
            *f = f0 dt/\dx/\dy/\dz
            sage: ssf = sf.hodge_star(g) ; ssf
            scalar field '**f' on the 4-dimensional manifold 'M'
            sage: ssf.show()
            **f: (t, x, y, z) |--> -f0
            sage: ssf == -f  # must hold for a Lorentzian metric             
            True

        Hodge star of a 1-form in Minkowksi spacetime::
        
            sage: a = OneForm(m, 'A')
            sage: var('At Ax Ay Az')
            (At, Ax, Ay, Az)
            sage: a[:] = (At, Ax, Ay, Az)
            sage: a.show()
            A = At dt + Ax dx + Ay dy + Az dz
            sage: sa = a.hodge_star(g) ; sa
            3-form '*A' on the 4-dimensional manifold 'M'
            sage: sa.show()
            *A = -Az dt/\dx/\dy + Ay dt/\dx/\dz - Ax dt/\dy/\dz - At dx/\dy/\dz
            sage: ssa = sa.hodge_star(g) ; ssa
            1-form '**A' on the 4-dimensional manifold 'M'
            sage: ssa.show()
            **A = At dt + Ax dx + Ay dy + Az dz
            sage: ssa == a  # must hold for a Lorentzian metric in dimension 4
            True

        Hodge star of a 2-form in Minkowksi spacetime::
        
            sage: F = DiffForm(m, 2, 'F')    
            sage: var('Ex Ey Ez Bx By Bz')
            (Ex, Ey, Ez, Bx, By, Bz)
            sage: F[0,1], F[0,2], F[0,3] = -Ex, -Ey, -Ez
            sage: F[1,2], F[1,3], F[2,3] = Bz, -By, Bx
            sage: F[:]
            [  0 -Ex -Ey -Ez]
            [ Ex   0  Bz -By]
            [ Ey -Bz   0  Bx]
            [ Ez  By -Bx   0]
            sage: sF = F.hodge_star(g) ; sF
            2-form '*F' on the 4-dimensional manifold 'M'
            sage: sF[:]
            [  0  Bx  By  Bz]
            [-Bx   0  Ez -Ey]
            [-By -Ez   0  Ex]
            [-Bz  Ey -Ex   0]
            sage: ssF = sF.hodge_star(g) ; ssF
            2-form '**F' on the 4-dimensional manifold 'M'
            sage: ssF[:]   
            [  0  Ex  Ey  Ez]
            [-Ex   0 -Bz  By]
            [-Ey  Bz   0 -Bx]
            [-Ez -By  Bx   0]
            sage: ssF.show()
            **F = Ex dt/\dx + Ey dt/\dy + Ez dt/\dz - Bz dx/\dy + By dx/\dz - Bx dy/\dz
            sage: F.show()
            F = -Ex dt/\dx - Ey dt/\dy - Ez dt/\dz + Bz dx/\dy - By dx/\dz + Bx dy/\dz
            sage: ssF == -F  # must hold for a Lorentzian metric in dimension 4
            True

        Test of the standard identity
        
        .. MATH::
            
            *(A\wedge B) = \epsilon(A^\sharp, B^\sharp, ., .)
            
        where `A` and `B` are any 1-forms and `A^\sharp` and `B^\sharp` the 
        vectors associated to them by the metric `g` (index raising)::

            sage: b = OneForm(m, 'B')
            sage: var('Bt Bx By Bz')
            (Bt, Bx, By, Bz)
            sage: b[:] = (Bt, Bx, By, Bz) ; b.show()
            B = Bt dt + Bx dx + By dy + Bz dz
            sage: epsilon = g.volume_form()
            sage: (a.wedge(b)).hodge_star(g) == epsilon.contract(0, a.up(g), 0).contract(0, b.up(g), 0)
            True

        """
        from sage.functions.other import factorial
        from utilities import format_unop_txt, format_unop_latex
        p = self.rank
        eps = metric.volume_form(p)
        if p == 0:
            resu = self * eps
        else:
            resu = self.contract(0, eps, 0)
            for j in range(1, p):
                resu = resu.self_contract(0, p - j)
            if p > 1:
                resu = resu / factorial(p)
        # Name and LaTeX name of the result:
        resu.name = format_unop_txt('*', self.name)
        resu.latex_name = format_unop_latex(r'\star ', self.latex_name)
        return resu
    def exterior_der(self, chart_name=None):
        r"""
        Compute the exterior derivative of the differential form. 
        
        INPUT:
        
        - ``chart_name`` -- (default: None): name of the chart used for the
          computation; if none is provided, the computation is performed in a
          coordinate basis where the components are known, or computable by 
          a component transformation, privileging the domain's default chart.
        
        OUTPUT:
        
        - the exterior derivative of ``self``. 
        
        EXAMPLE:
        
        Exterior derivative of a 1-form on a 4-dimensional manifold::
        
            sage: m = Manifold(4, 'M')
            sage: c_txyz.<t,x,y,z> = m.chart('t x y z', 'coord_txyz')           
            sage: a = OneForm(m, 'A')
            sage: a[:] = (t*x*y*z, z*y**2, x*z**2, x**2 + y**2)
            sage: da = a.exterior_der() ; da
            2-form 'dA' on the 4-dimensional manifold 'M'
            sage: da.view()
            dA = -t*y*z dt/\dx - t*x*z dt/\dy - t*x*y dt/\dz + (-2*y*z + z^2) dx/\dy + (-y^2 + 2*x) dx/\dz + (-2*x*z + 2*y) dy/\dz
            sage: latex(da)
            \mathrm{d}A
            
        The exterior derivative is nilpotent::
        
            sage: dda = da.exterior_der() ; dda
            3-form 'ddA' on the 4-dimensional manifold 'M'
            sage: dda.view()
            ddA = 0
            sage: dda == 0
            True

        """
        from sage.calculus.functional import diff
        from utilities import format_unop_txt, format_unop_latex
        if self._exterior_derivative is None:
            # A new computation is necessary:
            if chart_name is None:
                frame_name = self.pick_a_coord_basis()
                if frame_name is None:
                    raise ValueError("No coordinate basis could be found for " +
                                     "the differential form components.")
                chart_name = frame_name[:-2]
                chart = self.domain.atlas[chart_name]
            else:
                chart = self.domain.atlas[chart_name]
                frame_name = chart.frame.name
                if frame_name not in self.components:
                    raise ValueError("Components in the frame " + frame_name + 
                                     " have not been defined.")
            n = self.manifold.dim
            si = self.manifold.sindex
            sc = self.components[frame_name]
            dc = CompFullyAntiSym(self.domain.frames[frame_name], self.rank+1)
            for ind, val in sc._comp.items():
                for i in range(n):
                    ind_d = (i+si,) + ind
                    if len(ind_d) == len(set(ind_d)): # all indices are different
                          dc[[ind_d]] += val.function_chart(chart_name).diff(chart.xx[i])
            dc._del_zeros()
            # Name and LaTeX name of the result (rname and rlname):
            rname = format_unop_txt('d', self.name)
            rlname = format_unop_latex(r'\mathrm{d}', self.latex_name)
            # Final result
            self._exterior_derivative = DiffForm(self.domain, self.rank+1, 
                                                 rname, rlname)
            self._exterior_derivative.components[frame_name] = dc
        return self._exterior_derivative
Beispiel #4
0
    def exterior_der(self, chart_name=None):
        r"""
        Compute the exterior derivative of the differential form. 
        
        INPUT:
        
        - ``chart_name`` -- (default: None): name of the chart used for the
          computation; if none is provided, the computation is performed in a
          coordinate basis where the components are known, or computable by 
          a component transformation, privileging the manifold's default chart.
        
        OUTPUT:
        
        - the exterior derivative of ``self``. 
        
        EXAMPLE:
        
        Exterior derivative of a 1-form on a 4-dimensional manifold::
        
            sage: m = Manifold(4, 'M')
            sage: c_txyz = Chart(m, 't x y z', 'coord_txyz')           
            sage: a = OneForm(m, 'A')
            sage: a[:] = (t*x*y*z, z*y**2, x*z**2, x**2 + y**2)
            sage: da = a.exterior_der() ; da
            2-form 'dA' on the 4-dimensional manifold 'M'
            sage: da.show()
            dA = -t*y*z dt/\dx - t*x*z dt/\dy - t*x*y dt/\dz + (-2*y*z + z^2) dx/\dy + (-y^2 + 2*x) dx/\dz + (-2*x*z + 2*y) dy/\dz
            sage: latex(da)
            \mathrm{d}A
            
        The exterior derivative is nilpotent::
        
            sage: dda = da.exterior_der() ; dda
            3-form 'ddA' on the 4-dimensional manifold 'M'
            sage: dda.show()
            ddA = 0
            sage: dda == 0
            True

        """
        from sage.calculus.functional import diff
        from utilities import format_unop_txt, format_unop_latex
        if self._exterior_derivative is None:
            # A new computation is necessary:
            if chart_name is None:
                frame_name = self.pick_a_coord_basis()
                if frame_name is None:
                    raise ValueError(
                        "No coordinate basis could be found for " +
                        "the differential form components.")
                chart_name = frame_name[:-2]
                chart = self.manifold.atlas[chart_name]
            else:
                chart = self.manifold.atlas[chart_name]
                frame_name = chart.frame.name
                if frame_name not in self.components:
                    raise ValueError("Components in the frame " + frame_name +
                                     " have not been defined.")
            n = self.manifold.dim
            si = self.manifold.sindex
            sc = self.components[frame_name]
            dc = CompFullyAntiSym(self.manifold, self.rank + 1, frame_name)
            for ind, val in sc._comp.items():
                for i in range(n):
                    ind_d = (i + si, ) + ind
                    if len(ind_d) == len(
                            set(ind_d)):  # all indices are different
                        dc[[ind_d]] += val.function_chart(chart_name).diff(
                            chart.xx[i])
            dc._del_zeros()
            # Name and LaTeX name of the result (rname and rlname):
            rname = format_unop_txt('d', self.name)
            rlname = format_unop_latex(r'\mathrm{d}', self.latex_name)
            # Final result
            self._exterior_derivative = DiffForm(self.manifold, self.rank + 1,
                                                 rname, rlname)
            self._exterior_derivative.components[frame_name] = dc
        return self._exterior_derivative