summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTravis Scrimshaw <tscrimsh at umn.edu>2016-05-02 21:29:49 -0500
committerTravis Scrimshaw <tscrimsh at umn.edu>2016-05-02 21:29:49 -0500
commit0fd44d691614b07ffc2cb2ae63e6a00ed13a23e8 (patch)
treeb22447bdf0896f516be2fe6f0c35adb6c8671f80
parentMerge branch 'develop' into public/manifolds/top_manif_scalar_fields (diff)
Some cleanup and creating a parent for coordinate functions.
-rw-r--r--src/sage/manifolds/chart.py59
-rw-r--r--src/sage/manifolds/coord_func.py603
-rw-r--r--src/sage/manifolds/coord_func_symb.py502
-rw-r--r--src/sage/manifolds/scalarfield.py18
-rw-r--r--src/sage/manifolds/scalarfield_algebra.py4
5 files changed, 493 insertions, 693 deletions
diff --git a/src/sage/manifolds/chart.py b/src/sage/manifolds/chart.py
index 8be827d..4c074b8 100644
--- a/src/sage/manifolds/chart.py
+++ b/src/sage/manifolds/chart.py
@@ -312,22 +312,15 @@ class Chart(UniqueRepresentation, SageObject):
# subsets as keys
# The null and one functions of the coordinates:
base_field_type = self._domain.base_field_type()
- if base_field_type in ['real', 'complex']:
- self._zero_function = CoordFunctionSymb(self, 0)
- self._one_function = CoordFunctionSymb(self, 1)
- else:
- base_field = self._domain.base_field()
- 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:
if hasattr(dom, '_zero_scalar_field'):
# dom is an open set
- dom._zero_scalar_field._express[self] = self._zero_function
+ dom._zero_scalar_field._express[self] = self.function_ring().zero()
if hasattr(dom, '_one_scalar_field'):
# dom is an open set
- dom._one_scalar_field._express[self] = self._one_function
+ dom._one_scalar_field._express[self] = self.function_ring().one()
def _init_coordinates(self, coord_list):
r"""
@@ -844,6 +837,20 @@ class Chart(UniqueRepresentation, SageObject):
transformations = [transformations]
return CoordChange(chart1, chart2, *transformations)
+ def function_ring(self):
+ """
+ Return the ring of coordinate functions on ``self``.
+
+ EXAMPLES::
+
+ sage: M = Manifold(2, 'M', structure='topological')
+ sage: X.<x,y> = M.chart()
+ sage: X.function_ring()
+ Ring of coordinate functions on Chart (M, (x, y))
+ """
+ from sage.manifolds.coord_func_symb import CoordFunctionSymbRing
+ return CoordFunctionSymbRing(self)
+
def function(self, expression):
r"""
Define a coordinate function to the base field.
@@ -896,7 +903,7 @@ class Chart(UniqueRepresentation, SageObject):
sage: f
sin(x*y)
sage: type(f)
- <class 'sage.manifolds.coord_func_symb.CoordFunctionSymb'>
+ <class 'sage.manifolds.coord_func_symb.CoordFunctionSymbRing_with_category.element_class'>
sage: f.display()
(x, y) |--> sin(x*y)
sage: f(2,3)
@@ -907,7 +914,7 @@ class Chart(UniqueRepresentation, SageObject):
raise NotImplementedError("numerical coordinate function not " +
"implemented yet")
else:
- return CoordFunctionSymb(self, expression)
+ return self.function_ring()(expression)
def zero_function(self):
r"""
@@ -942,7 +949,7 @@ class Chart(UniqueRepresentation, SageObject):
sage: X.zero_function().display()
(x, y) |--> 0
sage: type(X.zero_function())
- <class 'sage.manifolds.coord_func_symb.CoordFunctionSymb'>
+ <class 'sage.manifolds.coord_func_symb.CoordFunctionSymbRing_with_category.element_class'>
The result is cached::
@@ -961,7 +968,7 @@ class Chart(UniqueRepresentation, SageObject):
(x, y) |--> 0
"""
- return self._zero_function
+ return self.function_ring().zero()
def one_function(self):
r"""
@@ -996,7 +1003,7 @@ class Chart(UniqueRepresentation, SageObject):
sage: X.one_function().display()
(x, y) |--> 1
sage: type(X.one_function())
- <class 'sage.manifolds.coord_func_symb.CoordFunctionSymb'>
+ <class 'sage.manifolds.coord_func_symb.CoordFunctionSymbRing_with_category.element_class'>
The result is cached::
@@ -1015,23 +1022,24 @@ class Chart(UniqueRepresentation, SageObject):
(x, y) |--> 1 + O(5^20)
"""
- return self._one_function
+ return self.function_ring().one()
def multifunction(self, *expressions):
r"""
Define a coordinate function to some Cartesian power of the base field.
- If `n` and `m` are two positive integers and `(U,\varphi)` is a chart on
- a topological manifold `M` of dimension `n` over a topological field `K`,
- a *multi-coordinate function* associated to `(U,\varphi)` is a map
+ If `n` and `m` are two positive integers and `(U, \varphi)` is a
+ chart on a topological manifold `M` of dimension `n` over a
+ topological field `K`, a *multi-coordinate function* associated
+ to `(U,\varphi)` is a map
.. MATH::
\begin{array}{llcl}
f:& V \subset K^n & \longrightarrow & K^m \\
- & (x^1,\ldots,x^n) & \longmapsto & (f_1(x^1,\ldots,x^n),\ldots,
- f_m(x^1,\ldots,x^n)) ,
+ & (x^1, \ldots, x^n) & \longmapsto & (f_1(x^1, \ldots, x^n),
+ \ldots, f_m(x^1, \ldots, x^n)),
\end{array}
where `V` is the codomain of `\varphi`. In other words, `f` is a
@@ -1051,10 +1059,10 @@ class Chart(UniqueRepresentation, SageObject):
OUTPUT:
- - an instance of :class:`~sage.manifolds.coord_func.MultiCoordFunction`
+ - a :class:`~sage.manifolds.coord_func.MultiCoordFunction`
representing `f`
- EXAMPLE:
+ EXAMPLES:
Function of two coordinates with values in `\RR^3`::
@@ -1062,11 +1070,14 @@ class Chart(UniqueRepresentation, SageObject):
sage: X.<x,y> = M.chart()
sage: f = X.multifunction(x+y, sin(x*y), x^2 + 3*y); f
Coordinate functions (x + y, sin(x*y), x^2 + 3*y) on the Chart (M, (x, y))
- sage: type(f)
- <class 'sage.manifolds.coord_func.MultiCoordFunction'>
sage: f(2,3)
(5, sin(6), 13)
+ TESTS::
+
+ sage: type(f)
+ <class 'sage.manifolds.coord_func.MultiCoordFunction'>
+
"""
from sage.manifolds.coord_func import MultiCoordFunction
return MultiCoordFunction(self, expressions)
diff --git a/src/sage/manifolds/coord_func.py b/src/sage/manifolds/coord_func.py
index 84a65ca..8e54e20 100644
--- a/src/sage/manifolds/coord_func.py
+++ b/src/sage/manifolds/coord_func.py
@@ -40,16 +40,17 @@ AUTHORS:
#*****************************************************************************
from sage.misc.abstract_method import abstract_method
+from sage.misc.cachefunc import cached_method
+from sage.structure.element import AlgebraElement
from sage.structure.sage_object import SageObject
-from sage.misc.latex import latex
-class CoordFunction(SageObject):
+class CoordFunction(AlgebraElement):
r"""
Abstract base class for coordinate functions.
If `(U, \varphi)` is a chart on a topological manifold `M` of
dimension `n` over a topological field `K`, a *coordinate function*
- associated to `(U, \varphi)` is a map `f: V\subset K^n \to K`, where
+ associated to `(U, \varphi)` is a map `f: V \subset K^n \to K`, where
`V` is the codomain of `\varphi`. In other words, `f` is a `K`-valued
function of the coordinates associated to the chart `(U, \varphi)`.
@@ -64,20 +65,20 @@ class CoordFunction(SageObject):
the chart `(U, \varphi)`
"""
- def __init__(self, chart):
+ def __init__(self, parent):
r"""
- Base constructor for derived classes.
+ Initialize ``self``.
TEST::
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
"""
- self._chart = chart
- self._nc = len(chart[:]) # number of coordinates
+ AlgebraElement.__init__(self, parent)
+ self._nc = len(parent._chart[:]) # number of coordinates
# ----------------------------------------------------------------
# Methods that do not need to be re-implemented by derived classes
@@ -85,8 +86,7 @@ class CoordFunction(SageObject):
def chart(self):
r"""
- Return the chart with respect to which the coordinate function
- is defined.
+ Return the chart with respect to which ``self`` is defined.
OUTPUT:
@@ -103,15 +103,15 @@ class CoordFunction(SageObject):
True
"""
- return self._chart
+ return self.parent()._chart
def scalar_field(self, name=None, latex_name=None):
r"""
- Construct the scalar field that has the coordinate function as
+ Construct the scalar field that has ``self`` as
coordinate expression.
The domain of the scalar field is the open subset covered by the
- chart on which the coordinate function is defined.
+ chart on which ``self`` is defined.
INPUT:
@@ -139,10 +139,11 @@ class CoordFunction(SageObject):
True
"""
- alg = self._chart.domain().scalar_field_algebra()
- return alg.element_class(alg, coord_expression={self._chart: self},
+ alg = self.parent()._chart.domain().scalar_field_algebra()
+ return alg.element_class(alg, coord_expression={self.parent()._chart: self},
name=name, latex_name=latex_name)
+ # TODO: This should be abstract up to SageObject at some point - TCS
def __ne__(self, other):
r"""
Inequality operator.
@@ -171,240 +172,6 @@ class CoordFunction(SageObject):
"""
return not (self == other)
- def __radd__(self, other):
- r"""
- Reflected addition operator: performs ``other + self``.
-
- INPUT:
-
- - ``other`` -- a :class:`CoordFunction` or a value
-
- OUTPUT:
-
- - coordinate function resulting from the addition of ``self`` to
- ``other``
-
- TESTS::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: f = X.function(x+y)
- sage: g = X.function(x*y)
- sage: f.__radd__(g)
- (x + 1)*y + x
- sage: f.__radd__(X.zero_function()) == f
- True
- sage: 2 + f # indirect doctest
- x + y + 2
-
- """
- return self.__add__(other) # since + is commutative
-
- def __iadd__(self, other):
- r"""
- In-place addition operator.
-
- INPUT:
-
- - ``other`` -- a :class:`CoordFunction` or a value
-
- OUTPUT:
-
- - coordinate function resulting from the addition of ``self`` and
- ``other``
-
- TESTS::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: f = X.function(x+y)
- sage: g = X.function(x*y)
- sage: f.__iadd__(g)
- (x + 1)*y + x
- sage: f += g; f
- (x + 1)*y + x
- sage: f.__iadd__(X.zero_function()) == f
- True
-
- """
- return self.__add__(other)
-
- def __rsub__(self, other):
- r"""
- Reflected subtraction operator: performs ``other - self``.
-
- INPUT:
-
- - ``other`` -- a :class:`CoordFunction` or a value
-
- OUTPUT:
-
- - coordinate function resulting from the subtraction of ``self``
- from ``other``
-
- TESTS::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: f = X.function(x+y)
- sage: g = X.function(x*y)
- sage: f.__rsub__(g)
- (x - 1)*y - x
- sage: f.__rsub__(g) == -f + g
- True
- sage: 2 - f # indirect doctest
- -x - y + 2
-
- """
- return self.__neg__().__add__(other)
-
- def __isub__(self, other):
- r"""
- In-place subtraction operator.
-
- INPUT:
-
- - ``other`` -- a :class:`CoordFunction` or a value
-
- OUTPUT:
-
- - coordinate function resulting from the subtraction of ``other``
- from ``self``
-
- TESTS::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: f = X.function(x+y)
- sage: g = X.function(x*y)
- sage: f.__isub__(g)
- -(x - 1)*y + x
- sage: f -= g; f
- -(x - 1)*y + x
- sage: f.__isub__(X.zero_function()) == f
- True
-
- """
- return self.__sub__(other)
-
- def __rmul__(self, other):
- r"""
- Reflected multiplication operator: performs ``other * self``.
-
- INPUT:
-
- - ``other`` -- a :class:`CoordFunction` or a value
-
- OUTPUT:
-
- - coordinate function resulting from the multiplication of ``other``
- by ``self``
-
- TESTS::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: f = X.function(x+y)
- sage: g = X.function(x*y)
- sage: f.__rmul__(g)
- x^2*y + x*y^2
- sage: f.__rmul__(g) == g*f
- True
- sage: f.__rmul__(X.one_function()) == f
- True
- sage: 2*f # indirect doctest
- 2*x + 2*y
-
- """
- return self.__mul__(other) # since * is commutative
-
- def __imul__(self, other):
- r"""
- In-place multiplication operator.
-
- INPUT:
-
- - ``other`` -- a :class:`CoordFunction` or a value
-
- OUTPUT:
-
- - coordinate function resulting from the multiplication of ``self``
- by ``other``
-
- TESTS::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: f = X.function(x+y)
- sage: g = X.function(x*y)
- sage: f.__imul__(g)
- x^2*y + x*y^2
- sage: f *= g; f
- x^2*y + x*y^2
- sage: f.__imul__(X.one_function()) == f
- True
-
- """
- return self.__mul__(other)
-
- def __rdiv__(self, other):
- r"""
- Reflected division operator: performs ``other / self``.
-
- INPUT:
-
- - ``other`` -- a :class:`CoordFunction` or a value
-
- OUTPUT:
-
- - coordinate function resulting from the division of ``other``
- by ``self``
-
- TESTS::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: f = X.function(x+y)
- sage: g = X.function(x*y)
- sage: f.__rdiv__(g)
- x*y/(x + y)
- sage: f.__rdiv__(g) == g/f
- True
- sage: 2/f # indirect doctest
- 2/(x + y)
-
- """
- return self.__invert__().__mul__(other)
-
- def __idiv__(self, other):
- r"""
- In-place division operator.
-
- INPUT:
-
- - ``other`` -- a :class:`CoordFunction` or a value
-
- OUTPUT:
-
- - coordinate function resulting from the division of ``self`` by
- ``other``
-
- TESTS::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: f = X.function(x+y)
- sage: g = X.function(x*y)
- sage: f.__idiv__(g)
- (x + y)/(x*y)
- sage: f /= g; f
- (x + y)/(x*y)
- sage: f.__idiv__(X.one_function()) == f
- True
-
- """
- return self.__div__(other)
-
# --------------------------------------------
# Methods to be implemented by derived classes
# --------------------------------------------
@@ -422,11 +189,11 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
sage: f._repr_()
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction._repr_ not implemented
+ NotImplementedError: <abstract method _repr_ at 0x...>
"""
@abstract_method
@@ -442,11 +209,11 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
sage: f._latex_()
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction._latex_ not implemented
+ NotImplementedError: <abstract method _latex_ at 0x...>
"""
@abstract_method
@@ -462,11 +229,11 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
sage: f.display()
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction.display not implemented
+ NotImplementedError: <abstract method display at 0x...>
"""
disp = display
@@ -489,11 +256,11 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
sage: f.expr()
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction.expr not implemented
+ NotImplementedError: <abstract method expr at 0x...>
"""
@@ -522,11 +289,11 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
sage: f.__call__(2,-3)
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction.__call__ not implemented
+ NotImplementedError: <abstract method __call__ at 0x...>
"""
@@ -543,11 +310,11 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
sage: f.is_zero()
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction.is_zero not implemented
+ NotImplementedError: <abstract method is_zero at 0x...>
"""
@@ -568,18 +335,19 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
sage: f.copy()
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction.copy not implemented
+ NotImplementedError: <abstract method copy at 0x...>
"""
@abstract_method
def diff(self, coord):
r"""
- Partial derivative with respect to a coordinate.
+ Return the partial derivative of ``self`` with respect to a
+ coordinate.
INPUT:
@@ -602,93 +370,11 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
sage: f.diff(x)
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction.diff not implemented
-
- """
-
- @abstract_method
- def __eq__(self, other):
- r"""
- Comparison (equality) operator.
-
- INPUT:
-
- - ``other`` -- a :class:`CoordFunction` or a value
-
- OUTPUT:
-
- - ``True`` if ``self`` is equal to ``other``, or ``False`` otherwise
-
- TESTS:
-
- This method must be implemented by derived classes; it is not
- implemented here::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
- sage: g = CoordFunction(X)
- sage: f == g
- Traceback (most recent call last):
- ...
- NotImplementedError: CoordFunction.__eq__ not implemented
-
- """
-
- def __pos__(self):
- r"""
- Unary plus operator.
-
- OUTPUT:
-
- - ``self``
-
- TESTS:
-
- Coordinate functions associated to a 2-dimensional chart::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: f = X.function(x+y^2)
- sage: g = +f; g
- y^2 + x
- sage: type(g)
- <class 'sage.manifolds.coord_func_symb.CoordFunctionSymb'>
- sage: g == f
- True
- sage: g is f
- True
-
- """
- return self
-
- @abstract_method
- def __neg__(self):
- r"""
- Unary minus operator.
-
- OUTPUT:
-
- - the opposite of the coordinate function ``self``
-
- TESTS:
-
- This method must be implemented by derived classes; it is not
- implemented here::
-
- sage: M = Manifold(2, 'M', structure='topological')
- sage: X.<x,y> = M.chart()
- sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
- sage: f.__neg__()
- Traceback (most recent call last):
- ...
- NotImplementedError: CoordFunction.__neg__ not implemented
+ NotImplementedError: <abstract method diff at 0x...>
"""
@@ -704,7 +390,7 @@ class CoordFunction(SageObject):
OUTPUT:
- - the inverse of the coordinate function ``self``
+ - the inverse of ``self``
TESTS:
@@ -714,16 +400,16 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
+ sage: f = CoordFunction(X.function_ring())
sage: f.__invert__()
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction.__invert__ not implemented
+ NotImplementedError: <abstract method __invert__ at 0x...>
"""
@abstract_method
- def __add__(self, other):
+ def _add_(self, other):
r"""
Addition operator.
@@ -744,16 +430,16 @@ class CoordFunction(SageObject):
sage: M = Manifold(2, 'M', structure='topological')
sage: X.<x,y> = M.chart()
sage: from sage.manifolds.coord_func import CoordFunction
- sage: f = CoordFunction(X)
- sage: f.__add__(2)
+ sage: f = CoordFunction(X.function_ring())
+ sage: f._add_(2)
Traceback (most recent call last):
...
- NotImplementedError: CoordFunction.__add__ not implemented
+ NotImplementedError: <abstract method