Characteristic cohomology classes - Manifolds

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

# Characteristic cohomology classes

A characteristic class \(\kappa\) is a natural transformation that associates with each vector bundle \(E \to M\) a cohomology class \(\kappa(E) \in H^*(M;R)\) such that for any continuous map \(f\colon N \to M\) from another topological manifold \(N\), the naturality condition is satisfied:

\[f^*\kappa(E) = \kappa(f^* E) \in H^*(N;R)\]

The cohomology class \(\kappa(E)\) is called characteristic cohomology class. Roughly speaking, characteristic cohomology classes measure the non-triviality of vector bundles.

One way to obtain and compute characteristic classes in the de Rham cohomology with coefficients in the ring \(\CC\) is via the so-called Chern-Weil theory using the curvature of a differentiable vector bundle.

For that let \(\nabla\) be a connection on \(E\), \(e\) a local frame on \(E\) and \(\Omega\) be the corresponding curvature matrix (see: `curvature_form()`).

Namely, if \(P: \mathrm{Mat}_{n \times n}(\CC) \to \CC\) is an invariant polynomial, the object

\[\left[ P \left( \Omega \right) \right] \in H^{2*}_{\mathrm{dR}}(M, \CC)\]

is well-defined, independent of the choice of \(\nabla\) (the proof can be found in [Roe1988] pp. 31) and fulfills the naturality condition. This is the foundation of the Chern-Weil theory and the following definitions.

Note

This documentation is rich of examples, but sparse in explanations. Please consult the references for more details.

AUTHORS:

- Michael Jung (2019) : initial version

- Michael Jung (2021) : new algorithm; complete refactoring

REFERENCES:

- [Mil1974]

- [Roe1988]

## Contents

We consider the following three types of classes:

- Additive Classes

- Multiplicative Classes

- Pfaffian Classes

## Additive Classes

In the complex case, let \(f\) be a holomorphic function around zero. Then we call

\[\left[\mathrm{tr}\left( f\left( \frac{\Omega}{2 \pi i} \right) \right)\right] \in H^{2*}_{\mathrm{dR}}(M, \CC)\]

the additive characteristic class associated to \(f\) of the complex vector bundle \(E\).

Important and predefined additive classes are:

- Chern Character with \(f(x) = \exp(x)\)

In the real case, let \(g\) be a holomorphic function around zero with \(g(0)=0\). Then we call

\[\left[\mathrm{tr}\left( \frac{1}{2} g\left( -\frac{\Omega^2}{4 \pi^2} \right) \right)\right] \in H^{4*}_{\mathrm{dR}}(M, \CC)\]

the additive characteristic class associated to \(g\) of the real vector bundle \(E\).

EXAMPLES:

Consider the Chern character on some 2-dimensional spacetime:

Sage

    sage: M = Manifold(2, 'M', structure='Lorentzian')
    sage: X.<t,x> = M.chart()
    sage: E = M.vector_bundle(1, 'E', field='complex'); E
    Differentiable complex vector bundle E -> M of rank 1 over the base space
     2-dimensional Lorentzian manifold M
    sage: e = E.local_frame('e')

Python

    >>> from sage.all import *
    >>> M = Manifold(Integer(2), 'M', structure='Lorentzian')
    >>> X = M.chart(names=('t', 'x',)); (t, x,) = X._first_ngens(2)
    >>> E = M.vector_bundle(Integer(1), 'E', field='complex'); E
    Differentiable complex vector bundle E -> M of rank 1 over the base space
     2-dimensional Lorentzian manifold M
    >>> e = E.local_frame('e')

Let us define the connection \(\nabla^E\) in terms of an electro-magnetic potential \(A(t)\):

Sage

    sage: nab = E.bundle_connection('nabla^E', latex_name=r'\nabla^E')
    sage: omega = M.one_form(name='omega')
    sage: A = function('A')
    sage: nab.set_connection_form(0, 0)[1] = I*A(t)
    sage: nab[0, 0].display()
    connection (0,0) of bundle connection nabla^E w.r.t. Local frame
     (E|_M, (e_0)) = I*A(t) dx
    sage: nab.set_immutable()

[Python]

    >>> from sage.all import *
    >>> nab = E.bundle_connection('nabla^E', latex_name=r'\nabla^E')
    >>> omega = M.one_form(name='omega')
    >>> A = function('A')
    >>> nab.set_connection_form(Integer(0), Integer(0))[Integer(1)] = I*A(t)
    >>> nab[Integer(0), Integer(0)].display()
    connection (0,0) of bundle connection nabla^E w.r.t. Local frame
     (E|_M, (e_0)) = I*A(t) dx
    >>> nab.set_immutable()

The Chern character is then given by:

Sage

    sage: ch = E.characteristic_cohomology_class('ChernChar'); ch
    Characteristic cohomology class ch(E) of the Differentiable complex vector
     bundle E -> M of rank 1 over the base space 2-dimensional Lorentzian
     manifold M

Python

    >>> from sage.all import *
    >>> ch = E.characteristic_cohomology_class('ChernChar'); ch
    Characteristic cohomology class ch(E) of the Differentiable complex vector
     bundle E -> M of rank 1 over the base space 2-dimensional Lorentzian
     manifold M

The corresponding characteristic form w.r.t. the bundle connection can be obtained via `get_form()`:

Sage

    sage: ch_form = ch.get_form(nab); ch_form.display_expansion()
    ch(E, nabla^E) = 1 + 1/2*d(A)/dt/pi dt∧dx

[Python]

    >>> from sage.all import *
    >>> ch_form = ch.get_form(nab); ch_form.display_expansion()
    ch(E, nabla^E) = 1 + 1/2*d(A)/dt/pi dt∧dx

## Multiplicative Classes

In the complex case, let \(f\) be a holomorphic function around zero. Then we call

\[\left[\det\left( f\left( \frac{\Omega}{2 \pi i} \right) \right)\right] \in H^{2*}_{\mathrm{dR}}(M, \CC)\]

the multiplicative characteristic class associated to \(f\) of the complex vector bundle \(E\).

Important and predefined multiplicative classes on complex vector bundles are:

- Chern class with \(f(x) = 1+x\)

- Todd class with \(f(x) = \frac{x}{1-\exp(-x)}\)

In the real case, let \(g\) be a holomorphic function around zero with \(g(0)=1\). Then we call

\[\left[\det\left( \sqrt{ g \left( -\frac{\Omega^2}{4 \pi^2} \right) } \right) \right] \in H^{4*}_{\mathrm{dR}}(M, \CC)\]

the multiplicative characteristic class associated to \(g\) on the real vector bundle \(E\).

Important and predefined multiplicative classes on real vector bundles are:

- Pontryagin class with \(g(x) = 1+x\)

- \(\hat{A}\) class with \(g(x) = \frac{\sqrt{x}/2}{\sinh(\sqrt{x}/2)}\)

- Hirzebruch class with \(g(x) = \frac{\sqrt{x}}{\tanh(\sqrt{x})}\)

EXAMPLES:

We consider the Chern class of the tautological line bundle \(\gamma^1\) over \(\CC\mathbf{P}^1\):

Sage

    sage: M = Manifold(2, 'CP^1', start_index=1)
    sage: U = M.open_subset('U')
    sage: c_cart.<x,y> = U.chart() # homogeneous coordinates in real terms
    sage: c_comp.<z, zbar> = U.chart(r'z:z zbar:\bar{z}') # complexification
    sage: cart_to_comp = c_cart.transition_map(c_comp, (x+I*y, x-I*y))
    sage: comp_to_cart = cart_to_comp.inverse()
    sage: E = M.vector_bundle(1, 'gamma^1', field='complex')
    sage: e = E.local_frame('e', domain=U)

Python

    >>> from sage.all import *
    >>> M = Manifold(Integer(2), 'CP^1', start_index=Integer(1))
    >>> U = M.open_subset('U')
    >>> c_cart = U.chart(names=('x', 'y',)); (x, y,) = c_cart._first_ngens(2)# homogeneous coordinates in real terms
    >>> c_comp = U.chart(r'z:z zbar:\bar{z}', names=('z', 'zbar',)); (z, zbar,) = c_comp._first_ngens(2)# complexification
    >>> cart_to_comp = c_cart.transition_map(c_comp, (x+I*y, x-I*y))
    >>> comp_to_cart = cart_to_comp.inverse()
    >>> E = M.vector_bundle(Integer(1), 'gamma^1', field='complex')
    >>> e = E.local_frame('e', domain=U)

To apply the Chern-Weil approach, we need a bundle connection in terms of a connection one form. To achieve this, we take the connection induced from the hermitian metric on the trivial bundle \(\CC^2 \times \CC\mathbf{P}^1 \supset \gamma^1\). In this the frame \(e\) corresponds to the section \([z:1] \mapsto (z,1)\) and its magnitude-squared is given by \(1+|z|^2\):

Sage

    sage: nab = E.bundle_connection('nabla')
    sage: omega = U.one_form(name='omega')
    sage: omega[c_comp.frame(),1,c_comp] = zbar/(1+z*zbar)
    sage: nab[e, 1, 1] = omega
    sage: nab.set_immutable()

[Python]

    >>> from sage.all import *
    >>> nab = E.bundle_connection('nabla')
    >>> omega = U.one_form(name='omega')
    >>> omega[c_comp.frame(),Integer(1),c_comp] = zbar/(Integer(1)+z*zbar)
    >>> nab[e, Integer(1), Integer(1)] = omega
    >>> nab.set_immutable()

Now, the Chern class can be constructed:

Sage

    sage: c = E.characteristic_cohomology_class('Chern'); c
    Characteristic cohomology class c(gamma^1) of the Differentiable complex
     vector bundle gamma^1 -> CP^1 of rank 1 over the base space 2-dimensional
     differentiable manifold CP^1
    sage: c_form = c.get_form(nab)
    sage: c_form.display_expansion(c_comp.frame(), chart=c_comp)
    c(gamma^1, nabla) = 1 + 1/2*I/(pi + pi*z^2*zbar^2 + 2*pi*z*zbar) dz∧dzbar

Python

    >>> from sage.all import *
    >>> c = E.characteristic_cohomology_class('Chern'); c
    Characteristic cohomology class c(gamma^1) of the Differentiable complex
     vector bundle gamma^1 -> CP^1 of rank 1 over the base space 2-dimensional
     differentiable manifold CP^1
    >>> c_form = c.get_form(nab)
    >>> c_form.display_expansion(c_comp.frame(), chart=c_comp)
    c(gamma^1, nabla) = 1 + 1/2*I/(pi + pi*z^2*zbar^2 + 2*pi*z*zbar) dz∧dzbar

Since \(U\) and \(\CC\mathbf{P}^1\) differ only by a point and therefore a null set, it is enough to integrate the top form over the domain \(U\):

Sage

    sage: integrate(integrate(c_form[2][[1,2]].expr(c_cart), x, -infinity, infinity).full_simplify(),
    ....:           y, -infinity, infinity)
    1

[Python]

    >>> from sage.all import *
    >>> integrate(integrate(c_form[Integer(2)][[Integer(1),Integer(2)]].expr(c_cart), x, -infinity, infinity).full_simplify(),
    ...           y, -infinity, infinity)
    1

The result shows that \(c_1(\gamma^1)\) generates the second integer cohomology of \(\CC\mathbf{P}^1\).

## Pfaffian Classes

Usually, there is no such thing as “Pfaffian classes” in literature. However, using the matrix’ Pfaffian and inspired by the aforementioned definitions, such classes can be defined as follows.

Let \(E\) be a real vector bundle of rank \(2n\) and \(f\) an odd real function being analytic at zero. Furthermore, let \(\Omega\) be skew-symmetric, which certainly will be true if \(\nabla\) is metric and \(e\) is orthonormal. Then we call

\[\left[\mathrm{Pf}\left( f\left( \frac{\Omega}{2 \pi} \right) \right)\right] \in H^{2n*}(M,\RR)\]

the Pfaffian class associated to f.

The most important Pfaffian class is the Euler class which is simply given by \(f(x)=x\).

EXAMPLES:

We consider the Euler class of \(S^2\):

Sage

    sage: M.<x,y> = manifolds.Sphere(2, coordinates='stereographic')
    sage: TM = M.tangent_bundle()
    sage: e_class = TM.characteristic_cohomology_class('Euler'); e_class
    Characteristic cohomology class e(TS^2) of the Tangent bundle TS^2 over the
     2-sphere S^2 of radius 1 smoothly embedded in the Euclidean space E^3

Python

    >>> from sage.all import *
    >>> M = manifolds.Sphere(Integer(2), coordinates='stereographic', names=('x', 'y',)); (x, y,) = M._first_ngens(2)
    >>> TM = M.tangent_bundle()
    >>> e_class = TM.characteristic_cohomology_class('Euler'); e_class
    Characteristic cohomology class e(TS^2) of the Tangent bundle TS^2 over the
     2-sphere S^2 of radius 1 smoothly embedded in the Euclidean space E^3

To compute a particular representative of the Euler class, we need to determine a connection, which is in this case given by the standard metric:

Sage

    sage: g = M.metric('g') # standard metric on S2, long time
    sage: nab = g.connection() # long time
    sage: nab.set_immutable() # long time

[Python]

    >>> from sage.all import *
    >>> g = M.metric('g') # standard metric on S2, long time
    >>> nab = g.connection() # long time
    >>> nab.set_immutable() # long time

Now the representative of the Euler class with respect to the connection \(\nabla_g\) induced by the standard metric can be computed:

Sage

    sage: e_class_form = e_class.get_form(nab) # long time
    sage: e_class_form.display_expansion() # long time
    e(TS^2, nabla_g) = 2/(pi + pi*x^4 + pi*y^4 + 2*pi*x^2 + 2*(pi + pi*x^2)*y^2) dx∧dy

Python

    >>> from sage.all import *
    >>> e_class_form = e_class.get_form(nab) # long time
    >>> e_class_form.display_expansion() # long time
    e(TS^2, nabla_g) = 2/(pi + pi*x^4 + pi*y^4 + 2*pi*x^2 + 2*(pi + pi*x^2)*y^2) dx∧dy

Let us check whether this form represents the Euler class correctly:

Sage

    sage: # long time
    sage: expr = e_class_form[2][[1,2]].expr()
    sage: expr = integrate(expr, x, -infinity, infinity)
    sage: expr = expr.simplify_full()
    sage: integrate(expr, y, -infinity, infinity)
    2

[Python]

    >>> from sage.all import *
    >>> # long time
    >>> expr = e_class_form[Integer(2)][[Integer(1),Integer(2)]].expr()
    >>> expr = integrate(expr, x, -infinity, infinity)
    >>> expr = expr.simplify_full()
    >>> integrate(expr, y, -infinity, infinity)
    2

As we can see, the integral coincides with the Euler characteristic of \(S^2\) so that our form actually represents the Euler class appropriately.

class sage.manifolds.differentiable.characteristic_cohomology_class.Algorithm_generic

  Bases: `SageObject`

  Abstract algorithm class to compute the characteristic forms of the generators.

  EXAMPLES:

  Sage

      sage: from sage.manifolds.differentiable.characteristic_cohomology_class import Algorithm_generic
      sage: algorithm = Algorithm_generic()
      sage: algorithm.get
      Cached version of <function Algorithm_generic.get at 0x...>
      sage: algorithm.get_local
      Traceback (most recent call last):
      ...
      NotImplementedError: <abstract method get_local at 0x...>
      sage: algorithm.get_gen_pow
      Cached version of <function Algorithm_generic.get_gen_pow at 0x...>

  Python

      >>> from sage.all import *
      >>> from sage.manifolds.differentiable.characteristic_cohomology_class import Algorithm_generic
      >>> algorithm = Algorithm_generic()
      >>> algorithm.get
      Cached version of <function Algorithm_generic.get at 0x...>
      >>> algorithm.get_local
      Traceback (most recent call last):
      ...
      NotImplementedError: <abstract method get_local at 0x...>
      >>> algorithm.get_gen_pow
      Cached version of <function Algorithm_generic.get_gen_pow at 0x...>

  get(nab)

    Return the global characteristic forms of the generators w.r.t. a given connection.

    The result is cached.

    OUTPUT:

    - a list containing the generator’s global characteristic forms as instances of `sage.manifolds.differentiable.diff_form.DiffForm`

    EXAMPLES:

    Sage

        sage: M = manifolds.EuclideanSpace(4)
        sage: TM = M.tangent_bundle()
        sage: g = M.metric()
        sage: nab = g.connection()
        sage: nab.set_immutable()

    Python

        >>> from sage.all import *
        >>> M = manifolds.EuclideanSpace(Integer(4))
        >>> TM = M.tangent_bundle()
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> nab.set_immutable()

    Sage

        sage: p = TM.characteristic_cohomology_class('Pontryagin')
        sage: p_form = p.get_form(nab); p_form # long time
        Mixed differential form p(TE^4, nabla_g) on the 4-dimensional
         Euclidean space E^4
        sage: p_form.display_expansion() # long time
        p(TE^4, nabla_g) = 1

    [Python]

        >>> from sage.all import *
        >>> p = TM.characteristic_cohomology_class('Pontryagin')
        >>> p_form = p.get_form(nab); p_form # long time
        Mixed differential form p(TE^4, nabla_g) on the 4-dimensional
         Euclidean space E^4
        >>> p_form.display_expansion() # long time
        p(TE^4, nabla_g) = 1

  get_gen_pow(nab, i, n)

    Return the \(n\)-th power of the \(i\)-th generator’s characteristic form w.r.t `nab`.

    The result is cached.

    EXAMPLES:

    Sage

        sage: M = manifolds.EuclideanSpace(8)
        sage: TM = M.tangent_bundle()
        sage: g = M.metric()
        sage: nab = g.connection()
        sage: nab.set_immutable()

    Python

        >>> from sage.all import *
        >>> M = manifolds.EuclideanSpace(Integer(8))
        >>> TM = M.tangent_bundle()
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> nab.set_immutable()

    Sage

        sage: A = TM.characteristic_cohomology_class('AHat')
        sage: A_form = A.get_form(nab); A_form  # long time
        Mixed differential form A^(TE^8, nabla_g) on the 8-dimensional
         Euclidean space E^8
        sage: A_form.display_expansion()  # long time
        A^(TE^8, nabla_g) = 1

    [Python]

        >>> from sage.all import *
        >>> A = TM.characteristic_cohomology_class('AHat')
        >>> A_form = A.get_form(nab); A_form  # long time
        Mixed differential form A^(TE^8, nabla_g) on the 8-dimensional
         Euclidean space E^8
        >>> A_form.display_expansion()  # long time
        A^(TE^8, nabla_g) = 1

  get_local(cmat)

    Abstract method to get the local forms of the generators w.r.t. a given curvature form matrix `cmat`.

    OUTPUT: list containing the generator’s local characteristic forms

    ALGORITHM:

    The inherited class determines the algorithm.

    EXAMPLES:

    4-dimensional Euclidean space:

    Sage

        sage: M = manifolds.EuclideanSpace(4)
        sage: TM = M.tangent_bundle()
        sage: g = M.metric()
        sage: nab = g.connection()
        sage: e = M.frames()[0]  # select standard frame
        sage: cmat = [ [nab.curvature_form(i, j, e)  # long time
        ....:           for j in TM.irange()]
        ....:         for i in TM.irange()]

    Python

        >>> from sage.all import *
        >>> M = manifolds.EuclideanSpace(Integer(4))
        >>> TM = M.tangent_bundle()
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> e = M.frames()[Integer(0)]  # select standard frame
        >>> cmat = [ [nab.curvature_form(i, j, e)  # long time
        ...           for j in TM.irange()]
        ...         for i in TM.irange()]

    Import the algorithm:

    Sage

        sage: from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginAlgorithm
        sage: algorithm = PontryaginAlgorithm()
        sage: [p1] = algorithm.get_local(cmat) # long time
        sage: p1.display() # long time
        0

    [Python]

        >>> from sage.all import *
        >>> from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginAlgorithm
        >>> algorithm = PontryaginAlgorithm()
        >>> [p1] = algorithm.get_local(cmat) # long time
        >>> p1.display() # long time
        0

    A concrete implementation is given by a `sage.misc.fast_methods.Singleton`:

    Sage

        sage: algorithm is PontryaginAlgorithm()
        True

    Python

        >>> from sage.all import *
        >>> algorithm is PontryaginAlgorithm()
        True

class sage.manifolds.differentiable.characteristic_cohomology_class.CharacteristicCohomologyClassRing(base, vbundle)

  Bases: `FiniteGCAlgebra`

  Characteristic cohomology class ring.

  Let \(E \to M\) be a real or complex vector bundle of rank \(k\) and \(R\) be a torsion-free subring of \(\CC\).

  Let \(BG\) be the classifying space of the group \(G\). As for vector bundles, we consider

  - \(G = O(k)\) if \(E\) is real,

  - \(G = SO(k)\) if \(E\) is real and oriented,

  - \(G = U(k)\) if \(E\) is complex.

  The cohomology ring \(H^*(BG; R)\) can be explicitly expressed for the aforementioned cases:

  \[\begin{split}H^*(BG; R) \cong \begin{cases} R[c_1, \ldots c_k] & \text{if } G = U(k), \\ R[p_1, \ldots p_{\lfloor \frac{k}{2}\rfloor}] & \text{if } G = O(k), \\ R[p_1, \ldots p_k, e] \big/ (p_k-e^2) & \text{if } G = SO(2k), \\ R[p_1, \ldots p_k, e] & \text{if } G = SO(2k+1). \\ \end{cases}\end{split}\]

  The Chern-Weil homomorphism relates the generators in the de Rham cohomology as follows. If \(\Omega\) is a curvature form matrix on \(E\), for the Chern classes we get

  \[\left[ \det\left( 1 + \frac{t \Omega}{2 \pi i} \right) \right] = 1 + \sum^k_{n=1} c_n(E) t^n,\]

  for the Pontryagin classes we have

  \[\left[ \det\left( 1 - \frac{t \Omega}{2 \pi} \right) \right] = 1 + \sum^{\lfloor\frac{k}{2} \rfloor}_{n=1} p_n(E) t^n,\]

  and for the Euler class we obtain

  \[\left[ \mathrm{Pf}\left(\frac{\Omega}{2 \pi} \right) \right] = e(E).\]

  Consequently, the cohomology ring \(H^*(BG; R)\) is mapped (not necessarily injectively) to a subring of \(H^*_\mathrm{dR}(M, \CC)\) via the Chern-Weil homomorphism. This implementation attempts to represent this subring.

  Note

  Some generators might have torsion in \(H^*(BG; R)\) giving a zero element in the de Rham cohomology. Those generators are still considered in the implementation. Generators whose degree exceed the dimension of the base space, however, are ignored.

  INPUT:

  - `base` – base ring

  - `vbundle` – vector bundle

  EXAMPLES:

  Characteristic cohomology class ring over the tangent bundle of an 8-dimensional manifold:

  Sage

      sage: M = Manifold(8, 'M')
      sage: TM = M.tangent_bundle()
      sage: CR = TM.characteristic_cohomology_class_ring(); CR
      Algebra of characteristic cohomology classes of the Tangent bundle TM
       over the 8-dimensional differentiable manifold M
      sage: CR.gens()
      (Characteristic cohomology class (p_1)(TM) of the Tangent bundle TM over
       the 8-dimensional differentiable manifold M,
       Characteristic cohomology class (p_2)(TM) of the Tangent bundle TM
       over the 8-dimensional differentiable manifold M)

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(8), 'M')
      >>> TM = M.tangent_bundle()
      >>> CR = TM.characteristic_cohomology_class_ring(); CR
      Algebra of characteristic cohomology classes of the Tangent bundle TM
       over the 8-dimensional differentiable manifold M
      >>> CR.gens()
      (Characteristic cohomology class (p_1)(TM) of the Tangent bundle TM over
       the 8-dimensional differentiable manifold M,
       Characteristic cohomology class (p_2)(TM) of the Tangent bundle TM
       over the 8-dimensional differentiable manifold M)

  The default base ring is \(\QQ\):

  Sage

      sage: CR.base_ring()
      Rational Field

  [Python]

      >>> from sage.all import *
      >>> CR.base_ring()
      Rational Field

  Characteristic cohomology class ring over a complex vector bundle:

  Sage

      sage: M = Manifold(4, 'M')
      sage: E = M.vector_bundle(2, 'E', field='complex')
      sage: CR_E = E.characteristic_cohomology_class_ring(); CR_E
      Algebra of characteristic cohomology classes of the Differentiable
       complex vector bundle E -> M of rank 2 over the base space
       4-dimensional differentiable manifold M
      sage: CR_E.gens()
      (Characteristic cohomology class (c_1)(E) of the Differentiable complex
       vector bundle E -> M of rank 2 over the base space 4-dimensional
       differentiable manifold M,
       Characteristic cohomology class (c_2)(E) of the Differentiable
       complex vector bundle E -> M of rank 2 over the base space
       4-dimensional differentiable manifold M)

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(4), 'M')
      >>> E = M.vector_bundle(Integer(2), 'E', field='complex')
      >>> CR_E = E.characteristic_cohomology_class_ring(); CR_E
      Algebra of characteristic cohomology classes of the Differentiable
       complex vector bundle E -> M of rank 2 over the base space
       4-dimensional differentiable manifold M
      >>> CR_E.gens()
      (Characteristic cohomology class (c_1)(E) of the Differentiable complex
       vector bundle E -> M of rank 2 over the base space 4-dimensional
       differentiable manifold M,
       Characteristic cohomology class (c_2)(E) of the Differentiable
       complex vector bundle E -> M of rank 2 over the base space
       4-dimensional differentiable manifold M)

  Characteristic cohomology class ring over an oriented manifold:

  Sage

      sage: S2 = manifolds.Sphere(2, coordinates='stereographic')
      sage: TS2 = S2.tangent_bundle()
      sage: S2.has_orientation()
      True
      sage: CR = TS2.characteristic_cohomology_class_ring()
      sage: CR.gens()
      (Characteristic cohomology class (e)(TS^2) of the Tangent bundle TS^2
       over the 2-sphere S^2 of radius 1 smoothly embedded in the Euclidean
       space E^3,)

  [Python]

      >>> from sage.all import *
      >>> S2 = manifolds.Sphere(Integer(2), coordinates='stereographic')
      >>> TS2 = S2.tangent_bundle()
      >>> S2.has_orientation()
      True
      >>> CR = TS2.characteristic_cohomology_class_ring()
      >>> CR.gens()
      (Characteristic cohomology class (e)(TS^2) of the Tangent bundle TS^2
       over the 2-sphere S^2 of radius 1 smoothly embedded in the Euclidean
       space E^3,)

  Element

    alias of `CharacteristicCohomologyClassRingElement`

class sage.manifolds.differentiable.characteristic_cohomology_class.CharacteristicCohomologyClassRingElement(parent, x, name=None, latex_name=None)

  Bases: `IndexedFreeModuleElement`

  Characteristic cohomology class.

  Let \(E \to M\) be a real/complex vector bundle of rank \(k\). A characteristic cohomology class of \(E\) is generated by either

  - Chern classes if \(E\) is complex,

  - Pontryagin classes if \(E\) is real,

  - Pontryagin classes and the Euler class if \(E\) is real and orientable,

  via the Chern-Weil homomorphism.

  For details about the ring structure, see `CharacteristicCohomologyClassRing`.

  To construct a characteristic cohomology class, please use `CharacteristicCohomologyClass()`.

  EXAMPLES:

  Sage

      sage: M = Manifold(12, 'M')
      sage: TM = M.tangent_bundle()
      sage: CR = TM.characteristic_cohomology_class_ring()
      sage: p1, p2, p3 = CR.gens()
      sage: p1*p2+p3
      Characteristic cohomology class (p_1⌣p_2 + p_3)(TM) of the Tangent
       bundle TM over the 12-dimensional differentiable manifold M
      sage: A = TM.characteristic_cohomology_class('AHat'); A
      Characteristic cohomology class A^(TM) of the Tangent bundle TM over
       the 12-dimensional differentiable manifold M
      sage: A == 1 - p1/24 + (7*p1^2-4*p2)/5760 + (44*p1*p2-31*p1^3-16*p3)/967680
      True

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(12), 'M')
      >>> TM = M.tangent_bundle()
      >>> CR = TM.characteristic_cohomology_class_ring()
      >>> p1, p2, p3 = CR.gens()
      >>> p1*p2+p3
      Characteristic cohomology class (p_1⌣p_2 + p_3)(TM) of the Tangent
       bundle TM over the 12-dimensional differentiable manifold M
      >>> A = TM.characteristic_cohomology_class('AHat'); A
      Characteristic cohomology class A^(TM) of the Tangent bundle TM over
       the 12-dimensional differentiable manifold M
      >>> A == Integer(1) - p1/Integer(24) + (Integer(7)*p1**Integer(2)-Integer(4)*p2)/Integer(5760) + (Integer(44)*p1*p2-Integer(31)*p1**Integer(3)-Integer(16)*p3)/Integer(967680)
      True

  get_form(nab)

    Return the characteristic form of `self`.

    INPUT:

    - `nab` – get the characteristic form w.r.t. to the connection `nab`

    OUTPUT:

    - an instance of `sage.manifolds.differentiable.mixed_form.MixedForm`

    EXAMPLES:

    Trivial characteristic form on Euclidean space:

    Sage

        sage: M = manifolds.EuclideanSpace(4)
        sage: TM = M.tangent_bundle()
        sage: one = TM.characteristic_cohomology_class_ring().one()
        sage: g = M.metric()
        sage: nab = g.connection()
        sage: nab.set_immutable()
        sage: one.get_form(nab)
        Mixed differential form one on the 4-dimensional Euclidean space E^4

    Python

        >>> from sage.all import *
        >>> M = manifolds.EuclideanSpace(Integer(4))
        >>> TM = M.tangent_bundle()
        >>> one = TM.characteristic_cohomology_class_ring().one()
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> nab.set_immutable()
        >>> one.get_form(nab)
        Mixed differential form one on the 4-dimensional Euclidean space E^4

    Pontryagin form on the 4-sphere:

    Sage

        sage: M = manifolds.Sphere(4)
        sage: TM = M.tangent_bundle()
        sage: p = TM.characteristic_cohomology_class('Pontryagin'); p
        Characteristic cohomology class p(TS^4) of the Tangent bundle TS^4
         over the 4-sphere S^4 of radius 1 smoothly embedded in the
         5-dimensional Euclidean space E^5
        sage: g = M.metric() # long time
        sage: nab = g.connection() # long time
        sage: nab.set_immutable() # long time
        sage: p_form = p.get_form(nab); p_form # long time
        Mixed differential form p(TS^4, nabla_g) on the 4-sphere S^4 of
         radius 1 smoothly embedded in the 5-dimensional Euclidean space E^5
        sage: p_form.display_expansion() # long time
        p(TS^4, nabla_g) = 1

    [Python]

        >>> from sage.all import *
        >>> M = manifolds.Sphere(Integer(4))
        >>> TM = M.tangent_bundle()
        >>> p = TM.characteristic_cohomology_class('Pontryagin'); p
        Characteristic cohomology class p(TS^4) of the Tangent bundle TS^4
         over the 4-sphere S^4 of radius 1 smoothly embedded in the
         5-dimensional Euclidean space E^5
        >>> g = M.metric() # long time
        >>> nab = g.connection() # long time
        >>> nab.set_immutable() # long time
        >>> p_form = p.get_form(nab); p_form # long time
        Mixed differential form p(TS^4, nabla_g) on the 4-sphere S^4 of
         radius 1 smoothly embedded in the 5-dimensional Euclidean space E^5
        >>> p_form.display_expansion() # long time
        p(TS^4, nabla_g) = 1

  representative(nab=None)

    Return any representative of `self`.

    INPUT:

    - `nab` – (default: `None`) if stated, return the representative w.r.t. to the connection `nab`; otherwise an arbitrary already computed representative will be chosen.

    OUTPUT:

    - an instance of `sage.manifolds.differentiable.mixed_form.MixedForm`

    EXAMPLES:

    Define the 4-dimensional Euclidean space:

    Sage

        sage: M = manifolds.EuclideanSpace(4)
        sage: TM = M.tangent_bundle()
        sage: one = TM.characteristic_cohomology_class_ring().one()

    Python

        >>> from sage.all import *
        >>> M = manifolds.EuclideanSpace(Integer(4))
        >>> TM = M.tangent_bundle()
        >>> one = TM.characteristic_cohomology_class_ring().one()

    No characteristic form has been computed so far, thus we get an error:

    Sage

        sage: one.representative()
        Traceback (most recent call last):
        ...
        AttributeError: cannot pick a representative

    [Python]

        >>> from sage.all import *
        >>> one.representative()
        Traceback (most recent call last):
        ...
        AttributeError: cannot pick a representative

    Get a characteristic form:

    Sage

        sage: g = M.metric()
        sage: nab = g.connection()
        sage: nab.set_immutable()
        sage: one.get_form(nab)
        Mixed differential form one on the 4-dimensional Euclidean space E^4

    Python

        >>> from sage.all import *
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> nab.set_immutable()
        >>> one.get_form(nab)
        Mixed differential form one on the 4-dimensional Euclidean space E^4

    Now, the result is cached and \(representative\) returns a form:

    Sage

        sage: one.representative()
        Mixed differential form one on the 4-dimensional Euclidean space E^4

    [Python]

        >>> from sage.all import *
        >>> one.representative()
        Mixed differential form one on the 4-dimensional Euclidean space E^4

    Alternatively, the option `nab` can be used to return the characteristic form w.r.t. a fixed connection:

    Sage

        sage: one.representative(nab)
        Mixed differential form one on the 4-dimensional Euclidean space E^4

    Python

        >>> from sage.all import *
        >>> one.representative(nab)
        Mixed differential form one on the 4-dimensional Euclidean space E^4

    See also

    `CharacteristicCohomologyClassRingElement.get_form()`

  set_name(name=None, latex_name=None)

    Set (or change) the text name and LaTeX name of the characteristic class.

    INPUT:

    - `name` – (string; default: `None`) name given to the characteristic cohomology class

    - `latex_name` – (string; default: `None`) LaTeX symbol to denote the characteristic cohomology class; if `None` while `name` is provided, the LaTeX symbol is set to `name`

    EXAMPLES:

    Sage

        sage: M = Manifold(8, 'M')
        sage: TM = M.tangent_bundle()
        sage: x = var('x')
        sage: k = TM.characteristic_cohomology_class(1+x^2,
        ....:                               class_type='multiplicative'); k
        Characteristic cohomology class (1 + p_1^2 - 2*p_2)(TM) of the
         Tangent bundle TM over the 8-dimensional differentiable manifold M
        sage: k.set_name(name='k', latex_name=r'\kappa')
        sage: k
        Characteristic cohomology class k(TM) of the Tangent bundle TM over
         the 8-dimensional differentiable manifold M
        sage: latex(k)
        \kappa\left(TM\right)

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(8), 'M')
        >>> TM = M.tangent_bundle()
        >>> x = var('x')
        >>> k = TM.characteristic_cohomology_class(Integer(1)+x**Integer(2),
        ...                               class_type='multiplicative'); k
        Characteristic cohomology class (1 + p_1^2 - 2*p_2)(TM) of the
         Tangent bundle TM over the 8-dimensional differentiable manifold M
        >>> k.set_name(name='k', latex_name=r'\kappa')
        >>> k
        Characteristic cohomology class k(TM) of the Tangent bundle TM over
         the 8-dimensional differentiable manifold M
        >>> latex(k)
        \kappa\left(TM\right)

class sage.manifolds.differentiable.characteristic_cohomology_class.ChernAlgorithm

  Bases: `Singleton`, `Algorithm_generic`

  Algorithm class to generate Chern forms.

  EXAMPLES:

  Define a complex line bundle over a 2-dimensional manifold:

  Sage

      sage: M = Manifold(2, 'M', structure='Lorentzian')
      sage: X.<t,x> = M.chart()
      sage: E = M.vector_bundle(1, 'E', field='complex'); E
      Differentiable complex vector bundle E -> M of rank 1 over the base space
       2-dimensional Lorentzian manifold M
      sage: e = E.local_frame('e')
      sage: nab = E.bundle_connection('nabla^E', latex_name=r'\nabla^E')
      sage: omega = M.one_form(name='omega')
      sage: A = function('A')
      sage: nab.set_connection_form(0, 0)[1] = I*A(t)
      sage: nab[0, 0].display()
      connection (0,0) of bundle connection nabla^E w.r.t. Local frame
       (E|_M, (e_0)) = I*A(t) dx
      sage: nab.set_immutable()

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(2), 'M', structure='Lorentzian')
      >>> X = M.chart(names=('t', 'x',)); (t, x,) = X._first_ngens(2)
      >>> E = M.vector_bundle(Integer(1), 'E', field='complex'); E
      Differentiable complex vector bundle E -> M of rank 1 over the base space
       2-dimensional Lorentzian manifold M
      >>> e = E.local_frame('e')
      >>> nab = E.bundle_connection('nabla^E', latex_name=r'\nabla^E')
      >>> omega = M.one_form(name='omega')
      >>> A = function('A')
      >>> nab.set_connection_form(Integer(0), Integer(0))[Integer(1)] = I*A(t)
      >>> nab[Integer(0), Integer(0)].display()
      connection (0,0) of bundle connection nabla^E w.r.t. Local frame
       (E|_M, (e_0)) = I*A(t) dx
      >>> nab.set_immutable()

  Import the algorithm and apply `nab` to it:

  Sage

      sage: from sage.manifolds.differentiable.characteristic_cohomology_class import ChernAlgorithm
      sage: algorithm = ChernAlgorithm()
      sage: algorithm.get(nab)
      [2-form on the 2-dimensional Lorentzian manifold M]
      sage: algorithm.get(nab)[0].display()
      1/2*d(A)/dt/pi dt∧dx

  [Python]

      >>> from sage.all import *
      >>> from sage.manifolds.differentiable.characteristic_cohomology_class import ChernAlgorithm
      >>> algorithm = ChernAlgorithm()
      >>> algorithm.get(nab)
      [2-form on the 2-dimensional Lorentzian manifold M]
      >>> algorithm.get(nab)[Integer(0)].display()
      1/2*d(A)/dt/pi dt∧dx

  Check some equalities:

  Sage

      sage: cmat = [[nab.curvature_form(0, 0, e)]]
      sage: algorithm.get(nab)[0] == algorithm.get_local(cmat)[0]  # bundle trivial
      True
      sage: algorithm.get_gen_pow(nab, 0, 1) == algorithm.get(nab)[0]
      True

  Python

      >>> from sage.all import *
      >>> cmat = [[nab.curvature_form(Integer(0), Integer(0), e)]]
      >>> algorithm.get(nab)[Integer(0)] == algorithm.get_local(cmat)[Integer(0)]  # bundle trivial
      True
      >>> algorithm.get_gen_pow(nab, Integer(0), Integer(1)) == algorithm.get(nab)[Integer(0)]
      True

  get_local(cmat)

    Return the local Chern forms w.r.t. a given curvature form matrix.

    OUTPUT:

    - a list containing the local characteristic Chern forms as instances of `sage.manifolds.differentiable.diff_form.DiffForm`

    ALGORITHM:

        The algorithm is based on the Faddeev-LeVerrier algorithm for the
        characteristic polynomial.

    EXAMPLES:

    Define a complex line bundle over a 2-dimensional manifold:

    Sage

        sage: M = Manifold(2, 'M', structure='Lorentzian')
        sage: X.<t,x> = M.chart()
        sage: E = M.vector_bundle(1, 'E', field='complex'); E
        Differentiable complex vector bundle E -> M of rank 1 over the base
         space 2-dimensional Lorentzian manifold M
        sage: e = E.local_frame('e')
        sage: nab = E.bundle_connection('nabla^E', latex_name=r'\nabla^E')
        sage: omega = M.one_form(name='omega')
        sage: A = function('A')
        sage: nab.set_connection_form(0, 0)[1] = I*A(t)
        sage: nab[0, 0].display()
        connection (0,0) of bundle connection nabla^E w.r.t. Local frame
         (E|_M, (e_0)) = I*A(t) dx
        sage: cmat = [[nab.curvature_form(i, j, e) for j in E.irange()]
        ....:         for i in E.irange()]

    Python

        >>> from sage.all import *
        >>> M = Manifold(Integer(2), 'M', structure='Lorentzian')
        >>> X = M.chart(names=('t', 'x',)); (t, x,) = X._first_ngens(2)
        >>> E = M.vector_bundle(Integer(1), 'E', field='complex'); E
        Differentiable complex vector bundle E -> M of rank 1 over the base
         space 2-dimensional Lorentzian manifold M
        >>> e = E.local_frame('e')
        >>> nab = E.bundle_connection('nabla^E', latex_name=r'\nabla^E')
        >>> omega = M.one_form(name='omega')
        >>> A = function('A')
        >>> nab.set_connection_form(Integer(0), Integer(0))[Integer(1)] = I*A(t)
        >>> nab[Integer(0), Integer(0)].display()
        connection (0,0) of bundle connection nabla^E w.r.t. Local frame
         (E|_M, (e_0)) = I*A(t) dx
        >>> cmat = [[nab.curvature_form(i, j, e) for j in E.irange()]
        ...         for i in E.irange()]

    Import the algorithm and apply `cmat` to it:

    Sage

        sage: from sage.manifolds.differentiable.characteristic_cohomology_class import ChernAlgorithm
        sage: algorithm = ChernAlgorithm()
        sage: algorithm.get_local(cmat)
        [2-form on the 2-dimensional Lorentzian manifold M]

    [Python]

        >>> from sage.all import *
        >>> from sage.manifolds.differentiable.characteristic_cohomology_class import ChernAlgorithm
        >>> algorithm = ChernAlgorithm()
        >>> algorithm.get_local(cmat)
        [2-form on the 2-dimensional Lorentzian manifold M]

class sage.manifolds.differentiable.characteristic_cohomology_class.EulerAlgorithm

  Bases: `Singleton`, `Algorithm_generic`

  Algorithm class to generate Euler forms.

  EXAMPLES:

  Consider the 2-dimensional Euclidean space:

  Sage

      sage: M = manifolds.EuclideanSpace(2)
      sage: g = M.metric()
      sage: nab = g.connection()
      sage: nab.set_immutable()

  Python

      >>> from sage.all import *
      >>> M = manifolds.EuclideanSpace(Integer(2))
      >>> g = M.metric()
      >>> nab = g.connection()
      >>> nab.set_immutable()

  Import the algorithm and apply `nab` to it:

  Sage

      sage: from sage.manifolds.differentiable.characteristic_cohomology_class import EulerAlgorithm
      sage: algorithm = EulerAlgorithm()
      sage: algorithm.get(nab)
      [2-form on the Euclidean plane E^2]
      sage: algorithm.get(nab)[0].display()
      0

  [Python]

      >>> from sage.all import *
      >>> from sage.manifolds.differentiable.characteristic_cohomology_class import EulerAlgorithm
      >>> algorithm = EulerAlgorithm()
      >>> algorithm.get(nab)
      [2-form on the Euclidean plane E^2]
      >>> algorithm.get(nab)[Integer(0)].display()
      0

  get(nab)

    Return the global characteristic forms of the generators w.r.t. a given connection.

    INPUT:

    - `nab` – a metric connection \(\nabla\)

    OUTPUT: list containing the global characteristic Euler form

    ALGORITHM:

    Assume that \(\nabla\) is compatible with the metric \(g\), and let \((s_1, \ldots, s_n)\) be any oriented frame. Denote by \(G_s = (g(s_i, s_j))_{ij}\) the metric tensor and let \(\Omega_s\) be the curvature form matrix of \(\nabla\) w.r.t. \(s\). Then, we get:

    \[\left(G_s \cdot \Omega_s \right)_{ij} = g\!\left(R(.,.)s_i, s_j\right),\]

    where \(R\) is the Riemannian curvature tensor w.r.t. \(\nabla\).

    The characteristic Euler form is now obtained by the expression

    \[\frac{1}{\sqrt{\left|\det(G_s)\right|}} \ \mathrm{Pf}\!\left(G_s \cdot \frac{\Omega_s}{2 \pi}\right).\]

    EXAMPLES:

    Consider the 2-sphere:

    Sage

        sage: M.<x,y> = manifolds.Sphere(2, coordinates='stereographic')
        sage: g = M.metric() # long time
        sage: nab = g.connection() # long time
        sage: nab.set_immutable() # long time

    Python

        >>> from sage.all import *
        >>> M = manifolds.Sphere(Integer(2), coordinates='stereographic', names=('x', 'y',)); (x, y,) = M._first_ngens(2)
        >>> g = M.metric() # long time
        >>> nab = g.connection() # long time
        >>> nab.set_immutable() # long time

    Import the algorithm and apply `nab` to it:

    Sage

        sage: from sage.manifolds.differentiable.characteristic_cohomology_class import EulerAlgorithm
        sage: algorithm = EulerAlgorithm()
        sage: algorithm.get(nab) # long time
        [2-form on the 2-sphere S^2 of radius 1 smoothly embedded in the
         Euclidean space E^3]
        sage: algorithm.get(nab)[0].display() # long time
        2/(pi + pi*x^4 + pi*y^4 + 2*pi*x^2 + 2*(pi + pi*x^2)*y^2) dx∧dy

    [Python]

        >>> from sage.all import *
        >>> from sage.manifolds.differentiable.characteristic_cohomology_class import EulerAlgorithm
        >>> algorithm = EulerAlgorithm()
        >>> algorithm.get(nab) # long time
        [2-form on the 2-sphere S^2 of radius 1 smoothly embedded in the
         Euclidean space E^3]
        >>> algorithm.get(nab)[Integer(0)].display() # long time
        2/(pi + pi*x^4 + pi*y^4 + 2*pi*x^2 + 2*(pi + pi*x^2)*y^2) dx∧dy

    REFERENCES:

    - [Che1944]

    - [Baer2020]

  get_local(cmat)

    Return the normalized Pfaffian w.r.t. a given curvature form matrix.

    The normalization is given by the factor \(\left(\frac{1}{2 \pi}\right)^{\frac{k}{2}}\), where \(k\) is the dimension of the curvature matrix.

    OUTPUT: list containing the normalized Pfaffian of a given curvature form

    Note

    In general, the output does not represent the local characteristic Euler form. The result is only guaranteed to be the local Euler form if `cmat` is given w.r.t. an orthonormal oriented frame. See `get()` for details.

    ALGORITHM:

        The algorithm is based on the Bär-Faddeev-LeVerrier algorithm for
        the Pfaffian.

    EXAMPLES:

    Consider the 2-sphere:

    Sage

        sage: M.<th,phi> = manifolds.Sphere(2)  # use spherical coordinates
        sage: TM = M.tangent_bundle()
        sage: g = M.metric()
        sage: nab = g.connection()
        sage: e = M.frames()[0]  # select frame (opposite orientation!)
        sage: cmat = [[nab.curvature_form(i, j, e) for j in TM.irange()]
        ....:         for i in TM.irange()]

    Python

        >>> from sage.all import *
        >>> M = manifolds.Sphere(Integer(2), names=('th', 'phi',)); (th, phi,) = M._first_ngens(2)# use spherical coordinates
        >>> TM = M.tangent_bundle()
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> e = M.frames()[Integer(0)]  # select frame (opposite orientation!)
        >>> cmat = [[nab.curvature_form(i, j, e) for j in TM.irange()]
        ...         for i in TM.irange()]

    We need some preprocessing because the frame is not orthonormal:

    Sage

        sage: gcmat = [[sum(g[[e, i, j]] * nab.curvature_form(j, k, e)
        ....:               for j in TM.irange())
        ....:           for k in TM.irange()] for i in TM.irange()]

    [Python]

        >>> from sage.all import *
        >>> gcmat = [[sum(g[[e, i, j]] * nab.curvature_form(j, k, e)
        ...               for j in TM.irange())
        ...           for k in TM.irange()] for i in TM.irange()]

    Now, `gcmat` is guaranteed to be skew-symmetric and can be applied to `get_local()`. Then, the result must be normalized:

    Sage

        sage: from sage.manifolds.differentiable.characteristic_cohomology_class import EulerAlgorithm
        sage: algorithm = EulerAlgorithm()
        sage: euler = -algorithm.get_local(gcmat)[0] / sqrt(g.det(frame=e))
        sage: euler.display()
        1/2*sin(th)/pi dth∧dphi

    Python

        >>> from sage.all import *
        >>> from sage.manifolds.differentiable.characteristic_cohomology_class import EulerAlgorithm
        >>> algorithm = EulerAlgorithm()
        >>> euler = -algorithm.get_local(gcmat)[Integer(0)] / sqrt(g.det(frame=e))
        >>> euler.display()
        1/2*sin(th)/pi dth∧dphi

class sage.manifolds.differentiable.characteristic_cohomology_class.PontryaginAlgorithm

  Bases: `Singleton`, `Algorithm_generic`

  Algorithm class to generate Pontryagin forms.

  EXAMPLES:

  5-dimensional Euclidean space:

  Sage

      sage: M = manifolds.EuclideanSpace(5)
      sage: g = M.metric()
      sage: nab = g.connection()
      sage: nab.set_immutable()

  Python

      >>> from sage.all import *
      >>> M = manifolds.EuclideanSpace(Integer(5))
      >>> g = M.metric()
      >>> nab = g.connection()
      >>> nab.set_immutable()

  Import the algorithm:

  Sage

      sage: from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginAlgorithm
      sage: algorithm = PontryaginAlgorithm()
      sage: [p1] = algorithm.get(nab) # long time
      sage: p1.display() # long time
      0

  [Python]

      >>> from sage.all import *
      >>> from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginAlgorithm
      >>> algorithm = PontryaginAlgorithm()
      >>> [p1] = algorithm.get(nab) # long time
      >>> p1.display() # long time
      0

  get_local(cmat)

    Return the local Pontryagin forms w.r.t. a given curvature form matrix.

    OUTPUT: list containing the local characteristic Pontryagin forms

    ALGORITHM:

        The algorithm is based on the Faddeev-LeVerrier algorithm for the
        characteristic polynomial.

    EXAMPLES:

    5-dimensional Euclidean space:

    Sage

        sage: M = manifolds.EuclideanSpace(5)
        sage: TM = M.tangent_bundle()
        sage: g = M.metric()
        sage: nab = g.connection()
        sage: e = M.frames()[0]  # select standard frame
        sage: cmat = [ [nab.curvature_form(i, j, e) # long time
        ....:           for j in TM.irange()]
        ....:         for i in TM.irange()]

    Python

        >>> from sage.all import *
        >>> M = manifolds.EuclideanSpace(Integer(5))
        >>> TM = M.tangent_bundle()
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> e = M.frames()[Integer(0)]  # select standard frame
        >>> cmat = [ [nab.curvature_form(i, j, e) # long time
        ...           for j in TM.irange()]
        ...         for i in TM.irange()]

    Import the algorithm:

    Sage

        sage: from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginAlgorithm
        sage: algorithm = PontryaginAlgorithm()
        sage: [p1] = algorithm.get_local(cmat) # long time
        sage: p1.display() # long time
        0

    [Python]

        >>> from sage.all import *
        >>> from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginAlgorithm
        >>> algorithm = PontryaginAlgorithm()
        >>> [p1] = algorithm.get_local(cmat) # long time
        >>> p1.display() # long time
        0

class sage.manifolds.differentiable.characteristic_cohomology_class.PontryaginEulerAlgorithm

  Bases: `Singleton`, `Algorithm_generic`

  Algorithm class to generate Euler and Pontryagin forms.

  EXAMPLES:

  6-dimensional Euclidean space:

  Sage

      sage: M = manifolds.EuclideanSpace(6)
      sage: g = M.metric()
      sage: nab = g.connection()
      sage: nab.set_immutable()

  Python

      >>> from sage.all import *
      >>> M = manifolds.EuclideanSpace(Integer(6))
      >>> g = M.metric()
      >>> nab = g.connection()
      >>> nab.set_immutable()

  Import the algorithm:

  Sage

      sage: from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginEulerAlgorithm
      sage: algorithm = PontryaginEulerAlgorithm()
      sage: e_form, p1_form = algorithm.get(nab)  # long time
      sage: e_form.display()  # long time
      0
      sage: p1_form.display()  # long time
      0

  [Python]

      >>> from sage.all import *
      >>> from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginEulerAlgorithm
      >>> algorithm = PontryaginEulerAlgorithm()
      >>> e_form, p1_form = algorithm.get(nab)  # long time
      >>> e_form.display()  # long time
      0
      >>> p1_form.display()  # long time
      0

  get(nab)

    Return the global characteristic forms of the generators w.r.t. a given connection.

    OUTPUT:

    - a list containing the global Euler form in the first entry, and the global Pontryagin forms in the remaining entries.

    EXAMPLES:

    4-dimensional Euclidean space:

    Sage

        sage: M = manifolds.EuclideanSpace(4)
        sage: g = M.metric()
        sage: nab = g.connection()
        sage: nab.set_immutable()

    Python

        >>> from sage.all import *
        >>> M = manifolds.EuclideanSpace(Integer(4))
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> nab.set_immutable()

    Import the algorithm:

    Sage

        sage: from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginEulerAlgorithm
        sage: algorithm = PontryaginEulerAlgorithm()
        sage: algorithm.get(nab) # long time
        [4-form on the 4-dimensional Euclidean space E^4,
         4-form on the 4-dimensional Euclidean space E^4]

    [Python]

        >>> from sage.all import *
        >>> from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginEulerAlgorithm
        >>> algorithm = PontryaginEulerAlgorithm()
        >>> algorithm.get(nab) # long time
        [4-form on the 4-dimensional Euclidean space E^4,
         4-form on the 4-dimensional Euclidean space E^4]

  get_gen_pow(nab, i, n)

    Return the \(n\)-th power of the \(i\)-th generator w.r.t `nab`.

    The result is cached.

    EXAMPLES:

    4-dimensional Euclidean space:

    Sage

        sage: M = manifolds.EuclideanSpace(4)
        sage: TM = M.tangent_bundle()
        sage: g = M.metric()
        sage: nab = g.connection()
        sage: nab.set_immutable()

    Python

        >>> from sage.all import *
        >>> M = manifolds.EuclideanSpace(Integer(4))
        >>> TM = M.tangent_bundle()
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> nab.set_immutable()

    Import the algorithm:

    Sage

        sage: from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginEulerAlgorithm
        sage: algorithm = PontryaginEulerAlgorithm()
        sage: e = algorithm.get_gen_pow(nab, 0, 1)  # Euler, long time
        sage: e.display() # long time
        0
        sage: p1_pow2 = algorithm.get_gen_pow(nab, 1, 2)  # 1st Pontryagin squared, long time
        sage: p1_pow2 # long time
        8-form zero on the 4-dimensional Euclidean space E^4

    [Python]

        >>> from sage.all import *
        >>> from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginEulerAlgorithm
        >>> algorithm = PontryaginEulerAlgorithm()
        >>> e = algorithm.get_gen_pow(nab, Integer(0), Integer(1))  # Euler, long time
        >>> e.display() # long time
        0
        >>> p1_pow2 = algorithm.get_gen_pow(nab, Integer(1), Integer(2))  # 1st Pontryagin squared, long time
        >>> p1_pow2 # long time
        8-form zero on the 4-dimensional Euclidean space E^4

  get_local(cmat)

    Return the local Euler and Pontryagin forms w.r.t. a given curvature form matrix.

    Note

    Similar as for `EulerAlgorithm`, the first entry only represents the Euler form if the curvature form matrix is chosen w.r.t. an orthonormal oriented frame. See `EulerAlgorithm.get_local()` for details.

    OUTPUT:

    - a list containing the local Euler form in the first entry, and the local Pontryagin forms in the remaining entries.

    EXAMPLES:

    6-dimensional Euclidean space:

    Sage

        sage: M = manifolds.EuclideanSpace(6)
        sage: TM = M.tangent_bundle()
        sage: g = M.metric()
        sage: nab = g.connection()
        sage: e = M.frames()[0]  # select the standard frame
        sage: cmat = [ [nab.curvature_form(i, j, e)  # long time
        ....:           for j in TM.irange()]
        ....:         for i in TM.irange() ]

    Python

        >>> from sage.all import *
        >>> M = manifolds.EuclideanSpace(Integer(6))
        >>> TM = M.tangent_bundle()
        >>> g = M.metric()
        >>> nab = g.connection()
        >>> e = M.frames()[Integer(0)]  # select the standard frame
        >>> cmat = [ [nab.curvature_form(i, j, e)  # long time
        ...           for j in TM.irange()]
        ...         for i in TM.irange() ]

    Import the algorithm:

    Sage

        sage: from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginEulerAlgorithm
        sage: algorithm = PontryaginEulerAlgorithm()
        sage: e, p1 = algorithm.get_local(cmat)  # long time
        sage: e.display()  # long time
        0
        sage: p1.display()  # long time
        0

    [Python]

        >>> from sage.all import *
        >>> from sage.manifolds.differentiable.characteristic_cohomology_class import PontryaginEulerAlgorithm
        >>> algorithm = PontryaginEulerAlgorithm()
        >>> e, p1 = algorithm.get_local(cmat)  # long time
        >>> e.display()  # long time
        0
        >>> p1.display()  # long time
        0

sage.manifolds.differentiable.characteristic_cohomology_class.additive_sequence(q, k, n=None)

  Turn the polynomial `q` into its additive sequence.

  Let \(q\) be a polynomial and \(x_1, \ldots x_n\) indeterminates. The additive sequence of \(q\) is then given by the polynomials \(Q_j\)

  \[\sum_{j=0}^n Q_j(\sigma_1, \ldots, \sigma_j) z^j = \sum_{i=1}^{k} q(z \,x_i),\]

  where \(\sigma_i\) is the \(i\)-th elementary symmetric polynomial in the indeterminates \(x_i\).

  INPUT:

  - `q` – polynomial to turn into its additive sequence

  - `k` – maximal index \(k\) of the sum

  - `n` – (default: `None`) the highest order of the sequence \(n\); if `None`, the order of `q` is assumed

  OUTPUT: a symmetric polynomial representing the additive sequence

  EXAMPLES:

  Sage

      sage: P.<x> = PolynomialRing(QQ)
      sage: from sage.manifolds.differentiable.characteristic_cohomology_class import additive_sequence
      sage: f = 1 + x - x^2
      sage: sym = additive_sequence(f, 2); sym
      2*e[] + e[1] - e[1, 1] + 2*e[2]

  Python

      >>> from sage.all import *
      >>> P = PolynomialRing(QQ, names=('x',)); (x,) = P._first_ngens(1)
      >>> from sage.manifolds.differentiable.characteristic_cohomology_class import additive_sequence
      >>> f = Integer(1) + x - x**Integer(2)
      >>> sym = additive_sequence(f, Integer(2)); sym
      2*e[] + e[1] - e[1, 1] + 2*e[2]

  The maximal order of the result can be stated with `n`:

  Sage

      sage: sym_1 = additive_sequence(f, 2, 1); sym_1
      2*e[] + e[1]

  [Python]

      >>> from sage.all import *
      >>> sym_1 = additive_sequence(f, Integer(2), Integer(1)); sym_1
      2*e[] + e[1]

sage.manifolds.differentiable.characteristic_cohomology_class.fast_wedge_power(form, n)

  Return the wedge product power of \(form\) using a square-and-wedge algorithm.

  INPUT:

  - `form` – a differential form

  - `n` – nonnegative integer

  EXAMPLES:

  Sage

      sage: M = Manifold(4, 'M')
      sage: X.<x,y,z,t> = M.chart()
      sage: omega = M.diff_form(2, name='omega')
      sage: omega[0,1] = t*y^2 + 2*x
      sage: omega[0,3] = z - 2*y
      sage: from sage.manifolds.differentiable.characteristic_cohomology_class import fast_wedge_power
      sage: fast_wedge_power(omega, 0)
      Scalar field 1 on the 4-dimensional differentiable manifold M
      sage: fast_wedge_power(omega, 1)
      2-form omega on the 4-dimensional differentiable manifold M
      sage: fast_wedge_power(omega, 2)
      4-form omega∧omega on the 4-dimensional differentiable manifold M

  Python

      >>> from sage.all import *
      >>> M = Manifold(Integer(4), 'M')
      >>> X = M.chart(names=('x', 'y', 'z', 't',)); (x, y, z, t,) = X._first_ngens(4)
      >>> omega = M.diff_form(Integer(2), name='omega')
      >>> omega[Integer(0),Integer(1)] = t*y**Integer(2) + Integer(2)*x
      >>> omega[Integer(0),Integer(3)] = z - Integer(2)*y
      >>> from sage.manifolds.differentiable.characteristic_cohomology_class import fast_wedge_power
      >>> fast_wedge_power(omega, Integer(0))
      Scalar field 1 on the 4-dimensional differentiable manifold M
      >>> fast_wedge_power(omega, Integer(1))
      2-form omega on the 4-dimensional differentiable manifold M
      >>> fast_wedge_power(omega, Integer(2))
      4-form omega∧omega on the 4-dimensional differentiable manifold M

sage.manifolds.differentiable.characteristic_cohomology_class.multiplicative_sequence(q, n=None)

  Turn the polynomial `q` into its multiplicative sequence.

  Let \(q\) be a polynomial and \(x_1, \ldots x_n\) indeterminates. The multiplicative sequence of \(q\) is then given by the polynomials \(K_j\)

  \[\sum_{j=0}^n K_j(\sigma_1, \ldots, \sigma_j) z^j = \prod_{i=1}^{n} q(z \,x_i),\]

  where \(\sigma_i\) is the \(i\)-th elementary symmetric polynomial in the indeterminates \(x_i\).

  INPUT:

  - `q` – polynomial to turn into its multiplicative sequence

  - `n` – (default: `None`) the highest order \(n\) of the sequence; if `None`, the order of `q` is assumed

  OUTPUT: a symmetric polynomial representing the multiplicative sequence

  EXAMPLES:

  Sage

      sage: P.<x> = PolynomialRing(QQ)
      sage: from sage.manifolds.differentiable.characteristic_cohomology_class import multiplicative_sequence
      sage: f = 1 + x - x^2
      sage: sym = multiplicative_sequence(f); sym
      e[] + e[1] - e[1, 1] + 3*e[2]

  Python

      >>> from sage.all import *
      >>> P = PolynomialRing(QQ, names=('x',)); (x,) = P._first_ngens(1)
      >>> from sage.manifolds.differentiable.characteristic_cohomology_class import multiplicative_sequence
      >>> f = Integer(1) + x - x**Integer(2)
      >>> sym = multiplicative_sequence(f); sym
      e[] + e[1] - e[1, 1] + 3*e[2]

  The maximal order of the result can be stated with `n`:

  Sage

      sage: sym_5 = multiplicative_sequence(f, n=5); sym_5
      e[] + e[1] - e[1, 1] + 3*e[2] - e[2, 1] + e[2, 2] + 4*e[3] - 3*e[3, 1]
       + e[3, 2] + 7*e[4] - 4*e[4, 1] + 11*e[5]

  [Python]

      >>> from sage.all import *
      >>> sym_5 = multiplicative_sequence(f, n=Integer(5)); sym_5
      e[] + e[1] - e[1, 1] + 3*e[2] - e[2, 1] + e[2, 2] + 4*e[3] - 3*e[3, 1]
       + e[3, 2] + 7*e[4] - 4*e[4, 1] + 11*e[5]