summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Gourgoulhon <eric.gourgoulhon@obspm.fr>2016-01-04 12:14:31 +0100
committerEric Gourgoulhon <eric.gourgoulhon@obspm.fr>2016-01-04 12:14:31 +0100
commit3cd03a48d847e12745ed8c25b23f19db141c179a (patch)
tree6d3fdb32c70a2105fcd53b2460cac90f9b4ffa69
parentRevert to AbstractNamedObject without argument full_name; restore _repr_() in... (diff)
Add methods lift() and retract() to ManifoldSubset; add method __eq__() in CoordChange
-rw-r--r--src/sage/manifolds/chart.py56
-rw-r--r--src/sage/manifolds/subset.py98
2 files changed, 130 insertions, 24 deletions
diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py
index 993f046..29e1c67 100644
--- a/src/sage/manifolds/chart.py
+++ b/src/sage/manifolds/chart.py
@@ -1631,11 +1631,7 @@ class CoordChange(SageObject):
Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v))
sage: type(X_to_Y)
<class 'sage.manifolds.chart.CoordChange'>
- sage: TestSuite(X_to_Y).run(skip='_test_pickling')
-
- .. TODO::
-
- fix _test_pickling
+ sage: TestSuite(X_to_Y).run()
"""
self._n1 = len(chart1._xx)
@@ -1696,6 +1692,55 @@ class CoordChange(SageObject):
"""
return latex(self._chart1) + r' \rightarrow ' + latex(self._chart2)
+ def __eq__(self, other):
+ r"""
+ Equality operator.
+
+ TESTS::
+
+ 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])
+ sage: X_to_Y == X_to_Y
+ True
+ sage: X_to_Y1 = X.transition_map(Y, [x+y, x-y])
+ sage: X_to_Y == X_to_Y1
+ True
+ sage: X_to_Y2 = X.transition_map(Y, [2*y, -x])
+ sage: X_to_Y == X_to_Y2
+ False
+ sage: Z.<w,z> = M.chart()
+ sage: X_to_Z = X.transition_map(Z, [x+y, x-y])
+ sage: X_to_Y == X_to_Z
+ False
+
+ """
+ if other is self:
+ return True
+ if not isinstance(other, CoordChange):
+ return False
+ return (self._chart1 == other._chart1) and \
+ (self._chart2 == other._chart2) and \
+ (self._transf == other._transf)
+
+ def __ne__(self, other):
+ r"""
+ Unequality operator.
+
+ TESTS::
+
+ 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])
+ sage: X_to_Y2 = X.transition_map(Y, [2*y, -x])
+ sage: X_to_Y != X_to_Y2
+ True
+
+ """
+ return not (self == other)
+
def __call__(self, *coords):
r"""
Compute the new coordinates from old ones.
@@ -2033,4 +2078,3 @@ class CoordChange(SageObject):
return FormattedExpansion(rtxt, rlatex)
disp = display
-
diff --git a/src/sage/manifolds/subset.py b/src/sage/manifolds/subset.py
index 56254d6..636ee88 100644
--- a/src/sage/manifolds/subset.py
+++ b/src/sage/manifolds/subset.py
@@ -152,14 +152,11 @@ class ManifoldSubset(AbstractSet):
<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'])
+ sage: TestSuite(A).run(skip='_test_elements')
- .. TODO::
+ .. NOTE::
- implement method ``lift`` so that ``_test_not_implemented_methods``
- is passed.
- NB: ``_test_elements`` cannot be passed without a proper
+ ``_test_elements`` cannot be passed without a proper
coordinate definition of the subset.
"""
@@ -190,6 +187,82 @@ class ManifoldSubset(AbstractSet):
"""
return "Subset {} of the {}".format(self._name, self._manifold)
+ def lift(self, p):
+ r"""
+ Lift map.
+
+ INPUT:
+
+ - ``p`` -- point of the subset
+
+ OUTPUT:
+
+ - the same point, considered as a point of the ambient manifold
+
+ EXAMPLE::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: A = M.open_subset('A', coord_def={X: x>0})
+ sage: p = A((1, -2)); p
+ Point on the 2-dimensional topological manifold M
+ sage: p.parent()
+ Open subset A of the 2-dimensional topological manifold M
+ sage: q = A.lift(p); q
+ Point on the 2-dimensional topological manifold M
+ sage: q.parent()
+ 2-dimensional topological manifold M
+ sage: q.coord()
+ (1, -2)
+ sage: (p == q) and (q == p)
+ True
+
+ """
+ return self._manifold(p)
+
+ def retract(self, p):
+ r"""
+ Retraction map.
+
+ INPUT:
+
+ - ``p`` -- point of the ambient manifold
+
+ OUTPUT:
+
+ - the same point, considered as a point of the subset
+
+ EXAMPLES::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: A = M.open_subset('A', coord_def={X: x>0})
+ sage: p = M((1, -2)); p
+ Point on the 2-dimensional topological manifold M
+ sage: p.parent()
+ 2-dimensional topological manifold M
+ sage: q = A.retract(p); q
+ Point on the 2-dimensional topological manifold M
+ sage: q.parent()
+ Open subset A of the 2-dimensional topological manifold M
+ sage: q.coord()
+ (1, -2)
+ sage: (q == p) and (p == q)
+ True
+
+ Of course, if the point does not belong to ``A``, the ``retract``
+ method fails::
+
+ sage: p = M((-1, 3)) # x < 0, so that p is not in A
+ sage: q = A.retract(p)
+ Traceback (most recent call last):
+ ...
+ ValueError: the Point on the 2-dimensional topological manifold M
+ is not in Open subset A of the 2-dimensional topological manifold M
+
+ """
+ return self(p)
+
def manifold(self):
r"""
Return the manifold of which the current object is a subset.
@@ -357,9 +430,6 @@ class ManifoldSubset(AbstractSet):
if other._name in self._intersections:
# the intersection has already been created:
return self._intersections[other._name]
-
- # TODO: Check to see if we've already created a union of ``self`` and ``other``
-
# the intersection must be created:
if latex_name is None:
if name is None:
@@ -453,9 +523,6 @@ class ManifoldSubset(AbstractSet):
if other._name in self._unions:
# the union has already been created:
return self._unions[other._name]
-
- # TODO: Check to see if we've already created a union of ``self`` and ``other``
-
# the union must be created:
if latex_name is None:
if name is None:
@@ -578,12 +645,7 @@ class OpenTopologicalSubmanifold(ManifoldSubset, TopologicalManifold):
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.
+ sage: TestSuite(A).run()
"""
# TODO: This test probably needs a better place, like open_subset