# 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:

## Contents#

We consider the following three types of 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: 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')


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

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()


The Chern character is then given by:

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


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

sage: 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: 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)


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: 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()


Now, the Chern class can be constructed:

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


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: integrate(integrate(c_form[2][[1,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: 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


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: g = M.metric('g') # standard metric on S2, long time
sage: nab = g.connection() # long time
sage: 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: 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


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

sage: expr = e_class_form[2][[1,2]].expr() # long time
sage: expr = integrate(expr, x, -infinity, infinity) # long time
sage: expr = expr.simplify_full() # long time
sage: integrate(expr, y, -infinity, infinity) # long time
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#

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

EXAMPLES:

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...>

get(nab)#

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

The result is cached.

OUTPUT:

EXAMPLES:

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

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

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: M = manifolds.EuclideanSpace(8)
sage: TM = M.tangent_bundle()
sage: g = M.metric()
sage: nab = g.connection()
sage: nab.set_immutable()

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

get_local(cmat)#

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

OUTPUT:

• a list containing the generator’s local characteristic forms

ALGORITHM:

The inherited class determines the algorithm.

EXAMPLES:

4-dimensional Euclidean space:

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()]       # long time
....:         for i in TM.irange()]         # long time


Import the algorithm:

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


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

sage: algorithm is PontryaginAlgorithm()
True

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

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: 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]


The default base ring is $$\QQ$$:

sage: CR.base_ring()
Rational Field


Characteristic cohomology class ring over a complex vector bundle:

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]


Characteristic cohomology class ring over an oriented manifold:

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]

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

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: 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

get_form(nab)#

Return the characteristic form of self.

INPUT:

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

OUTPUT:

EXAMPLES:

Trivial characteristic form on Euclidean space:

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


Pontryagin form on the 4-sphere:

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

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:

EXAMPLES:

Define the 4-dimensional Euclidean space:

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


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

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


Get a characteristic form:

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


Now, the result is cached and $$representative$$ returns a form:

sage: 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: one.representative(nab)
Mixed differential form one on the 4-dimensional Euclidean space E^4

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: 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)

class sage.manifolds.differentiable.characteristic_cohomology_class.ChernAlgorithm#

Algorithm class to generate Chern forms.

EXAMPLES:

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

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()


Import the algorithm and apply nab to it:

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


Check some equalities:

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

get_local(cmat)#

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

OUTPUT:

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: 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()]


Import the algorithm and apply cmat to it:

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]

class sage.manifolds.differentiable.characteristic_cohomology_class.EulerAlgorithm#

Algorithm class to generate Euler forms.

EXAMPLES:

Consider the 2-dimensional Euclidean space:

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


Import the algorithm and apply nab to it:

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

get(nab)#

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

INPUT:

• a metric connection $$\nabla$$

OUTPUT:

• a 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: 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


Import the algorithm and apply nab to it:

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


REFERENCES:

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:

• a 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: 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()]


We need some preprocessing because the frame is not orthonormal:

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()]


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

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

class sage.manifolds.differentiable.characteristic_cohomology_class.PontryaginAlgorithm#

Algorithm class to generate Pontryagin forms.

EXAMPLES:

5-dimensional Euclidean space:

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


Import the algorithm:

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

get_local(cmat)#

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

OUTPUT:

• a 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: 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()]       # long time
....:         for i in TM.irange()]         # long time


Import the algorithm:

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

class sage.manifolds.differentiable.characteristic_cohomology_class.PontryaginEulerAlgorithm#

Algorithm class to generate Euler and Pontryagin forms.

EXAMPLES:

6-dimensional Euclidean space:

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


Import the algorithm:

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

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: M = manifolds.EuclideanSpace(4)
sage: g = M.metric()
sage: nab = g.connection()
sage: nab.set_immutable()


Import the algorithm:

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]

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: M = manifolds.EuclideanSpace(4)
sage: TM = M.tangent_bundle()
sage: g = M.metric()
sage: nab = g.connection()
sage: nab.set_immutable()


Import the algorithm:

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

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: 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()]       # long time
....:         for i in TM.irange()]         # long time


Import the algorithm:

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


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: 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]


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

sage: sym_1 = additive_sequence(f, 2, 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 – a non-negative integer

EXAMPLES:

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

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: 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]


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

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]