summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Gourgoulhon <eric.gourgoulhon@obspm.fr>2015-12-15 17:11:26 +0100
committerEric Gourgoulhon <eric.gourgoulhon@obspm.fr>2015-12-15 17:11:26 +0100
commit3a525002469e0ef676a0dcf48f8f7f8683b85853 (patch)
tree8bed1baf2c5e0cbbe96831d6cdb85dbeec4650ca
parentMake AbstractSet inherit from UniqueRepresentation; correct doctests; start t... (diff)
Some class renaming; add more examples and doctests (full coverage)
-rw-r--r--src/sage/manifolds/abstract.py56
-rw-r--r--src/sage/manifolds/all.py2
-rw-r--r--src/sage/manifolds/chart.py14
-rw-r--r--src/sage/manifolds/manifold.py122
-rw-r--r--src/sage/manifolds/point.py10
-rw-r--r--src/sage/manifolds/structure.py19
-rw-r--r--src/sage/manifolds/subset.py238
7 files changed, 340 insertions, 121 deletions
diff --git a/src/sage/manifolds/abstract.py b/src/sage/manifolds/abstract.py
index 709f5a1..f38c128 100644
--- a/src/sage/manifolds/abstract.py
+++ b/src/sage/manifolds/abstract.py
@@ -5,8 +5,9 @@ These are base classes for the manifolds.
AUTHORS:
-- Eric Gourgoulhon (2015): initial version
-- Travis Scrimshaw (2015-11-25): Initial version
+- Travis Scrimshaw (2015-11-25): initial version
+- Eric Gourgoulhon (2015): some methods from previous TopologicalManifold class
+
"""
#*****************************************************************************
@@ -31,11 +32,19 @@ class AbstractNamedObject(object):
"""
An abstract object.
- An abstract object is a variable name and latex name.
+ An abstract object is a variable name and LaTeX name.
"""
def __init__(self, name, latex_name=None):
"""
Initialize ``self``.
+
+ TEST::
+
+ sage: from sage.manifolds.abstract import AbstractNamedObject
+ sage: a = AbstractNamedObject('a')
+ sage: type(a)
+ <class 'sage.manifolds.abstract.AbstractNamedObject'>
+
"""
if not isinstance(name, str):
raise TypeError("{} is not a string".format(name))
@@ -51,6 +60,14 @@ class AbstractNamedObject(object):
def _repr_(self):
"""
Return a string representation of ``self``.
+
+ TEST::
+
+ sage: from sage.manifolds.abstract import AbstractNamedObject
+ sage: a = AbstractNamedObject('a')
+ sage: a._repr_()
+ 'a'
+
"""
return self._name
@@ -79,7 +96,7 @@ class AbstractNamedObject(object):
....: structure='topological')
sage: M._latex_()
'\\mathcal{M}'
- sage: latex(M)
+ sage: latex(M) # indirect doctest
\mathcal{M}
"""
return self._latex_name
@@ -115,7 +132,7 @@ class AbstractSet(AbstractNamedObject, UniqueRepresentation, Parent):
# (key: subset name)
self._unions = {} # dict. of unions with other subsets (key: subset
# name)
- self._open_covers = set() # set of open covers of self
+ self._open_covers = [] # list of open covers of self
#### Methods required for any Parent in the category of sets:
@@ -276,7 +293,7 @@ class AbstractSet(AbstractNamedObject, UniqueRepresentation, Parent):
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)
+ return self._open_covers
def subsets(self):
r"""
@@ -319,7 +336,6 @@ class AbstractSet(AbstractNamedObject, UniqueRepresentation, Parent):
"""
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
@@ -373,9 +389,9 @@ class AbstractSet(AbstractNamedObject, UniqueRepresentation, Parent):
OUTPUT:
- - the subset, as an instance of :class:`ManifoldSubset`, or
+ - the subset, as an instance of :class:`~sage.manifolds.subset.ManifoldSubset`, or
of the derived class
- :class:`~sage.manifolds.manifold.Manifold` if ``is_open``
+ :class:`~sage.manifolds.subset.OpenTopologicalSubmanifold` if ``is_open``
is ``True``.
EXAMPLES:
@@ -403,8 +419,7 @@ class AbstractSet(AbstractNamedObject, UniqueRepresentation, Parent):
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 = ManifoldSubset(self.manifold(), name, latex_name=latex_name)
res._supersets.update(self._supersets)
for sd in self._supersets:
sd._subsets.add(res)
@@ -417,7 +432,7 @@ class AbstractSet(AbstractNamedObject, UniqueRepresentation, Parent):
The subset must have been previously created by the method
:meth:`subset` (or
- :meth:`~sage.manifolds.manifold.Manifold.open_subset`)
+ :meth:`~sage.manifolds.manifold.TopologicalManifold.open_subset`)
INPUT:
@@ -425,9 +440,9 @@ class AbstractSet(AbstractNamedObject, UniqueRepresentation, Parent):
OUTPUT:
- - instance of :class:`ManifoldSubset` (or
+ - instance of :class:`~sage.manifolds.subset.ManifoldSubset` (or
of the derived class
- :class:`~sage.manifolds.manifold.Manifold` for an open
+ :class:`~sage.manifolds.subset.OpenTopologicalSubmanifold` for an open
subset) representing the subset whose name is ``name``.
EXAMPLES::
@@ -557,17 +572,11 @@ class AbstractSet(AbstractNamedObject, UniqueRepresentation, Parent):
dom2._unions[dom1._name] = self
for oc1 in dom1._open_covers:
for oc2 in dom2._open_covers:
- oc = set(oc1) # Make a (shallow) copy
+ oc = oc1[:]
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
+ oc.append(s)
+ self._open_covers.append(oc)
def point(self, coords=None, chart=None, name=None, latex_name=None):
r"""
@@ -617,4 +626,3 @@ class AbstractSet(AbstractNamedObject, UniqueRepresentation, Parent):
name=name, latex_name=latex_name)
Element = ManifoldPoint
-
diff --git a/src/sage/manifolds/all.py b/src/sage/manifolds/all.py
index 367ca68..c7defde 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_constructor', 'Manifold')
+lazy_import('sage.manifolds.manifold', 'Manifold')
diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py
index 2752731..993f046 100644
--- a/src/sage/manifolds/chart.py
+++ b/src/sage/manifolds/chart.py
@@ -55,7 +55,7 @@ class Chart(UniqueRepresentation, SageObject):
INPUT:
- ``domain`` -- open subset `U` on which the chart is defined (must be
- an instance of :class:`~sage.manifolds.manifold.Manifold`)
+ an instance of :class:`~sage.manifolds.manifold.TopologicalManifold`)
- ``coordinates`` -- (default: ``''`` (empty string)) single string
defining the coordinate symbols, with ``' '`` (whitespace) as a
separator; each item has at most two fields, separated by ``:``:
@@ -202,7 +202,7 @@ class Chart(UniqueRepresentation, SageObject):
Manifold subsets have a *default chart*, which, unless changed via the
method
- :meth:`~sage.manifolds.manifold.Manifold.set_default_chart`,
+ :meth:`~sage.manifolds.manifold.TopologicalManifold.set_default_chart`,
is the first defined chart on the subset (or on a open subset of it)::
sage: M.default_chart()
@@ -247,8 +247,8 @@ class Chart(UniqueRepresentation, SageObject):
sage: TestSuite(X).run()
"""
- from sage.manifolds.manifold import Manifold
- if not isinstance(domain, Manifold):
+ from sage.manifolds.manifold import TopologicalManifold
+ if not isinstance(domain, TopologicalManifold):
raise TypeError("the first argument must be an open subset of " +
"a topological manifold")
if coordinates == '':
@@ -560,7 +560,7 @@ class Chart(UniqueRepresentation, SageObject):
INPUT:
- ``subset`` -- open subset `V` of the chart domain `U` (must be an
- instance of :class:`~sage.manifolds.manifold.Manifold`)
+ instance of :class:`~sage.manifolds.manifold.TopologicalManifold`)
- ``restrictions`` -- (default: ``None``) list of coordinate
restrictions defining the subset `V`.
A restriction can be any symbolic equality or
@@ -979,7 +979,7 @@ class RealChart(Chart):
Manifold subsets have a *default chart*, which, unless changed via the
method
- :meth:`~sage.manifolds.manifold.Manifold.set_default_chart`,
+ :meth:`~sage.manifolds.manifold.TopologicalManifold.set_default_chart`,
is the first defined chart on the subset (or on a open subset of it)::
sage: M.default_chart()
@@ -1402,7 +1402,7 @@ class RealChart(Chart):
INPUT:
- ``subset`` -- open subset `V` of the chart domain `U` (must be an
- instance of :class:`~sage.manifolds.manifold.Manifold`)
+ instance of :class:`~sage.manifolds.manifold.TopologicalManifold`)
- ``restrictions`` -- (default: ``None``) list of coordinate
restrictions defining the subset `V`.
A restriction can be any symbolic equality or
diff --git a/src/sage/manifolds/manifold.py b/src/sage/manifolds/manifold.py
index d1d4249..7123e21 100644
--- a/src/sage/manifolds/manifold.py
+++ b/src/sage/manifolds/manifold.py
@@ -1,5 +1,5 @@
r"""
-Manifolds
+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
@@ -10,14 +10,14 @@ 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:`Manifold`. Open subsets of topological manifolds
-are also implemented via :class:`Manifold`, since they are
-topological manifolds by themselves.
+:class:`TopologicalManifold`. Open subsets of topological manifolds
+are implemented via the subclass
+:class:`~sage.manifolds.subset.OpenTopologicalSubmanifold`.
In the current setting, topological manifolds are mostly described by
means of charts (see :class:`~sage.manifolds.chart.Chart`).
-:class:`Manifold` serves as a base class for more specific
+:class:`TopologicalManifold` serves as a base class for more specific
manifold classes.
The user interface is provided by the generic function :func:`Manifold`,
@@ -259,7 +259,8 @@ The following subsets and charts have been defined::
AUTHORS:
- Eric Gourgoulhon (2015): initial version
-- Travis Scrimshaw (2015): inheritance from AbstractSet
+- Travis Scrimshaw (2015): inheritance from
+ :class:`~sage.manifolds.abstract.AbstractSet`
REFERENCES:
@@ -297,9 +298,9 @@ from sage.manifolds.structure import TopologicalStructure, RealTopologicalStruct
#####################################################################
## Classes
-class Manifold(AbstractSet):
+class TopologicalManifold(AbstractSet):
r"""
- Manifold over a topological field `K`.
+ 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
@@ -358,7 +359,7 @@ class Manifold(AbstractSet):
sage: latex(M)
\mathcal{M}
sage: type(M)
- <class 'sage.manifolds.manifold.Manifold_with_category'>
+ <class 'sage.manifolds.manifold.TopologicalManifold_with_category'>
sage: M.base_field()
Real Field with 53 bits of precision
sage: dim(M)
@@ -430,11 +431,12 @@ class Manifold(AbstractSet):
Since an open subset of a topological manifold `M` is itself a
topological manifold, open subsets of `M` are instances of the class
- :class:`Manifold`::
+ :class:`TopologicalManifold` (actually of the subclass
+ :class:`~sage.manifolds.subset.OpenTopologicalSubmanifold`)::
sage: U = M.open_subset('U'); U
Open subset U of the 4-dimensional topological manifold M
- sage: isinstance(U, sage.manifolds.manifold.Manifold)
+ sage: isinstance(U, sage.manifolds.manifold.TopologicalManifold)
True
sage: U.base_field() == M.base_field()
True
@@ -464,6 +466,7 @@ class Manifold(AbstractSet):
3
sage: X.<x,y,z> = M.chart()
sage: TestSuite(M).run()
+
"""
# Initialization of the attributes _dim, _field and _start_index:
self._dim = n
@@ -507,7 +510,7 @@ class Manifold(AbstractSet):
# 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
+ self._open_covers.append([self]) # list of open covers of self
def _repr_(self):
r"""
@@ -690,7 +693,8 @@ class Manifold(AbstractSet):
"""
Return ``self`` since ``self`` is the ambient manifold.
- This is for compatibility with :class:`TopologicalSubmanifold`.
+ This is for compatibility with
+ :class:`~sage.manifolds.subset.ManifoldSubset`.
EXAMPLES::
@@ -707,7 +711,8 @@ class Manifold(AbstractSet):
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`.
+ :class:`~sage.manifolds.subset.OpenTopologicalSubmanifold`, which
+ inherits from :class:`TopologicalManifold`.
INPUT:
@@ -721,7 +726,8 @@ class Manifold(AbstractSet):
OUTPUT:
- - the open subset, as an instance of :class:`Manifold`.
+ - the open subset, as an instance of
+ :class:`~sage.manifolds.subset.OpenTopologicalSubmanifold`.
EXAMPLES:
@@ -735,7 +741,7 @@ class Manifold(AbstractSet):
topological manifold, on the same topological field and of the same
dimension as ``M``::
- sage: isinstance(A, sage.manifolds.manifold.Manifold)
+ sage: isinstance(A, sage.manifolds.manifold.TopologicalManifold)
True
sage: A.base_field() == M.base_field()
True
@@ -782,10 +788,10 @@ class Manifold(AbstractSet):
False
"""
- from sage.manifolds.subset import TopologicalSubmanifold
- resu = TopologicalSubmanifold(ambient=self.manifold(),
- name=name, latex_name=latex_name,
- category=self.category())
+ from sage.manifolds.subset import OpenTopologicalSubmanifold
+ resu = OpenTopologicalSubmanifold(ambient=self.manifold(),
+ name=name, latex_name=latex_name,
+ category=self.category())
resu._supersets.update(self._supersets)
for sd in self._supersets:
@@ -863,19 +869,32 @@ class Manifold(AbstractSet):
def union(self, other, name=None, latex_name=None):
r"""
- Return the union of ``self`` with ``other``.
+ Return the union of the manifold with a subset, i.e. the manifold
+ itself.
INPUT:
- - ``other`` -- another subset of the same manifold
+ - ``other`` -- a subset of the manifold
- ``name`` -- ignored
- ``latex_name`` -- ignored
OUTPUT:
- - ``self``
+ - the manifold
- EXAMPLES:
+ EXAMPLES::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: A = M.subset('A')
+ sage: M.union(A)
+ 2-dimensional topological manifold M
+ sage: M.union(A) is M
+ True
+ sage: B = A.subset('B')
+ sage: M.union(B) is M
+ True
+ sage: M.union(M) is M
+ True
"""
if other.manifold() is not self:
@@ -884,20 +903,31 @@ class Manifold(AbstractSet):
def intersection(self, other, name=None, latex_name=None):
r"""
- Return the intersection of the current subset with another subset.
+ Return the intersection of the manifold with a subset, i.e. the subset.
INPUT:
- - ``other`` -- another subset of the same manifold
+ - ``other`` -- a subset of the manifold
- ``name`` -- ignored
- ``latex_name`` -- ignored
OUTPUT:
- - instance of :class:`ManifoldSubset` representing the
- subset that is the intersection of the current subset with ``other``
+ - the subset ``other``
- EXAMPLES:
+ EXAMPLES::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: A = M.subset('A')
+ sage: M.intersection(A)
+ Subset A of the 2-dimensional topological manifold M
+ sage: M.intersection(A) is A
+ True
+ sage: B = A.subset('B')
+ sage: M.intersection(B) is B
+ True
+ sage: M.intersection(M) is M
+ True
"""
if other.manifold() is not self:
@@ -1493,6 +1523,21 @@ class Manifold(AbstractSet):
"""
return self._structure.chart(self, coordinates=coordinates, names=names)
+ def is_open(self):
+ """
+ Return if ``self`` is an open set.
+
+ In the present case (manifold), always return ``True``.
+
+ TEST::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: M.is_open()
+ True
+
+ """
+ return True
+
def superset(self, name=None, latex_name=None, is_open=False):
r"""
Return ``self`` since the only superset of the manifold is
@@ -1504,7 +1549,11 @@ class Manifold(AbstractSet):
- ``latex_name`` -- ignored
- ``is_open`` -- ignored
- EXAMPLES:
+ TEST::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: M.superset() is M
+ True
"""
return self
@@ -1512,9 +1561,8 @@ class Manifold(AbstractSet):
#####################################################################
## Constructor function
-def manifold_constructor(dim, name, latex_name=None,
- field='real', structure='smooth',
- start_index=0, **extra_kwds):
+def Manifold(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,7 +1601,7 @@ def manifold_constructor(dim, name, latex_name=None,
OUTPUT:
- a manifold of the specified type, as an instance of
- :class:`~sage.manifolds.manifold.Manifold` or one of its
+ :class:`~sage.manifolds.manifold.TopologicalManifold` or one of its
subclasses.
EXAMPLES:
@@ -1580,7 +1628,7 @@ def manifold_constructor(dim, name, latex_name=None,
3-dimensional topological manifold M over the Rational Field
See the documentation of class
- :class:`~sage.manifolds.manifold.Manifold` for more
+ :class:`~sage.manifolds.manifold.TopologicalManifold` for more
detailed examples.
.. RUBRIC:: Uniqueness of manifold objects
@@ -1666,5 +1714,5 @@ def manifold_constructor(dim, name, latex_name=None,
raise NotImplementedError("manifolds of type {} are not ".format(structure) +
"implemented")
- return Manifold(dim, name, latex_name, field, structure, start_index,
- unique_tag=getrandbits(128)*time())
+ return TopologicalManifold(dim, name, latex_name, field, structure, start_index,
+ unique_tag=getrandbits(128)*time())
diff --git a/src/sage/manifolds/point.py b/src/sage/manifolds/point.py
index 01fa11f..fac91f1 100644
--- a/src/sage/manifolds/point.py
+++ b/src/sage/manifolds/point.py
@@ -70,13 +70,13 @@ Points can be compared::
from sage.structure.element import Element
-# TODO: Inherit from AbstractNamedObject
class ManifoldPoint(Element):
r"""
Point of a topological manifold.
This is a Sage *element* class, the corresponding *parent* class being
- :class:`~sage.manifolds.manifold.Manifold`.
+ :class:`~sage.manifolds.manifold.TopologicalManifold`
+ or :class:`~sage.manifolds.subset.ManifoldSubset`
INPUT:
@@ -105,7 +105,7 @@ class ManifoldPoint(Element):
sage: p.coord() # coordinates of P in the subset's default chart
(a, b)
- Since points are Sage *elements*, the (facade) *parent* of which being the
+ Since points are Sage *elements*, the *parent* of which being the
subset on which they are defined, it is equivalent to write::
sage: p = M((a, b), name='P'); p
@@ -165,10 +165,10 @@ class ManifoldPoint(Element):
if len(coords) != parent.manifold().dimension():
raise ValueError("the number of coordinates must be equal " +
"to the manifold's dimension")
- from sage.manifolds.manifold import Manifold
+ from sage.manifolds.manifold import TopologicalManifold
if chart is None:
chart = parent._def_chart
- elif isinstance(parent, Manifold):
+ elif isinstance(parent, TopologicalManifold):
if chart not in parent._atlas:
raise ValueError("the {} has not been".format(chart) +
"defined on the {}".format(parent))
diff --git a/src/sage/manifolds/structure.py b/src/sage/manifolds/structure.py
index 132f0f7..89120b4 100644
--- a/src/sage/manifolds/structure.py
+++ b/src/sage/manifolds/structure.py
@@ -30,10 +30,19 @@ class TopologicalStructure(Singleton):
"""
chart = Chart
name = "topological"
+
def subcategory(self, cat):
"""
Return the subcategory of ``cat`` corresponding to the structure
of ``self``.
+
+ EXAMPLE::
+
+ sage: from sage.manifolds.structure import TopologicalStructure
+ sage: from sage.categories.manifolds import Manifolds
+ sage: TopologicalStructure().subcategory(Manifolds(RR))
+ Category of manifolds over Real Field with 53 bits of precision
+
"""
return cat
@@ -43,10 +52,18 @@ class RealTopologicalStructure(Singleton):
"""
chart = RealChart
name = "topological"
+
def subcategory(self, cat):
"""
Return the subcategory of ``cat`` corresponding to the structure
of ``self``.
+
+ EXAMPLE::
+
+ sage: from sage.manifolds.structure import RealTopologicalStructure
+ sage: from sage.categories.manifolds import Manifolds
+ sage: RealTopologicalStructure().subcategory(Manifolds(RR))
+ Category of manifolds over Real Field with 53 bits of precision
+
"""
return cat
-
diff --git a/src/sage/manifolds/subset.py b/src/sage/manifolds/subset.py
index 3d2fdd3..6f6c297 100644
--- a/src/sage/manifolds/subset.py
+++ b/src/sage/manifolds/subset.py
@@ -3,13 +3,15 @@ Subsets of topological manifolds
The class :class:`ManifoldSubset` implements generic subsets of a
topological manifold. Open subsets are implemented by the class
-:class:`~sage.manifolds.manifold.Manifold` (since an open subset of
-a manifold is a manifold by itself), which inherits from
-:class:`ManifoldSubset`.
+:class:`~sage.manifolds.subset.OpenTopologicalSubmanifold`, which inherits from
+both :class:`ManifoldSubset` and
+:class:`~sage.manifolds.manifold.TopologicalManifold`.
AUTHORS:
- Eric Gourgoulhon, Michal Bejger (2013-2015): initial version
+- Travis Scrimshaw (2015): inheritance from
+ :class:`~sage.manifolds.abstract.AbstractSet`
REFERENCES:
@@ -63,6 +65,7 @@ Lists of subsets after the above operations::
#*****************************************************************************
# Copyright (C) 2015 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
# Copyright (C) 2015 Michal Bejger <bejger@camk.edu.pl>
+# Copyright (C) 2015 Travis Scrimshaw <tscrimsh@umn.edu>
#
# Distributed under the terms of the GNU General Public License (GPL)
# as published by the Free Software Foundation; either version 2 of
@@ -72,25 +75,21 @@ Lists of subsets after the above operations::
from sage.categories.sets_cat import Sets
from sage.manifolds.abstract import AbstractSet
-from sage.manifolds.manifold import Manifold
+from sage.manifolds.manifold import TopologicalManifold
class ManifoldSubset(AbstractSet):
r"""
Subset of a topological manifold.
- The class :class:`ManifoldSubset` inherits from the generic Sage
- class :class:`~sage.structure.parent.Parent` and is declared to belong to
- the category of facade sets
- (see :meth:`~sage.categories.sets_cat.Sets.SubcategoryMethods.Facade`).
+ The class :class:`ManifoldSubset` inherits (via
+ :class:`~sage.manifolds.abstract.AbstractSet`) from the generic
+ class :class:`~sage.structure.parent.Parent`.
The corresponding element class is
- :class:`~sage.manifolds.point.ManifoldPoint`. A subset acts
- as a facade for the true parent of its points, which is the whole manifold
- (see example below).
+ :class:`~sage.manifolds.point.ManifoldPoint`.
Note that open subsets are not implemented directly by this class, but
- by the derived class :class:`~sage.manifolds.manifold.Manifold`
- (an open subset of a topological manifold being itself a topological
- manifold).
+ by the derived class
+ :class:`~sage.manifolds.subset.OpenTopologicalSubmanifold`.
INPUT:
@@ -98,8 +97,6 @@ class ManifoldSubset(AbstractSet):
- ``name`` -- string; name (symbol) given to the subset
- ``latex_name`` -- (default: ``None``) string: LaTeX symbol to denote the
subset; if none is provided, it is set to ``name``
- - ``category`` -- (default: ``None``) to specify the categeory; if ``None``,
- the category of sets (:class:`~sage.categories.sets_cat.Sets`) is used
EXAMPLES:
@@ -116,8 +113,8 @@ class ManifoldSubset(AbstractSet):
True
Instead of importing :class:`ManifoldSubset` in the global
- namespace, it is recommended to use the method :meth:`subset` to create a
- new subset::
+ namespace, it is recommended to use the method
+ :meth:`~sage.manifolds.abstract.AbstractSet.subset` to create a new subset::
sage: B = M.subset('B', latex_name=r'\mathcal{B}'); B
Subset B of the 2-dimensional topological manifold M
@@ -142,21 +139,33 @@ class ManifoldSubset(AbstractSet):
True
"""
- def __init__(self, manifold, name, latex_name=None, category=None):
+ def __init__(self, manifold, name, latex_name=None):
r"""
Construct a manifold subset.
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
+ sage: type(A)
+ <class 'sage.manifolds.subset.ManifoldSubset_with_category'>
+ sage: A.category()
+ Category of subobjects of sets
+ sage: TestSuite(A).run(skip=['_test_elements', \
+ '_test_not_implemented_methods'])
+
+ .. TODO::
+
+ implement method ``lift`` so that ``_test_not_implemented_methods``
+ is passed.
+ NB: ``_test_elements`` cannot be passed without a proper
+ coordinate definition of the subset.
+
"""
category = Sets().Subobjects()
AbstractSet.__init__(self, name=name, latex_name=latex_name,
- category=category)
-
+ category=category)
self._manifold = manifold
for dom in manifold._subsets:
if name == dom._name:
@@ -191,10 +200,15 @@ class ManifoldSubset(AbstractSet):
sage: A = M.subset('A')
sage: A.manifold()
2-dimensional topological manifold M
+ sage: A.manifold() is M
+ True
sage: B = A.subset('B')
- sage: B.manifold()
- 2-dimensional topological manifold M
- sage: M.manifold() is M
+ sage: B.manifold() is M
+ True
+
+ An alias is ``ambient``::
+
+ sage: A.ambient() is A.manifold()
True
"""
@@ -205,6 +219,19 @@ class ManifoldSubset(AbstractSet):
def is_open(self):
"""
Return if ``self`` is an open set.
+
+ This method always returns ``False``, since open subsets must be
+ constructed as instances of the subclass
+ :class:`~sage.manifolds.subset.OpenTopologicalSubmanifold`
+ (which redefines ``is_open``)
+
+ EXAMPLE::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: A = M.subset('A')
+ sage: A.is_open()
+ False
+
"""
return False
@@ -227,7 +254,7 @@ class ManifoldSubset(AbstractSet):
- the superset, as an instance of :class:`ManifoldSubset` or
of the derived class
- :class:`~sage.manifolds.manifold.Manifold` if ``is_open``
+ :class:`~sage.manifolds.subset.OpenTopologicalSubmanifold` if ``is_open``
is ``True``.
EXAMPLES:
@@ -235,26 +262,21 @@ class ManifoldSubset(AbstractSet):
Creating some superset of a given subset::
sage: M = Manifold(2, 'M', structure='topological')
- sage: a = M.subset('A')
- sage: b = a.superset('B'); b
+ sage: A = M.subset('A')
+ sage: B = A.superset('B'); B
Subset B of the 2-dimensional topological manifold M
- sage: b.list_of_subsets()
+ sage: B.list_of_subsets()
[Subset A of the 2-dimensional topological manifold M,
Subset B of the 2-dimensional topological manifold M]
- sage: a._supersets # random (set output)
+ sage: A._supersets # random (set output)
{Subset B of the 2-dimensional topological manifold M,
Subset A of the 2-dimensional topological manifold M,
2-dimensional topological manifold M}
- The superset of the whole manifold is itself::
-
- sage: M.superset('SM') is M
- True
-
Two supersets of a given subset are a priori different::
- sage: c = a.superset('C')
- sage: c == b
+ sage: C = A.superset('C')
+ sage: C == B
False
"""
@@ -469,17 +491,97 @@ class ManifoldSubset(AbstractSet):
res._open_covers.append(oc)
return res
-class TopologicalSubmanifold(ManifoldSubset, Manifold):
+#*****************************************************************************
+
+class OpenTopologicalSubmanifold(ManifoldSubset, TopologicalManifold):
"""
- A submanifold of a manifold, which is any open subset of a manifold.
+ An open submanifold of a topological manifold, which is any open subset
+ of the manifold.
+
+ EXAMPLE:
+
+ The unit ball of the Euclidean 2-plane::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: B = M.open_subset('B', coord_def={X: x^2+y^2<1})
+ sage: B
+ Open subset B of the 2-dimensional topological manifold M
+ sage: type(B)
+ <class 'sage.manifolds.subset.OpenTopologicalSubmanifold_with_category'>
+ sage: B.category()
+ Join of Category of subobjects of sets and Category of manifolds over
+ Real Field with 53 bits of precision
+
+ An open subset of a topological manifold being a topological manifold
+ by itself, ``B`` inherits of all the methods of class
+ :class:`~sage.manifolds.manifold.TopologicalManifold`::
+
+ sage: isinstance(B, sage.manifolds.manifold.TopologicalManifold)
+ True
+ sage: dim(B)
+ 2
+ sage: B.base_field()
+ Real Field with 53 bits of precision
+
+ Given the definition of ``B``, it is automatically endowed with a chart,
+ which is the restriction of ``X`` to ``B``::
+
+ sage: B.atlas()
+ [Chart (B, (x, y))]
+ sage: B.default_chart()
+ Chart (B, (x, y))
+ sage: B.default_chart() is X.restrict(B)
+ True
+
+ An point in ``B``::
+
+ sage: p = B.an_element(); p
+ Point on the 2-dimensional topological manifold M
+ sage: X(p) # the coordinates (x,y) of p
+ (0, 0)
+ sage: p in B
+ True
+
+ Checking whether various points, defined by their coordinates w.r.t.
+ chart ``X``, are in ``B``::
+
+ sage: M((0,1/2)) in B
+ True
+ sage: M((0,1)) in B
+ False
+ sage: M((1/2,1)) in B
+ False
+ sage: M((-1/2,1/3)) in B
+ True
+
"""
def __init__(self, ambient, name, latex_name=None, category=None):
"""
Initialize ``self``.
+
+ TESTS::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: A = M.open_subset('A', coord_def={X: x^2+y^2<1}); A
+ Open subset A of the 2-dimensional topological manifold M
+ sage: type(A)
+ <class 'sage.manifolds.subset.OpenTopologicalSubmanifold_with_category'>
+ sage: A.category()
+ Join of Category of subobjects of sets and Category of manifolds
+ over Real Field with 53 bits of precision
+ sage: TestSuite(A).run(skip='_test_not_implemented_methods')
+
+ .. TODO::
+
+ implement method ``lift`` so that ``_test_not_implemented_methods``
+ is passed.
+
"""
# TODO: This test probably needs a better place, like open_subset
- if not isinstance(ambient, Manifold):
- raise TypeError("the argument 'manifold' must be " +
+ if not isinstance(ambient, TopologicalManifold):
+ raise TypeError("the argument 'ambient' must be " +
"a topological manifold")
# This is copied from ManifoldSubset to avoid twice
@@ -493,13 +595,21 @@ class TopologicalSubmanifold(ManifoldSubset, Manifold):
ambient._subsets.add(self)
category = ambient.category().Subobjects()
- Manifold.__init__(self, ambient.dim(), name, latex_name,
- ambient._field, ambient._structure,
- ambient._sindex, category)
+ TopologicalManifold.__init__(self, ambient.dim(), name, latex_name,
+ ambient._field, ambient._structure,
+ ambient._sindex, category)
def _repr_(self):
"""
Return a string representation of ``self``.
+
+ TEST::
+
+ sage: M = Manifold(3, 'M', structure='topological')
+ sage: A = M.open_subset('A')
+ sage: A._repr_()
+ 'Open subset A of the 3-dimensional topological manifold M'
+
"""
return "Open subset {} of the {}".format(self._name, self._manifold)
@@ -523,10 +633,36 @@ class TopologicalSubmanifold(ManifoldSubset, Manifold):
- the superset, as an instance of :class:`ManifoldSubset` or
of the derived class
- :class:`~sage.manifolds.manifold.Manifold` if ``is_open``
+ :class:`~sage.manifolds.subset.OpenTopologicalSubmanifold` if ``is_open``
is ``True``.
- EXAMPLES:
+ EXAMPLES::
+
+ sage: M = Manifold(3, 'M', structure='topological')
+ sage: A = M.open_subset('A')
+ sage: B = A.superset('B'); B
+ Subset B of the 3-dimensional topological manifold M
+ sage: B.list_of_subsets()
+ [Open subset A of the 3-dimensional topological manifold M,
+ Subset B of the 3-dimensional topological manifold M]
+ sage: A._supersets # random (set output)
+ {Subset B of the 3-dimensional topological manifold M,
+ Open subset A of the 3-dimensional topological manifold M,
+ 3-dimensional topological manifold M}
+
+ Creating an open superset::
+
+ sage: C = A.superset('C', is_open=True); C
+ Open subset C of the 3-dimensional topological manifold M
+ sage: C.list_of_subsets()
+ [Open subset A of the 3-dimensional topological manifold M,
+ Open subset C of the 3-dimensional topological manifold M]
+ sage: A._supersets # random (set output)
+ {Subset B of the 3-dimensional topological manifold M,
+ Open subset A of the 3-dimensional topological manifold M,
+ Open subset C of the 3-dimensional topological manifold M,
+ 3-dimensional topological manifold M}
+
"""
res = ManifoldSubset.superset(self, name, latex_name, is_open)
if is_open:
@@ -539,5 +675,15 @@ class TopologicalSubmanifold(ManifoldSubset, Manifold):
def is_open(self):
"""
Return if ``self`` is an open set.
+
+ In the present case (open submanifold), always return ``True``.
+
+ EXAMPLE::
+
+ sage: M = Manifold(3, 'M', structure='topological')
+ sage: A = M.open_subset('A')
+ sage: A.is_open()
+ True
+
"""
return True