summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Gourgoulhon <eric.gourgoulhon@obspm.fr>2015-06-26 18:04:38 +0200
committerEric Gourgoulhon <eric.gourgoulhon@obspm.fr>2015-06-26 18:04:38 +0200
commit30e812a668e3fca229def326012bbc47a450b15e (patch)
treeec733f9da3626df92c8d4aadb79681a47893f40a
parentChanges in ContinuousMap, in particular in __invert__ (diff)
Minor modifications in CoordFunctionSymb and ContinuousMap.__invert__
-rw-r--r--src/sage/manifolds/chart.py34
-rw-r--r--src/sage/manifolds/continuous_map.py71
-rw-r--r--src/sage/manifolds/coord_func_symb.py22
-rw-r--r--src/sage/manifolds/manifold.py6
4 files changed, 86 insertions, 47 deletions
diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py
index 15d98ef..5e5eab1 100644
--- a/src/sage/manifolds/chart.py
+++ b/src/sage/manifolds/chart.py
@@ -296,10 +296,14 @@ class Chart(UniqueRepresentation, SageObject):
self._dom_restrict = {} # dict. of the restrictions of self to
# subsets of self._domain, with the
# subsets as keys
- # The null function of the coordinates:
- self._zero_function = CoordFunctionSymb(self, 0)
- # The "one" function of the coordinates:
- self._one_function = CoordFunctionSymb(self, 1)
+ # The null and one functions of the coordinates:
+ base_field = self._domain.base_field()
+ if base_field in ['real', 'complex']:
+ self._zero_function = CoordFunctionSymb(self, 0)
+ self._one_function = CoordFunctionSymb(self, 1)
+ else:
+ self._zero_function = CoordFunctionSymb(self, base_field.zero())
+ self._one_function = CoordFunctionSymb(self, base_field.one())
# Expression in self of the zero and one scalar fields of open sets
# containing the domain of self:
for dom in self._domain._supersets:
@@ -912,6 +916,17 @@ class Chart(UniqueRepresentation, SageObject):
sage: X.zero_function() is X.zero_function()
True
+ Zero function on a p-adic manifold::
+
+ sage: M = TopManifold(2, 'M', field=Qp(5)); M
+ 2-dimensional topological manifold M over the 5-adic Field with
+ capped relative precision 20
+ sage: X.<x,y> = M.chart()
+ sage: X.zero_function()
+ 0
+ sage: X.zero_function().display()
+ (x, y) |--> 0
+
"""
return self._zero_function
@@ -955,6 +970,17 @@ class Chart(UniqueRepresentation, SageObject):
sage: X.one_function() is X.one_function()
True
+ One function on a p-adic manifold::
+
+ sage: M = TopManifold(2, 'M', field=Qp(5)); M
+ 2-dimensional topological manifold M over the 5-adic Field with
+ capped relative precision 20
+ sage: X.<x,y> = M.chart()
+ sage: X.one_function()
+ 1 + O(5^20)
+ sage: X.one_function().display()
+ (x, y) |--> 1 + O(5^20)
+
"""
return self._one_function
diff --git a/src/sage/manifolds/continuous_map.py b/src/sage/manifolds/continuous_map.py
index 47778da..de89ed7 100644
--- a/src/sage/manifolds/continuous_map.py
+++ b/src/sage/manifolds/continuous_map.py
@@ -1683,19 +1683,10 @@ class ContinuousMap(Morphism):
return self._restrictions[(subdomain, subcodomain)]
- def __invert__(self, chart1=None, chart2=None):
+ def __invert__(self):
r"""
Return the inverse of ``self`` if ``self`` is a isomorphism.
- INPUT:
-
- - ``chart1`` -- (default: ``None``) chart in which the computation of the
- inverse is performed if necessary; if none is provided, the default
- chart of the domain of ``self`` will be used
- - ``chart2`` -- (default: ``None``) chart in which the computation of the
- inverse is performed if necessary; if none is provided, the default
- chart of the codomain of ``self`` will be used
-
OUTPUT:
- the inverse isomorphism
@@ -1725,6 +1716,18 @@ class ContinuousMap(Morphism):
sage: p1 == p
True
+ The result is cached::
+
+ sage: rot.inverse() is rot.inverse()
+ True
+
+ The notations ``^(-1)`` or ``~`` can also be used for the inverse::
+
+ sage: rot^(-1) is rot.inverse()
+ True
+ sage: ~rot is rot.inverse()
+ True
+
"""
from sage.symbolic.ring import SR
from sage.symbolic.relation import solve
@@ -1732,30 +1735,31 @@ class ContinuousMap(Morphism):
return self._inverse
if not self._is_isomorphism:
raise ValueError("the {} is not an isomorphism".format(self))
- if chart1 is None: chart1 = self._domain._def_chart
- if chart2 is None: chart2 = self._codomain._def_chart
- coord_map = self._coord_expression[(chart1, chart2)]
- n1 = len(chart1._xx)
- n2 = len(chart2._xx)
- # New symbolic variables (different from chart2._xx to allow for a
- # correct solution even when chart2 = chart1):
- x2 = [ SR.var('xxxx' + str(i)) for i in range(n2) ]
- equations = [ x2[i] == coord_map._functions[i]._express
- for i in range(n2) ]
- solutions = solve(equations, chart1._xx, solution_dict=True)
- if len(solutions) == 0:
- raise ValueError("no solution found")
- if len(solutions) > 1:
- raise ValueError("non-unique solution found")
- substitutions = dict(zip(x2, chart2._xx))
- inv_functions = [solutions[0][chart1._xx[i]].subs(substitutions)
+ coord_functions = {} # coordinate expressions of the result
+ for (chart1, chart2) in self._coord_expression:
+ coord_map = self._coord_expression[(chart1, chart2)]
+ n1 = len(chart1._xx)
+ n2 = len(chart2._xx)
+ # New symbolic variables (different from chart2._xx to allow for a
+ # correct solution even when chart2 = chart1):
+ x2 = [ SR.var('xxxx' + str(i)) for i in range(n2) ]
+ equations = [ x2[i] == coord_map._functions[i]._express
+ for i in range(n2) ]
+ solutions = solve(equations, chart1._xx, solution_dict=True)
+ if len(solutions) == 0:
+ raise ValueError("no solution found")
+ if len(solutions) > 1:
+ raise ValueError("non-unique solution found")
+ substitutions = dict(zip(x2, chart2._xx))
+ inv_functions = [solutions[0][chart1._xx[i]].subs(substitutions)
for i in range(n1)]
- for i in range(n1):
- x = inv_functions[i]
- try:
- inv_functions[i] = chart2._simplify(x)
- except AttributeError:
- pass
+ for i in range(n1):
+ x = inv_functions[i]
+ try:
+ inv_functions[i] = chart2._simplify(x)
+ except AttributeError:
+ pass
+ coord_functions[(chart2, chart1)] = inv_functions
if self._name is None:
name = None
else:
@@ -1765,7 +1769,6 @@ class ContinuousMap(Morphism):
else:
latex_name = self._latex_name + r'^{-1}'
homset = Hom(self._codomain, self._domain)
- coord_functions = {(chart2, chart1): inv_functions}
self._inverse = self.__class__(homset, coord_functions=coord_functions,
name=name, latex_name=latex_name,
is_isomorphism=True)
diff --git a/src/sage/manifolds/coord_func_symb.py b/src/sage/manifolds/coord_func_symb.py
index 9cd7e87..ca7c6fa 100644
--- a/src/sage/manifolds/coord_func_symb.py
+++ b/src/sage/manifolds/coord_func_symb.py
@@ -750,6 +750,9 @@ class CoordFunctionSymb(CoordFunction):
"""
return CoordFunctionSymb(self._chart,
self._simplify(SR(1) / self._express))
+ # NB: self._express.__invert__() would return 1/self._express
+ # (cf. the code of __invert__ in src/sage/symbolic/expression.pyx)
+ # Here we prefer SR(1)/self._express
def __add__(self, other):
r"""
@@ -796,9 +799,9 @@ class CoordFunctionSymb(CoordFunction):
"the same chart cannot be added")
res = self._simplify(self._express + other._express)
elif isinstance(other, (int, RingElement)):
- res = self._simplify(self._express + other)
+ res = self._simplify(self._express + SR(other))
else:
- # addition to a numerical coord. function shall fall in this case
+ # addition to a numerical coord. function shall fall into this case
return other.__radd__(self)
if res == 0:
return self._chart._zero_function
@@ -852,9 +855,10 @@ class CoordFunctionSymb(CoordFunction):
"the same chart cannot be subtracted")
res = self._simplify(self._express - other._express)
elif isinstance(other, (int, RingElement)):
- res = self._simplify(self._express - other)
+ res = self._simplify(self._express - SR(other))
else:
- # subtraction of a numerical coord. function shall fall in this case
+ # subtraction of a numerical coord. function shall fall into this
+ # case
return other.__rsub__(self)
if res == 0:
return self._chart._zero_function
@@ -906,10 +910,10 @@ class CoordFunctionSymb(CoordFunction):
"the same chart cannot be multiplied")
res = self._simplify(self._express * other._express)
elif isinstance(other, (int, RingElement)):
- res = self._simplify(self._express * other)
+ res = self._simplify(self._express * SR(other))
else:
- # multiplication by a numerical coord. function shall fall in this
- # case
+ # multiplication by a numerical coord. function shall fall into
+ # this case
return other.__rmul__(self)
if res == 0:
return self._chart._zero_function
@@ -968,9 +972,9 @@ class CoordFunctionSymb(CoordFunction):
"by zero")
res = self._simplify(self._express / other._express)
elif isinstance(other, (int, RingElement)):
- res = self._simplify(self._express / other)
+ res = self._simplify(self._express / SR(other))
else:
- # division by a numerical coord. function shall fall in this
+ # division by a numerical coord. function shall fall into this
# case
return other.__rdiv__(self)
if res == 0:
diff --git a/src/sage/manifolds/manifold.py b/src/sage/manifolds/manifold.py
index 12f8e06..ac7b1e0 100644
--- a/src/sage/manifolds/manifold.py
+++ b/src/sage/manifolds/manifold.py
@@ -356,6 +356,12 @@ class TopManifold(TopManifoldSubset):
sage: N = TopManifold(6, 'N', 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 = TopManifold(2, 'N', field=Qp(5)); N
+ 2-dimensional topological manifold N over the 5-adic Field with capped
+ relative precision 20
+
A manifold is a Sage *parent* object, in the category of sets::
sage: isinstance(M, Parent)