summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTravis Scrimshaw <tscrimsh at umn.edu>2015-11-25 14:48:06 -0600
committerTravis Scrimshaw <tscrimsh at umn.edu>2015-11-25 14:51:48 -0600
commit0fb39df7fafe7f0a765bf73b3f34a6cb41e65c40 (patch)
tree87d88971cc898e7aa11b48aebf067732249c1823
parentSome small tweaks as part of the review. (diff)
Refactoring the code to separate out the structural part of the manifold.u/tscrim/top_manifolds_refactor
-rw-r--r--src/sage/manifolds/abstract.py620
-rw-r--r--src/sage/manifolds/all.py2
-rw-r--r--src/sage/manifolds/chart.py114
-rw-r--r--src/sage/manifolds/manifold.py652
-rw-r--r--src/sage/manifolds/point.py143
-rw-r--r--src/sage/manifolds/structure.py52
-rw-r--r--src/sage/manifolds/subset.py824
7 files changed, 1335 insertions, 1072 deletions
diff --git a/src/sage/manifolds/abstract.py b/src/sage/manifolds/abstract.py
new file mode 100644
index 00000000..c0c012f
--- /dev/null
+++ b/src/sage/manifolds/abstract.py
@@ -0,0 +1,620 @@
+r"""
+Abstract objects and sets
+
+These are base classes for the manifolds.
+
+AUTHORS:
+
+- Eric Gourgoulhon (2015): initial version
+- Travis Scrimshaw (2015-11-25): Initial version
+"""
+
+#*****************************************************************************
+# Copyright (C) 2015 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
+# Copyright (C) 2015 Michal Bejger <bejger@camk.edu.pl>
+#
+# Distributed under the terms of the GNU General Public License (GPL)
+# as published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+# http://www.gnu.org/licenses/
+#*****************************************************************************
+
+from sage.structure.parent import Parent
+from sage.misc.fast_methods import Singleton, WithEqualityById
+from sage.categories.fields import Fields
+from sage.categories.manifolds import Manifolds
+from sage.categories.sets_cat import Sets
+from sage.rings.integer import Integer
+from sage.manifolds.point import ManifoldPoint
+
+class AbstractObject(object):
+ """
+ An abstract object.
+
+ An abstract object is a variable name and latex name.
+ """
+ def __init__(self, name, latex_name=None):
+ """
+ Initialize ``self``.
+ """
+ if not isinstance(name, str):
+ raise TypeError("{} is not a string".format(name))
+ self._name = name
+
+ if latex_name is None:
+ self._latex_name = self._name
+ else:
+ if not isinstance(latex_name, str):
+ raise TypeError("{} is not a string".format(latex_name))
+ self._latex_name = latex_name
+
+ def _repr_(self):
+ """
+ Return a string representation of ``self``.
+ """
+ return self._name
+
+ def _latex_(self):
+ r"""
+ LaTeX representation of ``self``.
+
+ TESTS::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: A = M.subset('A')
+ sage: A._latex_()
+ 'A'
+ sage: B = A.subset('B', latex_name=r'\mathcal{B}')
+ sage: B._latex_()
+ '\\mathcal{B}'
+ sage: latex(B) # indirect doctest
+ \mathcal{B}
+
+ sage: M = Manifold(3, 'M', structure='topological')
+ sage: M._latex_()
+ 'M'
+ sage: latex(M)
+ M
+ sage: M = Manifold(3, 'M', latex_name=r'\mathcal{M}',
+ ....: structure='topological')
+ sage: M._latex_()
+ '\\mathcal{M}'
+ sage: latex(M)
+ \mathcal{M}
+ """
+ return self._latex_name
+
+class AbstractSet(AbstractObject, WithEqualityById, Parent):
+ """
+ An abstract set.
+
+ An abstract set is an :class:`AbstractObject` along with its known
+ subsets, supersets, intersections, unions, and open covers.
+ """
+ def __init__(self, name, latex_name, base=None, category=None):
+ r"""
+ Initialize ``self``
+
+ TESTS::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: A = M.subset('A'); A
+ Subset A of the 2-dimensional topological manifold M
+ """
+ AbstractObject.__init__(self, name, latex_name)
+
+ category = Sets().or_subcategory(category)
+ Parent.__init__(self, base=base, category=category)
+
+ self._supersets = set([self]) # subsets containing self
+ self._subsets = set([self]) # subsets of self
+ self._top_subsets = set([self]) # subsets contained in self but not
+ # in another strict subset of self
+ self._intersections = {} # dict. of intersections with other subsets
+ # (key: subset name)
+ self._unions = {} # dict. of unions with other subsets (key: subset
+ # name)
+ self._open_covers = set() # set of open covers of self
+
+ #### Methods required for any Parent in the category of sets:
+
+ def _element_constructor_(self, coords=None, chart=None, name=None,
+ latex_name=None, check_coords=True):
+ r"""
+ Construct a point in the subset from its coordinates in some chart.
+
+ INPUT:
+
+ - ``coords`` -- (default: ``None``) either (i) the point coordinates
+ (as a tuple or a list) in the chart ``chart`` or (ii) another point
+ in the subset
+ - ``chart`` -- (default: ``None``) chart in which the coordinates are
+ given; if none is provided, the coordinates are assumed to refer to
+ the subset's default chart
+ - ``name`` -- (default: ``None``) name given to the point
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
+ point; if none is provided, the LaTeX symbol is set to ``name``
+ - ``check_coords`` -- (default: ``True``) determines whether ``coords``
+ are valid coordinates for the chart ``chart``; for symbolic
+ coordinates, it is recommended to set ``check_coords`` to ``False``.
+
+ OUTPUT:
+
+ - an instance of :class:`~sage.manifolds.point.ManifoldPoint`
+ representing a point in the current subset.
+
+ EXAMPLES::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: p = M((-2,3)); p # coord in the default chart
+ Point on the 2-dimensional topological manifold M
+ sage: X(p)
+ (-2, 3)
+
+ A generic subset has no default chart, so the chart must be explicited::
+
+ sage: A = M.subset('A')
+ sage: p = A((-2,3), chart=X); p
+ Point on the 2-dimensional topological manifold M
+ sage: X(p)
+ (-2, 3)
+ sage: p.containing_set()
+ Subset A of the 2-dimensional topological manifold M
+ sage: p in A
+ True
+
+ Coordinates in a chart with some coordinate restrictions::
+
+ sage: Y.<u,v> = M.chart('u:(-1,1) v:(-1,1)')
+ sage: p = A((0,1/2), chart=Y); p
+ Point on the 2-dimensional topological manifold M
+ sage: Y(p)
+ (0, 1/2)
+ sage: p = A((0,1/2), chart=Y, check_coords=False); p
+ Point on the 2-dimensional topological manifold M
+ sage: Y(p)
+ (0, 1/2)
+ sage: p = A((3,1/2), chart=Y)
+ Traceback (most recent call last):
+ ...
+ ValueError: the coordinates (3, 1/2) are not valid on the Chart (M, (u, v))
+
+ Specifying the name of the point::
+
+ sage: p = A((-2,3), chart=X, name='p'); p
+ Point p on the 2-dimensional topological manifold M
+
+ A point as entry::
+
+ sage: q = A(p); q
+ Point p on the 2-dimensional topological manifold M
+ sage: X(q)
+ (-2, 3)
+
+ """
+ if isinstance(coords, ManifoldPoint):
+ point = coords # for readability
+ # This should actually never happen by the coercion framework...
+ if point.parent() is self:
+ return point
+ if point in self:
+ resu = self.element_class(self, name=point._name,
+ latex_name=point._latex_name)
+ for chart, coords in point._coordinates.iteritems():
+ resu._coordinates[chart] = coords
+ return resu
+ else:
+ raise ValueError("the {}".format(point) +
+ " is not in {}".format(self))
+ return self.element_class(self, coords=coords, chart=chart, name=name,
+ latex_name=latex_name, check_coords=check_coords)
+
+ def _an_element_(self):
+ r"""
+ Construct some point in the subset.
+
+ EXAMPLES::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: A = M.subset('A')
+ sage: p = A._an_element_(); p
+ Point on the 2-dimensional topological manifold M
+ sage: p in A
+ True
+
+ """
+ #!# should be improved...
+ return self.element_class(self)
+
+ #### End of methods required for any Parent in the category of sets
+
+ def open_covers(self):
+ r"""
+ Return the list of open covers of the current subset.
+
+ If the current subset, `A` say, is a subset of the manifold `M`, an
+ *open cover* of `A` is list (indexed set) `(U_i)_{i\in I}` of
+ open subsets of `M` such that
+
+ .. MATH::
+
+ A \subset \bigcup_{i \in I} U_i
+
+ If `A` is open, we ask that the above inclusion is actually an
+ identity:
+
+ .. MATH::
+
+ A = \bigcup_{i \in I} U_i
+
+ EXAMPLES::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: M.open_covers()
+ [[2-dimensional topological manifold M]]
+ sage: U = M.open_subset('U')
+ sage: U.open_covers()
+ [[Open subset U of the 2-dimensional topological manifold M]]
+ sage: A = U.open_subset('A')
+ sage: B = U.open_subset('B')
+ sage: U.declare_union(A,B)
+ sage: U.open_covers()
+ [[Open subset U of the 2-dimensional topological manifold M],
+ [Open subset A of the 2-dimensional topological manifold M,
+ Open subset B of the 2-dimensional topological manifold M]]
+ sage: V = M.open_subset('V')
+ sage: M.declare_union(U,V)
+ sage: M.open_covers()
+ [[2-dimensional topological manifold M],
+ [Open subset U of the 2-dimensional topological manifold M,
+ Open subset V of the 2-dimensional topological manifold M],
+ [Open subset A of the 2-dimensional topological manifold M,
+ Open subset B of the 2-dimensional topological manifold M,
+ Open subset V of the 2-dimensional topological manifold M]]
+
+ """
+ return sorted(sorted(oc, key=lambda x: x._name) for oc in self._open_covers)
+
+ def subsets(self):
+ r"""
+ Return the set of subsets that have been defined on the current subset.
+
+ OUTPUT:
+
+ - A Python set containing all the subsets that have been defined on
+ the current subset.
+
+ .. NOTE::
+
+ To get the subsets as a list, used the method
+ :meth:`list_of_subsets` instead.
+
+ EXAMPLE:
+
+ Subsets of a 2-dimensional manifold::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: U = M.open_subset('U')
+ sage: V = M.subset('V')
+ sage: M.subsets() # random (set output)
+ {Subset V of the 2-dimensional topological manifold M,
+ 2-dimensional topological manifold M,
+ Open subset U of the 2-dimensional topological manifold M}
+ sage: type(M.subsets())
+ <type 'frozenset'>
+ sage: U in M.subsets()
+ True
+
+ The method :meth:`list_of_subsets` returns a list (sorted
+ alphabetically by the subset names) instead of a set::
+
+ sage: M.list_of_subsets()
+ [2-dimensional topological manifold M,
+ Open subset U of the 2-dimensional topological manifold M,
+ Subset V of the 2-dimensional topological manifold M]
+
+ """
+ return frozenset(self._subsets)
+
+ # Do we need this?
+ def list_of_subsets(self):
+ r"""
+ Return the list of subsets that have been defined on the current
+ subset.
+
+ The list is sorted by the alphabetical names of the subsets.
+
+ OUTPUT:
+
+ - A list containing all the subsets that have been defined on
+ the current subset.
+
+ .. NOTE::
+
+ To get the subsets as a Python set, used the method
+ :meth:`subsets` instead.
+
+ EXAMPLE:
+
+ Subsets of a 2-dimensional manifold::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: U = M.open_subset('U')
+ sage: V = M.subset('V')
+ sage: M.list_of_subsets()
+ [2-dimensional topological manifold M,
+ Open subset U of the 2-dimensional topological manifold M,
+ Subset V of the 2-dimensional topological manifold M]
+
+ The method :meth:`subsets` returns a set instead of a list::
+
+ sage: M.subsets() # random (set output)
+ {Subset V of the 2-dimensional topological manifold M,
+ 2-dimensional topological manifold M,
+ Open subset U of the 2-dimensional topological manifold M}
+
+ """
+ return sorted(self._subsets, key=lambda x: x._name)
+
+ def subset(self, name, latex_name=None, is_open=False):
+ r"""
+ Create a subset of ``self``.
+
+ INPUT:
+
+ - ``name`` -- name given to the subset
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
+ subset; if none is provided, it is set to ``name``
+ - ``is_open`` -- (default: ``False``) if ``True``, the created subset
+ is assumed to be open with respect to the manifold's topology
+
+ OUTPUT:
+
+ - the subset, as an instance of :class:`ManifoldSubset`, or
+ of the derived class
+ :class:`~sage.manifolds.manifold.Manifold` if ``is_open``
+ is ``True``.
+
+ EXAMPLES:
+
+ Creating a subset of a manifold::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: a = M.subset('A'); a
+ Subset A of the 2-dimensional topological manifold M
+
+ Creating a subset of A::
+
+ sage: b = a.subset('B', latex_name=r'\mathcal{B}'); b
+ Subset B of the 2-dimensional topological manifold M
+ sage: latex(b)
+ \mathcal{B}
+
+ We have then::
+
+ sage: b.is_subset(a)
+ True
+ sage: b in a.subsets()
+ True
+ """
+ if is_open:
+ return self.open_subset(name, latex_name=latex_name)
+ from sage.manifolds.subset import ManifoldSubset
+ res = ManifoldSubset(self.manifold(), name,
+ latex_name=latex_name)
+ res._supersets.update(self._supersets)
+ for sd in self._supersets:
+ sd._subsets.add(res)
+ self._top_subsets.add(res)
+ return res
+
+ def get_subset(self, name):
+ r"""
+ Get a subset by its name.
+
+ The subset must have been previously created by the method
+ :meth:`subset` (or
+ :meth:`~sage.manifolds.manifold.Manifold.open_subset`)
+
+ INPUT:
+
+ - ``name`` -- (string) name of the subset
+
+ OUTPUT:
+
+ - instance of :class:`ManifoldSubset` (or
+ of the derived class
+ :class:`~sage.manifolds.manifold.Manifold` for an open
+ subset) representing the subset whose name is ``name``.
+
+ EXAMPLES::
+
+ sage: M = Manifold(4, 'M', structure='topological')
+ sage: A = M.subset('A')
+ sage: B = A.subset('B')
+ sage: U = M.open_subset('U')
+ sage: M.list_of_subsets()
+ [Subset A of the 4-dimensional topological manifold M,
+ Subset B of the 4-dimensional topological manifold M,
+ 4-dimensional topological manifold M,
+ Open subset U of the 4-dimensional topological manifold M]
+ sage: M.get_subset('A')
+ Subset A of the 4-dimensional topological manifold M
+ sage: M.get_subset('A') is A
+ True
+ sage: M.get_subset('B') is B
+ True
+ sage: A.get_subset('B') is B
+ True
+ sage: M.get_subset('U')
+ Open subset U of the 4-dimensional topological manifold M
+ sage: M.get_subset('U') is U
+ True
+
+ """
+ for ss in self._subsets:
+ if ss._name == name:
+ return ss
+ raise ValueError("no subset of name '{}' found".format(name))
+
+ def is_subset(self, other):
+ r"""
+ Return ``True`` iff ``self`` is included in ``other``.
+
+ EXAMPLES:
+
+ Subsets on a 2-dimensional manifold::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: a = M.subset('A')
+ sage: b = a.subset('B')
+ sage: c = M.subset('C')
+ sage: a.is_subset(M)
+ True
+ sage: b.is_subset(a)
+ True
+ sage: b.is_subset(M)
+ True
+ sage: a.is_subset(b)
+ False
+ sage: c.is_subset(a)
+ False
+ """
+ return self in other._subsets
+
+ def __contains__(self, point):
+ r"""
+ Check whether ``point`` is contained in ``self``.
+
+ TESTS::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: A = M.subset('A')
+ sage: p = A((-2,3), chart=X); p
+ Point on the 2-dimensional topological manifold M
+ sage: A.__contains__(p)
+ True
+ sage: p in A # indirect doctest
+ True
+ sage: A.__contains__(A.an_element())
+ True
+ sage: q = M((0,0), chart=X); q
+ Point on the 2-dimensional topological manifold M
+ sage: A.__contains__(q)
+ False
+ """
+ # for efficiency, a quick test first:
+ if point.parent() is self:
+ return True
+ if point.parent().is_subset(self):
+ return True
+ #!# should be improved once coordinate definition have been introduced
+ # in ManifoldSubset
+ return False
+
+ def declare_union(self, dom1, dom2):
+ r"""
+ Declare that the current subset is the union of two subsets,
+ i.e. that
+
+ .. MATH::
+
+ U = U_1 \cup U_2,
+
+ where `U` is the current subset, `U_1 \subset U` and `U_2 \subset U`.
+
+ INPUT:
+
+ - ``dom1`` -- subset `U_1`
+ - ``dom2`` -- subset `U_2`
+
+ EXAMPLE::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: A = M.subset('A')
+ sage: B = M.subset('B')
+ sage: M.declare_union(A, B)
+ sage: A.union(B)
+ 2-dimensional topological manifold M
+
+ """
+ if dom1 == dom2:
+ if dom1 != self:
+ raise ValueError("the union of two identical sets must be " +
+ "this set")
+ return
+ if not dom1.is_subset(self):
+ raise TypeError("the {} is not a subset of ".format(dom1) +
+ "the {}".format(self))
+ if not dom2.is_subset(self):
+ raise TypeError("the {} is not a subset of ".format(dom2) +
+ "the {}".format(self))
+ dom1._unions[dom2._name] = self
+ dom2._unions[dom1._name] = self
+ for oc1 in dom1._open_covers:
+ for oc2 in dom2._open_covers:
+ oc = set(oc1) # Make a (shallow) copy
+ for s in oc2:
+ if s not in oc:
+ oc.add(s)
+ self._open_covers.add(frozenset(oc))
+
+ def is_open(self):
+ """
+ Return if ``self`` is an open set.
+ """
+ return True
+
+ def point(self, coords=None, chart=None, name=None, latex_name=None):
+ r"""
+ Define a point in ``self``.
+
+ See :class:`~sage.manifolds.point.ManifoldPoint` for a
+ complete documentation.
+
+ INPUT:
+
+ - ``coords`` -- the point coordinates (as a tuple or a list) in the
+ chart specified by ``chart``
+ - ``chart`` -- (default: ``None``) chart in which the point coordinates
+ are given; if ``None``, the coordinates are assumed to refer to
+ the default chart of the current subset
+ - ``name`` -- (default: ``None``) name given to the point
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
+ point; if ``None``, the LaTeX symbol is set to ``name``
+
+ OUTPUT:
+
+ - the declared point, as an instance of
+ :class:`~sage.manifolds.point.ManifoldPoint`.
+
+ EXAMPLES:
+
+ Points on a 2-dimensional manifold::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: c_xy.<x,y> = M.chart()
+ sage: p = M.point((1,2), name='p'); p
+ Point p on the 2-dimensional topological manifold M
+ sage: p in M
+ True
+ sage: a = M.open_subset('A')
+ sage: c_uv.<u,v> = a.chart()
+ sage: q = a.point((-1,0), name='q'); q
+ Point q on the 2-dimensional topological manifold M
+ sage: q in a
+ True
+ sage: p._coordinates
+ {Chart (M, (x, y)): (1, 2)}
+ sage: q._coordinates
+ {Chart (A, (u, v)): (-1, 0)}
+ """
+ return self.element_class(self, coords=coords, chart=chart,
+ name=name, latex_name=latex_name)
+
+ Element = ManifoldPoint
+
diff --git a/src/sage/manifolds/all.py b/src/sage/manifolds/all.py
index c7defde..367ca68 100644
--- a/src/sage/manifolds/all.py
+++ b/src/sage/manifolds/all.py
@@ -1,2 +1,2 @@
from sage.misc.lazy_import import lazy_import
-lazy_import('sage.manifolds.manifold', 'Manifold')
+lazy_import('sage.manifolds.manifold', 'manifold_constructor', 'Manifold')
diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py
index 660007b..8101cca 100644
--- a/src/sage/manifolds/chart.py
+++ b/src/sage/manifolds/chart.py
@@ -36,16 +36,15 @@ from sage.misc.fast_methods import WithEqualityById
from sage.symbolic.ring import SR
from sage.rings.infinity import Infinity
from sage.misc.latex import latex
-from sage.manifolds.manifold import TopologicalManifold
class Chart(WithEqualityById, SageObject):
r"""
- Chart on a topological manifold.
+ Chart on a manifold.
- Given a topological manifold `M` of dimension `n` over a topological field
- `K`, a *chart* on `M` is a pair `(U,\varphi)`, where `U` is an open subset
- of `M` and `\varphi: U \rightarrow V \subset K^n` is a homeomorphism from
- `U` to an open subset `V` of `K^n`.
+ Given a (topological) manifold `M` of dimension `n` over a topological
+ field `K`, a *chart* on `M` is a pair `(U,\varphi)`, where `U` is an
+ open subset of `M` and `\varphi: U \rightarrow V \subset K^n` is a
+ homeomorphism from `U` to an open subset `V` of `K^n`.
The components `(x^1, \ldots, x^n)` of `\varphi`, defined by
`\varphi(p) = (x^1(p), \ldots, x^n(p)) \in K^n` for any point
@@ -54,7 +53,7 @@ class Chart(WithEqualityById, SageObject):
INPUT:
- ``domain`` -- open subset `U` on which the chart is defined (must be
- an instance of :class:`~sage.manifolds.manifold.TopologicalManifold`)
+ an instance of :class:`~sage.manifolds.manifold.Manifold`)
- ``coordinates`` -- (default: ``''`` (empty string)) single string
defining the coordinate symbols, with ``' '`` (whitespace) as a
separator; each item has at most two fields, separated by ``:``:
@@ -78,7 +77,7 @@ class Chart(WithEqualityById, SageObject):
A chart on a complex 2-dimensional topological manifold::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X = M.chart('x y'); X
Chart (M, (x, y))
sage: latex(X)
@@ -95,7 +94,7 @@ class Chart(WithEqualityById, SageObject):
side of the chart declaration (there is then no need to pass the string
``'x y'`` to ``chart()``)::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x,y> = M.chart(); X
Chart (M, (x, y))
@@ -110,7 +109,7 @@ class Chart(WithEqualityById, SageObject):
names and do not have to coincide with the coordinate symbols;
for instance, one may write::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x1,y1> = M.chart('x y'); X
Chart (M, (x, y))
@@ -127,7 +126,7 @@ class Chart(WithEqualityById, SageObject):
However, having the name of the Python variable coincide with the
coordinate symbol is quite convenient; so it is recommended to declare::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x,y> = M.chart()
In the above example, the chart X covers entirely the manifold ``M``::
@@ -169,7 +168,7 @@ class Chart(WithEqualityById, SageObject):
default, it starts at 0, but this can be changed via the parameter
``start_index``::
- sage: M1 = Manifold(2, 'M_1', field='complex', type='topological',
+ sage: M1 = Manifold(2, 'M_1', field='complex', structure='topological',
....: start_index=1)
sage: Z.<u,v> = M1.chart()
sage: Z[1], Z[2]
@@ -194,7 +193,7 @@ class Chart(WithEqualityById, SageObject):
Manifold subsets have a *default chart*, which, unless changed via the
method
- :meth:`~sage.manifolds.manifold.TopologicalManifold.set_default_chart`,
+ :meth:`~sage.manifolds.manifold.Manifold.set_default_chart`,
is the first defined chart on the subset (or on a open subset of it)::
sage: M.default_chart()
@@ -228,7 +227,7 @@ class Chart(WithEqualityById, SageObject):
TESTS::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x,y> = M.chart()
sage: X
Chart (M, (x, y))
@@ -239,7 +238,8 @@ class Chart(WithEqualityById, SageObject):
sage: TestSuite(X).run()
"""
- if not isinstance(domain, TopologicalManifold):
+ from sage.manifolds.manifold import Manifold
+ if not isinstance(domain, Manifold):
raise TypeError("the first argument must be an open subset of " +
"a topological manifold")
if coordinates == '':
@@ -313,7 +313,7 @@ class Chart(WithEqualityById, SageObject):
TESTS::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<z1, z2> = M.chart()
sage: X._init_coordinates(['z1', 'z2'])
sage: X
@@ -344,7 +344,7 @@ class Chart(WithEqualityById, SageObject):
TESTS::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x,y> = M.chart()
sage: X
Chart (M, (x, y))
@@ -358,7 +358,7 @@ class Chart(WithEqualityById, SageObject):
TESTS::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x,y> = M.chart()
sage: X._latex_()
'\\left(M,(x, y)\\right)'
@@ -394,7 +394,7 @@ class Chart(WithEqualityById, SageObject):
TESTS::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: X.__reduce__()
(<class 'sage.manifolds.chart.RealChart'>,
@@ -426,7 +426,7 @@ class Chart(WithEqualityById, SageObject):
TESTS::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: X.__getstate__()
[]
@@ -448,7 +448,7 @@ class Chart(WithEqualityById, SageObject):
TESTS::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: X._restrictions
[]
@@ -472,7 +472,7 @@ class Chart(WithEqualityById, SageObject):
TESTS::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: X._test_pickling()
sage: X.add_restrictions(x < 0)
@@ -502,7 +502,7 @@ class Chart(WithEqualityById, SageObject):
EXAMPLES::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x,y> = M.chart()
sage: X[0]
x
@@ -513,7 +513,7 @@ class Chart(WithEqualityById, SageObject):
The index range is controlled by the parameter ``start_index``::
- sage: M = Manifold(2, 'M', field='complex', type='topological',
+ sage: M = Manifold(2, 'M', field='complex', structure='topological',
....: start_index=1)
sage: X.<x,y> = M.chart()
sage: X[1]
@@ -554,7 +554,7 @@ class Chart(WithEqualityById, SageObject):
EXAMPLES::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x,y> = M.chart()
sage: p = M.point((1+i, 2-i), chart=X)
sage: X(p)
@@ -571,7 +571,7 @@ class Chart(WithEqualityById, SageObject):
EXAMPLES::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: X.domain()
2-dimensional topological manifold M
@@ -589,7 +589,7 @@ class Chart(WithEqualityById, SageObject):
EXAMPLES::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: U = M.open_subset('U')
sage: X.<x,y> = U.chart()
sage: X.manifold()
@@ -621,7 +621,7 @@ class Chart(WithEqualityById, SageObject):
EXAMPLES::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x,y> = M.chart()
sage: X.add_restrictions(abs(x) > 1)
sage: X.valid_coordinates(2+i, 1)
@@ -650,7 +650,7 @@ class Chart(WithEqualityById, SageObject):
INPUT:
- ``subset`` -- open subset `V` of the chart domain `U` (must be an
- instance of :class:`~sage.manifolds.manifold.TopologicalManifold`)
+ instance of :class:`~sage.manifolds.manifold.Manifold`)
- ``restrictions`` -- (default: ``None``) list of coordinate
restrictions defining the subset `V`.
A restriction can be any symbolic equality or
@@ -675,7 +675,7 @@ class Chart(WithEqualityById, SageObject):
Coordinates on the unit open ball of `\CC^2` as a subchart
of the global coordinates of `\CC^2`::
- sage: M = Manifold(2, 'C^2', field='complex', type='topological')
+ sage: M = Manifold(2, 'C^2', field='complex', structure='topological')
sage: X.<z1, z2> = M.chart()
sage: B = M.open_subset('B')
sage: X_B = X.restrict(B, abs(z1)^2 + abs(z2)^2 < 1); X_B
@@ -726,7 +726,7 @@ class Chart(WithEqualityById, SageObject):
EXAMPLE::
- sage: M = Manifold(2, 'M', field='complex', type='topological')
+ sage: M = Manifold(2, 'M', field='complex', structure='topological')
sage: X.<x,y> = M.chart()
sage: X.add_restrictions([abs(x)<1, y!=0])
sage: X.valid_coordinates(0, i)
@@ -761,7 +761,7 @@ class Chart(WithEqualityById, SageObject):
parameters = None
# Check of restrictions:
if self._restrictions:
- substitutions = {x: coordintes[i] for i,x in enumerate(self._xx)}
+ substitutions = dict(zip(self._xx, coordinates))
if parameters:
substitutions.update(parameters)
for restrict in self._restrictions:
@@ -831,7 +831,7 @@ class Chart(WithEqualityById, SageObject):
Transition map between two stereographic charts on the circle `S^1`::
- sage: M = Manifold(1, 'S^1', type='topological')
+ sage: M = Manifold(1, 'S^1', structure='topological')
sage: U = M.open_subset('U') # Complement of the North pole
sage: cU.<x> = U.chart() # Stereographic chart from the North pole
sage: V = M.open_subset('V') # Complement of the South pole
@@ -861,7 +861,7 @@ class Chart(WithEqualityById, SageObject):
Transition map between the spherical chart and the Cartesian
one on `\RR^2`::
- sage: M = Manifold(2, 'R^2', type='topological')
+ sage: M = Manifold(2, 'R^2', structure='topological')
sage: c_cart.<x,y> = M.chart()
sage: U = M.open_subset('U') # the complement of the half line {y=0, x >= 0}
sage: c_spher.<r,phi> = U.chart(r'r:(0,+oo) phi:(0,2*pi):\phi')
@@ -951,7 +951,7 @@ class RealChart(Chart):
Cartesian coordinates on `\RR^3`::
- sage: M = Manifold(3, 'R^3', r'\RR^3', type='topological',
+ sage: M = Manifold(3, 'R^3', r'\RR^3', structure='topological',
....: start_index=1)
sage: c_cart = M.chart('x y z'); c_cart
Chart (R^3, (x, y, z))
@@ -966,7 +966,7 @@ class RealChart(Chart):
side of the chart declaration (there is then no need to pass the string
``'x y z'`` to ``chart()``)::
- sage: M = Manifold(3, 'R^3', r'\RR^3', type='topological',
+ sage: M = Manifold(3, 'R^3', r'\RR^3', structure='topological',
....: start_index=1)
sage: c_cart.<x,y,z> = M.chart(); c_cart
Chart (R^3, (x, y, z))
@@ -982,7 +982,7 @@ class RealChart(Chart):
names and do not have to coincide with the coordinate symbols; for
instance, one may write::
- sage: M = Manifold(3, 'R^3', r'\RR^3', type='topological', start_index=1)
+ sage: M = Manifold(3, 'R^3', r'\RR^3', structure='topological', start_index=1)
sage: c_cart.<x1,y1,z1> = M.chart('x y z'); c_cart
Chart (R^3, (x, y, z))
@@ -998,7 +998,7 @@ class RealChart(Chart):
coordinate symbol is quite convenient; so it is recommended to declare::
sage: forget() # for doctests only
- sage: M = Manifold(3, 'R^3', r'\RR^3', type='topological', start_index=1)
+ sage: M = Manifold(3, 'R^3', r'\RR^3', structure='topological', start_index=1)
sage: c_cart.<x,y,z> = M.chart()
Spherical coordinates on the subset `U` of `\RR^3` that is the
@@ -1069,7 +1069,7 @@ class RealChart(Chart):
Manifold subsets have a *default chart*, which, unless changed via the
method
- :meth:`~sage.manifolds.manifold.TopologicalManifold.set_default_chart`,
+ :meth:`~sage.manifolds.manifold.Manifold.set_default_chart`,
is the first defined chart on the subset (or on a open subset of it)::
sage: M.default_chart()
@@ -1128,7 +1128,7 @@ class RealChart(Chart):
TESTS::
sage: forget() # for doctests only
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: X
Chart (M, (x, y))
@@ -1157,7 +1157,7 @@ class RealChart(Chart):
TESTS::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: X._init_coordinates(['x', 'y'])
sage: X
@@ -1253,7 +1253,7 @@ class RealChart(Chart):
Some coordinate bounds on a 2-dimensional manifold::
sage: forget() # for doctests only
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: c_xy.<x,y> = M.chart('x y:[0,1)')
sage: c_xy.coord_bounds(0) # x in (-oo,+oo) (the default)
((-Infinity, False), (+Infinity, False))
@@ -1301,7 +1301,7 @@ class RealChart(Chart):
Ranges of coordinates on a 2-dimensional manifold::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: X.coord_range()
x: (-oo, +oo); y: (-oo, +oo)
@@ -1393,7 +1393,7 @@ class RealChart(Chart):
Cartesian coordinates on the open unit disc in $\RR^2$::
- sage: M = Manifold(2, 'M', type='topological') # the open unit disc
+ sage: M = Manifold(2, 'M', structure='topological') # the open unit disc
sage: X.<x,y> = M.chart()
sage: X.add_restrictions(x^2+y^2<1)
sage: X.valid_coordinates(0,2)
@@ -1492,7 +1492,7 @@ class RealChart(Chart):
INPUT:
- ``subset`` -- open subset `V` of the chart domain `U` (must be an
- instance of :class:`~sage.manifolds.manifold.TopologicalManifold`)
+ instance of :class:`~sage.manifolds.manifold.Manifold`)
- ``restrictions`` -- (default: ``None``) list of coordinate
restrictions defining the subset `V`.
A restriction can be any symbolic equality or
@@ -1517,7 +1517,7 @@ class RealChart(Chart):
Cartesian coordinates on the unit open disc in `\RR^2` as a subchart
of the global Cartesian coordinates::
- sage: M = Manifold(2, 'R^2', type='topological')
+ sage: M = Manifold(2, 'R^2', structure='topological')
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
sage: D = M.open_subset('D') # the unit open disc
sage: c_cart_D = c_cart.restrict(D, x^2+y^2<1)
@@ -1588,7 +1588,7 @@ class RealChart(Chart):
Cartesian coordinates on a square interior::
sage: forget() # for doctest only
- sage: M = Manifold(2, 'M', type='topological') # the square interior
+ sage: M = Manifold(2, 'M', structure='topological') # the square interior
sage: X.<x,y> = M.chart('x:(-2,2) y:(-2,2)')
sage: X.valid_coordinates(0,1)
True
@@ -1694,7 +1694,7 @@ class CoordChange(SageObject):
Transition map on a 2-dimensional topological manifold::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: Y.<u,v> = M.chart()
sage: X_to_Y = X.transition_map(Y, [x+y, x-y])
@@ -1713,7 +1713,7 @@ class CoordChange(SageObject):
TESTS::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: Y.<u,v> = M.chart()
sage: X_to_Y = X.transition_map(Y, [x+y, x-y])
@@ -1753,7 +1753,7 @@ class CoordChange(SageObject):
TESTS::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: Y.<u,v> = M.chart()
sage: X_to_Y = X.transition_map(Y, [x+y, x-y])
@@ -1774,7 +1774,7 @@ class CoordChange(SageObject):
TESTS::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: Y.<u,v> = M.chart()
sage: X_to_Y = X.transition_map(Y, [x+y, x-y])
@@ -1800,7 +1800,7 @@ class CoordChange(SageObject):
EXAMPLE::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: Y.<u,v> = M.chart()
sage: X_to_Y = X.transition_map(Y, [x+y, x-y])
@@ -1830,7 +1830,7 @@ class CoordChange(SageObject):
Inverse of a coordinate transformation corresponding to a pi/3-rotation
in the plane::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: c_xy.<x,y> = M.chart()
sage: c_uv.<u,v> = M.chart()
sage: xy_to_uv = c_xy.transition_map(c_uv, ((x - sqrt(3)*y)/2, (sqrt(3)*x + y)/2))
@@ -1935,7 +1935,7 @@ class CoordChange(SageObject):
From spherical coordinates to Cartesian ones in the plane::
- sage: M = Manifold(2, 'R^2', type='topological')
+ sage: M = Manifold(2, 'R^2', structure='topological')
sage: U = M.open_subset('U') # the complement of the half line {y=0, x>= 0}
sage: c_cart.<x,y> = U.chart()
sage: c_spher.<r,ph> = U.chart(r'r:(0,+oo) ph:(0,2*pi):\phi')
@@ -1996,7 +1996,7 @@ class CoordChange(SageObject):
EXAMPLE::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: U.<u,v> = M.chart()
sage: X_to_U = X.transition_map(U, (x+y, x-y))
@@ -2038,7 +2038,7 @@ class CoordChange(SageObject):
EXAMPLE::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: Y.<u,v> = M.chart()
sage: X_to_Y = X.transition_map(Y, [x+y, x-y])
@@ -2079,7 +2079,7 @@ class CoordChange(SageObject):
From spherical coordinates to Cartesian ones in the plane::
- sage: M = Manifold(2, 'R^2', type='topological')
+ sage: M = Manifold(2, 'R^2', structure='topological')
sage: U = M.open_subset('U') # the complement of the half line {y=0, x>= 0}
sage: c_cart.<x,y> = U.chart()
sage: c_spher.<r,ph> = U.chart(r'r:(0,+oo) ph:(0,2*pi):\phi')
diff --git a/src/sage/manifolds/manifold.py b/src/sage/manifolds/manifold.py
index 4abf1bb..b42350b 100644
--- a/src/sage/manifolds/manifold.py
+++ b/src/sage/manifolds/manifold.py
@@ -1,5 +1,5 @@
r"""
-Topological manifolds
+Manifolds
Given a topological field `K` (in most applications, `K = \RR` or
`K = \CC`) and a non-negative integer `n`, a *topological manifold of
@@ -10,25 +10,25 @@ dimension* `n` *over K* is a topological space `M` such that
- every point in `M` has a neighborhood homeomorphic to `K^n`
Topological manifolds are implemented via the class
-:class:`TopologicalManifold`. Open subsets of topological manifolds
-are also implemented via :class:`TopologicalManifold`, since they are
+:class:`Manifold`. Open subsets of topological manifolds
+are also implemented via :class:`Manifold`, since they are
topological manifolds by themselves.
In the current setting, topological manifolds are mostly described by
means of charts (see :class:`~sage.manifolds.chart.Chart`).
-:class:`TopologicalManifold` serves as a base class for more specific
+:class:`Manifold` serves as a base class for more specific
manifold classes.
The user interface is provided by the generic function :func:`Manifold`,
-with the argument ``type`` set to ``'topological'``.
+with the argument ``structure`` set to ``'topological'``.
.. RUBRIC:: 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', type='topological')
+ sage: M = Manifold(2, 'S^2', structure='topological')
sage: M
2-dimensional topological manifold S^2
@@ -175,7 +175,7 @@ Similarly::
We declare the Riemann sphere `\CC^*` as a 1-dimensional topological manifold
over `\CC`::
- sage: M = Manifold(1, 'C*', type='topological', field='complex'); M
+ 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
@@ -284,14 +284,20 @@ REFERENCES:
from sage.categories.fields import Fields
from sage.categories.manifolds import Manifolds
+from sage.categories.sets_cat import Sets
from sage.rings.all import CC
from sage.rings.real_mpfr import RR, RealField_class
from sage.rings.complex_field import ComplexField_class
-from sage.manifolds.subset import TopologicalManifoldSubset
+from sage.rings.integer import Integer
+from sage.manifolds.abstract import AbstractSet
+from sage.manifolds.structure import TopologicalStructure, RealTopologicalStructure
-class TopologicalManifold(TopologicalManifoldSubset):
+#####################################################################
+## Classes
+
+class Manifold(AbstractSet):
r"""
- Topological manifold over a topological field `K`.
+ 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
@@ -302,7 +308,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
- every point in `M` has a neighborhood homeomorphic to `K^n`.
This is a Sage *parent* class, the corresponding *element*
- class being :class:`~sage.manifolds.point.TopologicalManifoldPoint`.
+ class being :class:`~sage.manifolds.point.ManifoldPoint`.
INPUT:
@@ -336,13 +342,13 @@ class TopologicalManifold(TopologicalManifoldSubset):
A 4-dimensional topological manifold (over `\RR`)::
- sage: M = Manifold(4, 'M', latex_name=r'\mathcal{M}', type='topological')
+ 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'>
+ <class 'sage.manifolds.manifold.Manifold_with_category'>
sage: M.base_field()
Real Field with 53 bits of precision
sage: dim(M)
@@ -351,28 +357,28 @@ class TopologicalManifold(TopologicalManifoldSubset):
The input parameter ``start_index`` defines the range of indices
on the manifold::
- sage: M = Manifold(4, 'M', type='topological')
+ sage: M = Manifold(4, 'M', structure='topological')
sage: list(M.irange())
[0, 1, 2, 3]
- sage: M = Manifold(4, 'M', type='topological', start_index=1)
+ sage: M = Manifold(4, 'M', structure='topological', start_index=1)
sage: list(M.irange())
[1, 2, 3, 4]
- sage: list(Manifold(4, 'M', type='topological', start_index=-2).irange())
+ sage: list(Manifold(4, 'M', structure='topological', start_index=-2).irange())
[-2, -1, 0, 1]
A complex manifold::
- sage: N = Manifold(3, 'N', type='topological', field='complex'); N
+ 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', type='topological', field=QQ); N
+ 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', type='topological', field=Qp(5)); N
+ 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
@@ -407,18 +413,18 @@ class TopologicalManifold(TopologicalManifoldSubset):
True
The manifold's points are instances of class
- :class:`~sage.manifolds.point.TopologicalManifoldPoint`::
+ :class:`~sage.manifolds.point.ManifoldPoint`::
- sage: isinstance(p, sage.manifolds.point.TopologicalManifoldPoint)
+ 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
- :class:`TopologicalManifold`::
+ :class:`Manifold`::
sage: U = M.open_subset('U'); U
Open subset U of the 4-dimensional topological manifold M
- sage: isinstance(U, sage.manifolds.manifold.TopologicalManifold)
+ sage: isinstance(U, sage.manifolds.manifold.Manifold)
True
sage: U.base_field() == M.base_field()
True
@@ -431,15 +437,15 @@ class TopologicalManifold(TopologicalManifoldSubset):
sage: TestSuite(M).run()
"""
- def __init__(self, n, name, latex_name=None, field='real', start_index=0,
- category=None, ambient_manifold=None):
+ def __init__(self, n, name, latex_name, field, structure,
+ start_index, category=None):
r"""
Construct a topological manifold.
TESTS::
sage: M = Manifold(3, 'M', latex_name=r'\mathbb{M}',
- ....: type='topological', start_index=1)
+ ....: structure='topological', start_index=1)
sage: M
3-dimensional topological manifold M
sage: latex(M)
@@ -448,14 +454,8 @@ class TopologicalManifold(TopologicalManifoldSubset):
3
sage: X.<x,y,z> = M.chart()
sage: TestSuite(M).run()
-
"""
# Initialization of the attributes _dim, _field and _start_index:
- from sage.rings.integer import Integer
- if not isinstance(n, (int, Integer)):
- raise TypeError("the manifold dimension must be an integer")
- if n<1:
- raise ValueError("the manifold dimension must be strictly positive")
self._dim = n
if field == 'real':
self._field = RR
@@ -473,20 +473,17 @@ class TopologicalManifold(TopologicalManifoldSubset):
self._field_type = 'complex'
else:
self._field_type = 'neither_real_nor_complex'
+
+ self._structure = structure
+ category = Manifolds(self._field).or_subcategory(category)
+ category = self._structure.subcategory(category)
+
+ AbstractSet.__init__(self, name, latex_name, self._field, category)
+
if not isinstance(start_index, (int, Integer)):
raise TypeError("the starting index must be an integer")
self._sindex = start_index
- category = Manifolds(self._field).or_subcategory(category)
- if ambient_manifold is None:
- ambient_manifold = self
- elif not isinstance(ambient_manifold, TopologicalManifold):
- raise TypeError("the argument 'ambient_manifold' must be " +
- "a topological manifold")
- # Initialization as a subset of the ambient manifold (possibly itself):
- TopologicalManifoldSubset.__init__(self, ambient_manifold, name,
- latex_name=latex_name, category=category)
- self._is_open = True
- self._open_covers = [[self]] # list of open covers of self
+
self._atlas = [] # list of charts defined on subsets of self
self._top_charts = [] # list of charts defined on subsets of self
# that are not subcharts of charts on larger subsets
@@ -500,23 +497,25 @@ class TopologicalManifold(TopologicalManifoldSubset):
# domains are self (if non-empty, self is a coordinate domain):
self._covering_charts = []
+ self._open_covers.add(frozenset([self])) # set of open covers of self
+
def _repr_(self):
r"""
Return a string representation of the manifold.
TESTS::
- sage: M = Manifold(3, 'M', type='topological')
+ sage: M = Manifold(3, 'M', structure='topological')
sage: M._repr_()
'3-dimensional topological manifold M'
sage: repr(M) # indirect doctest
'3-dimensional topological manifold M'
sage: M # indirect doctest
3-dimensional topological manifold M
- sage: M = Manifold(3, 'M', type='topological', field='complex')
+ sage: M = Manifold(3, 'M', structure='topological', field='complex')
sage: M._repr_()
'Complex 3-dimensional topological manifold M'
- sage: M = Manifold(3, 'M', type='topological', field=QQ)
+ sage: M = Manifold(3, 'M', structure='topological', field=QQ)
sage: M._repr_()
'3-dimensional topological manifold M over the Rational Field'
@@ -528,48 +527,27 @@ class TopologicalManifold(TopologicalManifoldSubset):
'Open subset U of the 3-dimensional topological manifold M over the Rational Field'
"""
- if self._manifold is self:
- if self._field_type == 'real':
- return "{}-dimensional topological manifold {}".format(
- self._dim, self._name)
- elif self._field_type == 'complex':
- return "Complex {}-dimensional topological manifold {}".format(
- self._dim, self._name)
- return "{}-dimensional topological manifold {} over the {}".format(
- self._dim, self._name, self._field)
- else:
- return "Open subset {} of the {}".format(self._name, self._manifold)
-
- def _latex_(self):
- r"""
- Return a LaTeX representation of the manifold.
-
- TESTS::
-
- sage: M = Manifold(3, 'M', type='topological')
- sage: M._latex_()
- 'M'
- sage: latex(M)
- M
- sage: M = Manifold(3, 'M', latex_name=r'\mathcal{M}',
- ....: type='topological')
- sage: M._latex_()
- '\\mathcal{M}'
- sage: latex(M)
- \mathcal{M}
-
- """
- return self._latex_name
-
+ if self._field_type == 'real':
+ return "{}-dimensional {} manifold {}".format(self._dim,
+ self._structure.name,
+ self._name)
+ elif self._field_type == 'complex':
+ return "Complex {}-dimensional {} manifold {}".format(self._dim,
+ self._structure.name,
+ self._name)
+ return "{}-dimensional {} manifold {} over the {}".format(self._dim,
+ self._structure.name, self._name, self._field)
+
+ # TODO: Check if this is still needed...
def __reduce__(self):
r"""
Reduction function for the pickle protocol.
TESTS::
- sage: M = Manifold(3, 'M', type='topological')
+ sage: M = Manifold(3, 'M', structure='topological')
sage: M.__reduce__()
- (<class 'sage.manifolds.manifold.TopologicalManifold'>,
+ (<class 'sage.manifolds.manifold.Manifold'>,
(3,
'M',
'M',
@@ -579,7 +557,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
None))
sage: U = M.open_subset('U')
sage: U.__reduce__()
- (<class 'sage.manifolds.manifold.TopologicalManifold'>,
+ (<class 'sage.manifolds.manifold.Manifold'>,
(3,
'U',
'U',
@@ -596,13 +574,9 @@ class TopologicalManifold(TopologicalManifoldSubset):
Open subset U of the 3-dimensional topological manifold M
"""
- if self._manifold is self:
- ambient_manifold = None
- else:
- ambient_manifold = self._manifold
- return (TopologicalManifold, (self._dim, self._name, self._latex_name,
- self._field, self._sindex,
- self.category(), ambient_manifold))
+ return (Manifold, (self._dim, self._name, self._latex_name,
+ self._field, self._structure, self._sindex,
+ self.category()))
def _test_pickling(self, **options):
r"""
@@ -617,9 +591,9 @@ class TopologicalManifold(TopologicalManifoldSubset):
TESTS::
- sage: M = Manifold(3, 'M', type='topological')
+ sage: M = Manifold(3, 'M', structure='topological')
sage: M._test_pickling()
- sage: M = Manifold(3, 'M', type='topological', field='complex')
+ sage: M = Manifold(3, 'M', structure='topological', field='complex')
sage: M._test_pickling()
"""
@@ -637,7 +611,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
EXAMPLES::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: p = M._an_element_(); p
Point on the 2-dimensional topological manifold M
@@ -734,7 +708,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
EXAMPLES::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: p = M.point((1,2), chart=X)
sage: M.__contains__(p)
@@ -754,9 +728,9 @@ class TopologicalManifold(TopologicalManifoldSubset):
"""
# for efficiency, a quick test first:
- if point._subset is self:
+ if point.parent() is self:
return True
- if point._subset.is_subset(self):
+ if point.parent().is_subset(self):
return True
for chart in self._atlas:
if chart in point._coordinates:
@@ -769,13 +743,229 @@ class TopologicalManifold(TopologicalManifoldSubset):
return True
return False
+ def manifold(self):
+ """
+ Return ``self`` since ``self`` is the ambient manifold.
+
+ This is for compatibility with :class:`TopologicalSubmanifold`.
+
+ EXAMPLES::
+
+ sage: M = Manifold(2, 'R^2', structure='topological')
+ sage: M.manifold() is M
+ True
+ """
+ return self
+
+ def open_subset(self, name, latex_name=None, coord_def={}):
+ r"""
+ Create an open subset of the manifold.
+
+ An open subset is a set that is (i) included in the manifold and (ii)
+ open with respect to the manifold's topology. It is a topological
+ manifold by itself. Hence the returned object is an instance of
+ :class:`Manifold`.
+
+ INPUT:
+
+ - ``name`` -- name given to the open subset
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
+ subset; if none is provided, it is set to ``name``
+ - ``coord_def`` -- (default: {}) definition of the subset in
+ terms of coordinates; ``coord_def`` must a be dictionary with keys
+ charts on the manifold and values the symbolic expressions formed by
+ the coordinates to define the subset.
+
+ OUTPUT:
+
+ - the open subset, as an instance of :class:`Manifold`.
+
+ EXAMPLES:
+
+ Creating an open subset of a 2-dimensional manifold::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: A = M.open_subset('A'); A
+ Open subset A of the 2-dimensional topological manifold M
+
+ As an open subset of a topological manifold, ``A`` is itself a
+ topological manifold, on the same topological field and of the same
+ dimension as ``M``::
+
+ sage: isinstance(A, sage.manifolds.manifold.Manifold)
+ True
+ sage: A.base_field() == M.base_field()
+ True
+ sage: dim(A) == dim(M)
+ True
+
+ Creating an open subset of ``A``::
+
+ sage: B = A.open_subset('B'); B
+ Open subset B of the 2-dimensional topological manifold M
+
+ We have then::
+
+ sage: A.subsets() # random (set output)
+ {Open subset B of the 2-dimensional topological manifold M,
+ Open subset A of the 2-dimensional topological manifold M}
+ sage: B.is_subset(A)
+ True
+ sage: B.is_subset(M)
+ True
+
+ Defining an open subset by some coordinate restrictions: the open
+ unit disk in `\RR^2`::
+
+ sage: M = Manifold(2, 'R^2', structure='topological')
+ sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
+ sage: U = M.open_subset('U', coord_def={c_cart: x^2+y^2<1}); U
+ Open subset U of the 2-dimensional topological manifold R^2
+
+ Since the argument ``coord_def`` has been set, ``U`` is automatically
+ provided with a chart, which is the restriction of the Cartesian one
+ to ``U``::
+
+ sage: U.atlas()
+ [Chart (U, (x, y))]
+
+ Therefore, one can immediately check whether a point belongs to U::
+
+ sage: M.point((0,0)) in U
+ True
+ sage: M.point((1/2,1/3)) in U
+ True
+ sage: M.point((1,2)) in U
+ False
+
+ """
+ from sage.manifolds.subset import TopologicalSubmanifold
+ resu = TopologicalSubmanifold(ambient=self.manifold(),
+ name=name, latex_name=latex_name,
+ category=self.category())
+
+ resu._supersets.update(self._supersets)
+ for sd in self._supersets:
+ sd._subsets.add(resu)
+ self._top_subsets.add(resu)
+ # Charts on the result from the coordinate definition:
+ for chart, restrictions in coord_def.iteritems():
+ if chart not in self._atlas:
+ raise ValueError("the {} does not belong to ".format(chart) +
+ "the atlas of {}".format(self))
+ chart.restrict(resu, restrictions)
+ # Transition maps on the result inferred from those of self:
+ for chart1 in coord_def:
+ for chart2 in coord_def:
+ if chart2 != chart1 and (chart1, chart2) in self._coord_changes:
+ self._coord_changes[(chart1, chart2)].restrict(resu)
+ return resu
+
+ def get_chart(self, coordinates, domain=None):
+ r"""
+ Get a chart from its coordinates.
+
+ The chart must have been previously created by the method
+ :meth:`chart`.
+
+ INPUT:
+
+ - ``coordinates`` -- single string composed of the coordinate symbols
+ separated by a space
+ - ``domain`` -- (default: ``None``) string containing the name of the
+ chart's domain, which must be a subset of the current manifold; if
+ ``None``, the current manifold is assumed.
+
+ OUTPUT:
+
+ - instance of
+ :class:`~sage.manifolds.chart.Chart` (or of the subclass
+ :class:`~sage.manifolds.chart.RealChart`) representing the chart
+ corresponding to the above specifications.
+
+ EXAMPLES::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: M.get_chart('x y')
+ Chart (M, (x, y))
+ sage: M.get_chart('x y') is X
+ True
+ sage: U = M.open_subset('U', coord_def={X: (y!=0,x<0)})
+ sage: Y.<r, ph> = U.chart(r'r:(0,+oo) ph:(0,2*pi):\phi')
+ sage: M.atlas()
+ [Chart (M, (x, y)), Chart (U, (x, y)), Chart (U, (r, ph))]
+ sage: M.get_chart('x y', domain='U')
+ Chart (U, (x, y))
+ sage: M.get_chart('x y', domain='U') is X.restrict(U)
+ True
+ sage: U.get_chart('r ph')
+ Chart (U, (r, ph))
+ sage: M.get_chart('r ph', domain='U')
+ Chart (U, (r, ph))
+ sage: M.get_chart('r ph', domain='U') is Y
+ True
+
+ """
+ if domain is None:
+ dom = self
+ else:
+ dom = self.get_subset(domain)
+ try:
+ return dom._charts_by_coord[coordinates]
+ except KeyError:
+ raise KeyError("the coordinates '{}' ".format(coordinates) +
+ "do not correspond to any chart with " +
+ "the {} as domain".format(dom))
+
+ def union(self, other, name=None, latex_name=None):
+ r"""
+ Return the union of ``self`` with ``other``.
+
+ INPUT:
+
+ - ``other`` -- another subset of the same manifold
+ - ``name`` -- ignored
+ - ``latex_name`` -- ignored
+
+ OUTPUT:
+
+ - ``self``
+
+ EXAMPLES::
+ """
+ if other.manifold() is not self:
+ raise ValueError("{} is not a subset of this manifold".format(other))
+ return self
+
+ def intersection(self, other, name=None, latex_name=None):
+ r"""
+ Return the intersection of the current subset with another subset.
+
+ INPUT:
+
+ - ``other`` -- another subset of the same manifold
+ - ``name`` -- ignored
+ - ``latex_name`` -- ignored
+
+ OUTPUT:
+
+ - instance of :class:`ManifoldSubset` representing the
+ subset that is the intersection of the current subset with ``other``
+
+ EXAMPLES::
+ """
+ if other.manifold() is not self:
+ raise ValueError("{} is not a subset of this manifold".format(other))
+ return other
+
def dimension(self):
r"""
Return the dimension of the manifold over its base field.
EXAMPLE::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: M.dimension()
2
@@ -804,13 +994,13 @@ class TopologicalManifold(TopologicalManifoldSubset):
EXAMPLES::
- sage: M = Manifold(3, 'M', type='topological')
+ sage: M = Manifold(3, 'M', structure='topological')
sage: M.base_field()
Real Field with 53 bits of precision
- sage: M = Manifold(3, 'M', type='topological', field='complex')
+ sage: M = Manifold(3, 'M', structure='topological', field='complex')
sage: M.base_field()
Complex Field with 53 bits of precision
- sage: M = Manifold(3, 'M', type='topological', field=QQ)
+ sage: M = Manifold(3, 'M', structure='topological', field=QQ)
sage: M.base_field()
Rational Field
@@ -832,13 +1022,13 @@ class TopologicalManifold(TopologicalManifoldSubset):
EXAMPLES::
- sage: M = Manifold(3, 'M', type='topological')
+ sage: M = Manifold(3, 'M', structure='topological')
sage: M.base_field_type()
'real'
- sage: M = Manifold(3, 'M', type='topological', field='complex')
+ sage: M = Manifold(3, 'M', structure='topological', field='complex')
sage: M.base_field_type()
'complex'
- sage: M = Manifold(3, 'M', type='topological', field=QQ)
+ sage: M = Manifold(3, 'M', structure='topological', field=QQ)
sage: M.base_field_type()
'neither_real_nor_complex'
@@ -860,10 +1050,10 @@ class TopologicalManifold(TopologicalManifoldSubset):
EXAMPLES::
- sage: M = Manifold(3, 'M', type='topological')
+ sage: M = Manifold(3, 'M', structure='topological')
sage: M.start_index()
0
- sage: M = Manifold(3, 'M', type='topological', start_index=1)
+ sage: M = Manifold(3, 'M', structure='topological', start_index=1)
sage: M.start_index()
1
@@ -889,7 +1079,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Index range on a 4-dimensional manifold::
- sage: M = Manifold(4, 'M', type='topological')
+ sage: M = Manifold(4, 'M', structure='topological')
sage: for i in M.irange():
....: print i,
....:
@@ -903,7 +1093,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Index range on a 4-dimensional manifold with starting index=1::
- sage: M = Manifold(4, 'M', type='topological', start_index=1)
+ sage: M = Manifold(4, 'M', structure='topological', start_index=1)
sage: for i in M.irange():
....: print i,
....:
@@ -946,7 +1136,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Indices on a 2-dimensional manifold::
- sage: M = Manifold(2, 'M', type='topological', start_index=1)
+ sage: M = Manifold(2, 'M', structure='topological', start_index=1)
sage: for ind in M.index_generator(2):
....: print ind
....:
@@ -996,7 +1186,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Let us consider `\RR^2` as a 2-dimensional manifold::
- sage: M = Manifold(2, 'R^2', type='topological')
+ sage: M = Manifold(2, 'R^2', structure='topological')
Immediately after the manifold creation, the atlas is empty, since no
chart has been defined yet::
@@ -1031,7 +1221,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
:meth:`top_charts`
"""
- return self._atlas
+ return list(self._atlas) # Make a (shallow) copy
def top_charts(self):
r"""
@@ -1047,7 +1237,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Charts on a 2-dimensional manifold::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: U = M.open_subset('U', coord_def={X: x>0})
sage: Y.<u,v> = U.chart()
@@ -1066,7 +1256,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
manifold.
"""
- return self._top_charts
+ return list(self._top_charts) # Make a (shallow) copy
def default_chart(self):
r"""
@@ -1084,7 +1274,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Default chart on a 2-dimensional manifold and on some subsets::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: M.chart('x y')
Chart (M, (x, y))
sage: M.chart('u v')
@@ -1112,7 +1302,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Charts on a 2-dimensional manifold::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: c_xy.<x,y> = M.chart()
sage: c_uv.<u,v> = M.chart()
sage: M.default_chart()
@@ -1157,7 +1347,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Change of coordinates on a 2-dimensional manifold::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: c_xy.<x,y> = M.chart()
sage: c_uv.<u,v> = M.chart()
sage: c_xy.transition_map(c_uv, (x+y, x-y)) # defines the coord. change
@@ -1185,7 +1375,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Various changes of coordinates on a 2-dimensional manifold::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: c_xy.<x,y> = M.chart()
sage: c_uv.<u,v> = M.chart()
sage: xy_to_uv = c_xy.transition_map(c_uv, [x+y, x-y])
@@ -1231,7 +1421,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
EXAMPLES::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: U = M.open_subset('U')
sage: X.<x,y> = U.chart()
sage: U.is_manifestly_coordinate_domain()
@@ -1243,119 +1433,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
True
"""
- return not self._covering_charts == []
-
- def open_subset(self, name, latex_name=None, coord_def={}):
- r"""
- Create an open subset of the manifold.
-
- An open subset is a set that is (i) included in the manifold and (ii)
- open with respect to the manifold's topology. It is a topological
- manifold by itself. Hence the returned object is an instance of
- :class:`TopologicalManifold`.
-
- INPUT:
-
- - ``name`` -- name given to the open subset
- - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
- subset; if none is provided, it is set to ``name``
- - ``coord_def`` -- (default: {}) definition of the subset in
- terms of coordinates; ``coord_def`` must a be dictionary with keys
- charts on the manifold and values the symbolic expressions formed by
- the coordinates to define the subset.
-
- OUTPUT:
-
- - the open subset, as an instance of :class:`TopologicalManifold`.
-
- EXAMPLES:
-
- Creating an open subset of a 2-dimensional manifold::
-
- sage: M = Manifold(2, 'M', type='topological')
- sage: A = M.open_subset('A'); A
- Open subset A of the 2-dimensional topological manifold M
-
- As an open subset of a topological manifold, ``A`` is itself a
- topological manifold, on the same topological field and of the same
- dimension as ``M``::
-
- sage: isinstance(A, sage.manifolds.manifold.TopologicalManifold)
- True
- sage: A.base_field() == M.base_field()
- True
- sage: dim(A) == dim(M)
- True
-
- Creating an open subset of ``A``::
-
- sage: B = A.open_subset('B'); B
- Open subset B of the 2-dimensional topological manifold M
-
- We have then::
-
- sage: A.subsets() # random (set output)
- {Open subset B of the 2-dimensional topological manifold M,
- Open subset A of the 2-dimensional topological manifold M}
- sage: B.is_subset(A)
- True
- sage: B.is_subset(M)
- True
-
- Defining an open subset by some coordinate restrictions: the open
- unit disk in `\RR^2`::
-
- sage: M = Manifold(2, 'R^2', type='topological')
- sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
- sage: U = M.open_subset('U', coord_def={c_cart: x^2+y^2<1}); U
- Open subset U of the 2-dimensional topological manifold R^2
-
- Since the argument ``coord_def`` has been set, ``U`` is automatically
- provided with a chart, which is the restriction of the Cartesian one
- to ``U``::
-
- sage: U.atlas()
- [Chart (U, (x, y))]
-
- Therefore, one can immediately check whether a point belongs to U::
-
- sage: M.point((0,0)) in U
- True
- sage: M.point((1/2,1/3)) in U
- True
- sage: M.point((1,2)) in U
- False
-
- """
- resu = TopologicalManifold(self._dim, name, latex_name=latex_name,
- field=self._field, start_index=self._sindex,
- category=self.category(),
- ambient_manifold=self._manifold)
- #!# NB: the above could have been
- # resu = type(self).__base__(...)
- # instead of resu = TopologicalManifold(...)
- # to allow for open_subset() of derived classes to call first this
- # version,
- # but, because of the category framework, it could NOT have been
- # resu = type(self)(...)
- # cf. the discussion in
- # https://groups.google.com/forum/#!topic/sage-devel/jHlFxhMDf3Y
- resu._supersets.update(self._supersets)
- for sd in self._supersets:
- sd._subsets.add(resu)
- self._top_subsets.add(resu)
- # Charts on the result from the coordinate definition:
- for chart, restrictions in coord_def.iteritems():
- if chart not in self._atlas:
- raise ValueError("the {} does not belong to ".format(chart) +
- "the atlas of {}".format(self))
- chart.restrict(resu, restrictions)
- # Transition maps on the result inferred from those of self:
- for chart1 in coord_def:
- for chart2 in coord_def:
- if chart2 != chart1 and (chart1, chart2) in self._coord_changes:
- self._coord_changes[(chart1, chart2)].restrict(resu)
- return resu
+ return bool(self._covering_charts)
def chart(self, coordinates='', names=None):
r"""
@@ -1417,7 +1495,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
Chart on a 2-dimensional manifold::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: U = M.open_subset('U')
sage: X = U.chart('x y'); X
Chart (U, (x, y))
@@ -1447,7 +1525,7 @@ class TopologicalManifold(TopologicalManifoldSubset):
left-hand side of the chart declaration (there is then no need to
pass the string 'x y' to chart())::
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
sage: U = M.open_subset('U')
sage: X.<x,y> = U.chart(); X
Chart (U, (x, y))
@@ -1468,70 +1546,29 @@ class TopologicalManifold(TopologicalManifoldSubset):
especially regarding the coordinates ranges and restrictions.
"""
- from sage.manifolds.chart import Chart, RealChart
- if self._field_type == 'real':
- return RealChart(self, coordinates=coordinates, names=names)
- return Chart(self, coordinates=coordinates, names=names)
+ return self._structure.chart(self, coordinates=coordinates, names=names)
- def get_chart(self, coordinates, domain=None):
+ def superset(self, name=None, latex_name=None, is_open=False):
r"""
- Get a chart from its coordinates.
-
- The chart must have been previously created by the method
- :meth:`chart`.
+ Return ``self`` since the only superset of the manifold is
+ the manifold.
INPUT:
- - ``coordinates`` -- single string composed of the coordinate symbols
- separated by a space
- - ``domain`` -- (default: ``None``) string containing the name of the
- chart's domain, which must be a subset of the current manifold; if
- ``None``, the current manifold is assumed.
-
- OUTPUT:
-
- - instance of
- :class:`~sage.manifolds.chart.Chart` (or of the subclass
- :class:`~sage.manifolds.chart.RealChart`) representing the chart
- corresponding to the above specifications.
+ - ``name`` -- ignored
+ - ``latex_name`` -- ignored
+ - ``is_open`` -- ignored
EXAMPLES::
-
- sage: M = Manifold(2, 'M', type='topological')
- sage: X.<x,y> = M.chart()
- sage: M.get_chart('x y')
- Chart (M, (x, y))
- sage: M.get_chart('x y') is X
- True
- sage: U = M.open_subset('U', coord_def={X: (y!=0,x<0)})
- sage: Y.<r, ph> = U.chart(r'r:(0,+oo) ph:(0,2*pi):\phi')
- sage: M.atlas()
- [Chart (M, (x, y)), Chart (U, (x, y)), Chart (U, (r, ph))]
- sage: M.get_chart('x y', domain='U')
- Chart (U, (x, y))
- sage: M.get_chart('x y', domain='U') is X.restrict(U)
- True
- sage: U.get_chart('r ph')
- Chart (U, (r, ph))
- sage: M.get_chart('r ph', domain='U')
- Chart (U, (r, ph))
- sage: M.get_chart('r ph', domain='U') is Y
- True
-
"""
- if domain is None:
- dom = self
- else:
- dom = self.get_subset(domain)
- try:
- return dom._charts_by_coord[coordinates]
- except KeyError:
- raise KeyError("the coordinates '{}' ".format(coordinates) +
- "do not correspond to any chart with " +
- "the {} as domain".format(dom))
+ return self
+
+#####################################################################
+## Constructor function
-def Manifold(dim, name, latex_name=None, field='real', type='smooth',
- start_index=0, **extra_kwds):
+def manifold_constructor(dim, name, latex_name=None,
+ field='real', structure='smooth',
+ start_index=0, **extra_kwds):
r"""
Construct a manifold of a given type over a topological field `K`.
@@ -1553,8 +1590,8 @@ def Manifold(dim, name, latex_name=None, field='real', type='smooth',
:class:`~sage.categories.topological_spaces.TopologicalSpaces`)
for other types of manifolds
- - ``type`` -- (default: ``'smooth'``) to specify the type of manifold;
- allowed values are
+ - ``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
@@ -1570,41 +1607,41 @@ def Manifold(dim, name, latex_name=None, field='real', type='smooth',
OUTPUT:
- a manifold of the specified type, as an instance of
- :class:`~sage.manifolds.manifold.TopologicalManifold` or one of its
+ :class:`~sage.manifolds.manifold.Manifold` or one of its
subclasses.
EXAMPLES:
A 3-dimensional real topological manifold::
- sage: M = Manifold(3, 'M', type='topological'); M
+ 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', type='topological', field='real'); M
+ sage: M = Manifold(3, 'M', structure='topological', field='real'); M
3-dimensional topological manifold M
A complex topological manifold::
- sage: M = Manifold(3, 'M', type='topological', field='complex'); M
+ 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', type='topological', field=QQ); M
+ sage: M = Manifold(3, 'M', structure='topological', field=QQ); M
3-dimensional topological manifold M over the Rational Field
See the documentation of class
- :class:`~sage.manifolds.manifold.TopologicalManifold` for more
+ :class:`~sage.manifolds.manifold.Manifold` for more
detailed examples.
.. RUBRIC:: Uniqueness of manifold objects
Suppose we construct a manifold named `M`::
- sage: M = Manifold(2, 'M', type='topological')
+ 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
@@ -1612,7 +1649,7 @@ def Manifold(dim, name, latex_name=None, field='real', type='smooth',
reference::
sage: M_old = M # for reference
- sage: M = Manifold(2, 'M', type='topological')
+ sage: M = Manifold(2, 'M', structure='topological')
This results in a brand new object::
@@ -1666,12 +1703,21 @@ def Manifold(dim, name, latex_name=None, field='real', type='smooth',
sage: isinstance(M, sage.misc.fast_methods.WithEqualityById)
True
-
"""
- type_ = type # in case the built