Characteristic Classes¶
A characteristic class \(\kappa\) is a natural transformation that associates to 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:
Roughly speaking, characteristic classes measure the nontriviality 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 socalled ChernWeil 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
is welldefined, 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 ChernWeil theory and therefore 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
REFERENCES:
Contents¶
We consider the following three types of classes:
Additive Classes¶
In the complex case, let \(f\) be a holomorphic function around zero. Then we call
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
the additive characteristic class associated to \(g\) of the real vector bundle \(E\).
EXAMPLES:
Consider the Chern character on some 2dimensional 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
2dimensional Lorentzian manifold M
sage: e = E.local_frame('e')
Let us define the connection \(\nabla^E\) in terms of an electromagnetic 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: omega[1] = I*A(t)
sage: omega.display()
omega = I*A(t) dx
sage: nab.set_connection_form(0, 0, omega)
The Chern character is then given by:
sage: ch = E.characteristic_class('ChernChar'); ch
Characteristic class ch of additive type associated to e^x on the
Differentiable complex vector bundle E > M of rank 1 over the base space
2dimensional Lorentzian manifold M
sage: ch_form = ch.get_form(nab); ch_form.display_expansion()
ch(E, nabla^E) = [1] + [0] + [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
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
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, xI*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 ChernWeil 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 magnitudesquared 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.set_connection_form(1, 1, omega, frame=e)
Now, the Chern class can be constructed:
sage: c = E.characteristic_class('Chern'); c
Characteristic class c of multiplicative type associated to x + 1 on the
Differentiable complex vector bundle gamma^1 > CP^1 of rank 1 over the
base space 2dimensional 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] + [0] + [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 skewsymmetric, which certainly will be true if \(\nabla\) is metric and \(e\) is orthonormal. Then we call
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 = Manifold(2, name='S2', latex_name=r'S^2', start_index=1)
sage: U = M.open_subset('U') ; V = M.open_subset('V')
sage: M.declare_union(U,V) # M is the union of U and V
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
sage: xy_to_uv = c_xy.transition_map(c_uv,
....: (x/(x^2+y^2), y/(x^2+y^2)),
....: intersection_name='W',
....: restrictions1= x^2+y^2!=0,
....: restrictions2= u^2+v^2!=0)
sage: uv_to_xy = xy_to_uv.inverse()
sage: eU = c_xy.frame() ; eV = c_uv.frame()
sage: TM = M.tangent_bundle()
sage: e_class = TM.characteristic_class('Euler'); e_class
Characteristic class e of Pfaffian type associated to x on the Tangent
bundle TS2 over the 2dimensional differentiable manifold S2
To compute a particular representative of the Euler class, we need to determine a connection:
sage: g = M.metric('g') # standard metric on S2
sage: g[eU,1,1], g[eU,2,2] = 4/(1+x^2+y^2)^2, 4/(1+x^2+y^2)^2
sage: g[eV,1,1], g[eV,2,2] = 4/(1+u^2+v^2)^2, 4/(1+u^2+v^2)^2
sage: nab = g.connection()
In case of the the Euler class, skewsymmetric curvature matrices are needed for the Pfaffian. For this, we need to define the curvature matrices by hand:
sage: cmatrix_U = [[nab.curvature_form(i,j,eU) for j in TM.irange()]
....: for i in TM.irange()]
sage: cmatrix_V = [[nab.curvature_form(i,j,eV) for j in TM.irange()]
....: for i in TM.irange()]
Fortunately, both curvature matrices are already skewsymmetric:
sage: for i in range(TM.rank()):
....: for j in range(TM.rank()):
....: print(cmatrix_U[i][j].display())
curvature (1,1) of connection nabla_g w.r.t. Coordinate frame
(U, (d/dx,d/dy)) = 0
curvature (1,2) of connection nabla_g w.r.t. Coordinate frame
(U, (d/dx,d/dy)) = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dx/\dy
curvature (2,1) of connection nabla_g w.r.t. Coordinate frame
(U, (d/dx,d/dy)) = 4/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1) dx/\dy
curvature (2,2) of connection nabla_g w.r.t. Coordinate frame
(U, (d/dx,d/dy)) = 0
sage: for i in range(TM.rank()):
....: for j in range(TM.rank()):
....: print(cmatrix_V[i][j].display())
curvature (1,1) of connection nabla_g w.r.t. Coordinate frame
(V, (d/du,d/dv)) = 0
curvature (1,2) of connection nabla_g w.r.t. Coordinate frame
(V, (d/du,d/dv)) = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) du/\dv
curvature (2,1) of connection nabla_g w.r.t. Coordinate frame
(V, (d/du,d/dv)) = 4/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1) du/\dv
curvature (2,2) of connection nabla_g w.r.t. Coordinate frame
(V, (d/du,d/dv)) = 0
Now the representative of the Euler class with respect to the connection \(\nabla_g\) induced by the standard metric can be computed:
sage: cmatrices = {eU: cmatrix_U, eV: cmatrix_V}
sage: e_class_form = e_class.get_form(nab, cmatrices)
sage: e_class_form.display_expansion()
e(TS2, nabla_g) = [0] + [0] + [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: integrate(integrate(e_class_form[2][[1,2]].expr(), x, infinity, infinity).simplify_full(),
....: 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_class.
CharacteristicClass
(vbundle, func, class_type='multiplicative', name=None, latex_name=None)¶ Bases:
sage.structure.unique_representation.UniqueRepresentation
,sage.structure.sage_object.SageObject
An instance of this class represents a characteristic class on some differentiable vector bundle over the field \(\RR\) or \(\CC\).
INPUT:
 vbundle – vector bundle on which the characteristic class should be defined
 func – symbolic expression representing the function to which
self
should be associated to  class_type – (default:
'multiplicative'
) class type of the characteristic class; at this stage, the following options are possible:'multiplicative'
– returns a class of multiplicative type, using the determinant'additive'
– returns a class of additive type, using the trace'Pfaffian'
– returns a class of Pfaffian type, using the Pfaffian
name
– string representation given to the characteristic classlatex_name
– (default:None
) LaTeX name given to the characteristic class
EXAMPLES:
Get characteristic classes using predefined ones:
sage: M = Manifold(4, 'M') sage: TM = M.tangent_bundle() sage: TM.characteristic_class('Pontryagin') Characteristic class p of multiplicative type associated to x + 1 on the Tangent bundle TM over the 4dimensional differentiable manifold M sage: TM.characteristic_class('Hirzebruch') Characteristic class L of multiplicative type associated to sqrt(x)/tanh(sqrt(x)) on the Tangent bundle TM over the 4dimensional differentiable manifold M sage: TM.characteristic_class('AHat') Characteristic class A^ of multiplicative type associated to 1/2*sqrt(x)/sinh(1/2*sqrt(x)) on the Tangent bundle TM over the 4dimensional differentiable manifold M
The vector bundle’s base field and definition domain of the characteristic class must fit together, otherwise an error message occurs:
sage: TM.characteristic_class('Chern') Traceback (most recent call last): ... ValueError: base field must be complex for class 'Chern'
If your favourite class is not predefined yet, the associated function can be put manually:
sage: cl = TM.characteristic_class(1+x^2, name='cl'); cl Characteristic class cl of multiplicative type associated to x^2 + 1 on the Tangent bundle TM over the 4dimensional differentiable manifold M

class_type
()¶ Return the class type of
self
.EXAMPLES:
sage: M = Manifold(2, 'M') sage: TM = M.tangent_bundle() sage: ch = TM.characteristic_class(exp(x), class_type='additive', ....: name='ch', latex_name=r'\mathrm{ch}') sage: ch.class_type() 'additive'

function
()¶ Return the function corresponding to this characteristic class.
EXAMPLES:
sage: M = Manifold(2, 'M') sage: TM = M.tangent_bundle() sage: e_class = TM.characteristic_class('Euler') sage: e_class.function() x sage: AHat = TM.characteristic_class('AHat') sage: AHat.function() 1/2*sqrt(x)/sinh(1/2*sqrt(x)) sage: c = TM.characteristic_class(1+x, name='c') sage: c.function() x + 1

get_form
(connection, cmatrices=None)¶ Return the form representing
self
with respect to the given connectionconnection
.INPUT:
connection
– connection to which the form should be associated to; this can be either a bundle connection as an instance ofBundleConnection
or, in case of the tensor bundle, an affine connection as an instance ofAffineConnection
cmatrices
– (default:None
) a dictionary of curvature matrices with local frames as keys and curvature matrices as items; ifNone
, Sage tries to get the curvature matrices from the connection
OUTPUT:
 mixed form as an instance of
MixedForm
representing the total characteristic class
Note
Be aware that depending on the characteristic class and complexity of the manifold, computation times may vary a lot. In addition, if not done before, the curvature form is computed from the connection, here. If this behaviour is not wanted and the curvature form is already known, please use the argument
cmatrices
.EXAMPLES:
Again, consider the Chern character on some 2dimensional 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 2dimensional Lorentzian manifold M sage: e = E.local_frame('e')
And again, we define the connection \(\nabla^E\) in terms of an electromagnetic 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: omega[1] = I*A(t) sage: omega.display() omega = I*A(t) dx sage: nab.set_connection_form(0, 0, omega)
The Chern character is then given by:
sage: ch = E.characteristic_class('ChernChar'); ch Characteristic class ch of additive type associated to e^x on the Differentiable complex vector bundle E > M of rank 1 over the base space 2dimensional Lorentzian manifold M
Inserting the connection, the result is a mixed differential form with a priori nonzero components in even degrees:
sage: ch_form = ch.get_form(nab); ch_form Mixed differential form ch(E, nabla^E) on the 2dimensional Lorentzian manifold M sage: ch_form.display() ch(E, nabla^E) = ch_0(E, nabla^E) + zero + ch_1(E, nabla^E) sage: ch_form.display_expansion() ch(E, nabla^E) = [1] + [0] + [1/2*d(A)/dt/pi dt/\dx]
Due to long computation times, the form is saved:
sage: ch_form is ch.get_form(nab) True