Topological Manifolds¶
Given a topological field \(K\) (in most applications, \(K = \RR\) or \(K = \CC\)) and a non-negative integer \(n\), a topological manifold of dimension \(n\) over K is a topological space \(M\) such that
- \(M\) is a Hausdorff space,
- \(M\) is second countable,
- every point in \(M\) has a neighborhood homeomorphic to \(K^n\).
Topological manifolds are implemented via the class
TopologicalManifold
. Open subsets of topological manifolds
are also implemented via TopologicalManifold
, since they are
topological manifolds by themselves.
In the current setting, topological manifolds are mostly described by
means of charts (see Chart
).
TopologicalManifold
serves as a base class for more specific
manifold classes.
The user interface is provided by the generic function
Manifold()
, with
with the argument structure
set to 'topological'
.
Example 1: the 2-sphere as a topological manifold of dimension 2 over \(\RR\)
One starts by declaring \(S^2\) as a 2-dimensional topological manifold:
sage: M = Manifold(2, 'S^2', structure='topological')
sage: M
2-dimensional topological manifold S^2
Since the base topological field has not been specified in the argument list
of Manifold
, \(\RR\) is assumed:
sage: M.base_field()
Real Field with 53 bits of precision
sage: dim(M)
2
Let us consider the complement of a point, the “North pole” say; this is an open subset of \(S^2\), which we call \(U\):
sage: U = M.open_subset('U'); U
Open subset U of the 2-dimensional topological manifold S^2
A standard chart on \(U\) is provided by the stereographic projection from the North pole to the equatorial plane:
sage: stereoN.<x,y> = U.chart(); stereoN
Chart (U, (x, y))
Thanks to the operator <x,y>
on the left-hand side, the coordinates
declared in a chart (here \(x\) and \(y\)), are accessible by their names;
they are Sage’s symbolic variables:
sage: y
y
sage: type(y)
<type 'sage.symbolic.expression.Expression'>
The South pole is the point of coordinates \((x, y) = (0, 0)\) in the above chart:
sage: S = U.point((0,0), chart=stereoN, name='S'); S
Point S on the 2-dimensional topological manifold S^2
Let us call \(V\) the open subset that is the complement of the South pole and let us introduce on it the chart induced by the stereographic projection from the South pole to the equatorial plane:
sage: V = M.open_subset('V'); V
Open subset V of the 2-dimensional topological manifold S^2
sage: stereoS.<u,v> = V.chart(); stereoS
Chart (V, (u, v))
The North pole is the point of coordinates \((u, v) = (0, 0)\) in this chart:
sage: N = V.point((0,0), chart=stereoS, name='N'); N
Point N on the 2-dimensional topological manifold S^2
To fully construct the manifold, we declare that it is the union of \(U\) and \(V\):
sage: M.declare_union(U,V)
and we provide the transition map between the charts stereoN
=
\((U, (x, y))\) and stereoS
= \((V, (u, v))\), denoting by \(W\) the
intersection of \(U\) and \(V\) (\(W\) is the subset of \(U\) defined by
\(x^2 + y^2 \neq 0\), as well as the subset of \(V\) defined by
\(u^2 + v^2 \neq 0\)):
sage: stereoN_to_S = stereoN.transition_map(stereoS, [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: stereoN_to_S
Change of coordinates from Chart (W, (x, y)) to Chart (W, (u, v))
sage: stereoN_to_S.display()
u = x/(x^2 + y^2)
v = y/(x^2 + y^2)
We give the name W
to the Python variable representing \(W = U \cap V\):
sage: W = U.intersection(V)
The inverse of the transition map is computed by the method
sage.manifolds.chart.CoordChange.inverse()
:
sage: stereoN_to_S.inverse()
Change of coordinates from Chart (W, (u, v)) to Chart (W, (x, y))
sage: stereoN_to_S.inverse().display()
x = u/(u^2 + v^2)
y = v/(u^2 + v^2)
At this stage, we have four open subsets on \(S^2\):
sage: M.list_of_subsets()
[2-dimensional topological manifold S^2,
Open subset U of the 2-dimensional topological manifold S^2,
Open subset V of the 2-dimensional topological manifold S^2,
Open subset W of the 2-dimensional topological manifold S^2]
\(W\) is the open subset that is the complement of the two poles:
sage: N in W or S in W
False
The North pole lies in \(V\) and the South pole in \(U\):
sage: N in V, N in U
(True, False)
sage: S in U, S in V
(True, False)
The manifold’s (user) atlas contains four charts, two of them being restrictions of charts to a smaller domain:
sage: M.atlas()
[Chart (U, (x, y)), Chart (V, (u, v)),
Chart (W, (x, y)), Chart (W, (u, v))]
Let us consider the point of coordinates \((1, 2)\) in the chart stereoN
:
sage: p = M.point((1,2), chart=stereoN, name='p'); p
Point p on the 2-dimensional topological manifold S^2
sage: p.parent()
2-dimensional topological manifold S^2
sage: p in W
True
The coordinates of \(p\) in the chart stereoS
are computed by letting
the chart act on the point:
sage: stereoS(p)
(1/5, 2/5)
Given the definition of \(p\), we have of course:
sage: stereoN(p)
(1, 2)
Similarly:
sage: stereoS(N)
(0, 0)
sage: stereoN(S)
(0, 0)
A continuous map \(S^2 \to \RR\) (scalar field):
sage: f = M.scalar_field({stereoN: atan(x^2+y^2), stereoS: pi/2-atan(u^2+v^2)},
....: name='f')
sage: f
Scalar field f on the 2-dimensional topological manifold S^2
sage: f.display()
f: S^2 --> R
on U: (x, y) |--> arctan(x^2 + y^2)
on V: (u, v) |--> 1/2*pi - arctan(u^2 + v^2)
sage: f(p)
arctan(5)
sage: f(N)
1/2*pi
sage: f(S)
0
sage: f.parent()
Algebra of scalar fields on the 2-dimensional topological manifold S^2
sage: f.parent().category()
Category of commutative algebras over Symbolic Ring
Example 2: the Riemann sphere as a topological manifold of dimension 1 over \(\CC\)
We declare the Riemann sphere \(\CC^*\) as a 1-dimensional topological manifold over \(\CC\):
sage: M = Manifold(1, 'C*', structure='topological', field='complex'); M
Complex 1-dimensional topological manifold C*
We introduce a first open subset, which is actually \(\CC = \CC^*\setminus\{\infty\}\) if we interpret \(\CC^*\) as the Alexandroff one-point compactification of \(\CC\):
sage: U = M.open_subset('U')
A natural chart on \(U\) is then nothing but the identity map of \(\CC\), hence we denote the associated coordinate by \(z\):
sage: Z.<z> = U.chart()
The origin of the complex plane is the point of coordinate \(z = 0\):
sage: O = U.point((0,), chart=Z, name='O'); O
Point O on the Complex 1-dimensional topological manifold C*
Another open subset of \(\CC^*\) is \(V = \CC^*\setminus\{O\}\):
sage: V = M.open_subset('V')
We define a chart on \(V\) such that the point at infinity is the point of coordinate \(0\) in this chart:
sage: W.<w> = V.chart(); W
Chart (V, (w,))
sage: inf = M.point((0,), chart=W, name='inf', latex_name=r'\infty')
sage: inf
Point inf on the Complex 1-dimensional topological manifold C*
To fully construct the Riemann sphere, we declare that it is the union of \(U\) and \(V\):
sage: M.declare_union(U,V)
and we provide the transition map between the two charts as \(w = 1 / z\) on \(A = U \cap V\):
sage: Z_to_W = Z.transition_map(W, 1/z, intersection_name='A',
....: restrictions1= z!=0, restrictions2= w!=0)
sage: Z_to_W
Change of coordinates from Chart (A, (z,)) to Chart (A, (w,))
sage: Z_to_W.display()
w = 1/z
sage: Z_to_W.inverse()
Change of coordinates from Chart (A, (w,)) to Chart (A, (z,))
sage: Z_to_W.inverse().display()
z = 1/w
Let consider the complex number \(i\) as a point of the Riemann sphere:
sage: i = M((I,), chart=Z, name='i'); i
Point i on the Complex 1-dimensional topological manifold C*
Its coordinates w.r.t. the charts Z
and W
are:
sage: Z(i)
(I,)
sage: W(i)
(-I,)
and we have:
sage: i in U
True
sage: i in V
True
The following subsets and charts have been defined:
sage: M.list_of_subsets()
[Open subset A of the Complex 1-dimensional topological manifold C*,
Complex 1-dimensional topological manifold C*,
Open subset U of the Complex 1-dimensional topological manifold C*,
Open subset V of the Complex 1-dimensional topological manifold C*]
sage: M.atlas()
[Chart (U, (z,)), Chart (V, (w,)), Chart (A, (z,)), Chart (A, (w,))]
A constant map \(\CC^* \rightarrow \CC\):
sage: f = M.constant_scalar_field(3+2*I, name='f'); f
Scalar field f on the Complex 1-dimensional topological manifold C*
sage: f.display()
f: C* --> C
on U: z |--> 2*I + 3
on V: w |--> 2*I + 3
sage: f(O)
2*I + 3
sage: f(i)
2*I + 3
sage: f(inf)
2*I + 3
sage: f.parent()
Algebra of scalar fields on the Complex 1-dimensional topological
manifold C*
sage: f.parent().category()
Category of commutative algebras over Symbolic Ring
AUTHORS:
- Eric Gourgoulhon (2015): initial version
- Travis Scrimshaw (2015): structure described via
TopologicalStructure
orRealTopologicalStructure
REFERENCES:
-
sage.manifolds.manifold.
Manifold
(dim, name, latex_name=None, field='real', structure='smooth', start_index=0, **extra_kwds)¶ Construct a manifold of a given type over a topological field.
Given a topological field \(K\) (in most applications, \(K = \RR\) or \(K = \CC\)) and a non-negative integer \(n\), a topological manifold of dimension \(n\) over K is a topological space \(M\) such that
- \(M\) is a Hausdorff space,
- \(M\) is second countable, and
- every point in \(M\) has a neighborhood homeomorphic to \(K^n\).
A real manifold is a manifold over \(\RR\). A differentiable (resp. smooth, resp. analytic) manifold is a manifold such that all transition maps are differentiable (resp. smooth, resp. analytic). A pseudo-Riemannian manifold is a real differentiable manifold equipped with a metric tensor \(g\) (i.e. a field of non-degenerate symmetric bilinear forms), with the two subcases of Riemannian manifold (\(g\) positive-definite) and Lorentzian manifold (\(g\) has signature \(n-2\) or \(2-n\)).
INPUT:
dim
– positive integer; dimension of the manifoldname
– string; name (symbol) given to the manifoldlatex_name
– (default:None
) string; LaTeX symbol to denote the manifold; if none are provided, it is set toname
field
– (default:'real'
) field \(K\) on which the manifold is defined; allowed values are'real'
or an object of typeRealField
(e.g.RR
) for a manifold over \(\RR\)'complex'
or an object of typeComplexField
(e.g.CC
) for a manifold over \(\CC\)- an object in the category of topological fields (see
Fields
andTopologicalSpaces
) for other types of manifolds
structure
– (default:'smooth'
) to specify the structure or type of manifold; allowed values are'topological'
or'top'
for a topological manifold'differentiable'
or'diff'
for a differentiable manifold'smooth'
for a smooth manifold'analytic'
for an analytic manifold'pseudo-Riemannian'
for a real differentiable manifold equipped with a pseudo-Riemannian metric; the signature is specified via the keyword argumentsignature
(see below)'Riemannian'
for a real differentiable manifold equipped with a Riemannian (i.e. positive definite) metric'Lorentzian'
for a real differentiable manifold equipped with a Lorentzian metric; the signature convention is specified by the keyword argumentsignature='positive'
(default) or'negative'
start_index
– (default: 0) integer; lower value of the range of indices used for “indexed objects” on the manifold, e.g. coordinates in a chartextra_kwds
– keywords meaningful only for some specific types of manifolds:diff_degree
– (only for differentiable manifolds; default:infinity
): the degree of differentiabilityambient
– (only to construct a submanifold): the ambient manifoldmetric_name
– (only for pseudo-Riemannian manifolds; default:'g'
) string; name (symbol) given to the metricmetric_latex_name
– (only for pseudo-Riemannian manifolds; default:None
) string; LaTeX symbol to denote the metric; if none is provided, the symbol is set tometric_name
signature
– (only for pseudo-Riemannian manifolds; default:None
) signature \(S\) of the metric as a single integer: \(S = n_+ - n_-\), where \(n_+\) (resp. \(n_-\)) is the number of positive terms (resp. negative terms) in any diagonal writing of the metric components; ifsignature
is not provided, \(S\) is set to the manifold’s dimension (Riemannian signature); for Lorentzian manifolds the valuessignature='positive'
(default) orsignature='negative'
are allowed to indicate the chosen signature convention.
OUTPUT:
- a manifold of the specified type, as an instance of
TopologicalManifold
or one of its subclassesDifferentiableManifold
orPseudoRiemannianManifold
EXAMPLES:
A 3-dimensional real topological manifold:
sage: M = Manifold(3, 'M', structure='topological'); M 3-dimensional topological manifold M
Given the default value of the parameter
field
, the above is equivalent to:sage: M = Manifold(3, 'M', structure='topological', field='real'); M 3-dimensional topological manifold M
A complex topological manifold:
sage: M = Manifold(3, 'M', structure='topological', field='complex'); M Complex 3-dimensional topological manifold M
A topological manifold over \(\QQ\):
sage: M = Manifold(3, 'M', structure='topological', field=QQ); M 3-dimensional topological manifold M over the Rational Field
A 3-dimensional real differentiable manifold of class \(C^4\):
sage: M = Manifold(3, 'M', field='real', structure='differentiable', ....: diff_degree=4); M 3-dimensional differentiable manifold M
Since the default value of the parameter
field
is'real'
, the above is equivalent to:sage: M = Manifold(3, 'M', structure='differentiable', diff_degree=4) sage: M 3-dimensional differentiable manifold M sage: M.base_field_type() 'real'
A 3-dimensional real smooth manifold:
sage: M = Manifold(3, 'M', structure='differentiable', diff_degree=+oo) sage: M 3-dimensional differentiable manifold M
Instead of
structure='differentiable', diff_degree=+oo
, it suffices to usestructure='smooth'
to get the same result:sage: M = Manifold(3, 'M', structure='smooth'); M 3-dimensional differentiable manifold M sage: M.diff_degree() +Infinity
Actually, since
'smooth'
is the default value of the parameterstructure
, the creation of a real smooth manifold can be shortened to:sage: M = Manifold(3, 'M'); M 3-dimensional differentiable manifold M sage: M.diff_degree() +Infinity
For a complex smooth manifold, we have to set the parameter
field
:sage: M = Manifold(3, 'M', field='complex'); M 3-dimensional complex manifold M sage: M.diff_degree() +Infinity
See the documentation of classes
TopologicalManifold
,DifferentiableManifold
andPseudoRiemannianManifold
for more detailed examples.Uniqueness of manifold objects
Suppose we construct a manifold named \(M\):
sage: M = Manifold(2, 'M', structure='topological') sage: X.<x,y> = M.chart()
At some point, we change our mind and would like to restart with a new manifold, using the same name \(M\) and keeping the previous manifold for reference:
sage: M_old = M # for reference sage: M = Manifold(2, 'M', structure='topological')
This results in a brand new object:
sage: M.atlas() []
The object
M_old
is intact:sage: M_old.atlas() [Chart (M, (x, y))]
Both objects have the same display:
sage: M 2-dimensional topological manifold M sage: M_old 2-dimensional topological manifold M
but they are different:
sage: M != M_old True
Let us introduce a chart on
M
, using the same coordinate symbols as forM_old
:sage: X.<x,y> = M.chart()
The charts are displayed in the same way:
sage: M.atlas() [Chart (M, (x, y))] sage: M_old.atlas() [Chart (M, (x, y))]
but they are actually different:
sage: M.atlas()[0] != M_old.atlas()[0] True
Moreover, the two manifolds
M
andM_old
are still considered distinct:sage: M != M_old True
This reflects the fact that the equality of manifold objects holds only for identical objects, i.e. one has
M1 == M2
if, and only if,M1 is M2
. Actually, the manifold classes inherit fromWithEqualityById
:sage: isinstance(M, sage.misc.fast_methods.WithEqualityById) True
-
sage.manifolds.manifold.
TopologicalManifold
¶ Topological manifold over a topological field \(K\).
Given a topological field \(K\) (in most applications, \(K = \RR\) or \(K = \CC\)) and a non-negative integer \(n\), a topological manifold of dimension \(n\) over K is a topological space \(M\) such that
- \(M\) is a Hausdorff space,
- \(M\) is second countable, and
- every point in \(M\) has a neighborhood homeomorphic to \(K^n\).
This is a Sage parent class, the corresponding element class being
ManifoldPoint
.INPUT:
n
– positive integer; dimension of the manifoldname
– string; name (symbol) given to the manifoldfield
– field \(K\) on which the manifold is defined; allowed values are'real'
or an object of typeRealField
(e.g.,RR
) for a manifold over \(\RR\)'complex'
or an object of typeComplexField
(e.g.,CC
) for a manifold over \(\CC\)- an object in the category of topological fields (see
Fields
andTopologicalSpaces
) for other types of manifolds
structure
– manifold structure (seeTopologicalStructure
orRealTopologicalStructure
)base_manifold
– (default:None
) if notNone
, must be a topological manifold; the created object is then an open subset ofbase_manifold
latex_name
– (default:None
) string; LaTeX symbol to denote the manifold; if none are provided, it is set toname
start_index
– (default: 0) integer; lower value of the range of indices used for “indexed objects” on the manifold, e.g., coordinates in a chartcategory
– (default:None
) to specify the category; ifNone
,Manifolds(field)
is assumed (see the categoryManifolds
)unique_tag
– (default:None
) tag used to force the construction of a new object when all the other arguments have been used previously (withoutunique_tag
, theUniqueRepresentation
behavior inherited fromManifoldSubset
would return the previously constructed object corresponding to these arguments)
EXAMPLES:
A 4-dimensional topological manifold (over \(\RR\)):
sage: M = Manifold(4, 'M', latex_name=r'\mathcal{M}', structure='topological') sage: M 4-dimensional topological manifold M sage: latex(M) \mathcal{M} sage: type(M) <class 'sage.manifolds.manifold.TopologicalManifold_with_category'> sage: M.base_field() Real Field with 53 bits of precision sage: dim(M) 4
The input parameter
start_index
defines the range of indices on the manifold:sage: M = Manifold(4, 'M', structure='topological') sage: list(M.irange()) [0, 1, 2, 3] sage: M = Manifold(4, 'M', structure='topological', start_index=1) sage: list(M.irange()) [1, 2, 3, 4] sage: list(Manifold(4, 'M', structure='topological', start_index=-2).irange()) [-2, -1, 0, 1]
A complex manifold:
sage: N = Manifold(3, 'N', structure='topological', field='complex'); N Complex 3-dimensional topological manifold N
A manifold over \(\QQ\):
sage: N = Manifold(6, 'N', structure='topological', field=QQ); N 6-dimensional topological manifold N over the Rational Field
A manifold over \(\QQ_5\), the field of 5-adic numbers:
sage: N = Manifold(2, 'N', structure='topological', field=Qp(5)); N 2-dimensional topological manifold N over the 5-adic Field with capped relative precision 20
A manifold is a Sage parent object, in the category of topological manifolds over a given topological field (see
Manifolds
):sage: isinstance(M, Parent) True sage: M.category() Category of manifolds over Real Field with 53 bits of precision sage: from sage.categories.manifolds import Manifolds sage: M.category() is Manifolds(RR) True sage: M.category() is Manifolds(M.base_field()) True sage: M in Manifolds(RR) True sage: N in Manifolds(Qp(5)) True
The corresponding Sage elements are points:
sage: X.<t, x, y, z> = M.chart() sage: p = M.an_element(); p Point on the 4-dimensional topological manifold M sage: p.parent() 4-dimensional topological manifold M sage: M.is_parent_of(p) True sage: p in M True
The manifold’s points are instances of class
ManifoldPoint
:sage: isinstance(p, sage.manifolds.point.ManifoldPoint) True
Since an open subset of a topological manifold \(M\) is itself a topological manifold, open subsets of \(M\) are instances of the class
TopologicalManifold
:sage: U = M.open_subset('U'); U Open subset U of the 4-dimensional topological manifold M sage: isinstance(U, sage.manifolds.manifold.TopologicalManifold) True sage: U.base_field() == M.base_field() True sage: dim(U) == dim(M) True sage: U.category() Join of Category of subobjects of sets and Category of manifolds over Real Field with 53 bits of precision
The manifold passes all the tests of the test suite relative to its category:
sage: TestSuite(M).run()
See also