Pseudo-Riemannian Metrics and Degenerate Metrics - Manifolds

Skip to content
Back to top
View this page
Edit this page

# Pseudo-Riemannian Metrics and Degenerate Metrics

The class `PseudoRiemannianMetric` implements pseudo-Riemannian metrics on differentiable manifolds over \(\RR\). The derived class `PseudoRiemannianMetricParal` is devoted to metrics with values on a parallelizable manifold.

The class `DegenerateMetric` implements degenerate (or null or lightlike) metrics on differentiable manifolds over \(\RR\). The derived class `DegenerateMetricParal` is devoted to metrics with values on a parallelizable manifold.

AUTHORS:

- Eric Gourgoulhon, Michal Bejger (2013-2015) : initial version

- Pablo Angulo (2016) : Schouten, Cotton and Cotton-York tensors

- Florentin Jaffredo (2018) : series expansion for the inverse metric

- Hans Fotsing Tetsing (2019) : degenerate metrics

- Marius Gerbershagen (2022) : compute volume forms with contravariant indices only as needed

REFERENCES:

- [KN1963]

- [Lee1997]

- [ONe1983]

- [DB1996]

- [DS2010]

class sage.manifolds.differentiable.metric.DegenerateMetric(vector_field_module, name, signature=None, latex_name=None)

  Bases: `TensorField`

  Degenerate (or null or lightlike) metric with values on an open subset of a differentiable manifold.

  An instance of this class is a field of degenerate symmetric bilinear forms (metric field) along a differentiable manifold \(U\) with values on a differentiable manifold \(M\) over \(\RR\), via a differentiable mapping \(\Phi: U \rightarrow M\). The standard case of a degenerate metric field on a manifold corresponds to \(U=M\) and \(\Phi = \mathrm{Id}_M\). Other common cases are \(\Phi\) being an immersion and \(\Phi\) being a curve in \(M\) (\(U\) is then an open interval of \(\RR\)).

  A degenerate metric \(g\) is a field on \(U\), such that at each point \(p\in U\), \(g(p)\) is a bilinear map of the type:

  \[g(p):\ T_q M\times T_q M \longrightarrow \RR\]

  where \(T_q M\) stands for the tangent space to the manifold \(M\) at the point \(q=\Phi(p)\), such that \(g(p)\) is symmetric: \(\forall (u,v)\in T_q M\times T_q M, \ g(p)(v,u) = g(p)(u,v)\) and degenerate: \(\exists v\in T_q M;\ \ g(p)(u,v) = 0\ \ \forall u\in T_qM\).

  Note

  If \(M\) is parallelizable, the class `DegenerateMetricParal` should be used instead.

  INPUT:

  - `vector_field_module` – module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(\Phi(U)\subset M\)

  - `name` – name given to the metric

  - `signature` – (default: `None`) signature \(S\) of the metric as a tuple: \(S = (n_+, n_-, n_0)\), where \(n_+\) (resp. \(n_-\), resp. \(n_0\)) is the number of positive terms (resp. negative terms, resp. zero tems) in any diagonal writing of the metric components; if `signature` is not provided, \(S\) is set to \((ndim-1, 0, 1)\), being \(ndim\) the manifold’s dimension

  - `latex_name` – (default: `None`) LaTeX symbol to denote the metric; if `None`, it is formed from `name`

  EXAMPLES:

  Lightlike cone:

  Sage

      sage: M = Manifold(3, 'M'); X.<x,y,z> = M.chart()
      sage: g = M.metric('g', signature=(2,0,1)); g
      degenerate metric g on the 3-dimensional differentiable manifold M
      sage: det(g)
      Scalar field zero on the 3-dimensional differentiable manifold M
      sage: g.parent()
      Free module T^(0,2)(M) of type-(0,2) tensors fields on the
      3-dimensional differentiable manifold M
      sage: g[0,0], g[0,1], g[0,2] = (y^2 + z^2)/(x^2 + y^2 + z^2), \
      ....: - x*y/(x^2 + y^2 + z^2), - x*z/(x^2 + y^2 + z^2)
      sage: g[1,1], g[1,2], g[2,2] = (x^2 + z^2)/(x^2 + y^2 + z^2), \
      ....: - y*z/(x^2 + y^2 + z^2), (x^2 + y^2)/(x^2 + y^2 + z^2)
      sage: g.disp()
      g = (y^2 + z^2)/(x^2 + y^2 + z^2) dx⊗dx - x*y/(x^2 + y^2 + z^2) dx⊗dy
      - x*z/(x^2 + y^2 + z^2) dx⊗dz - x*y/(x^2 + y^2 + z^2) dy⊗dx
      + (x^2 + z^2)/(x^2 + y^2 + z^2) dy⊗dy - y*z/(x^2 + y^2 + z^2) dy⊗dz
      - x*z/(x^2 + y^2 + z^2) dz⊗dx - y*z/(x^2 + y^2 + z^2) dz⊗dy
      + (x^2 + y^2)/(x^2 + y^2 + z^2) dz⊗dz

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(3), 'M'); X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3)
      >>> g = M.metric('g', signature=(Integer(2),Integer(0),Integer(1))); g
      degenerate metric g on the 3-dimensional differentiable manifold M
      >>> det(g)
      Scalar field zero on the 3-dimensional differentiable manifold M
      >>> g.parent()
      Free module T^(0,2)(M) of type-(0,2) tensors fields on the
      3-dimensional differentiable manifold M
      >>> g[Integer(0),Integer(0)], g[Integer(0),Integer(1)], g[Integer(0),Integer(2)] = (y**Integer(2) + z**Integer(2))/(x**Integer(2) + y**Integer(2) + z**Integer(2)), - x*y/(x**Integer(2) + y**Integer(2) + z**Integer(2)), - x*z/(x**Integer(2) + y**Integer(2) + z**Integer(2))
      >>> g[Integer(1),Integer(1)], g[Integer(1),Integer(2)], g[Integer(2),Integer(2)] = (x**Integer(2) + z**Integer(2))/(x**Integer(2) + y**Integer(2) + z**Integer(2)), - y*z/(x**Integer(2) + y**Integer(2) + z**Integer(2)), (x**Integer(2) + y**Integer(2))/(x**Integer(2) + y**Integer(2) + z**Integer(2))
      >>> g.disp()
      g = (y^2 + z^2)/(x^2 + y^2 + z^2) dx⊗dx - x*y/(x^2 + y^2 + z^2) dx⊗dy
      - x*z/(x^2 + y^2 + z^2) dx⊗dz - x*y/(x^2 + y^2 + z^2) dy⊗dx
      + (x^2 + z^2)/(x^2 + y^2 + z^2) dy⊗dy - y*z/(x^2 + y^2 + z^2) dy⊗dz
      - x*z/(x^2 + y^2 + z^2) dz⊗dx - y*z/(x^2 + y^2 + z^2) dz⊗dy
      + (x^2 + y^2)/(x^2 + y^2 + z^2) dz⊗dz

  The position vector is a lightlike vector field:

  Sage

      sage: v = M.vector_field()
      sage: v[0], v[1], v[2] = x , y, z
      sage: g(v, v).disp()
      M → ℝ
      (x, y, z) ↦ 0

  [Python]

      >>> from sage.all import *
      >>> v = M.vector_field()
      >>> v[Integer(0)], v[Integer(1)], v[Integer(2)] = x , y, z
      >>> g(v, v).disp()
      M → ℝ
      (x, y, z) ↦ 0

  det()

    alias of `determinant()`.

  determinant()

    Determinant of a degenerate metric is always ‘0’.

    EXAMPLES:

    Sage

        sage: S = Manifold(2, 'S')
        sage: g = S.metric('g', signature=([0,1,1]))
        sage: g.determinant()
        Scalar field zero on the 2-dimensional differentiable manifold S

    Python

        >>> from sage.all import *
        >>> S = Manifold(Integer(2), 'S')
        >>> g = S.metric('g', signature=([Integer(0),Integer(1),Integer(1)]))
        >>> g.determinant()
        Scalar field zero on the 2-dimensional differentiable manifold S

  restrict(subdomain, dest_map=None)

    Return the restriction of the metric to some subdomain.

    If the restriction has not been defined yet, it is constructed here.

    INPUT:

    - `subdomain` – open subset \(U\) of the metric’s domain (must be an instance of `DifferentiableManifold`)

    - `dest_map` – (default: `None`) destination map \(\Phi:\ U \rightarrow V\), where \(V\) is a subdomain of `self._codomain` (type: `DiffMap`) If `None`, the restriction of `self._vmodule._dest_map` to \(U\) is used.

    OUTPUT:

    - instance of `DegenerateMetric` representing the restriction.

    EXAMPLES:

    Sage

        sage: M = Manifold(5, 'M')
        sage: g = M.metric('g', signature=(3,1,1))
        sage: U = M.open_subset('U')
        sage: g.restrict(U)
        degenerate metric g on the Open subset U of the 5-dimensional
        differentiable manifold M
        sage: g.restrict(U).signature()
        (3, 1, 1)

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(5), 'M')
        >>> g = M.metric('g', signature=(Integer(3),Integer(1),Integer(1)))
        >>> U = M.open_subset('U')
        >>> g.restrict(U)
        degenerate metric g on the Open subset U of the 5-dimensional
        differentiable manifold M
        >>> g.restrict(U).signature()
        (3, 1, 1)

    See the top documentation of `DegenerateMetric` for more examples.

  set(symbiform)

    Define the metric from a field of symmetric bilinear forms.

    INPUT:

    - `symbiform` – instance of `TensorField` representing a field of symmetric bilinear forms

    EXAMPLES:

    Metric defined from a field of symmetric bilinear forms on a non-parallelizable 2-dimensional manifold:

    Sage

        sage: M = Manifold(2, 'M')
        sage: U = M.open_subset('U') ; V = M.open_subset('V')
        sage: M.declare_union(U,V)   # M is the union of U and V
        sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
        sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W',
        ....:                              restrictions1= x>0, restrictions2= u+v>0)
        sage: uv_to_xy = xy_to_uv.inverse()
        sage: W = U.intersection(V)
        sage: eU = c_xy.frame() ; eV = c_uv.frame()
        sage: h = M.sym_bilin_form_field(name='h')
        sage: h[eU,0,0], h[eU,0,1], h[eU,1,1] = 1+x, x*y, 1-y
        sage: h.add_comp_by_continuation(eV, W, c_uv)
        sage: h.display(eU)
        h = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-y + 1) dy⊗dy
        sage: h.display(eV)
        h = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv
         + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv
        sage: g = M.metric('g')
        sage: g.set(h)
        sage: g.display(eU)
        g = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-y + 1) dy⊗dy
        sage: g.display(eV)
        g = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv
         + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M')
        >>> U = M.open_subset('U') ; V = M.open_subset('V')
        >>> M.declare_union(U,V)   # M is the union of U and V
        >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2); c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)
        >>> xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W',
        ...                              restrictions1= x>Integer(0), restrictions2= u+v>Integer(0))
        >>> uv_to_xy = xy_to_uv.inverse()
        >>> W = U.intersection(V)
        >>> eU = c_xy.frame() ; eV = c_uv.frame()
        >>> h = M.sym_bilin_form_field(name='h')
        >>> h[eU,Integer(0),Integer(0)], h[eU,Integer(0),Integer(1)], h[eU,Integer(1),Integer(1)] = Integer(1)+x, x*y, Integer(1)-y
        >>> h.add_comp_by_continuation(eV, W, c_uv)
        >>> h.display(eU)
        h = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-y + 1) dy⊗dy
        >>> h.display(eV)
        h = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv
         + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv
        >>> g = M.metric('g')
        >>> g.set(h)
        >>> g.display(eU)
        g = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-y + 1) dy⊗dy
        >>> g.display(eV)
        g = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv
         + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv

  signature()

    Signature of the metric.

    OUTPUT:

    - signature of a degenerate metric is defined as the tuple \((n_+,n_-,n_0)\), where \(n_+\) (resp. \(n_-\), resp. \(n_0\)) is the number of positive terms (resp. negative terms, resp. zero terms) eigenvalues

    EXAMPLES:

    Signatures on a 3-dimensional manifold:

    Sage

        sage: M = Manifold(3, 'M')
        sage: g = M.metric('g', signature=(1,1,1))
        sage: g.signature()
        (1, 1, 1)
        sage: M = Manifold(3, 'M', structure='degenerate_metric')
        sage: g = M.metric()
        sage: g.signature()
        (0, 2, 1)

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'M')
        >>> g = M.metric('g', signature=(Integer(1),Integer(1),Integer(1)))
        >>> g.signature()
        (1, 1, 1)
        >>> M = Manifold(Integer(3), 'M', structure='degenerate_metric')
        >>> g = M.metric()
        >>> g.signature()
        (0, 2, 1)

class sage.manifolds.differentiable.metric.DegenerateMetricParal(vector_field_module, name, signature=None, latex_name=None)

  Bases: `DegenerateMetric`, `TensorFieldParal`

  Degenerate (or null or lightlike) metric with values on an open subset of a differentiable manifold.

  An instance of this class is a field of degenerate symmetric bilinear forms (metric field) along a differentiable manifold \(U\) with values on a differentiable manifold \(M\) over \(\RR\), via a differentiable mapping \(\Phi: U \rightarrow M\). The standard case of a degenerate metric field on a manifold corresponds to \(U=M\) and \(\Phi = \mathrm{Id}_M\). Other common cases are \(\Phi\) being an immersion and \(\Phi\) being a curve in \(M\) (\(U\) is then an open interval of \(\RR\)).

  A degenerate metric \(g\) is a field on \(U\), such that at each point \(p\in U\), \(g(p)\) is a bilinear map of the type:

  \[g(p):\ T_q M\times T_q M \longrightarrow \RR\]

  where \(T_q M\) stands for the tangent space to the manifold \(M\) at the point \(q=\Phi(p)\), such that \(g(p)\) is symmetric: \(\forall (u,v)\in T_q M\times T_q M, \ g(p)(v,u) = g(p)(u,v)\) and degenerate: \(\exists v\in T_q M;\ \ g(p)(u,v) = 0\ \ \forall u\in T_qM\).

  Note

  If \(M\) is not parallelizable, the class `DegenerateMetric` should be used instead.

  INPUT:

  - `vector_field_module` – module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(\Phi(U)\subset M\)

  - `name` – name given to the metric

  - `signature` – (default: `None`) signature \(S\) of the metric as a tuple: \(S = (n_+, n_-, n_0)\), where \(n_+\) (resp. \(n_-\), resp. \(n_0\)) is the number of positive terms (resp. negative terms, resp. zero tems) in any diagonal writing of the metric components; if `signature` is not provided, \(S\) is set to \((ndim-1, 0, 1)\), being \(ndim\) the manifold’s dimension

  - `latex_name` – (default: `None`) LaTeX symbol to denote the metric; if `None`, it is formed from `name`

  EXAMPLES:

  Lightlike cone:

  Sage

      sage: M = Manifold(3, 'M'); X.<x,y,z> = M.chart()
      sage: g = M.metric('g', signature=(2,0,1)); g
      degenerate metric g on the 3-dimensional differentiable manifold M
      sage: det(g)
      Scalar field zero on the 3-dimensional differentiable manifold M
      sage: g.parent()
      Free module T^(0,2)(M) of type-(0,2) tensors fields on the
      3-dimensional differentiable manifold M
      sage: g[0,0], g[0,1], g[0,2] = (y^2 + z^2)/(x^2 + y^2 + z^2), \
      ....: - x*y/(x^2 + y^2 + z^2), - x*z/(x^2 + y^2 + z^2)
      sage: g[1,1], g[1,2], g[2,2] = (x^2 + z^2)/(x^2 + y^2 + z^2), \
      ....: - y*z/(x^2 + y^2 + z^2), (x^2 + y^2)/(x^2 + y^2 + z^2)
      sage: g.disp()
      g = (y^2 + z^2)/(x^2 + y^2 + z^2) dx⊗dx - x*y/(x^2 + y^2 + z^2) dx⊗dy
      - x*z/(x^2 + y^2 + z^2) dx⊗dz - x*y/(x^2 + y^2 + z^2) dy⊗dx
      + (x^2 + z^2)/(x^2 + y^2 + z^2) dy⊗dy - y*z/(x^2 + y^2 + z^2) dy⊗dz
      - x*z/(x^2 + y^2 + z^2) dz⊗dx - y*z/(x^2 + y^2 + z^2) dz⊗dy
      + (x^2 + y^2)/(x^2 + y^2 + z^2) dz⊗dz

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(3), 'M'); X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3)
      >>> g = M.metric('g', signature=(Integer(2),Integer(0),Integer(1))); g
      degenerate metric g on the 3-dimensional differentiable manifold M
      >>> det(g)
      Scalar field zero on the 3-dimensional differentiable manifold M
      >>> g.parent()
      Free module T^(0,2)(M) of type-(0,2) tensors fields on the
      3-dimensional differentiable manifold M
      >>> g[Integer(0),Integer(0)], g[Integer(0),Integer(1)], g[Integer(0),Integer(2)] = (y**Integer(2) + z**Integer(2))/(x**Integer(2) + y**Integer(2) + z**Integer(2)), - x*y/(x**Integer(2) + y**Integer(2) + z**Integer(2)), - x*z/(x**Integer(2) + y**Integer(2) + z**Integer(2))
      >>> g[Integer(1),Integer(1)], g[Integer(1),Integer(2)], g[Integer(2),Integer(2)] = (x**Integer(2) + z**Integer(2))/(x**Integer(2) + y**Integer(2) + z**Integer(2)), - y*z/(x**Integer(2) + y**Integer(2) + z**Integer(2)), (x**Integer(2) + y**Integer(2))/(x**Integer(2) + y**Integer(2) + z**Integer(2))
      >>> g.disp()
      g = (y^2 + z^2)/(x^2 + y^2 + z^2) dx⊗dx - x*y/(x^2 + y^2 + z^2) dx⊗dy
      - x*z/(x^2 + y^2 + z^2) dx⊗dz - x*y/(x^2 + y^2 + z^2) dy⊗dx
      + (x^2 + z^2)/(x^2 + y^2 + z^2) dy⊗dy - y*z/(x^2 + y^2 + z^2) dy⊗dz
      - x*z/(x^2 + y^2 + z^2) dz⊗dx - y*z/(x^2 + y^2 + z^2) dz⊗dy
      + (x^2 + y^2)/(x^2 + y^2 + z^2) dz⊗dz

  The position vector is a lightlike vector field:

  Sage

      sage: v = M.vector_field()
      sage: v[0], v[1], v[2] = x , y, z
      sage: g(v, v).disp()
      M → ℝ
      (x, y, z) ↦ 0

  [Python]

      >>> from sage.all import *
      >>> v = M.vector_field()
      >>> v[Integer(0)], v[Integer(1)], v[Integer(2)] = x , y, z
      >>> g(v, v).disp()
      M → ℝ
      (x, y, z) ↦ 0

  restrict(subdomain, dest_map=None)

    Return the restriction of the metric to some subdomain.

    If the restriction has not been defined yet, it is constructed here.

    INPUT:

    - `subdomain` – open subset \(U\) of the metric’s domain (must be an instance of `DifferentiableManifold`)

    - `dest_map` – (default: `None`) destination map \(\Phi:\ U \rightarrow V\), where \(V\) is a subdomain of `self._codomain` (type: `DiffMap`) If `None`, the restriction of `self._vmodule._dest_map` to \(U\) is used.

    OUTPUT:

    - instance of `DegenerateMetric` representing the restriction.

    EXAMPLES:

    Sage

        sage: M = Manifold(5, 'M')
        sage: g = M.metric('g', signature=(3,1,1))
        sage: U = M.open_subset('U')
        sage: g.restrict(U)
        degenerate metric g on the Open subset U of the 5-dimensional differentiable manifold M
        sage: g.restrict(U).signature()
        (3, 1, 1)

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(5), 'M')
        >>> g = M.metric('g', signature=(Integer(3),Integer(1),Integer(1)))
        >>> U = M.open_subset('U')
        >>> g.restrict(U)
        degenerate metric g on the Open subset U of the 5-dimensional differentiable manifold M
        >>> g.restrict(U).signature()
        (3, 1, 1)

    See the top documentation of `DegenerateMetric` for more examples.

  set(symbiform)

    Define the metric from a field of symmetric bilinear forms.

    INPUT:

    - `symbiform` – instance of `TensorField` representing a field of symmetric bilinear forms

    EXAMPLES:

    Metric defined from a field of symmetric bilinear forms on a parallelizable 3-dimensional manifold:

    Sage

        sage: M = Manifold(3, 'M', start_index=1);
        sage: X.<x,y,z> = M.chart()
        sage: dx, dy = X.coframe()[1], X.coframe()[2]
        sage: b = dx*dx + dy*dy
        sage: g = M.metric('g', signature=(1,1,1)); g
        degenerate metric g on the 3-dimensional differentiable manifold M
        sage: g.set(b)
        sage: g.display()
        g = dx⊗dx + dy⊗dy

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'M', start_index=Integer(1));
        >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3)
        >>> dx, dy = X.coframe()[Integer(1)], X.coframe()[Integer(2)]
        >>> b = dx*dx + dy*dy
        >>> g = M.metric('g', signature=(Integer(1),Integer(1),Integer(1))); g
        degenerate metric g on the 3-dimensional differentiable manifold M
        >>> g.set(b)
        >>> g.display()
        g = dx⊗dx + dy⊗dy

class sage.manifolds.differentiable.metric.PseudoRiemannianMetric(vector_field_module, name, signature=None, latex_name=None)

  Bases: `TensorField`

  Pseudo-Riemannian metric with values on an open subset of a differentiable manifold.

  An instance of this class is a field of nondegenerate symmetric bilinear forms (metric field) along a differentiable manifold \(U\) with values on a differentiable manifold \(M\) over \(\RR\), via a differentiable mapping \(\Phi: U \rightarrow M\). The standard case of a metric field on a manifold corresponds to \(U=M\) and \(\Phi = \mathrm{Id}_M\). Other common cases are \(\Phi\) being an immersion and \(\Phi\) being a curve in \(M\) (\(U\) is then an open interval of \(\RR\)).

  A metric \(g\) is a field on \(U\), such that at each point \(p\in U\), \(g(p)\) is a bilinear map of the type:

  \[g(p):\ T_q M\times T_q M \longrightarrow \RR\]

  where \(T_q M\) stands for the tangent space to the manifold \(M\) at the point \(q=\Phi(p)\), such that \(g(p)\) is symmetric: \(\forall (u,v)\in T_q M\times T_q M, \ g(p)(v,u) = g(p)(u,v)\) and nondegenerate: \((\forall v\in T_q M,\ \ g(p)(u,v) = 0) \Longrightarrow u=0\).

  Note

  If \(M\) is parallelizable, the class `PseudoRiemannianMetricParal` should be used instead.

  INPUT:

  - `vector_field_module` – module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(\Phi(U)\subset M\)

  - `name` – name given to the metric

  - `signature` – (default: `None`) signature \(S\) of the metric as a single integer: \(S = n_+ - n_-\), where \(n_+\) (resp. \(n_-\)) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components; if `signature` is `None`, \(S\) is set to the dimension of manifold \(M\) (Riemannian signature)

  - `latex_name` – (default: `None`) LaTeX symbol to denote the metric; if `None`, it is formed from `name`

  EXAMPLES:

  Let us construct the standard metric on the sphere \(S^2\), described in terms of stereographic coordinates, from the North pole (open subset \(U\)) and from the South pole (open subset \(V\)):

  Sage

      sage: M = Manifold(2, 'S^2', start_index=1)
      sage: U = M.open_subset('U') ; V = M.open_subset('V')
      sage: M.declare_union(U,V)   # S^2 is the union of U and V
      sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart() # stereographic coord
      sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
      ....:                 intersection_name='W', restrictions1= x^2+y^2!=0,
      ....:                 restrictions2= u^2+v^2!=0)
      sage: uv_to_xy = xy_to_uv.inverse()
      sage: eU = c_xy.frame() ; eV = c_uv.frame()
      sage: g = M.metric('g') ; g
      Riemannian metric g on the 2-dimensional differentiable manifold S^2

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(2), 'S^2', start_index=Integer(1))
      >>> U = M.open_subset('U') ; V = M.open_subset('V')
      >>> M.declare_union(U,V)   # S^2 is the union of U and V
      >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2); c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)# stereographic coord
      >>> xy_to_uv = c_xy.transition_map(c_uv, (x/(x**Integer(2)+y**Integer(2)), y/(x**Integer(2)+y**Integer(2))),
      ...                 intersection_name='W', restrictions1= x**Integer(2)+y**Integer(2)!=Integer(0),
      ...                 restrictions2= u**Integer(2)+v**Integer(2)!=Integer(0))
      >>> uv_to_xy = xy_to_uv.inverse()
      >>> eU = c_xy.frame() ; eV = c_uv.frame()
      >>> g = M.metric('g') ; g
      Riemannian metric g on the 2-dimensional differentiable manifold S^2

  The metric is considered as a tensor field of type (0,2) on \(S^2\):

  Sage

      sage: g.parent()
      Module T^(0,2)(S^2) of type-(0,2) tensors fields on the 2-dimensional
       differentiable manifold S^2

  [Python]

      >>> from sage.all import *
      >>> g.parent()
      Module T^(0,2)(S^2) of type-(0,2) tensors fields on the 2-dimensional
       differentiable manifold S^2

  We define \(g\) by its components on domain \(U\):

  Sage

      sage: g[eU,1,1], g[eU,2,2] = 4/(1+x^2+y^2)^2, 4/(1+x^2+y^2)^2
      sage: g.display(eU)
      g = 4/(x^2 + y^2 + 1)^2 dx⊗dx + 4/(x^2 + y^2 + 1)^2 dy⊗dy

  Python

      >>> from sage.all import *
      >>> g[eU,Integer(1),Integer(1)], g[eU,Integer(2),Integer(2)] = Integer(4)/(Integer(1)+x**Integer(2)+y**Integer(2))**Integer(2), Integer(4)/(Integer(1)+x**Integer(2)+y**Integer(2))**Integer(2)
      >>> g.display(eU)
      g = 4/(x^2 + y^2 + 1)^2 dx⊗dx + 4/(x^2 + y^2 + 1)^2 dy⊗dy

  A matrix view of the components:

  Sage

      sage: g[eU,:]
      [4/(x^2 + y^2 + 1)^2                   0]
      [                  0 4/(x^2 + y^2 + 1)^2]

  [Python]

      >>> from sage.all import *
      >>> g[eU,:]
      [4/(x^2 + y^2 + 1)^2                   0]
      [                  0 4/(x^2 + y^2 + 1)^2]

  The components of \(g\) on domain \(V\) expressed in terms of coordinates \((u,v)\) are obtained by applying (i) the tensor transformation law on \(W = U\cap V\) and (ii) some analytical continuation:

  Sage

      sage: W = U.intersection(V)
      sage: g.add_comp_by_continuation(eV, W, chart=c_uv)
      sage: g.apply_map(factor, frame=eV, keep_other_components=True) # for a nicer display
      sage: g.display(eV)
      g = 4/(u^2 + v^2 + 1)^2 du⊗du + 4/(u^2 + v^2 + 1)^2 dv⊗dv

  Python

      >>> from sage.all import *
      >>> W = U.intersection(V)
      >>> g.add_comp_by_continuation(eV, W, chart=c_uv)
      >>> g.apply_map(factor, frame=eV, keep_other_components=True) # for a nicer display
      >>> g.display(eV)
      g = 4/(u^2 + v^2 + 1)^2 du⊗du + 4/(u^2 + v^2 + 1)^2 dv⊗dv

  At this stage, the metric is fully defined on the whole sphere. Its restriction to some subdomain is itself a metric (by default, it bears the same symbol):

  Sage

      sage: g.restrict(U)
      Riemannian metric g on the Open subset U of the 2-dimensional
       differentiable manifold S^2
      sage: g.restrict(U).parent()
      Free module T^(0,2)(U) of type-(0,2) tensors fields on the Open subset
       U of the 2-dimensional differentiable manifold S^2

  [Python]

      >>> from sage.all import *
      >>> g.restrict(U)
      Riemannian metric g on the Open subset U of the 2-dimensional
       differentiable manifold S^2
      >>> g.restrict(U).parent()
      Free module T^(0,2)(U) of type-(0,2) tensors fields on the Open subset
       U of the 2-dimensional differentiable manifold S^2

  The parent of \(g|_U\) is a free module because is \(U\) is a parallelizable domain, contrary to \(S^2\). Actually, \(g\) and \(g|_U\) have different Python type:

  Sage

      sage: type(g)
      <class 'sage.manifolds.differentiable.metric.PseudoRiemannianMetric'>
      sage: type(g.restrict(U))
      <class 'sage.manifolds.differentiable.metric.PseudoRiemannianMetricParal'>

  Python

      >>> from sage.all import *
      >>> type(g)
      <class 'sage.manifolds.differentiable.metric.PseudoRiemannianMetric'>
      >>> type(g.restrict(U))
      <class 'sage.manifolds.differentiable.metric.PseudoRiemannianMetricParal'>

  As a field of bilinear forms, the metric acts on pairs of vector fields, yielding a scalar field:

  Sage

      sage: a = M.vector_field({eU: [x, 2+y]}, name='a')
      sage: a.add_comp_by_continuation(eV, W, chart=c_uv)
      sage: b = M.vector_field({eU: [-y, x]}, name='b')
      sage: b.add_comp_by_continuation(eV, W, chart=c_uv)
      sage: s = g(a,b) ; s
      Scalar field g(a,b) on the 2-dimensional differentiable manifold S^2
      sage: s.display()
      g(a,b): S^2 → ℝ
      on U: (x, y) ↦ 8*x/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1)
      on V: (u, v) ↦ 8*(u^3 + u*v^2)/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1)

  [Python]

      >>> from sage.all import *
      >>> a = M.vector_field({eU: [x, Integer(2)+y]}, name='a')
      >>> a.add_comp_by_continuation(eV, W, chart=c_uv)
      >>> b = M.vector_field({eU: [-y, x]}, name='b')
      >>> b.add_comp_by_continuation(eV, W, chart=c_uv)
      >>> s = g(a,b) ; s
      Scalar field g(a,b) on the 2-dimensional differentiable manifold S^2
      >>> s.display()
      g(a,b): S^2 → ℝ
      on U: (x, y) ↦ 8*x/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1)
      on V: (u, v) ↦ 8*(u^3 + u*v^2)/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1)

  The inverse metric is:

  Sage

      sage: ginv = g.inverse() ; ginv
      Tensor field inv_g of type (2,0) on the 2-dimensional differentiable
       manifold S^2
      sage: ginv.parent()
      Module T^(2,0)(S^2) of type-(2,0) tensors fields on the 2-dimensional
       differentiable manifold S^2
      sage: latex(ginv)
      g^{-1}
      sage: ginv.display(eU)
      inv_g = (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) ∂/∂x⊗∂/∂x
       + (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) ∂/∂y⊗∂/∂y
      sage: ginv.display(eV)
      inv_g = (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) ∂/∂u⊗∂/∂u
       + (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) ∂/∂v⊗∂/∂v

  Python

      >>> from sage.all import *
      >>> ginv = g.inverse() ; ginv
      Tensor field inv_g of type (2,0) on the 2-dimensional differentiable
       manifold S^2
      >>> ginv.parent()
      Module T^(2,0)(S^2) of type-(2,0) tensors fields on the 2-dimensional
       differentiable manifold S^2
      >>> latex(ginv)
      g^{-1}
      >>> ginv.display(eU)
      inv_g = (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) ∂/∂x⊗∂/∂x
       + (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) ∂/∂y⊗∂/∂y
      >>> ginv.display(eV)
      inv_g = (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) ∂/∂u⊗∂/∂u
       + (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) ∂/∂v⊗∂/∂v

  We have:

  Sage

      sage: ginv.restrict(U) is g.restrict(U).inverse()
      True
      sage: ginv.restrict(V) is g.restrict(V).inverse()
      True
      sage: ginv.restrict(W) is g.restrict(W).inverse()
      True

  [Python]

      >>> from sage.all import *
      >>> ginv.restrict(U) is g.restrict(U).inverse()
      True
      >>> ginv.restrict(V) is g.restrict(V).inverse()
      True
      >>> ginv.restrict(W) is g.restrict(W).inverse()
      True

  To get the volume form (Levi-Civita tensor) associated with \(g\), we have first to define an orientation on \(S^2\). The standard orientation is that in which `eV` is right-handed; indeed, once supplemented by the outward unit normal, `eV` give birth to a right-handed frame with respect to the standard orientation of the ambient Euclidean space \(E^3\). With such an orientation, `eU` is then left-handed and in order to define an orientation on the whole of \(S^2\), we introduce a vector frame on \(U\) by swapping `eU`’s vectors:

  Sage

      sage: f = U.vector_frame('f', (eU[2], eU[1]))
      sage: M.set_orientation([eV, f])

  Python

      >>> from sage.all import *
      >>> f = U.vector_frame('f', (eU[Integer(2)], eU[Integer(1)]))
      >>> M.set_orientation([eV, f])

  We have then, factorizing the components for a nicer display:

  Sage

      sage: eps = g.volume_form() ; eps
      2-form eps_g on the 2-dimensional differentiable manifold S^2
      sage: eps.apply_map(factor, frame=eU, keep_other_components=True)
      sage: eps.apply_map(factor, frame=eV, keep_other_components=True)
      sage: eps.display(eU)
      eps_g = -4/(x^2 + y^2 + 1)^2 dx∧dy
      sage: eps.display(eV)
      eps_g = 4/(u^2 + v^2 + 1)^2 du∧dv

  [Python]

      >>> from sage.all import *
      >>> eps = g.volume_form() ; eps
      2-form eps_g on the 2-dimensional differentiable manifold S^2
      >>> eps.apply_map(factor, frame=eU, keep_other_components=True)
      >>> eps.apply_map(factor, frame=eV, keep_other_components=True)
      >>> eps.display(eU)
      eps_g = -4/(x^2 + y^2 + 1)^2 dx∧dy
      >>> eps.display(eV)
      eps_g = 4/(u^2 + v^2 + 1)^2 du∧dv

  The unique non-trivial component of the volume form is, up to a sign depending of the chosen orientation, nothing but the square root of the determinant of \(g\) in the corresponding frame:

  Sage

      sage: eps[[eU,1,2]] == -g.sqrt_abs_det(eU)
      True
      sage: eps[[eV,1,2]] == g.sqrt_abs_det(eV)
      True

  Python

      >>> from sage.all import *
      >>> eps[[eU,Integer(1),Integer(2)]] == -g.sqrt_abs_det(eU)
      True
      >>> eps[[eV,Integer(1),Integer(2)]] == g.sqrt_abs_det(eV)
      True

  The Levi-Civita connection associated with the metric \(g\):

  Sage

      sage: nabla = g.connection() ; nabla
      Levi-Civita connection nabla_g associated with the Riemannian metric g
       on the 2-dimensional differentiable manifold S^2
      sage: latex(nabla)
      \nabla_{g}

  [Python]

      >>> from sage.all import *
      >>> nabla = g.connection() ; nabla
      Levi-Civita connection nabla_g associated with the Riemannian metric g
       on the 2-dimensional differentiable manifold S^2
      >>> latex(nabla)
      \nabla_{g}

  The Christoffel symbols \(\Gamma^i_{\ \, jk}\) associated with some coordinates:

  Sage

      sage: g.christoffel_symbols(c_xy)
      3-indices components w.r.t. Coordinate frame (U, (∂/∂x,∂/∂y)), with
       symmetry on the index positions (1, 2)
      sage: g.christoffel_symbols(c_xy)[:]
      [[[-2*x/(x^2 + y^2 + 1), -2*y/(x^2 + y^2 + 1)],
        [-2*y/(x^2 + y^2 + 1), 2*x/(x^2 + y^2 + 1)]],
       [[2*y/(x^2 + y^2 + 1), -2*x/(x^2 + y^2 + 1)],
        [-2*x/(x^2 + y^2 + 1), -2*y/(x^2 + y^2 + 1)]]]
      sage: g.christoffel_symbols(c_uv)[:]
      [[[-2*u/(u^2 + v^2 + 1), -2*v/(u^2 + v^2 + 1)],
        [-2*v/(u^2 + v^2 + 1), 2*u/(u^2 + v^2 + 1)]],
       [[2*v/(u^2 + v^2 + 1), -2*u/(u^2 + v^2 + 1)],
        [-2*u/(u^2 + v^2 + 1), -2*v/(u^2 + v^2 + 1)]]]

  Python

      >>> from sage.all import *
      >>> g.christoffel_symbols(c_xy)
      3-indices components w.r.t. Coordinate frame (U, (∂/∂x,∂/∂y)), with
       symmetry on the index positions (1, 2)
      >>> g.christoffel_symbols(c_xy)[:]
      [[[-2*x/(x^2 + y^2 + 1), -2*y/(x^2 + y^2 + 1)],
        [-2*y/(x^2 + y^2 + 1), 2*x/(x^2 + y^2 + 1)]],
       [[2*y/(x^2 + y^2 + 1), -2*x/(x^2 + y^2 + 1)],
        [-2*x/(x^2 + y^2 + 1), -2*y/(x^2 + y^2 + 1)]]]
      >>> g.christoffel_symbols(c_uv)[:]
      [[[-2*u/(u^2 + v^2 + 1), -2*v/(u^2 + v^2 + 1)],
        [-2*v/(u^2 + v^2 + 1), 2*u/(u^2 + v^2 + 1)]],
       [[2*v/(u^2 + v^2 + 1), -2*u/(u^2 + v^2 + 1)],
        [-2*u/(u^2 + v^2 + 1), -2*v/(u^2 + v^2 + 1)]]]

  The Christoffel symbols are nothing but the connection coefficients w.r.t. the coordinate frame:

  Sage

      sage: g.christoffel_symbols(c_xy) is nabla.coef(c_xy.frame())
      True
      sage: g.christoffel_symbols(c_uv) is nabla.coef(c_uv.frame())
      True

  [Python]

      >>> from sage.all import *
      >>> g.christoffel_symbols(c_xy) is nabla.coef(c_xy.frame())
      True
      >>> g.christoffel_symbols(c_uv) is nabla.coef(c_uv.frame())
      True

  Test that \(\nabla\) is the connection compatible with \(g\):

  Sage

      sage: t = nabla(g) ; t
      Tensor field nabla_g(g) of type (0,3) on the 2-dimensional
       differentiable manifold S^2
      sage: t.display(eU)
      nabla_g(g) = 0
      sage: t.display(eV)
      nabla_g(g) = 0
      sage: t == 0
      True

  Python

      >>> from sage.all import *
      >>> t = nabla(g) ; t
      Tensor field nabla_g(g) of type (0,3) on the 2-dimensional
       differentiable manifold S^2
      >>> t.display(eU)
      nabla_g(g) = 0
      >>> t.display(eV)
      nabla_g(g) = 0
      >>> t == Integer(0)
      True

  The Riemann curvature tensor of \(g\):

  Sage

      sage: riem = g.riemann() ; riem
      Tensor field Riem(g) of type (1,3) on the 2-dimensional differentiable
       manifold S^2
      sage: riem.display(eU)
      Riem(g) = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) ∂/∂x⊗dy⊗dx⊗dy
       - 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) ∂/∂x⊗dy⊗dy⊗dx
       - 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) ∂/∂y⊗dx⊗dx⊗dy
       + 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) ∂/∂y⊗dx⊗dy⊗dx
      sage: riem.display(eV)
      Riem(g) = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) ∂/∂u⊗dv⊗du⊗dv
       - 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) ∂/∂u⊗dv⊗dv⊗du
       - 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) ∂/∂v⊗du⊗du⊗dv
       + 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) ∂/∂v⊗du⊗dv⊗du

  [Python]

      >>> from sage.all import *
      >>> riem = g.riemann() ; riem
      Tensor field Riem(g) of type (1,3) on the 2-dimensional differentiable
       manifold S^2
      >>> riem.display(eU)
      Riem(g) = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) ∂/∂x⊗dy⊗dx⊗dy
       - 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) ∂/∂x⊗dy⊗dy⊗dx
       - 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) ∂/∂y⊗dx⊗dx⊗dy
       + 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) ∂/∂y⊗dx⊗dy⊗dx
      >>> riem.display(eV)
      Riem(g) = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) ∂/∂u⊗dv⊗du⊗dv
       - 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) ∂/∂u⊗dv⊗dv⊗du
       - 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) ∂/∂v⊗du⊗du⊗dv
       + 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) ∂/∂v⊗du⊗dv⊗du

  The Ricci tensor of \(g\):

  Sage

      sage: ric = g.ricci() ; ric
      Field of symmetric bilinear forms Ric(g) on the 2-dimensional
       differentiable manifold S^2
      sage: ric.display(eU)
      Ric(g) = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dx⊗dx
       + 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dy⊗dy
      sage: ric.display(eV)
      Ric(g) = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) du⊗du
       + 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) dv⊗dv
      sage: ric == g
      True

  Python

      >>> from sage.all import *
      >>> ric = g.ricci() ; ric
      Field of symmetric bilinear forms Ric(g) on the 2-dimensional
       differentiable manifold S^2
      >>> ric.display(eU)
      Ric(g) = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dx⊗dx
       + 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dy⊗dy
      >>> ric.display(eV)
      Ric(g) = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) du⊗du
       + 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) dv⊗dv
      >>> ric == g
      True

  The Ricci scalar of \(g\):

  Sage

      sage: r = g.ricci_scalar() ; r
      Scalar field r(g) on the 2-dimensional differentiable manifold S^2
      sage: r.display()
      r(g): S^2 → ℝ
      on U: (x, y) ↦ 2
      on V: (u, v) ↦ 2

  [Python]

      >>> from sage.all import *
      >>> r = g.ricci_scalar() ; r
      Scalar field r(g) on the 2-dimensional differentiable manifold S^2
      >>> r.display()
      r(g): S^2 → ℝ
      on U: (x, y) ↦ 2
      on V: (u, v) ↦ 2

  In dimension 2, the Riemann tensor can be expressed entirely in terms of the Ricci scalar \(r\):

  \[R^i_{\ \, jlk} = \frac{r}{2} \left( \delta^i_{\ \, k} g_{jl} - \delta^i_{\ \, l} g_{jk} \right)\]

  This formula can be checked here, with the r.h.s. rewritten as \(-r g_{j[k} \delta^i_{\ \, l]}\):

  Sage

      sage: delta = M.tangent_identity_field()
      sage: riem == - r*(g*delta).antisymmetrize(2,3)
      True

  Python

      >>> from sage.all import *
      >>> delta = M.tangent_identity_field()
      >>> riem == - r*(g*delta).antisymmetrize(Integer(2),Integer(3))
      True

  christoffel_symbols(chart=None)

    Christoffel symbols of `self` with respect to a chart.

    INPUT:

    - `chart` – (default: `None`) chart with respect to which the Christoffel symbols are required; if none is provided, the default chart of the metric’s domain is assumed.

    OUTPUT:

    - the set of Christoffel symbols in the given chart, as an instance of `CompWithSym`

    EXAMPLES:

    Christoffel symbols of the flat metric on \(\RR^3\) with respect to spherical coordinates:

    Sage

        sage: M = Manifold(3, 'R3', r'\RR^3', start_index=1)
        sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        sage: X.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2], g[3,3] = 1, r^2, r^2*sin(th)^2
        sage: g.display()  # the standard flat metric expressed in spherical coordinates
        g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
        sage: Gam = g.christoffel_symbols() ; Gam
        3-indices components w.r.t. Coordinate frame (U, (∂/∂r,∂/∂th,∂/∂ph)),
         with symmetry on the index positions (1, 2)
        sage: type(Gam)
        <class 'sage.tensor.modules.comp.CompWithSym'>
        sage: Gam[:]
        [[[0, 0, 0], [0, -r, 0], [0, 0, -r*sin(th)^2]],
        [[0, 1/r, 0], [1/r, 0, 0], [0, 0, -cos(th)*sin(th)]],
        [[0, 0, 1/r], [0, 0, cos(th)/sin(th)], [1/r, cos(th)/sin(th), 0]]]
        sage: Gam[1,2,2]
        -r
        sage: Gam[2,1,2]
        1/r
        sage: Gam[3,1,3]
        1/r
        sage: Gam[3,2,3]
        cos(th)/sin(th)
        sage: Gam[2,3,3]
        -cos(th)*sin(th)

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'R3', r'\RR^3', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        >>> X = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi', names=('r', 'th', 'ph',)); (r, th, ph,) = X._first_ngens(3)
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = Integer(1), r**Integer(2), r**Integer(2)*sin(th)**Integer(2)
        >>> g.display()  # the standard flat metric expressed in spherical coordinates
        g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
        >>> Gam = g.christoffel_symbols() ; Gam
        3-indices components w.r.t. Coordinate frame (U, (∂/∂r,∂/∂th,∂/∂ph)),
         with symmetry on the index positions (1, 2)
        >>> type(Gam)
        <class 'sage.tensor.modules.comp.CompWithSym'>
        >>> Gam[:]
        [[[0, 0, 0], [0, -r, 0], [0, 0, -r*sin(th)^2]],
        [[0, 1/r, 0], [1/r, 0, 0], [0, 0, -cos(th)*sin(th)]],
        [[0, 0, 1/r], [0, 0, cos(th)/sin(th)], [1/r, cos(th)/sin(th), 0]]]
        >>> Gam[Integer(1),Integer(2),Integer(2)]
        -r
        >>> Gam[Integer(2),Integer(1),Integer(2)]
        1/r
        >>> Gam[Integer(3),Integer(1),Integer(3)]
        1/r
        >>> Gam[Integer(3),Integer(2),Integer(3)]
        cos(th)/sin(th)
        >>> Gam[Integer(2),Integer(3),Integer(3)]
        -cos(th)*sin(th)

    Note that a better display of the Christoffel symbols is provided by the method `christoffel_symbols_display()`:

    Sage

        sage: g.christoffel_symbols_display()
        Gam^r_th,th = -r
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,th = 1/r
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,ph = 1/r
        Gam^ph_th,ph = cos(th)/sin(th)

    [Python]

        >>> from sage.all import *
        >>> g.christoffel_symbols_display()
        Gam^r_th,th = -r
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,th = 1/r
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,ph = 1/r
        Gam^ph_th,ph = cos(th)/sin(th)

  christoffel_symbols_display(chart=None, symbol=None, latex_symbol=None, index_labels=None, index_latex_labels=None, coordinate_labels=True, only_nonzero=True, only_nonredundant=True)

    Display the Christoffel symbols w.r.t. to a given chart, one per line.

    The output is either text-formatted (console mode) or LaTeX-formatted (notebook mode).

    INPUT:

    - `chart` – (default: `None`) chart with respect to which the Christoffel symbols are defined; if none is provided, the default chart of the metric’s domain is assumed.

    - `symbol` – (default: `None`) string specifying the symbol of the connection coefficients; if `None`, ‘Gam’ is used

    - `latex_symbol` – (default: `None`) string specifying the LaTeX symbol for the components; if `None`, ‘\Gamma’ is used

    - `index_labels` – (default: `None`) list of strings representing the labels of each index; if `None`, coordinate symbols are used except if `coordinate_symbols` is set to `False`, in which case integer labels are used

    - `index_latex_labels` – (default: `None`) list of strings representing the LaTeX labels of each index; if `None`, coordinate LaTeX symbols are used, except if `coordinate_symbols` is set to `False`, in which case integer labels are used

    - `coordinate_labels` – boolean (default: `True`); if `True`, coordinate symbols are used by default (instead of integers)

    - `only_nonzero` – boolean (default: `True`); if `True`, only nonzero connection coefficients are displayed

    - `only_nonredundant` – boolean (default: `True`); if `True`, only nonredundant (w.r.t. the symmetry of the last two indices) connection coefficients are displayed

    EXAMPLES:

    Christoffel symbols of the flat metric on \(\RR^3\) with respect to spherical coordinates:

    Sage

        sage: M = Manifold(3, 'R3', r'\RR^3', start_index=1)
        sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        sage: X.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2], g[3,3] = 1, r^2, r^2*sin(th)^2
        sage: g.display()  # the standard flat metric expressed in spherical coordinates
        g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
        sage: g.christoffel_symbols_display()
        Gam^r_th,th = -r
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,th = 1/r
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,ph = 1/r
        Gam^ph_th,ph = cos(th)/sin(th)

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'R3', r'\RR^3', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        >>> X = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi', names=('r', 'th', 'ph',)); (r, th, ph,) = X._first_ngens(3)
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = Integer(1), r**Integer(2), r**Integer(2)*sin(th)**Integer(2)
        >>> g.display()  # the standard flat metric expressed in spherical coordinates
        g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
        >>> g.christoffel_symbols_display()
        Gam^r_th,th = -r
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,th = 1/r
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,ph = 1/r
        Gam^ph_th,ph = cos(th)/sin(th)

    To list all nonzero Christoffel symbols, including those that can be deduced by symmetry, use `only_nonredundant=False`:

    Sage

        sage: g.christoffel_symbols_display(only_nonredundant=False)
        Gam^r_th,th = -r
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,th = 1/r
        Gam^th_th,r = 1/r
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,ph = 1/r
        Gam^ph_th,ph = cos(th)/sin(th)
        Gam^ph_ph,r = 1/r
        Gam^ph_ph,th = cos(th)/sin(th)

    [Python]

        >>> from sage.all import *
        >>> g.christoffel_symbols_display(only_nonredundant=False)
        Gam^r_th,th = -r
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,th = 1/r
        Gam^th_th,r = 1/r
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,ph = 1/r
        Gam^ph_th,ph = cos(th)/sin(th)
        Gam^ph_ph,r = 1/r
        Gam^ph_ph,th = cos(th)/sin(th)

    Listing all Christoffel symbols (except those that can be deduced by symmetry), including the vanishing one:

    Sage

        sage: g.christoffel_symbols_display(only_nonzero=False)
        Gam^r_r,r = 0
        Gam^r_r,th = 0
        Gam^r_r,ph = 0
        Gam^r_th,th = -r
        Gam^r_th,ph = 0
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,r = 0
        Gam^th_r,th = 1/r
        Gam^th_r,ph = 0
        Gam^th_th,th = 0
        Gam^th_th,ph = 0
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,r = 0
        Gam^ph_r,th = 0
        Gam^ph_r,ph = 1/r
        Gam^ph_th,th = 0
        Gam^ph_th,ph = cos(th)/sin(th)
        Gam^ph_ph,ph = 0

    Python

        >>> from sage.all import *
        >>> g.christoffel_symbols_display(only_nonzero=False)
        Gam^r_r,r = 0
        Gam^r_r,th = 0
        Gam^r_r,ph = 0
        Gam^r_th,th = -r
        Gam^r_th,ph = 0
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,r = 0
        Gam^th_r,th = 1/r
        Gam^th_r,ph = 0
        Gam^th_th,th = 0
        Gam^th_th,ph = 0
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,r = 0
        Gam^ph_r,th = 0
        Gam^ph_r,ph = 1/r
        Gam^ph_th,th = 0
        Gam^ph_th,ph = cos(th)/sin(th)
        Gam^ph_ph,ph = 0

    Using integer labels:

    Sage

        sage: g.christoffel_symbols_display(coordinate_labels=False)
        Gam^1_22 = -r
        Gam^1_33 = -r*sin(th)^2
        Gam^2_12 = 1/r
        Gam^2_33 = -cos(th)*sin(th)
        Gam^3_13 = 1/r
        Gam^3_23 = cos(th)/sin(th)

    [Python]

        >>> from sage.all import *
        >>> g.christoffel_symbols_display(coordinate_labels=False)
        Gam^1_22 = -r
        Gam^1_33 = -r*sin(th)^2
        Gam^2_12 = 1/r
        Gam^2_33 = -cos(th)*sin(th)
        Gam^3_13 = 1/r
        Gam^3_23 = cos(th)/sin(th)

  connection(name=None, latex_name=None, init_coef=True)

    Return the unique torsion-free affine connection compatible with `self`.

    This is the so-called Levi-Civita connection.

    INPUT:

    - `name` – (default: `None`) name given to the Levi-Civita connection; if `None`, it is formed from the metric name

    - `latex_name` – (default: `None`) LaTeX symbol to denote the Levi-Civita connection; if `None`, it is set to `name`, or if the latter is None as well, it formed from the symbol \(\nabla\) and the metric symbol

    - `init_coef` – boolean (default: `True`); determines whether the connection coefficients are initialized, as Christoffel symbols in the top charts of the domain of `self` (i.e. disregarding the subcharts)

    OUTPUT:

    - the Levi-Civita connection, as an instance of `LeviCivitaConnection`

    EXAMPLES:

    Levi-Civita connection associated with the Euclidean metric on \(\RR^3\):

    Sage

        sage: M = Manifold(3, 'R^3', start_index=1)

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'R^3', start_index=Integer(1))

    Let us use spherical coordinates on \(\RR^3\):

    Sage

        sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        sage: c_spher.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2], g[3,3] = 1, r^2 , (r*sin(th))^2  # the Euclidean metric
        sage: g.connection()
        Levi-Civita connection nabla_g associated with the Riemannian
         metric g on the Open subset U of the 3-dimensional differentiable
         manifold R^3
        sage: g.connection().display()  # Nonzero connection coefficients
        Gam^r_th,th = -r
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,th = 1/r
        Gam^th_th,r = 1/r
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,ph = 1/r
        Gam^ph_th,ph = cos(th)/sin(th)
        Gam^ph_ph,r = 1/r
        Gam^ph_ph,th = cos(th)/sin(th)

    [Python]

        >>> from sage.all import *
        >>> U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        >>> c_spher = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi', names=('r', 'th', 'ph',)); (r, th, ph,) = c_spher._first_ngens(3)
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = Integer(1), r**Integer(2) , (r*sin(th))**Integer(2)  # the Euclidean metric
        >>> g.connection()
        Levi-Civita connection nabla_g associated with the Riemannian
         metric g on the Open subset U of the 3-dimensional differentiable
         manifold R^3
        >>> g.connection().display()  # Nonzero connection coefficients
        Gam^r_th,th = -r
        Gam^r_ph,ph = -r*sin(th)^2
        Gam^th_r,th = 1/r
        Gam^th_th,r = 1/r
        Gam^th_ph,ph = -cos(th)*sin(th)
        Gam^ph_r,ph = 1/r
        Gam^ph_th,ph = cos(th)/sin(th)
        Gam^ph_ph,r = 1/r
        Gam^ph_ph,th = cos(th)/sin(th)

    Test of compatibility with the metric:

    Sage

        sage: Dg = g.connection()(g) ; Dg
        Tensor field nabla_g(g) of type (0,3) on the Open subset U of the
         3-dimensional differentiable manifold R^3
        sage: Dg == 0
        True
        sage: Dig = g.connection()(g.inverse()) ; Dig
        Tensor field nabla_g(inv_g) of type (2,1) on the Open subset U of
         the 3-dimensional differentiable manifold R^3
        sage: Dig == 0
        True

    Python

        >>> from sage.all import *
        >>> Dg = g.connection()(g) ; Dg
        Tensor field nabla_g(g) of type (0,3) on the Open subset U of the
         3-dimensional differentiable manifold R^3
        >>> Dg == Integer(0)
        True
        >>> Dig = g.connection()(g.inverse()) ; Dig
        Tensor field nabla_g(inv_g) of type (2,1) on the Open subset U of
         the 3-dimensional differentiable manifold R^3
        >>> Dig == Integer(0)
        True

  cotton(name=None, latex_name=None)

    Return the Cotton conformal tensor associated with the metric. The tensor has type (0,3) and is defined in terms of the Schouten tensor \(S\) (see `schouten()`):

    \[C_{ijk} = (n-2) \left(\nabla_k S_{ij} - \nabla_j S_{ik}\right)\]

    INPUT:

    - `name` – (default: `None`) name given to the Cotton conformal tensor; if `None`, it is set to “Cot(g)”, where “g” is the metric’s name

    - `latex_name` – (default: `None`) LaTeX symbol to denote the Cotton conformal tensor; if `None`, it is set to “\mathrm{Cot}(g)”, where “g” is the metric’s name

    OUTPUT:

    - the Cotton conformal tensor \(Cot\), as an instance of `TensorField`

    EXAMPLES:

    Checking that the Cotton tensor identically vanishes on a conformally flat 3-dimensional manifold, for instance the hyperbolic space \(H^3\):

    Sage

        sage: M = Manifold(3, 'H^3', start_index=1)
        sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        sage: X.<rh,th,ph> = U.chart(r'rh:(0,+oo):\rho th:(0,pi):\theta  ph:(0,2*pi):\phi')
        sage: g = U.metric('g')
        sage: b = var('b')
        sage: g[1,1], g[2,2], g[3,3] = b^2, (b*sinh(rh))^2, (b*sinh(rh)*sin(th))^2
        sage: g.display()  # standard metric on H^3:
        g = b^2 drh⊗drh + b^2*sinh(rh)^2 dth⊗dth
         + b^2*sin(th)^2*sinh(rh)^2 dph⊗dph
        sage: Cot = g.cotton() ; Cot # long time
        Tensor field Cot(g) of type (0,3) on the Open subset U of the
         3-dimensional differentiable manifold H^3
        sage: Cot == 0 # long time
        True

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'H^3', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        >>> X = U.chart(r'rh:(0,+oo):\rho th:(0,pi):\theta  ph:(0,2*pi):\phi', names=('rh', 'th', 'ph',)); (rh, th, ph,) = X._first_ngens(3)
        >>> g = U.metric('g')
        >>> b = var('b')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = b**Integer(2), (b*sinh(rh))**Integer(2), (b*sinh(rh)*sin(th))**Integer(2)
        >>> g.display()  # standard metric on H^3:
        g = b^2 drh⊗drh + b^2*sinh(rh)^2 dth⊗dth
         + b^2*sin(th)^2*sinh(rh)^2 dph⊗dph
        >>> Cot = g.cotton() ; Cot # long time
        Tensor field Cot(g) of type (0,3) on the Open subset U of the
         3-dimensional differentiable manifold H^3
        >>> Cot == Integer(0) # long time
        True

  cotton_york(name=None, latex_name=None)

    Return the Cotton-York conformal tensor associated with the metric. The tensor has type (0,2) and is only defined for manifolds of dimension 3. It is defined in terms of the Cotton tensor \(C\) (see `cotton()`) or the Schouten tensor \(S\) (see `schouten()`):

    \[CY_{ij} = \frac{1}{2} \epsilon^{kl}_{\ \ \, i} C_{jlk} = \epsilon^{kl}_{\ \ \, i} \nabla_k S_{lj}\]

    INPUT:

    - `name` – (default: `None`) name given to the Cotton-York tensor; if `None`, it is set to “CY(g)”, where “g” is the metric’s name

    - `latex_name` – (default: `None`) LaTeX symbol to denote the Cotton-York tensor; if `None`, it is set to “\mathrm{CY}(g)”, where “g” is the metric’s name

    OUTPUT:

    - the Cotton-York conformal tensor \(CY\), as an instance of `TensorField`

    EXAMPLES:

    Compute the determinant of the Cotton-York tensor for the Heisenberg group with the left invariant metric:

    Sage

        sage: M = Manifold(3, 'Nil', start_index=1)
        sage: X.<x,y,z> = M.chart()
        sage: g = M.riemannian_metric('g')
        sage: g[1,1], g[2,2], g[2,3], g[3,3] = 1, 1+x^2, -x, 1
        sage: g.display()
        g = dx⊗dx + (x^2 + 1) dy⊗dy - x dy⊗dz - x dz⊗dy + dz⊗dz
        sage: CY = g.cotton_york() ; CY # long time
        Tensor field CY(g) of type (0,2) on the 3-dimensional
         differentiable manifold Nil
        sage: CY.display()  # long time
        CY(g) = 1/2 dx⊗dx + (-x^2 + 1/2) dy⊗dy + x dy⊗dz + x dz⊗dy - dz⊗dz
        sage: det(CY[:]) # long time
        -1/4

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'Nil', start_index=Integer(1))
        >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3)
        >>> g = M.riemannian_metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(2),Integer(3)], g[Integer(3),Integer(3)] = Integer(1), Integer(1)+x**Integer(2), -x, Integer(1)
        >>> g.display()
        g = dx⊗dx + (x^2 + 1) dy⊗dy - x dy⊗dz - x dz⊗dy + dz⊗dz
        >>> CY = g.cotton_york() ; CY # long time
        Tensor field CY(g) of type (0,2) on the 3-dimensional
         differentiable manifold Nil
        >>> CY.display()  # long time
        CY(g) = 1/2 dx⊗dx + (-x^2 + 1/2) dy⊗dy + x dy⊗dz + x dz⊗dy - dz⊗dz
        >>> det(CY[:]) # long time
        -1/4

  det(frame=None)

    alias of `determinant()`.

  determinant(frame=None)

    Determinant of the metric components in the specified frame.

    INPUT:

    - `frame` – (default: `None`) vector frame with respect to which the components \(g_{ij}\) of the metric are defined; if `None`, the default frame of the metric’s domain is used. If a chart is provided instead of a frame, the associated coordinate frame is used

    OUTPUT:

    - the determinant \(\det (g_{ij})\), as an instance of `DiffScalarField`

    EXAMPLES:

    Metric determinant on a 2-dimensional manifold:

    Sage

        sage: M = Manifold(2, 'M', start_index=1)
        sage: X.<x,y> = M.chart()
        sage: g = M.metric('g')
        sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y
        sage: g[:]
        [ x + 1    x*y]
        [   x*y -y + 1]
        sage: s = g.determinant()  # determinant in M's default frame
        sage: s.expr()
        -x^2*y^2 - (x + 1)*y + x + 1

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M', start_index=Integer(1))
        >>> X = M.chart(names=('x', 'y',)); (x, y,) = X._first_ngens(2)
        >>> g = M.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(1), Integer(2)], g[Integer(2), Integer(2)] = Integer(1)+x, x*y , Integer(1)-y
        >>> g[:]
        [ x + 1    x*y]
        [   x*y -y + 1]
        >>> s = g.determinant()  # determinant in M's default frame
        >>> s.expr()
        -x^2*y^2 - (x + 1)*y + x + 1

    A shortcut is `det()`:

    Sage

        sage: g.det() == g.determinant()
        True

    [Python]

        >>> from sage.all import *
        >>> g.det() == g.determinant()
        True

    The notation `det(g)` can be used:

    Sage

        sage: det(g) == g.determinant()
        True

    Python

        >>> from sage.all import *
        >>> det(g) == g.determinant()
        True

    Determinant in a frame different from the default’s one:

    Sage

        sage: Y.<u,v> = M.chart()
        sage: ch_X_Y = X.transition_map(Y, [x+y, x-y])
        sage: ch_X_Y.inverse()
        Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y))
        sage: g.comp(Y.frame())[:, Y]
        [ 1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2                            1/4*u]
        [                           1/4*u -1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2]
        sage: g.determinant(Y.frame()).expr()
        -1/4*x^2*y^2 - 1/4*(x + 1)*y + 1/4*x + 1/4
        sage: g.determinant(Y.frame()).expr(Y)
        -1/64*u^4 - 1/64*v^4 + 1/32*(u^2 + 2)*v^2 - 1/16*u^2 + 1/4*v + 1/4

    [Python]

        >>> from sage.all import *
        >>> Y = M.chart(names=('u', 'v',)); (u, v,) = Y._first_ngens(2)
        >>> ch_X_Y = X.transition_map(Y, [x+y, x-y])
        >>> ch_X_Y.inverse()
        Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y))
        >>> g.comp(Y.frame())[:, Y]
        [ 1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2                            1/4*u]
        [                           1/4*u -1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2]
        >>> g.determinant(Y.frame()).expr()
        -1/4*x^2*y^2 - 1/4*(x + 1)*y + 1/4*x + 1/4
        >>> g.determinant(Y.frame()).expr(Y)
        -1/64*u^4 - 1/64*v^4 + 1/32*(u^2 + 2)*v^2 - 1/16*u^2 + 1/4*v + 1/4

    A chart can be passed instead of a frame:

    Sage

        sage: g.determinant(X) is g.determinant(X.frame())
        True
        sage: g.determinant(Y) is g.determinant(Y.frame())
        True

    Python

        >>> from sage.all import *
        >>> g.determinant(X) is g.determinant(X.frame())
        True
        >>> g.determinant(Y) is g.determinant(Y.frame())
        True

    The metric determinant depends on the frame:

    Sage

        sage: g.determinant(X.frame()) == g.determinant(Y.frame())
        False

    [Python]

        >>> from sage.all import *
        >>> g.determinant(X.frame()) == g.determinant(Y.frame())
        False

    Using SymPy as symbolic engine:

    Sage

        sage: M.set_calculus_method('sympy')
        sage: g = M.metric('g')
        sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y
        sage: s = g.determinant()  # determinant in M's default frame
        sage: s.expr()
        -x**2*y**2 + x - y*(x + 1) + 1

    Python

        >>> from sage.all import *
        >>> M.set_calculus_method('sympy')
        >>> g = M.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(1), Integer(2)], g[Integer(2), Integer(2)] = Integer(1)+x, x*y , Integer(1)-y
        >>> s = g.determinant()  # determinant in M's default frame
        >>> s.expr()
        -x**2*y**2 + x - y*(x + 1) + 1

  hodge_star(pform)

    Compute the Hodge dual of a differential form with respect to the metric.

    If the differential form is a \(p\)-form \(A\), its Hodge dual with respect to the metric \(g\) is the \((n-p)\)-form \(*A\) defined by

    \[*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 \(n\) is the manifold’s dimension, \(\epsilon\) is the volume \(n\)-form associated with \(g\) (see `volume_form()`) and the indices \(k_1,\ldots, k_p\) are raised with \(g\).

    Notice that the Hodge star dual requires an orientable manifold with a preferred orientation, see `orientation()` for details.

    INPUT:

    - `pform` – a \(p\)-form \(A\); must be an instance of `DiffScalarField` for \(p=0\) and of `DiffForm` or `DiffFormParal` for \(p\geq 1\).

    OUTPUT:

    - the \((n-p)\)-form \(*A\)

    EXAMPLES:

    Hodge dual of a 1-form in the Euclidean space \(R^3\):

    Sage

        sage: M = Manifold(3, 'M', start_index=1)
        sage: X.<x,y,z> = M.chart()
        sage: g = M.metric('g')
        sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1
        sage: var('Ax Ay Az')
        (Ax, Ay, Az)
        sage: a = M.one_form(Ax, Ay, Az, name='A')
        sage: sa = g.hodge_star(a) ; sa
        2-form *A on the 3-dimensional differentiable manifold M
        sage: sa.display()
        *A = Az dx∧dy - Ay dx∧dz + Ax dy∧dz
        sage: ssa = g.hodge_star(sa) ; ssa
        1-form **A on the 3-dimensional differentiable manifold M
        sage: ssa.display()
        **A = Ax dx + Ay dy + Az dz
        sage: ssa == a  # must hold for a Riemannian metric in dimension 3
        True

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'M', start_index=Integer(1))
        >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3)
        >>> g = M.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = Integer(1), Integer(1), Integer(1)
        >>> var('Ax Ay Az')
        (Ax, Ay, Az)
        >>> a = M.one_form(Ax, Ay, Az, name='A')
        >>> sa = g.hodge_star(a) ; sa
        2-form *A on the 3-dimensional differentiable manifold M
        >>> sa.display()
        *A = Az dx∧dy - Ay dx∧dz + Ax dy∧dz
        >>> ssa = g.hodge_star(sa) ; ssa
        1-form **A on the 3-dimensional differentiable manifold M
        >>> ssa.display()
        **A = Ax dx + Ay dy + Az dz
        >>> ssa == a  # must hold for a Riemannian metric in dimension 3
        True

    Hodge dual of a 0-form (scalar field) in \(R^3\):

    Sage

        sage: f = M.scalar_field(function('F')(x,y,z), name='f')
        sage: sf = g.hodge_star(f) ; sf
        3-form *f on the 3-dimensional differentiable manifold M
        sage: sf.display()
        *f = F(x, y, z) dx∧dy∧dz
        sage: ssf = g.hodge_star(sf) ; ssf
        Scalar field **f on the 3-dimensional differentiable manifold M
        sage: ssf.display()
        **f: M → ℝ
           (x, y, z) ↦ F(x, y, z)
        sage: ssf == f # must hold for a Riemannian metric
        True

    [Python]

        >>> from sage.all import *
        >>> f = M.scalar_field(function('F')(x,y,z), name='f')
        >>> sf = g.hodge_star(f) ; sf
        3-form *f on the 3-dimensional differentiable manifold M
        >>> sf.display()
        *f = F(x, y, z) dx∧dy∧dz
        >>> ssf = g.hodge_star(sf) ; ssf
        Scalar field **f on the 3-dimensional differentiable manifold M
        >>> ssf.display()
        **f: M → ℝ
           (x, y, z) ↦ F(x, y, z)
        >>> ssf == f # must hold for a Riemannian metric
        True

    Hodge dual of a 0-form in Minkowski spacetime:

    Sage

        sage: M = Manifold(4, 'M')
        sage: X.<t,x,y,z> = M.chart()
        sage: g = M.lorentzian_metric('g')
        sage: g[0,0], g[1,1], g[2,2], g[3,3] = -1, 1, 1, 1
        sage: g.display()  # Minkowski metric
        g = -dt⊗dt + dx⊗dx + dy⊗dy + dz⊗dz
        sage: var('f0')
        f0
        sage: f = M.scalar_field(f0, name='f')
        sage: sf = g.hodge_star(f) ; sf
        4-form *f on the 4-dimensional differentiable manifold M
        sage: sf.display()
        *f = f0 dt∧dx∧dy∧dz
        sage: ssf = g.hodge_star(sf) ; ssf
        Scalar field **f on the 4-dimensional differentiable manifold M
        sage: ssf.display()
        **f: M → ℝ
           (t, x, y, z) ↦ -f0
        sage: ssf == -f  # must hold for a Lorentzian metric
        True

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(4), 'M')
        >>> X = M.chart(names=('t', 'x', 'y', 'z',)); (t, x, y, z,) = X._first_ngens(4)
        >>> g = M.lorentzian_metric('g')
        >>> g[Integer(0),Integer(0)], g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = -Integer(1), Integer(1), Integer(1), Integer(1)
        >>> g.display()  # Minkowski metric
        g = -dt⊗dt + dx⊗dx + dy⊗dy + dz⊗dz
        >>> var('f0')
        f0
        >>> f = M.scalar_field(f0, name='f')
        >>> sf = g.hodge_star(f) ; sf
        4-form *f on the 4-dimensional differentiable manifold M
        >>> sf.display()
        *f = f0 dt∧dx∧dy∧dz
        >>> ssf = g.hodge_star(sf) ; ssf
        Scalar field **f on the 4-dimensional differentiable manifold M
        >>> ssf.display()
        **f: M → ℝ
           (t, x, y, z) ↦ -f0
        >>> ssf == -f  # must hold for a Lorentzian metric
        True

    Hodge dual of a 1-form in Minkowski spacetime:

    Sage

        sage: var('At Ax Ay Az')
        (At, Ax, Ay, Az)
        sage: a = M.one_form(At, Ax, Ay, Az, name='A')
        sage: a.display()
        A = At dt + Ax dx + Ay dy + Az dz
        sage: sa = g.hodge_star(a) ; sa
        3-form *A on the 4-dimensional differentiable manifold M
        sage: sa.display()
        *A = -Az dt∧dx∧dy + Ay dt∧dx∧dz - Ax dt∧dy∧dz - At dx∧dy∧dz
        sage: ssa = g.hodge_star(sa) ; ssa
        1-form **A on the 4-dimensional differentiable manifold M
        sage: ssa.display()
        **A = At dt + Ax dx + Ay dy + Az dz
        sage: ssa == a  # must hold for a Lorentzian metric in dimension 4
        True

    [Python]

        >>> from sage.all import *
        >>> var('At Ax Ay Az')
        (At, Ax, Ay, Az)
        >>> a = M.one_form(At, Ax, Ay, Az, name='A')
        >>> a.display()
        A = At dt + Ax dx + Ay dy + Az dz
        >>> sa = g.hodge_star(a) ; sa
        3-form *A on the 4-dimensional differentiable manifold M
        >>> sa.display()
        *A = -Az dt∧dx∧dy + Ay dt∧dx∧dz - Ax dt∧dy∧dz - At dx∧dy∧dz
        >>> ssa = g.hodge_star(sa) ; ssa
        1-form **A on the 4-dimensional differentiable manifold M
        >>> ssa.display()
        **A = At dt + Ax dx + Ay dy + Az dz
        >>> ssa == a  # must hold for a Lorentzian metric in dimension 4
        True

    Hodge dual of a 2-form in Minkowski spacetime:

    Sage

        sage: F = M.diff_form(2, name='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 = g.hodge_star(F) ; sF
        2-form *F on the 4-dimensional differentiable manifold M
        sage: sF[:]
        [  0  Bx  By  Bz]
        [-Bx   0  Ez -Ey]
        [-By -Ez   0  Ex]
        [-Bz  Ey -Ex   0]
        sage: ssF = g.hodge_star(sF) ; ssF
        2-form **F on the 4-dimensional differentiable manifold M
        sage: ssF[:]
        [  0  Ex  Ey  Ez]
        [-Ex   0 -Bz  By]
        [-Ey  Bz   0 -Bx]
        [-Ez -By  Bx   0]
        sage: ssF.display()
        **F = Ex dt∧dx + Ey dt∧dy + Ez dt∧dz - Bz dx∧dy + By dx∧dz
         - Bx dy∧dz
        sage: F.display()
        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

    Python

        >>> from sage.all import *
        >>> F = M.diff_form(Integer(2), name='F')
        >>> var('Ex Ey Ez Bx By Bz')
        (Ex, Ey, Ez, Bx, By, Bz)
        >>> F[Integer(0),Integer(1)], F[Integer(0),Integer(2)], F[Integer(0),Integer(3)] = -Ex, -Ey, -Ez
        >>> F[Integer(1),Integer(2)], F[Integer(1),Integer(3)], F[Integer(2),Integer(3)] = Bz, -By, Bx
        >>> F[:]
        [  0 -Ex -Ey -Ez]
        [ Ex   0  Bz -By]
        [ Ey -Bz   0  Bx]
        [ Ez  By -Bx   0]
        >>> sF = g.hodge_star(F) ; sF
        2-form *F on the 4-dimensional differentiable manifold M
        >>> sF[:]
        [  0  Bx  By  Bz]
        [-Bx   0  Ez -Ey]
        [-By -Ez   0  Ex]
        [-Bz  Ey -Ex   0]
        >>> ssF = g.hodge_star(sF) ; ssF
        2-form **F on the 4-dimensional differentiable manifold M
        >>> ssF[:]
        [  0  Ex  Ey  Ez]
        [-Ex   0 -Bz  By]
        [-Ey  Bz   0 -Bx]
        [-Ez -By  Bx   0]
        >>> ssF.display()
        **F = Ex dt∧dx + Ey dt∧dy + Ez dt∧dz - Bz dx∧dy + By dx∧dz
         - Bx dy∧dz
        >>> F.display()
        F = -Ex dt∧dx - Ey dt∧dy - Ez dt∧dz + Bz dx∧dy - By dx∧dz
         + Bx dy∧dz
        >>> ssF == -F  # must hold for a Lorentzian metric in dimension 4
        True

    Test of the standard identity

    \[*(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

        sage: var('Bt Bx By Bz')
        (Bt, Bx, By, Bz)
        sage: b = M.one_form(Bt, Bx, By, Bz, name='B')
        sage: b.display()
        B = Bt dt + Bx dx + By dy + Bz dz
        sage: epsilon = g.volume_form()
        sage: g.hodge_star(a.wedge(b)) == epsilon.contract(0,a.up(g)).contract(0,b.up(g))
        True

    [Python]

        >>> from sage.all import *
        >>> var('Bt Bx By Bz')
        (Bt, Bx, By, Bz)
        >>> b = M.one_form(Bt, Bx, By, Bz, name='B')
        >>> b.display()
        B = Bt dt + Bx dx + By dy + Bz dz
        >>> epsilon = g.volume_form()
        >>> g.hodge_star(a.wedge(b)) == epsilon.contract(Integer(0),a.up(g)).contract(Integer(0),b.up(g))
        True

  inverse(expansion_symbol=None, order=1)

    Return the inverse metric.

    INPUT:

    - `expansion_symbol` – (default: `None`) symbolic variable; if specified, the inverse will be expanded in power series with respect to this variable (around its zero value)

    - `order` – integer (default: 1); the order of the expansion if `expansion_symbol` is not `None`; the order is defined as the degree of the polynomial representing the truncated power series in `expansion_symbol`; currently only first order inverse is supported

    If `expansion_symbol` is set, then the zeroth order metric must be invertible. Moreover, subsequent calls to this method will return a cached value, even when called with the default value (to enable computation of derived quantities). To reset, use `_del_derived()`.

    OUTPUT:

    - instance of `TensorField` with `tensor_type` = (2,0) representing the inverse metric

    EXAMPLES:

    Inverse of the standard metric on the 2-sphere:

    Sage

        sage: M = Manifold(2, 'S^2', start_index=1)
        sage: U = M.open_subset('U') ; V = M.open_subset('V')
        sage: M.declare_union(U,V)  # S^2 is the union of U and V
        sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart() # stereographic coord.
        sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
        ....:                 intersection_name='W', restrictions1= x^2+y^2!=0,
        ....:                 restrictions2= u^2+v^2!=0)
        sage: uv_to_xy = xy_to_uv.inverse()
        sage: W = U.intersection(V)  # the complement of the two poles
        sage: eU = c_xy.frame() ; eV = c_uv.frame()
        sage: g = M.metric('g')
        sage: g[eU,1,1], g[eU,2,2] = 4/(1+x^2+y^2)^2, 4/(1+x^2+y^2)^2
        sage: g.add_comp_by_continuation(eV, W, c_uv)
        sage: ginv = g.inverse(); ginv
        Tensor field inv_g of type (2,0) on the 2-dimensional differentiable manifold S^2
        sage: ginv.display(eU)
        inv_g = (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) ∂/∂x⊗∂/∂x
         + (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) ∂/∂y⊗∂/∂y
        sage: ginv.display(eV)
        inv_g = (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) ∂/∂u⊗∂/∂u
         + (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) ∂/∂v⊗∂/∂v

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'S^2', start_index=Integer(1))
        >>> U = M.open_subset('U') ; V = M.open_subset('V')
        >>> M.declare_union(U,V)  # S^2 is the union of U and V
        >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2); c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)# stereographic coord.
        >>> xy_to_uv = c_xy.transition_map(c_uv, (x/(x**Integer(2)+y**Integer(2)), y/(x**Integer(2)+y**Integer(2))),
        ...                 intersection_name='W', restrictions1= x**Integer(2)+y**Integer(2)!=Integer(0),
        ...                 restrictions2= u**Integer(2)+v**Integer(2)!=Integer(0))
        >>> uv_to_xy = xy_to_uv.inverse()
        >>> W = U.intersection(V)  # the complement of the two poles
        >>> eU = c_xy.frame() ; eV = c_uv.frame()
        >>> g = M.metric('g')
        >>> g[eU,Integer(1),Integer(1)], g[eU,Integer(2),Integer(2)] = Integer(4)/(Integer(1)+x**Integer(2)+y**Integer(2))**Integer(2), Integer(4)/(Integer(1)+x**Integer(2)+y**Integer(2))**Integer(2)
        >>> g.add_comp_by_continuation(eV, W, c_uv)
        >>> ginv = g.inverse(); ginv
        Tensor field inv_g of type (2,0) on the 2-dimensional differentiable manifold S^2
        >>> ginv.display(eU)
        inv_g = (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) ∂/∂x⊗∂/∂x
         + (1/4*x^4 + 1/4*y^4 + 1/2*(x^2 + 1)*y^2 + 1/2*x^2 + 1/4) ∂/∂y⊗∂/∂y
        >>> ginv.display(eV)
        inv_g = (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) ∂/∂u⊗∂/∂u
         + (1/4*u^4 + 1/4*v^4 + 1/2*(u^2 + 1)*v^2 + 1/2*u^2 + 1/4) ∂/∂v⊗∂/∂v

    Let us check that `ginv` is indeed the inverse of `g`:

    Sage

        sage: s = g.contract(ginv); s  # contraction of last index of g with first index of ginv
        Tensor field of type (1,1) on the 2-dimensional differentiable manifold S^2
        sage: s == M.tangent_identity_field()
        True

    [Python]

        >>> from sage.all import *
        >>> s = g.contract(ginv); s  # contraction of last index of g with first index of ginv
        Tensor field of type (1,1) on the 2-dimensional differentiable manifold S^2
        >>> s == M.tangent_identity_field()
        True

  restrict(subdomain, dest_map=None)

    Return the restriction of the metric to some subdomain.

    If the restriction has not been defined yet, it is constructed here.

    INPUT:

    - `subdomain` – open subset \(U\) of the metric’s domain (must be an instance of `DifferentiableManifold`)

    - `dest_map` – (default: `None`) destination map \(\Phi:\ U \rightarrow V\), where \(V\) is a subdomain of `self._codomain` (type: `DiffMap`) If `None`, the restriction of `self._vmodule._dest_map` to \(U\) is used.

    OUTPUT:

    - instance of `PseudoRiemannianMetric` representing the restriction.

    EXAMPLES:

    Sage

        sage: M = Manifold(5, 'M')
        sage: g = M.metric('g', signature=3)
        sage: U = M.open_subset('U')
        sage: g.restrict(U)
        Lorentzian metric g on the Open subset U of the
         5-dimensional differentiable manifold M
        sage: g.restrict(U).signature()
        3

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(5), 'M')
        >>> g = M.metric('g', signature=Integer(3))
        >>> U = M.open_subset('U')
        >>> g.restrict(U)
        Lorentzian metric g on the Open subset U of the
         5-dimensional differentiable manifold M
        >>> g.restrict(U).signature()
        3

    See the top documentation of `PseudoRiemannianMetric` for more examples.

  ricci(name=None, latex_name=None)

    Return the Ricci tensor associated with the metric.

    This method is actually a shortcut for `self.connection().ricci()`

    The Ricci tensor is the tensor field \(Ric\) of type (0,2) defined from the Riemann curvature tensor \(R\) by

    \[Ric(u, v) = R(e^i, u, e_i, v)\]

    for any vector fields \(u\) and \(v\), \((e_i)\) being any vector frame and \((e^i)\) the dual coframe.

    INPUT:

    - `name` – (default: `None`) name given to the Ricci tensor; if none, it is set to “Ric(g)”, where “g” is the metric’s name

    - `latex_name` – (default: `None`) LaTeX symbol to denote the Ricci tensor; if none, it is set to “\mathrm{Ric}(g)”, where “g” is the metric’s name

    OUTPUT:

    - the Ricci tensor \(Ric\), as an instance of `TensorField` of tensor type (0,2) and symmetric

    EXAMPLES:

    Ricci tensor of the standard metric on the 2-sphere:

    Sage

        sage: M = Manifold(2, 'S^2', start_index=1)
        sage: U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates)
        sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: a = var('a') # the sphere radius
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2] = a^2, a^2*sin(th)^2
        sage: g.display() # standard metric on the 2-sphere of radius a:
        g = a^2 dth⊗dth + a^2*sin(th)^2 dph⊗dph
        sage: g.ricci()
        Field of symmetric bilinear forms Ric(g) on the Open subset U of
         the 2-dimensional differentiable manifold S^2
        sage: g.ricci()[:]
        [        1         0]
        [        0 sin(th)^2]
        sage: g.ricci() == a^(-2) * g
        True

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'S^2', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates)
        >>> c_spher = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi', names=('th', 'ph',)); (th, ph,) = c_spher._first_ngens(2)
        >>> a = var('a') # the sphere radius
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)] = a**Integer(2), a**Integer(2)*sin(th)**Integer(2)
        >>> g.display() # standard metric on the 2-sphere of radius a:
        g = a^2 dth⊗dth + a^2*sin(th)^2 dph⊗dph
        >>> g.ricci()
        Field of symmetric bilinear forms Ric(g) on the Open subset U of
         the 2-dimensional differentiable manifold S^2
        >>> g.ricci()[:]
        [        1         0]
        [        0 sin(th)^2]
        >>> g.ricci() == a**(-Integer(2)) * g
        True

  ricci_scalar(name=None, latex_name=None)

    Return the Ricci scalar associated with the metric.

    The Ricci scalar is the scalar field \(r\) defined from the Ricci tensor \(Ric\) and the metric tensor \(g\) by

    \[r = g^{ij} Ric_{ij}\]

    INPUT:

    - `name` – (default: `None`) name given to the Ricci scalar; if none, it is set to “r(g)”, where “g” is the metric’s name

    - `latex_name` – (default: `None`) LaTeX symbol to denote the Ricci scalar; if none, it is set to “\mathrm{r}(g)”, where “g” is the metric’s name

    OUTPUT:

    - the Ricci scalar \(r\), as an instance of `DiffScalarField`

    EXAMPLES:

    Ricci scalar of the standard metric on the 2-sphere:

    Sage

        sage: M = Manifold(2, 'S^2', start_index=1)
        sage: U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates)
        sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: a = var('a') # the sphere radius
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2] = a^2, a^2*sin(th)^2
        sage: g.display() # standard metric on the 2-sphere of radius a:
        g = a^2 dth⊗dth + a^2*sin(th)^2 dph⊗dph
        sage: g.ricci_scalar()
        Scalar field r(g) on the Open subset U of the 2-dimensional
         differentiable manifold S^2
        sage: g.ricci_scalar().display() # The Ricci scalar is constant:
        r(g): U → ℝ
           (th, ph) ↦ 2/a^2

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'S^2', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates)
        >>> c_spher = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi', names=('th', 'ph',)); (th, ph,) = c_spher._first_ngens(2)
        >>> a = var('a') # the sphere radius
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)] = a**Integer(2), a**Integer(2)*sin(th)**Integer(2)
        >>> g.display() # standard metric on the 2-sphere of radius a:
        g = a^2 dth⊗dth + a^2*sin(th)^2 dph⊗dph
        >>> g.ricci_scalar()
        Scalar field r(g) on the Open subset U of the 2-dimensional
         differentiable manifold S^2
        >>> g.ricci_scalar().display() # The Ricci scalar is constant:
        r(g): U → ℝ
           (th, ph) ↦ 2/a^2

  riemann(name=None, latex_name=None)

    Return the Riemann curvature tensor associated with the metric.

    This method is actually a shortcut for `self.connection().riemann()`

    The Riemann curvature tensor is the tensor field \(R\) of type (1,3) defined by

    \[R(\omega, u, v, w) = \left\langle \omega, \nabla_u \nabla_v w - \nabla_v \nabla_u w - \nabla_{[u, v]} w \right\rangle\]

    for any 1-form \(\omega\) and any vector fields \(u\), \(v\) and \(w\).

    INPUT:

    - `name` – (default: `None`) name given to the Riemann tensor; if none, it is set to “Riem(g)”, where “g” is the metric’s name

    - `latex_name` – (default: `None`) LaTeX symbol to denote the Riemann tensor; if none, it is set to “\mathrm{Riem}(g)”, where “g” is the metric’s name

    OUTPUT:

    - the Riemann curvature tensor \(R\), as an instance of `TensorField`

    EXAMPLES:

    Riemann tensor of the standard metric on the 2-sphere:

    Sage

        sage: M = Manifold(2, 'S^2', start_index=1)
        sage: U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates)
        sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: a = var('a') # the sphere radius
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2] = a^2, a^2*sin(th)^2
        sage: g.display() # standard metric on the 2-sphere of radius a:
        g = a^2 dth⊗dth + a^2*sin(th)^2 dph⊗dph
        sage: g.riemann()
        Tensor field Riem(g) of type (1,3) on the Open subset U of the
         2-dimensional differentiable manifold S^2
        sage: g.riemann()[:]
        [[[[0, 0], [0, 0]], [[0, sin(th)^2], [-sin(th)^2, 0]]],
         [[[0, -1], [1, 0]], [[0, 0], [0, 0]]]]

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'S^2', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates)
        >>> c_spher = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi', names=('th', 'ph',)); (th, ph,) = c_spher._first_ngens(2)
        >>> a = var('a') # the sphere radius
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)] = a**Integer(2), a**Integer(2)*sin(th)**Integer(2)
        >>> g.display() # standard metric on the 2-sphere of radius a:
        g = a^2 dth⊗dth + a^2*sin(th)^2 dph⊗dph
        >>> g.riemann()
        Tensor field Riem(g) of type (1,3) on the Open subset U of the
         2-dimensional differentiable manifold S^2
        >>> g.riemann()[:]
        [[[[0, 0], [0, 0]], [[0, sin(th)^2], [-sin(th)^2, 0]]],
         [[[0, -1], [1, 0]], [[0, 0], [0, 0]]]]

    In dimension 2, the Riemann tensor can be expressed entirely in terms of the Ricci scalar \(r\):

    \[R^i_{\ \, jlk} = \frac{r}{2} \left( \delta^i_{\ \, k} g_{jl} - \delta^i_{\ \, l} g_{jk} \right)\]

    This formula can be checked here, with the r.h.s. rewritten as \(-r g_{j[k} \delta^i_{\ \, l]}\):

    Sage

        sage: g.riemann() == \
        ....:  -g.ricci_scalar()*(g*U.tangent_identity_field()).antisymmetrize(2,3)
        True

    [Python]

        >>> from sage.all import *
        >>> g.riemann() ==  -g.ricci_scalar()*(g*U.tangent_identity_field()).antisymmetrize(Integer(2),Integer(3))
        True

    Using SymPy as symbolic engine:

    Sage

        sage: M.set_calculus_method('sympy')
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2] = a**2, a**2*sin(th)**2
        sage: g.riemann()[:]
        [[[[0, 0], [0, 0]],
          [[0, sin(2*th)/(2*tan(th)) - cos(2*th)],
           [-sin(2*th)/(2*tan(th)) + cos(2*th), 0]]],
         [[[0, -1], [1, 0]], [[0, 0], [0, 0]]]]

    Python

        >>> from sage.all import *
        >>> M.set_calculus_method('sympy')
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)] = a**Integer(2), a**Integer(2)*sin(th)**Integer(2)
        >>> g.riemann()[:]
        [[[[0, 0], [0, 0]],
          [[0, sin(2*th)/(2*tan(th)) - cos(2*th)],
           [-sin(2*th)/(2*tan(th)) + cos(2*th), 0]]],
         [[[0, -1], [1, 0]], [[0, 0], [0, 0]]]]

  schouten(name=None, latex_name=None)

    Return the Schouten tensor associated with the metric.

    The Schouten tensor is the tensor field \(Sc\) of type (0,2) defined from the Ricci curvature tensor \(Ric\) (see `ricci()`) and the scalar curvature \(r\) (see `ricci_scalar()`) and the metric \(g\) by

    \[Sc(u, v) = \frac{1}{n-2}\left(Ric(u, v) + \frac{r}{2(n-1)}g(u,v) \right)\]

    for any vector fields \(u\) and \(v\).

    INPUT:

    - `name` – (default: `None`) name given to the Schouten tensor; if none, it is set to “Schouten(g)”, where “g” is the metric’s name

    - `latex_name` – (default: `None`) LaTeX symbol to denote the Schouten tensor; if none, it is set to “\mathrm{Schouten}(g)”, where “g” is the metric’s name

    OUTPUT:

    - the Schouten tensor \(Sc\), as an instance of `TensorField` of tensor type (0,2) and symmetric

    EXAMPLES:

    Schouten tensor of the left invariant metric of Heisenberg’s Nil group:

    Sage

        sage: M = Manifold(3, 'Nil', start_index=1)
        sage: X.<x,y,z> = M.chart()
        sage: g = M.riemannian_metric('g')
        sage: g[1,1], g[2,2], g[2,3], g[3,3] = 1, 1+x^2, -x, 1
        sage: g.display()
        g = dx⊗dx + (x^2 + 1) dy⊗dy - x dy⊗dz - x dz⊗dy + dz⊗dz
        sage: g.schouten()
        Field of symmetric bilinear forms Schouten(g) on the 3-dimensional
         differentiable manifold Nil
        sage: g.schouten().display()
        Schouten(g) = -3/8 dx⊗dx + (5/8*x^2 - 3/8) dy⊗dy - 5/8*x dy⊗dz
         - 5/8*x dz⊗dy + 5/8 dz⊗dz

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'Nil', start_index=Integer(1))
        >>> X = M.chart(names=('x', 'y', 'z',)); (x, y, z,) = X._first_ngens(3)
        >>> g = M.riemannian_metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(2),Integer(3)], g[Integer(3),Integer(3)] = Integer(1), Integer(1)+x**Integer(2), -x, Integer(1)
        >>> g.display()
        g = dx⊗dx + (x^2 + 1) dy⊗dy - x dy⊗dz - x dz⊗dy + dz⊗dz
        >>> g.schouten()
        Field of symmetric bilinear forms Schouten(g) on the 3-dimensional
         differentiable manifold Nil
        >>> g.schouten().display()
        Schouten(g) = -3/8 dx⊗dx + (5/8*x^2 - 3/8) dy⊗dy - 5/8*x dy⊗dz
         - 5/8*x dz⊗dy + 5/8 dz⊗dz

  set(symbiform)

    Define the metric from a field of symmetric bilinear forms.

    INPUT:

    - `symbiform` – instance of `TensorField` representing a field of symmetric bilinear forms

    EXAMPLES:

    Metric defined from a field of symmetric bilinear forms on a non-parallelizable 2-dimensional manifold:

    Sage

        sage: M = Manifold(2, 'M')
        sage: U = M.open_subset('U') ; V = M.open_subset('V')
        sage: M.declare_union(U,V)   # M is the union of U and V
        sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
        sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W',
        ....:                              restrictions1= x>0, restrictions2= u+v>0)
        sage: uv_to_xy = xy_to_uv.inverse()
        sage: W = U.intersection(V)
        sage: eU = c_xy.frame() ; eV = c_uv.frame()
        sage: h = M.sym_bilin_form_field(name='h')
        sage: h[eU,0,0], h[eU,0,1], h[eU,1,1] = 1+x, x*y, 1-y
        sage: h.add_comp_by_continuation(eV, W, c_uv)
        sage: h.display(eU)
        h = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-y + 1) dy⊗dy
        sage: h.display(eV)
        h = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv
         + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv
        sage: g = M.metric('g')
        sage: g.set(h)
        sage: g.display(eU)
        g = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-y + 1) dy⊗dy
        sage: g.display(eV)
        g = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv
         + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M')
        >>> U = M.open_subset('U') ; V = M.open_subset('V')
        >>> M.declare_union(U,V)   # M is the union of U and V
        >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2); c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)
        >>> xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W',
        ...                              restrictions1= x>Integer(0), restrictions2= u+v>Integer(0))
        >>> uv_to_xy = xy_to_uv.inverse()
        >>> W = U.intersection(V)
        >>> eU = c_xy.frame() ; eV = c_uv.frame()
        >>> h = M.sym_bilin_form_field(name='h')
        >>> h[eU,Integer(0),Integer(0)], h[eU,Integer(0),Integer(1)], h[eU,Integer(1),Integer(1)] = Integer(1)+x, x*y, Integer(1)-y
        >>> h.add_comp_by_continuation(eV, W, c_uv)
        >>> h.display(eU)
        h = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-y + 1) dy⊗dy
        >>> h.display(eV)
        h = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv
         + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv
        >>> g = M.metric('g')
        >>> g.set(h)
        >>> g.display(eU)
        g = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-y + 1) dy⊗dy
        >>> g.display(eV)
        g = (1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2) du⊗du + 1/4*u du⊗dv
         + 1/4*u dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2) dv⊗dv

  signature()

    Signature of the metric.

    OUTPUT:

    - signature \(S\) of the metric, defined as the integer \(S = n_+ - n_-\), where \(n_+\) (resp. \(n_-\)) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components

    EXAMPLES:

    Signatures on a 2-dimensional manifold:

    Sage

        sage: M = Manifold(2, 'M')
        sage: g = M.metric('g') # if not specified, the signature is Riemannian
        sage: g.signature()
        2
        sage: h = M.metric('h', signature=0)
        sage: h.signature()
        0

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M')
        >>> g = M.metric('g') # if not specified, the signature is Riemannian
        >>> g.signature()
        2
        >>> h = M.metric('h', signature=Integer(0))
        >>> h.signature()
        0

  sqrt_abs_det(frame=None)

    Square root of the absolute value of the determinant of the metric components in the specified frame.

    INPUT:

    - `frame` – (default: `None`) vector frame with respect to which the components \(g_{ij}\) of `self` are defined; if `None`, the domain’s default frame is used. If a chart is provided, the associated coordinate frame is used

    OUTPUT:

    - \(\sqrt{|\det (g_{ij})|}\), as an instance of `DiffScalarField`

    EXAMPLES:

    Standard metric in the Euclidean space \(\RR^3\) with spherical coordinates:

    Sage

        sage: M = Manifold(3, 'M', start_index=1)
        sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        sage: c_spher.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2], g[3,3] = 1, r^2, (r*sin(th))^2
        sage: g.display()
        g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
        sage: g.sqrt_abs_det().expr()
        r^2*sin(th)

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'M', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        >>> c_spher = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi', names=('r', 'th', 'ph',)); (r, th, ph,) = c_spher._first_ngens(3)
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = Integer(1), r**Integer(2), (r*sin(th))**Integer(2)
        >>> g.display()
        g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
        >>> g.sqrt_abs_det().expr()
        r^2*sin(th)

    Metric determinant on a 2-dimensional manifold:

    Sage

        sage: M = Manifold(2, 'M', start_index=1)
        sage: X.<x,y> = M.chart()
        sage: g = M.metric('g')
        sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y
        sage: g[:]
        [ x + 1    x*y]
        [   x*y -y + 1]
        sage: s = g.sqrt_abs_det() ; s
        Scalar field on the 2-dimensional differentiable manifold M
        sage: s.expr()
        sqrt(-x^2*y^2 - (x + 1)*y + x + 1)

    [Python]

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M', start_index=Integer(1))
        >>> X = M.chart(names=('x', 'y',)); (x, y,) = X._first_ngens(2)
        >>> g = M.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(1), Integer(2)], g[Integer(2), Integer(2)] = Integer(1)+x, x*y , Integer(1)-y
        >>> g[:]
        [ x + 1    x*y]
        [   x*y -y + 1]
        >>> s = g.sqrt_abs_det() ; s
        Scalar field on the 2-dimensional differentiable manifold M
        >>> s.expr()
        sqrt(-x^2*y^2 - (x + 1)*y + x + 1)

    Determinant in a frame different from the default’s one:

    Sage

        sage: Y.<u,v> = M.chart()
        sage: ch_X_Y = X.transition_map(Y, [x+y, x-y])
        sage: ch_X_Y.inverse()
        Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y))
        sage: g[Y.frame(),:,Y]
        [ 1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2                            1/4*u]
        [                           1/4*u -1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2]
        sage: g.sqrt_abs_det(Y.frame()).expr()
        1/2*sqrt(abs(x^2*y^2 + (x + 1)*y - x - 1))
        sage: g.sqrt_abs_det(Y.frame()).expr(Y)
        1/8*sqrt(abs(u^4 + v^4 - 2*(u^2 + 2)*v^2 + 4*u^2 - 16*v - 16))

    Python

        >>> from sage.all import *
        >>> Y = M.chart(names=('u', 'v',)); (u, v,) = Y._first_ngens(2)
        >>> ch_X_Y = X.transition_map(Y, [x+y, x-y])
        >>> ch_X_Y.inverse()
        Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y))
        >>> g[Y.frame(),:,Y]
        [ 1/8*u^2 - 1/8*v^2 + 1/4*v + 1/2                            1/4*u]
        [                           1/4*u -1/8*u^2 + 1/8*v^2 + 1/4*v + 1/2]
        >>> g.sqrt_abs_det(Y.frame()).expr()
        1/2*sqrt(abs(x^2*y^2 + (x + 1)*y - x - 1))
        >>> g.sqrt_abs_det(Y.frame()).expr(Y)
        1/8*sqrt(abs(u^4 + v^4 - 2*(u^2 + 2)*v^2 + 4*u^2 - 16*v - 16))

    A chart can be passed instead of a frame:

    Sage

        sage: g.sqrt_abs_det(Y) is g.sqrt_abs_det(Y.frame())
        True

    [Python]

        >>> from sage.all import *
        >>> g.sqrt_abs_det(Y) is g.sqrt_abs_det(Y.frame())
        True

    The metric determinant depends on the frame:

    Sage

        sage: g.sqrt_abs_det(X.frame()) == g.sqrt_abs_det(Y.frame())
        False

    Python

        >>> from sage.all import *
        >>> g.sqrt_abs_det(X.frame()) == g.sqrt_abs_det(Y.frame())
        False

    Using SymPy as symbolic engine:

    Sage

        sage: M.set_calculus_method('sympy')
        sage: g = M.metric('g')
        sage: g[1,1], g[1, 2], g[2, 2] = 1+x, x*y , 1-y
        sage: g.sqrt_abs_det().expr()
        sqrt(-x**2*y**2 - x*y + x - y + 1)
        sage: g.sqrt_abs_det(Y.frame()).expr()
        sqrt(Abs(x**2*y**2 + x*y - x + y - 1))/2
        sage: g.sqrt_abs_det(Y.frame()).expr(Y)
        sqrt(Abs(-u**4 + 2*u**2*v**2 - 4*u**2 - v**4 + 4*v**2 + 16*v + 16))/8

    [Python]

        >>> from sage.all import *
        >>> M.set_calculus_method('sympy')
        >>> g = M.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(1), Integer(2)], g[Integer(2), Integer(2)] = Integer(1)+x, x*y , Integer(1)-y
        >>> g.sqrt_abs_det().expr()
        sqrt(-x**2*y**2 - x*y + x - y + 1)
        >>> g.sqrt_abs_det(Y.frame()).expr()
        sqrt(Abs(x**2*y**2 + x*y - x + y - 1))/2
        >>> g.sqrt_abs_det(Y.frame()).expr(Y)
        sqrt(Abs(-u**4 + 2*u**2*v**2 - 4*u**2 - v**4 + 4*v**2 + 16*v + 16))/8

  volume_form(contra=0)

    Volume form (Levi-Civita tensor) \(\epsilon\) associated with the metric.

    The volume form \(\epsilon\) is an \(n\)-form (\(n\) being the manifold’s dimension) such that for any oriented vector basis \((e_i)\) which is orthonormal with respect to the metric, the condition

    \[\epsilon(e_1,\ldots,e_n) = 1\]

    holds.

    Notice that a volume form requires an orientable manifold with a preferred orientation, see `orientation()` for details.

    INPUT:

    - `contra` – (default: 0) number of contravariant indices of the returned tensor

    OUTPUT:

    - if `contra = 0` (default value): the volume \(n\)-form \(\epsilon\), as an instance of `DiffForm`

    - if `contra = k`, with \(1\leq k \leq n\), the tensor field of type (k,n-k) formed from \(\epsilon\) by raising the first k indices with the metric (see method `up()`); the output is then an instance of `TensorField`, with the appropriate antisymmetries, or of the subclass `MultivectorField` if \(k=n\)

    EXAMPLES:

    Volume form on \(\RR^3\) with spherical coordinates, using the standard orientation, which is predefined:

    Sage

        sage: M = Manifold(3, 'M', start_index=1)
        sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        sage: c_spher.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2], g[3,3] = 1, r^2, (r*sin(th))^2
        sage: g.display()
        g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
        sage: eps = g.volume_form() ; eps
        3-form eps_g on the Open subset U of the 3-dimensional
         differentiable manifold M
        sage: eps.display()
        eps_g = r^2*sin(th) dr∧dth∧dph
        sage: eps[[1,2,3]] == g.sqrt_abs_det()
        True
        sage: latex(eps)
        \epsilon_{g}

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'M', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        >>> c_spher = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi', names=('r', 'th', 'ph',)); (r, th, ph,) = c_spher._first_ngens(3)
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = Integer(1), r**Integer(2), (r*sin(th))**Integer(2)
        >>> g.display()
        g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
        >>> eps = g.volume_form() ; eps
        3-form eps_g on the Open subset U of the 3-dimensional
         differentiable manifold M
        >>> eps.display()
        eps_g = r^2*sin(th) dr∧dth∧dph
        >>> eps[[Integer(1),Integer(2),Integer(3)]] == g.sqrt_abs_det()
        True
        >>> latex(eps)
        \epsilon_{g}

    The tensor field of components \(\epsilon^i_{\ \, jk}\) (`contra=1`):

    Sage

        sage: eps1 = g.volume_form(1) ; eps1
        Tensor field of type (1,2) on the Open subset U of the
         3-dimensional differentiable manifold M
        sage: eps1.symmetries()
        no symmetry;  antisymmetry: (1, 2)
        sage: eps1[:]
        [[[0, 0, 0], [0, 0, r^2*sin(th)], [0, -r^2*sin(th), 0]],
         [[0, 0, -sin(th)], [0, 0, 0], [sin(th), 0, 0]],
         [[0, 1/sin(th), 0], [-1/sin(th), 0, 0], [0, 0, 0]]]

    [Python]

        >>> from sage.all import *
        >>> eps1 = g.volume_form(Integer(1)) ; eps1
        Tensor field of type (1,2) on the Open subset U of the
         3-dimensional differentiable manifold M
        >>> eps1.symmetries()
        no symmetry;  antisymmetry: (1, 2)
        >>> eps1[:]
        [[[0, 0, 0], [0, 0, r^2*sin(th)], [0, -r^2*sin(th), 0]],
         [[0, 0, -sin(th)], [0, 0, 0], [sin(th), 0, 0]],
         [[0, 1/sin(th), 0], [-1/sin(th), 0, 0], [0, 0, 0]]]

    The tensor field of components \(\epsilon^{ij}_{\ \ k}\) (`contra=2`):

    Sage

        sage: eps2 = g.volume_form(2) ; eps2
        Tensor field of type (2,1) on the Open subset U of the
         3-dimensional differentiable manifold M
        sage: eps2.symmetries()
        no symmetry;  antisymmetry: (0, 1)
        sage: eps2[:]
        [[[0, 0, 0], [0, 0, sin(th)], [0, -1/sin(th), 0]],
         [[0, 0, -sin(th)], [0, 0, 0], [1/(r^2*sin(th)), 0, 0]],
         [[0, 1/sin(th), 0], [-1/(r^2*sin(th)), 0, 0], [0, 0, 0]]]

    Python

        >>> from sage.all import *
        >>> eps2 = g.volume_form(Integer(2)) ; eps2
        Tensor field of type (2,1) on the Open subset U of the
         3-dimensional differentiable manifold M
        >>> eps2.symmetries()
        no symmetry;  antisymmetry: (0, 1)
        >>> eps2[:]
        [[[0, 0, 0], [0, 0, sin(th)], [0, -1/sin(th), 0]],
         [[0, 0, -sin(th)], [0, 0, 0], [1/(r^2*sin(th)), 0, 0]],
         [[0, 1/sin(th), 0], [-1/(r^2*sin(th)), 0, 0], [0, 0, 0]]]

    The tensor field of components \(\epsilon^{ijk}\) (`contra=3`):

    Sage

        sage: eps3 = g.volume_form(3) ; eps3
        3-vector field on the Open subset U of the 3-dimensional
         differentiable manifold M
        sage: eps3.tensor_type()
        (3, 0)
        sage: eps3.symmetries()
        no symmetry;  antisymmetry: (0, 1, 2)
        sage: eps3[:]
        [[[0, 0, 0], [0, 0, 1/(r^2*sin(th))], [0, -1/(r^2*sin(th)), 0]],
         [[0, 0, -1/(r^2*sin(th))], [0, 0, 0], [1/(r^2*sin(th)), 0, 0]],
         [[0, 1/(r^2*sin(th)), 0], [-1/(r^2*sin(th)), 0, 0], [0, 0, 0]]]
        sage: eps3[1,2,3]
        1/(r^2*sin(th))
        sage: eps3[[1,2,3]] * g.sqrt_abs_det() == 1
        True

    [Python]

        >>> from sage.all import *
        >>> eps3 = g.volume_form(Integer(3)) ; eps3
        3-vector field on the Open subset U of the 3-dimensional
         differentiable manifold M
        >>> eps3.tensor_type()
        (3, 0)
        >>> eps3.symmetries()
        no symmetry;  antisymmetry: (0, 1, 2)
        >>> eps3[:]
        [[[0, 0, 0], [0, 0, 1/(r^2*sin(th))], [0, -1/(r^2*sin(th)), 0]],
         [[0, 0, -1/(r^2*sin(th))], [0, 0, 0], [1/(r^2*sin(th)), 0, 0]],
         [[0, 1/(r^2*sin(th)), 0], [-1/(r^2*sin(th)), 0, 0], [0, 0, 0]]]
        >>> eps3[Integer(1),Integer(2),Integer(3)]
        1/(r^2*sin(th))
        >>> eps3[[Integer(1),Integer(2),Integer(3)]] * g.sqrt_abs_det() == Integer(1)
        True

    If the manifold has no predefined orientation, an orientation must be set before invoking `volume_form()`. For instance let consider the 2-sphere described by the stereographic charts from the North and South pole:

    Sage

        sage: M = Manifold(2, 'M', structure='Riemannian')
        sage: U = M.open_subset('U'); V = M.open_subset('V')
        sage: M.declare_union(U, V)
        sage: c_xy.<x,y> = U.chart()  # stereographic chart from the North pole
        sage: c_uv.<u,v> = V.chart()  # stereographic chart from the South pole
        sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
        ....:                intersection_name='W', restrictions1= x^2+y^2!=0,
        ....:                restrictions2= u^2+v^2!=0)
        sage: uv_to_xy = xy_to_uv.inverse()
        sage: eU = c_xy.frame(); eV = c_uv.frame()
        sage: g = M.metric()
        sage: g[eU,0,0], g[eU,1,1] = 4/(1+x^2+y^2)^2, 4/(1+x^2+y^2)^2
        sage: g.add_comp_by_continuation(eV, U.intersection(V), chart=c_uv)
        sage: eps = g.volume_form()
        Traceback (most recent call last):
        ...
        ValueError: 2-dimensional Riemannian manifold M must admit an
         orientation

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M', structure='Riemannian')
        >>> U = M.open_subset('U'); V = M.open_subset('V')
        >>> M.declare_union(U, V)
        >>> c_xy = U.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2)# stereographic chart from the North pole
        >>> c_uv = V.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)# stereographic chart from the South pole
        >>> xy_to_uv = c_xy.transition_map(c_uv, (x/(x**Integer(2)+y**Integer(2)), y/(x**Integer(2)+y**Integer(2))),
        ...                intersection_name='W', restrictions1= x**Integer(2)+y**Integer(2)!=Integer(0),
        ...                restrictions2= u**Integer(2)+v**Integer(2)!=Integer(0))
        >>> uv_to_xy = xy_to_uv.inverse()
        >>> eU = c_xy.frame(); eV = c_uv.frame()
        >>> g = M.metric()
        >>> g[eU,Integer(0),Integer(0)], g[eU,Integer(1),Integer(1)] = Integer(4)/(Integer(1)+x**Integer(2)+y**Integer(2))**Integer(2), Integer(4)/(Integer(1)+x**Integer(2)+y**Integer(2))**Integer(2)
        >>> g.add_comp_by_continuation(eV, U.intersection(V), chart=c_uv)
        >>> eps = g.volume_form()
        Traceback (most recent call last):
        ...
        ValueError: 2-dimensional Riemannian manifold M must admit an
         orientation

    Let us define the orientation of `M` such that `eU` is right-handed; `eV` is then left-handed and in order to define an orientation on the whole of `M`, we introduce a vector frame on `V` by swapping `eV`’s vectors:

    Sage

        sage: f = V.vector_frame('f', (eV[1], eV[0]))
        sage: M.set_orientation([eU, f])

    [Python]

        >>> from sage.all import *
        >>> f = V.vector_frame('f', (eV[Integer(1)], eV[Integer(0)]))
        >>> M.set_orientation([eU, f])

    We have then, factorizing the components for a nicer display:

    Sage

        sage: eps = g.volume_form()
        sage: eps.apply_map(factor, frame=eU, keep_other_components=True)
        sage: eps.apply_map(factor, frame=eV, keep_other_components=True)
        sage: eps.display(eU)
        eps_g = 4/(x^2 + y^2 + 1)^2 dx∧dy
        sage: eps.display(eV)
        eps_g = -4/(u^2 + v^2 + 1)^2 du∧dv

    Python

        >>> from sage.all import *
        >>> eps = g.volume_form()
        >>> eps.apply_map(factor, frame=eU, keep_other_components=True)
        >>> eps.apply_map(factor, frame=eV, keep_other_components=True)
        >>> eps.display(eU)
        eps_g = 4/(x^2 + y^2 + 1)^2 dx∧dy
        >>> eps.display(eV)
        eps_g = -4/(u^2 + v^2 + 1)^2 du∧dv

    Note the minus sign in the above expression, reflecting the fact that `eV` is left-handed with respect to the chosen orientation.

  weyl(name=None, latex_name=None)

    Return the Weyl conformal tensor associated with the metric.

    The Weyl conformal tensor is the tensor field \(C\) of type (1,3) defined as the trace-free part of the Riemann curvature tensor \(R\)

    INPUT:

    - `name` – (default: `None`) name given to the Weyl conformal tensor; if `None`, it is set to “C(g)”, where “g” is the metric’s name

    - `latex_name` – (default: `None`) LaTeX symbol to denote the Weyl conformal tensor; if `None`, it is set to “\mathrm{C}(g)”, where “g” is the metric’s name

    OUTPUT:

    - the Weyl conformal tensor \(C\), as an instance of `TensorField`

    EXAMPLES:

    Checking that the Weyl tensor identically vanishes on a 3-dimensional manifold, for instance the hyperbolic space \(H^3\):

    Sage

        sage: M = Manifold(3, 'H^3', start_index=1)
        sage: U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        sage: X.<rh,th,ph> = U.chart(r'rh:(0,+oo):\rho th:(0,pi):\theta  ph:(0,2*pi):\phi')
        sage: g = U.metric('g')
        sage: b = var('b')
        sage: g[1,1], g[2,2], g[3,3] = b^2, (b*sinh(rh))^2, (b*sinh(rh)*sin(th))^2
        sage: g.display()  # standard metric on H^3:
        g = b^2 drh⊗drh + b^2*sinh(rh)^2 dth⊗dth
         + b^2*sin(th)^2*sinh(rh)^2 dph⊗dph
        sage: C = g.weyl() ; C
        Tensor field C(g) of type (1,3) on the Open subset U of the
         3-dimensional differentiable manifold H^3
        sage: C == 0
        True

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(3), 'H^3', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of the half-plane (y=0, x>=0)
        >>> X = U.chart(r'rh:(0,+oo):\rho th:(0,pi):\theta  ph:(0,2*pi):\phi', names=('rh', 'th', 'ph',)); (rh, th, ph,) = X._first_ngens(3)
        >>> g = U.metric('g')
        >>> b = var('b')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)], g[Integer(3),Integer(3)] = b**Integer(2), (b*sinh(rh))**Integer(2), (b*sinh(rh)*sin(th))**Integer(2)
        >>> g.display()  # standard metric on H^3:
        g = b^2 drh⊗drh + b^2*sinh(rh)^2 dth⊗dth
         + b^2*sin(th)^2*sinh(rh)^2 dph⊗dph
        >>> C = g.weyl() ; C
        Tensor field C(g) of type (1,3) on the Open subset U of the
         3-dimensional differentiable manifold H^3
        >>> C == Integer(0)
        True

class sage.manifolds.differentiable.metric.PseudoRiemannianMetricParal(vector_field_module, name, signature=None, latex_name=None)

  Bases: `PseudoRiemannianMetric`, `TensorFieldParal`

  Pseudo-Riemannian metric with values on a parallelizable manifold.

  An instance of this class is a field of nondegenerate symmetric bilinear forms (metric field) along a differentiable manifold \(U\) with values in a parallelizable manifold \(M\) over \(\RR\), via a differentiable mapping \(\Phi: U \rightarrow M\). The standard case of a metric field on a manifold corresponds to \(U=M\) and \(\Phi = \mathrm{Id}_M\). Other common cases are \(\Phi\) being an immersion and \(\Phi\) being a curve in \(M\) (\(U\) is then an open interval of \(\RR\)).

  A metric \(g\) is a field on \(U\), such that at each point \(p\in U\), \(g(p)\) is a bilinear map of the type:

  \[g(p):\ T_q M\times T_q M \longrightarrow \RR\]

  where \(T_q M\) stands for the tangent space to manifold \(M\) at the point \(q=\Phi(p)\), such that \(g(p)\) is symmetric: \(\forall (u,v)\in T_q M\times T_q M, \ g(p)(v,u) = g(p)(u,v)\) and nondegenerate: \((\forall v\in T_q M,\ \ g(p)(u,v) = 0) \Longrightarrow u=0\).

  Note

  If \(M\) is not parallelizable, the class `PseudoRiemannianMetric` should be used instead.

  INPUT:

  - `vector_field_module` – free module \(\mathfrak{X}(U,\Phi)\) of vector fields along \(U\) with values on \(\Phi(U)\subset M\)

  - `name` – name given to the metric

  - `signature` – (default: `None`) signature \(S\) of the metric as a single integer: \(S = n_+ - n_-\), where \(n_+\) (resp. \(n_-\)) is the number of positive terms (resp. number of negative terms) in any diagonal writing of the metric components; if `signature` is `None`, \(S\) is set to the dimension of manifold \(M\) (Riemannian signature)

  - `latex_name` – (default: `None`) LaTeX symbol to denote the metric; if `None`, it is formed from `name`

  EXAMPLES:

  Metric on a 2-dimensional manifold:

  Sage

      sage: M = Manifold(2, 'M', start_index=1)
      sage: c_xy.<x,y> = M.chart()
      sage: g = M.metric('g') ; g
      Riemannian metric g on the 2-dimensional differentiable manifold M
      sage: latex(g)
      g

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(2), 'M', start_index=Integer(1))
      >>> c_xy = M.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2)
      >>> g = M.metric('g') ; g
      Riemannian metric g on the 2-dimensional differentiable manifold M
      >>> latex(g)
      g

  A metric is a special kind of tensor field and therefore inheritates all the properties from class `TensorField`:

  Sage

      sage: g.parent()
      Free module T^(0,2)(M) of type-(0,2) tensors fields on the
       2-dimensional differentiable manifold M
      sage: g.tensor_type()
      (0, 2)
      sage: g.symmetries()  # g is symmetric:
      symmetry: (0, 1);  no antisymmetry

  [Python]

      >>> from sage.all import *
      >>> g.parent()
      Free module T^(0,2)(M) of type-(0,2) tensors fields on the
       2-dimensional differentiable manifold M
      >>> g.tensor_type()
      (0, 2)
      >>> g.symmetries()  # g is symmetric:
      symmetry: (0, 1);  no antisymmetry

  Setting the metric components in the manifold’s default frame:

  Sage

      sage: g[1,1], g[1,2], g[2,2] = 1+x, x*y, 1-x
      sage: g[:]
      [ x + 1    x*y]
      [   x*y -x + 1]
      sage: g.display()
      g = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-x + 1) dy⊗dy

  Python

      >>> from sage.all import *
      >>> g[Integer(1),Integer(1)], g[Integer(1),Integer(2)], g[Integer(2),Integer(2)] = Integer(1)+x, x*y, Integer(1)-x
      >>> g[:]
      [ x + 1    x*y]
      [   x*y -x + 1]
      >>> g.display()
      g = (x + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (-x + 1) dy⊗dy

  Metric components in a frame different from the manifold’s default one:

  Sage

      sage: c_uv.<u,v> = M.chart()  # new chart on M
      sage: xy_to_uv = c_xy.transition_map(c_uv, [x+y, x-y]) ; xy_to_uv
      Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v))
      sage: uv_to_xy = xy_to_uv.inverse() ; uv_to_xy
      Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y))
      sage: M.atlas()
      [Chart (M, (x, y)), Chart (M, (u, v))]
      sage: M.frames()
      [Coordinate frame (M, (∂/∂x,∂/∂y)), Coordinate frame (M, (∂/∂u,∂/∂v))]
      sage: g[c_uv.frame(),:]  # metric components in frame c_uv.frame() expressed in M's default chart (x,y)
      [ 1/2*x*y + 1/2          1/2*x]
      [         1/2*x -1/2*x*y + 1/2]
      sage: g.display(c_uv.frame())
      g = (1/2*x*y + 1/2) du⊗du + 1/2*x du⊗dv + 1/2*x dv⊗du
       + (-1/2*x*y + 1/2) dv⊗dv
      sage: g[c_uv.frame(),:,c_uv]   # metric components in frame c_uv.frame() expressed in chart (u,v)
      [ 1/8*u^2 - 1/8*v^2 + 1/2            1/4*u + 1/4*v]
      [           1/4*u + 1/4*v -1/8*u^2 + 1/8*v^2 + 1/2]
      sage: g.display(c_uv.frame(), c_uv)
      g = (1/8*u^2 - 1/8*v^2 + 1/2) du⊗du + (1/4*u + 1/4*v) du⊗dv
       + (1/4*u + 1/4*v) dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/2) dv⊗dv

  [Python]

      >>> from sage.all import *
      >>> c_uv = M.chart(names=('u', 'v',)); (u, v,) = c_uv._first_ngens(2)# new chart on M
      >>> xy_to_uv = c_xy.transition_map(c_uv, [x+y, x-y]) ; xy_to_uv
      Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v))
      >>> uv_to_xy = xy_to_uv.inverse() ; uv_to_xy
      Change of coordinates from Chart (M, (u, v)) to Chart (M, (x, y))
      >>> M.atlas()
      [Chart (M, (x, y)), Chart (M, (u, v))]
      >>> M.frames()
      [Coordinate frame (M, (∂/∂x,∂/∂y)), Coordinate frame (M, (∂/∂u,∂/∂v))]
      >>> g[c_uv.frame(),:]  # metric components in frame c_uv.frame() expressed in M's default chart (x,y)
      [ 1/2*x*y + 1/2          1/2*x]
      [         1/2*x -1/2*x*y + 1/2]
      >>> g.display(c_uv.frame())
      g = (1/2*x*y + 1/2) du⊗du + 1/2*x du⊗dv + 1/2*x dv⊗du
       + (-1/2*x*y + 1/2) dv⊗dv
      >>> g[c_uv.frame(),:,c_uv]   # metric components in frame c_uv.frame() expressed in chart (u,v)
      [ 1/8*u^2 - 1/8*v^2 + 1/2            1/4*u + 1/4*v]
      [           1/4*u + 1/4*v -1/8*u^2 + 1/8*v^2 + 1/2]
      >>> g.display(c_uv.frame(), c_uv)
      g = (1/8*u^2 - 1/8*v^2 + 1/2) du⊗du + (1/4*u + 1/4*v) du⊗dv
       + (1/4*u + 1/4*v) dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/2) dv⊗dv

  As a shortcut of the above command, on can pass just the chart `c_uv` to `display`, the vector frame being then assumed to be the coordinate frame associated with the chart:

  Sage

      sage: g.display(c_uv)
      g = (1/8*u^2 - 1/8*v^2 + 1/2) du⊗du + (1/4*u + 1/4*v) du⊗dv
       + (1/4*u + 1/4*v) dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/2) dv⊗dv

  Python

      >>> from sage.all import *
      >>> g.display(c_uv)
      g = (1/8*u^2 - 1/8*v^2 + 1/2) du⊗du + (1/4*u + 1/4*v) du⊗dv
       + (1/4*u + 1/4*v) dv⊗du + (-1/8*u^2 + 1/8*v^2 + 1/2) dv⊗dv

  The inverse metric is obtained via `inverse()`:

  Sage

      sage: ig = g.inverse() ; ig
      Tensor field inv_g of type (2,0) on the 2-dimensional differentiable
       manifold M
      sage: ig[:]
      [ (x - 1)/(x^2*y^2 + x^2 - 1)      x*y/(x^2*y^2 + x^2 - 1)]
      [     x*y/(x^2*y^2 + x^2 - 1) -(x + 1)/(x^2*y^2 + x^2 - 1)]
      sage: ig.display()
      inv_g = (x - 1)/(x^2*y^2 + x^2 - 1) ∂/∂x⊗∂/∂x
       + x*y/(x^2*y^2 + x^2 - 1) ∂/∂x⊗∂/∂y + x*y/(x^2*y^2 + x^2 - 1) ∂/∂y⊗∂/∂x
       - (x + 1)/(x^2*y^2 + x^2 - 1) ∂/∂y⊗∂/∂y

  [Python]

      >>> from sage.all import *
      >>> ig = g.inverse() ; ig
      Tensor field inv_g of type (2,0) on the 2-dimensional differentiable
       manifold M
      >>> ig[:]
      [ (x - 1)/(x^2*y^2 + x^2 - 1)      x*y/(x^2*y^2 + x^2 - 1)]
      [     x*y/(x^2*y^2 + x^2 - 1) -(x + 1)/(x^2*y^2 + x^2 - 1)]
      >>> ig.display()
      inv_g = (x - 1)/(x^2*y^2 + x^2 - 1) ∂/∂x⊗∂/∂x
       + x*y/(x^2*y^2 + x^2 - 1) ∂/∂x⊗∂/∂y + x*y/(x^2*y^2 + x^2 - 1) ∂/∂y⊗∂/∂x
       - (x + 1)/(x^2*y^2 + x^2 - 1) ∂/∂y⊗∂/∂y

  inverse(expansion_symbol=None, order=1)

    Return the inverse metric.

    INPUT:

    - `expansion_symbol` – (default: `None`) symbolic variable; if specified, the inverse will be expanded in power series with respect to this variable (around its zero value)

    - `order` – integer (default: 1); the order of the expansion if `expansion_symbol` is not `None`; the order is defined as the degree of the polynomial representing the truncated power series in `expansion_symbol`; currently only first order inverse is supported

    If `expansion_symbol` is set, then the zeroth order metric must be invertible. Moreover, subsequent calls to this method will return a cached value, even when called with the default value (to enable computation of derived quantities). To reset, use `_del_derived()`.

    OUTPUT:

    - instance of `TensorFieldParal` with `tensor_type` = (2,0) representing the inverse metric

    EXAMPLES:

    Inverse metric on a 2-dimensional manifold:

    Sage

        sage: M = Manifold(2, 'M', start_index=1)
        sage: c_xy.<x,y> = M.chart()
        sage: g = M.metric('g')
        sage: g[1,1], g[1,2], g[2,2] = 1+x, x*y, 1-x
        sage: g[:]  # components in the manifold's default frame
        [ x + 1    x*y]
        [   x*y -x + 1]
        sage: ig = g.inverse() ; ig
        Tensor field inv_g of type (2,0) on the 2-dimensional
          differentiable manifold M
        sage: ig[:]
        [ (x - 1)/(x^2*y^2 + x^2 - 1)      x*y/(x^2*y^2 + x^2 - 1)]
        [     x*y/(x^2*y^2 + x^2 - 1) -(x + 1)/(x^2*y^2 + x^2 - 1)]

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M', start_index=Integer(1))
        >>> c_xy = M.chart(names=('x', 'y',)); (x, y,) = c_xy._first_ngens(2)
        >>> g = M.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(1),Integer(2)], g[Integer(2),Integer(2)] = Integer(1)+x, x*y, Integer(1)-x
        >>> g[:]  # components in the manifold's default frame
        [ x + 1    x*y]
        [   x*y -x + 1]
        >>> ig = g.inverse() ; ig
        Tensor field inv_g of type (2,0) on the 2-dimensional
          differentiable manifold M
        >>> ig[:]
        [ (x - 1)/(x^2*y^2 + x^2 - 1)      x*y/(x^2*y^2 + x^2 - 1)]
        [     x*y/(x^2*y^2 + x^2 - 1) -(x + 1)/(x^2*y^2 + x^2 - 1)]

    If the metric is modified, the inverse metric is automatically updated:

    Sage

        sage: g[1,2] = 0 ; g[:]
        [ x + 1      0]
        [     0 -x + 1]
        sage: g.inverse()[:]
        [ 1/(x + 1)          0]
        [         0 -1/(x - 1)]

    [Python]

        >>> from sage.all import *
        >>> g[Integer(1),Integer(2)] = Integer(0) ; g[:]
        [ x + 1      0]
        [     0 -x + 1]
        >>> g.inverse()[:]
        [ 1/(x + 1)          0]
        [         0 -1/(x - 1)]

    Using SymPy as symbolic engine:

    Sage

        sage: M.set_calculus_method('sympy')
        sage: g[1,1], g[1,2], g[2,2] = 1+x, x*y, 1-x
        sage: g[:]  # components in the manifold's default frame
        [x + 1   x*y]
        [  x*y 1 - x]
        sage: g.inverse()[:]
        [ (x - 1)/(x**2*y**2 + x**2 - 1)      x*y/(x**2*y**2 + x**2 - 1)]
        [     x*y/(x**2*y**2 + x**2 - 1) -(x + 1)/(x**2*y**2 + x**2 - 1)]

    Python

        >>> from sage.all import *
        >>> M.set_calculus_method('sympy')
        >>> g[Integer(1),Integer(1)], g[Integer(1),Integer(2)], g[Integer(2),Integer(2)] = Integer(1)+x, x*y, Integer(1)-x
        >>> g[:]  # components in the manifold's default frame
        [x + 1   x*y]
        [  x*y 1 - x]
        >>> g.inverse()[:]
        [ (x - 1)/(x**2*y**2 + x**2 - 1)      x*y/(x**2*y**2 + x**2 - 1)]
        [     x*y/(x**2*y**2 + x**2 - 1) -(x + 1)/(x**2*y**2 + x**2 - 1)]

    Demonstration of the series expansion capabilities:

    Sage

        sage: M = Manifold(4, 'M', structure='Lorentzian')
        sage: C.<t,x,y,z> = M.chart()
        sage: e = var('e')
        sage: g = M.metric()
        sage: h = M.tensor_field(0, 2, sym=(0,1))
        sage: g[0, 0], g[1, 1], g[2, 2], g[3, 3] = -1, 1, 1, 1
        sage: h[0, 1], h[1, 2], h[2, 3] = 1, 1, 1
        sage: g.set(g + e*h)

    [Python]

        >>> from sage.all import *
        >>> M = Manifold(Integer(4), 'M', structure='Lorentzian')
        >>> C = M.chart(names=('t', 'x', 'y', 'z',)); (t, x, y, z,) = C._first_ngens(4)
        >>> e = var('e')
        >>> g = M.metric()
        >>> h = M.tensor_field(Integer(0), Integer(2), sym=(Integer(0),Integer(1)))
        >>> g[Integer(0), Integer(0)], g[Integer(1), Integer(1)], g[Integer(2), Integer(2)], g[Integer(3), Integer(3)] = -Integer(1), Integer(1), Integer(1), Integer(1)
        >>> h[Integer(0), Integer(1)], h[Integer(1), Integer(2)], h[Integer(2), Integer(3)] = Integer(1), Integer(1), Integer(1)
        >>> g.set(g + e*h)

    If `e` is a small parameter, `g` is a tridiagonal approximation of the Minkowski metric:

    Sage

        sage: g[:]
        [-1  e  0  0]
        [ e  1  e  0]
        [ 0  e  1  e]
        [ 0  0  e  1]

    Python

        >>> from sage.all import *
        >>> g[:]
        [-1  e  0  0]
        [ e  1  e  0]
        [ 0  e  1  e]
        [ 0  0  e  1]

    The inverse, truncated to first order in `e`, is:

    Sage

        sage: g.inverse(expansion_symbol=e)[:]
        [-1  e  0  0]
        [ e  1 -e  0]
        [ 0 -e  1 -e]
        [ 0  0 -e  1]

    [Python]

        >>> from sage.all import *
        >>> g.inverse(expansion_symbol=e)[:]
        [-1  e  0  0]
        [ e  1 -e  0]
        [ 0 -e  1 -e]
        [ 0  0 -e  1]

    If `inverse()` is called subsequently, the result will be the same. This allows for all computations to be made to first order:

    Sage

        sage: g.inverse()[:]
        [-1  e  0  0]
        [ e  1 -e  0]
        [ 0 -e  1 -e]
        [ 0  0 -e  1]

    Python

        >>> from sage.all import *
        >>> g.inverse()[:]
        [-1  e  0  0]
        [ e  1 -e  0]
        [ 0 -e  1 -e]
        [ 0  0 -e  1]

  restrict(subdomain, dest_map=None)

    Return the restriction of the metric to some subdomain.

    If the restriction has not been defined yet, it is constructed here.

    INPUT:

    - `subdomain` – open subset \(U\) of `self._domain` (must be an instance of `DifferentiableManifold`)

    - `dest_map` – (default: `None`) destination map \(\Phi:\ U \rightarrow V\), where \(V\) is a subdomain of `self._codomain` (type: `DiffMap`) If `None`, the restriction of `self._vmodule._dest_map` to \(U\) is used.

    OUTPUT:

    - instance of `PseudoRiemannianMetricParal` representing the restriction.

    EXAMPLES:

    Restriction of a Lorentzian metric on \(\RR^2\) to the upper half plane:

    Sage

        sage: M = Manifold(2, 'M')
        sage: X.<x,y> = M.chart()
        sage: g = M.lorentzian_metric('g')
        sage: g[0,0], g[1,1] = -1, 1
        sage: U = M.open_subset('U', coord_def={X: y>0})
        sage: gU = g.restrict(U); gU
        Lorentzian metric g on the Open subset U of the 2-dimensional
         differentiable manifold M
        sage: gU.signature()
        0
        sage: gU.display()
        g = -dx⊗dx + dy⊗dy

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M')
        >>> X = M.chart(names=('x', 'y',)); (x, y,) = X._first_ngens(2)
        >>> g = M.lorentzian_metric('g')
        >>> g[Integer(0),Integer(0)], g[Integer(1),Integer(1)] = -Integer(1), Integer(1)
        >>> U = M.open_subset('U', coord_def={X: y>Integer(0)})
        >>> gU = g.restrict(U); gU
        Lorentzian metric g on the Open subset U of the 2-dimensional
         differentiable manifold M
        >>> gU.signature()
        0
        >>> gU.display()
        g = -dx⊗dx + dy⊗dy

  ricci_scalar(name=None, latex_name=None)

    Return the metric’s Ricci scalar.

    The Ricci scalar is the scalar field \(r\) defined from the Ricci tensor \(Ric\) and the metric tensor \(g\) by

    \[r = g^{ij} Ric_{ij}\]

    INPUT:

    - `name` – (default: `None`) name given to the Ricci scalar; if none, it is set to “r(g)”, where “g” is the metric’s name

    - `latex_name` – (default: `None`) LaTeX symbol to denote the Ricci scalar; if none, it is set to “\mathrm{r}(g)”, where “g” is the metric’s name

    OUTPUT:

    - the Ricci scalar \(r\), as an instance of `DiffScalarField`

    EXAMPLES:

    Ricci scalar of the standard metric on the 2-sphere:

    Sage

        sage: M = Manifold(2, 'S^2', start_index=1)
        sage: U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates)
        sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
        sage: a = var('a') # the sphere radius
        sage: g = U.metric('g')
        sage: g[1,1], g[2,2] = a^2, a^2*sin(th)^2
        sage: g.display() # standard metric on the 2-sphere of radius a:
        g = a^2 dth⊗dth + a^2*sin(th)^2 dph⊗dph
        sage: g.ricci_scalar()
        Scalar field r(g) on the Open subset U of the 2-dimensional
         differentiable manifold S^2
        sage: g.ricci_scalar().display() # The Ricci scalar is constant:
        r(g): U → ℝ
           (th, ph) ↦ 2/a^2

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'S^2', start_index=Integer(1))
        >>> U = M.open_subset('U') # the complement of a meridian (domain of spherical coordinates)
        >>> c_spher = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi', names=('th', 'ph',)); (th, ph,) = c_spher._first_ngens(2)
        >>> a = var('a') # the sphere radius
        >>> g = U.metric('g')
        >>> g[Integer(1),Integer(1)], g[Integer(2),Integer(2)] = a**Integer(2), a**Integer(2)*sin(th)**Integer(2)
        >>> g.display() # standard metric on the 2-sphere of radius a:
        g = a^2 dth⊗dth + a^2*sin(th)^2 dph⊗dph
        >>> g.ricci_scalar()
        Scalar field r(g) on the Open subset U of the 2-dimensional
         differentiable manifold S^2
        >>> g.ricci_scalar().display() # The Ricci scalar is constant:
        r(g): U → ℝ
           (th, ph) ↦ 2/a^2

  set(symbiform)

    Define the metric from a field of symmetric bilinear forms.

    INPUT:

    - `symbiform` – instance of `TensorFieldParal` representing a field of symmetric bilinear forms

    EXAMPLES:

    Sage

        sage: M = Manifold(2, 'M')
        sage: X.<x,y> = M.chart()
        sage: s = M.sym_bilin_form_field(name='s')
        sage: s[0,0], s[0,1], s[1,1] = 1+x^2, x*y, 1+y^2
        sage: g = M.metric('g')
        sage: g.set(s)
        sage: g.display()
        g = (x^2 + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (y^2 + 1) dy⊗dy

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M')
        >>> X = M.chart(names=('x', 'y',)); (x, y,) = X._first_ngens(2)
        >>> s = M.sym_bilin_form_field(name='s')
        >>> s[Integer(0),Integer(0)], s[Integer(0),Integer(1)], s[Integer(1),Integer(1)] = Integer(1)+x**Integer(2), x*y, Integer(1)+y**Integer(2)
        >>> g = M.metric('g')
        >>> g.set(s)
        >>> g.display()
        g = (x^2 + 1) dx⊗dx + x*y dx⊗dy + x*y dy⊗dx + (y^2 + 1) dy⊗dy