summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Gourgoulhon <eric.gourgoulhon@obspm.fr>2015-06-17 10:46:21 +0200
committerEric Gourgoulhon <eric.gourgoulhon@obspm.fr>2015-06-17 10:46:21 +0200
commit77416edb0f78a2c96c36476656bd56eb81c95f43 (patch)
tree6bdd44da5b5bd62d9c97d1c3ab9f2e093ee19ef3
parentMore doctests in sage/manifolds/utilities.py (diff)
Reorganization of documentation of ExpressionNice.
Improve documentation of ScalarField.
-rw-r--r--src/sage/manifolds/scalarfield.py83
-rw-r--r--src/sage/manifolds/utilities.py289
2 files changed, 188 insertions, 184 deletions
diff --git a/src/sage/manifolds/scalarfield.py b/src/sage/manifolds/scalarfield.py
index b5f63ed..b14545b 100644
--- a/src/sage/manifolds/scalarfield.py
+++ b/src/sage/manifolds/scalarfield.py
@@ -374,7 +374,7 @@ class ScalarField(CommutativeAlgebraElement):
sage: (f-c)+c == f
True
- We may add a number (interpretted as a constant scalar field) to a scalar
+ We may add a number (interpreted as a constant scalar field) to a scalar
field::
sage: s = f + 1 ; s
@@ -385,11 +385,28 @@ class ScalarField(CommutativeAlgebraElement):
on V: (u, v) |--> (2*u^2 + 2*v^2 + 1)/(u^2 + v^2 + 1)
sage: (f+1)-1 == f
True
+
+ The number can represented by a symbolic variable::
+
sage: s = a + f ; s
Scalar field on the 2-dimensional topological manifold M
sage: s == c + f
True
+ However if the symbolic variable is a chart coordinate, the addition
+ is performed only on the chart domain::
+
+ sage: s = f + x; s
+ Scalar field on the 2-dimensional topological manifold M
+ sage: s.display()
+ M --> R
+ on U: (x, y) |--> (x^3 + x*y^2 + x + 1)/(x^2 + y^2 + 1)
+ sage: s = f + u; s
+ Scalar field on the 2-dimensional topological manifold M
+ sage: s.display()
+ M --> R
+ on V: (u, v) |--> (u^3 + (u + 1)*v^2 + u^2 + u)/(u^2 + v^2 + 1)
+
The addition of two scalar fields with different domains is possible if
the domain of one of them is a subset of the domain of the other; the
domain of the result is then this subset::
@@ -414,7 +431,8 @@ class ScalarField(CommutativeAlgebraElement):
In Sage framework, the addition of `f` and `g` is permitted because
there is a *coercion* of the parent of `f`, namely `C^0(M)`, to
- the parent of `g`, namely `C^0(U)`::
+ the parent of `g`, namely `C^0(U)` (see
+ :class:`~sage.manifolds.scalarfield_algebra.ScalarFieldAlgebra`)::
sage: CM = M.scalar_field_algebra()
sage: CU = U.scalar_field_algebra()
@@ -445,6 +463,20 @@ class ScalarField(CommutativeAlgebraElement):
on U: (x, y) |--> a/(x^2 + y^2 + 1)
on V: (u, v) |--> (a*u^2 + a*v^2)/(u^2 + v^2 + 1)
+ However, if the symbolic variable is a chart coordinate, the multiplication
+ is performed only in the corresponding chart::
+
+ sage: s = x*f; s
+ Scalar field on the 2-dimensional topological manifold M
+ sage: s.display()
+ M --> R
+ on U: (x, y) |--> x/(x^2 + y^2 + 1)
+ sage: s = u*f; s
+ Scalar field on the 2-dimensional topological manifold M
+ sage: s.display()
+ M --> R
+ on V: (u, v) |--> (u^3 + u*v^2)/(u^2 + v^2 + 1)
+
Some tests::
sage: 0*f == 0
@@ -1932,15 +1964,19 @@ class ScalarField(CommutativeAlgebraElement):
other._latex_name)
return result
- def _lmul_(self, number):
+ def _rmul_(self, number):
r"""
- Multiplication on the left of a scalar field by a number.
+ Reflected multiplication operator: performs ``number * self``
+
+ This implements the multiplication of a scalar field on the left
+ by a number.
INPUT:
- - ``number`` -- an element of the ring on which the algebra is defined;
- mathematically, this should be an element of the topological field
- on which the manifold is constructed
+ - ``number`` -- an element of the ring on which the scalar field
+ algebra is defined; this should be an element of the topological
+ field on which the manifold is constructed (possibly represented
+ by a symbolic expression)
OUPUT:
@@ -1951,21 +1987,21 @@ class ScalarField(CommutativeAlgebraElement):
sage: M = TopManifold(2, 'M')
sage: X.<x,y> = M.chart()
sage: f = M.scalar_field({X: x+y}, name='f')
- sage: s = f._lmul_(2); s
+ sage: s = f._rmul_(2); s
Scalar field on the 2-dimensional topological manifold M
sage: s.display()
M --> R
(x, y) |--> 2*x + 2*y
sage: s == 2*f
True
- sage: f._lmul_(pi).display()
+ sage: f._rmul_(pi).display()
M --> R
(x, y) |--> pi*x + pi*y
- sage: f._lmul_(pi) == pi*f
+ sage: f._rmul_(pi) == pi*f
True
- sage: f._lmul_(0) == M.zero_scalar_field()
+ sage: f._rmul_(0) == M.zero_scalar_field()
True
- sage: f._lmul_(1) == f
+ sage: f._rmul_(1) == f
True
"""
@@ -1996,26 +2032,33 @@ class ScalarField(CommutativeAlgebraElement):
result._express[chart] = number * expr
return result
- def _rmul_(self, number):
+ def _lmul_(self, number):
r"""
- Multiplication on the right of a scalar field by a number.
+ Multiplication on the right: performs ``self * number``
+
+ This differs from ``_mul_(self, other)`` by the fact that ``number``
+ is not assumed to be a scalar field defined on the same domain as
+ ``self``, contrary to ``other`` in ``_mul_(self, other)``. In
+ practice, ``number`` is a an element of the field on which the
+ scalar field algebra is defined
INPUT:
- - ``number`` -- an element of the ring on which the algebra is defined;
- mathematically, this should be an element of the topological field
- on which the manifold is constructed
+ - ``number`` -- an element of the ring on which the scalar field
+ algebra is defined; this should be an element of the topological
+ field on which the manifold is constructed (possibly represented
+ by a symbolic expression)
OUPUT:
- - the scalar field ``number*self``
+ - the scalar field ``self*number``
TESTS::
sage: M = TopManifold(2, 'M')
sage: X.<x,y> = M.chart()
sage: f = M.scalar_field({X: x+y}, name='f')
- sage: s = f._rmul_(2); s
+ sage: s = f._lmul_(2); s
Scalar field on the 2-dimensional topological manifold M
sage: s.display()
M --> R
@@ -2024,7 +2067,7 @@ class ScalarField(CommutativeAlgebraElement):
True
"""
- return self._lmul_(number) # since the algebra is commutative
+ return self._rmul_(number) # since the algebra is commutative
######### End of CommutativeAlgebraElement arithmetic operators ########
diff --git a/src/sage/manifolds/utilities.py b/src/sage/manifolds/utilities.py
index 19d88de..12fa42c 100644
--- a/src/sage/manifolds/utilities.py
+++ b/src/sage/manifolds/utilities.py
@@ -6,13 +6,15 @@ and display of symbolic expressions.
AUTHORS:
-- Eric Gourgoulhon, Michal Bejger (2013-2015) : initial version
+- Michal Bejger (2015) : class :class:`ExpressionNice`
+- Eric Gourgoulhon (2015) : simplification functions
"""
#******************************************************************************
-# Copyright (C) 2015 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
+#
# Copyright (C) 2015 Michal Bejger <bejger@camk.edu.pl>
+# Copyright (C) 2015 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
#
# Distributed under the terms of the GNU General Public License (GPL)
# as published by the Free Software Foundation; either version 2 of
@@ -409,16 +411,97 @@ def simplify_chain_generic(expr):
class ExpressionNice(Expression):
r"""
- Modification of the Expression class for a ''human-friendly''
- display of derivatives.
+ Subclass of :class:`~sage.symbolic.expression.Expression` for a
+ ''human-friendly'' display of partial derivatives and the possibility to
+ shorten the display by skipping the arguments of symbolic functions.
INPUT:
- ``ex`` -- symbolic expression
- OUTPUT:
+ EXAMPLES:
+
+ An expression formed with callable symbolic expressions::
+
+ sage: var('x y z')
+ (x, y, z)
+ sage: f = function('f', x, y)
+ sage: g = f.diff(y).diff(x)
+ sage: h = function('h', y, z)
+ sage: k = h.diff(z)
+ sage: fun = x*g + y*(k-z)^2
- - modified string or LaTeX representation of the expression.
+ The standard Pynac display of partial derivatives::
+
+ sage: fun
+ y*(z - D[1](h)(y, z))^2 + x*D[0, 1](f)(x, y)
+ sage: latex(fun)
+ y {\left(z - D[1]\left(h\right)\left(y, z\right)\right)}^{2}
+ + x D[0, 1]\left(f\right)\left(x, y\right)
+
+ With :class:`ExpressionNice`, the Pynac notation ``D[...]`` is replaced
+ by textbook-like notation::
+
+ sage: from sage.manifolds.utilities import ExpressionNice
+ sage: ExpressionNice(fun)
+ y*(z - d(h)/dz)^2 + x*d^2(f)/dxdy
+ sage: latex(ExpressionNice(fun))
+ y {\left(z - \frac{\partial\,h}{\partial z}\right)}^{2}
+ + x \frac{\partial^2\,f}{\partial x\partial y}
+
+ An example when function variables are themselve functions::
+
+ sage: f = function('f', x, y)
+ sage: g = function('g', x, f) # the second variable is the function f
+ sage: fun = (g.diff(x))*x - x^2*f.diff(x,y)
+ sage: fun
+ -x^2*D[0, 1](f)(x, y) + (D[0](f)(x, y)*D[1](g)(x, f(x, y)) + D[0](g)(x, f(x, y)))*x
+ sage: ExpressionNice(fun)
+ -x^2*d^2(f)/dxdy + (d(f)/dx*d(g)/df + d(g)/dx)*x
+ sage: latex(ExpressionNice(fun))
+ -x^{2} \frac{\partial^2\,f}{\partial x\partial y}
+ + {\left(\frac{\partial\,f}{\partial x} \frac{\partial\,g}{\partial f}
+ + \frac{\partial\,g}{\partial x}\right)} x
+
+ Note that ``D[1](f)(x, g(x,y))`` is rendered as ``d(f)/dg``.
+
+ An example with multiple differentiations::
+
+ sage: fun = f.diff(x,x,y,y,x)*x
+ sage: fun
+ x*D[0, 0, 0, 1, 1](f)(x, y)
+ sage: ExpressionNice(fun)
+ x*d^5(f)/dx^3dy^2
+ sage: latex(ExpressionNice(fun))
+ x \frac{\partial^5\,f}{\partial x^3\partial y^2}
+
+ Parentheses are added around powers of partial derivatives to avoid any
+ confusion::
+
+ sage: fun = f.diff(y)^2
+ sage: fun
+ D[1](f)(x, y)^2
+ sage: ExpressionNice(fun)
+ (d(f)/dy)^2
+ sage: latex(ExpressionNice(fun))
+ \left(\frac{\partial\,f}{\partial y}\right)^{2}
+
+ The explicit mention of function arguments can be omitted for the sake of
+ brievety::
+
+ sage: fun = fun*f
+ sage: ExpressionNice(fun)
+ f(x, y)*(d(f)/dy)^2
+ sage: omit_function_args(True)
+ sage: ExpressionNice(fun)
+ f*(d(f)/dy)^2
+ sage: latex(ExpressionNice(fun))
+ f \left(\frac{\partial\,f}{\partial y}\right)^{2}
+ sage: omit_function_args(False) # revert to standard display
+ sage: ExpressionNice(fun)
+ f(x, y)*(d(f)/dy)^2
+ sage: latex(ExpressionNice(fun))
+ f\left(x, y\right) \left(\frac{\partial\,f}{\partial y}\right)^{2}
"""
@@ -446,7 +529,7 @@ class ExpressionNice(Expression):
r"""
String representation of the object.
- EXAMPLES::
+ EXAMPLE::
sage: var('x y z')
(x, y, z)
@@ -461,56 +544,6 @@ class ExpressionNice(Expression):
sage: ExpressionNice(fun)
y*(z - d(h)/dz)^2 + x*d^2(f)/dxdy
- A check for a case when function variables are functions too:
- D[1](f)(x, g(x,y)) should render as d(f)/dg
-
- sage: var('x y')
- (x, y)
- sage: f = function('f', x, y)
- sage: g = function('g', x, f)
- sage: fun = (g.diff(x))*x - x^2*f.diff(x,y)
- sage: fun
- -x^2*D[0, 1](f)(x, y) + (D[0](f)(x, y)*D[1](g)(x, f(x, y)) + D[0](g)(x, f(x, y)))*x
- sage: from sage.manifolds.utilities import ExpressionNice
- sage: ExpressionNice(fun)
- -x^2*d^2(f)/dxdy + (d(f)/dx*d(g)/df + d(g)/dx)*x
-
- Multiple differentiation over the same variable is grouped for brevity:
- D[0, 0](f)(x) should render as d^2(f)/dx^2
-
- sage: var('x y')
- (x, y)
- sage: f = function('f', x, y)
- sage: fun = f.diff(x,x,y,y,x)*x
- sage: fun
- x*D[0, 0, 0, 1, 1](f)(x, y)
- sage: from sage.manifolds.utilities import ExpressionNice
- sage: ExpressionNice(fun)
- x*d^5(f)/dx^3dy^2
-
- If diff operator is raised to some power, put brackets around:
- D[1](f)(x, y)^2 should render as (d(f)/dy)^2
-
- sage: var('x y')
- (x, y)
- sage: f = function('f', x, y)
- sage: fun = f.diff(y)^2
- sage: fun
- D[1](f)(x, y)^2
- sage: from sage.manifolds.utilities import ExpressionNice
- sage: ExpressionNice(fun)
- (d(f)/dy)^2
-
- omit_function_args tests:
-
- sage: fun = fun*f
- sage: fun
- f(x, y)*D[1](f)(x, y)^2
- sage: from sage.manifolds.utilities import ExpressionNice
- sage: omit_function_args(True)
- sage: ExpressionNice(fun)
- f*(d(f)/dy)^2
-
"""
d = self._parent._repr_element_(self)
@@ -522,7 +555,7 @@ class ExpressionNice(Expression):
# find all occurences of diff
list_d = []
- list_derivarives(self, list_d)
+ _list_derivatives(self, list_d)
# process the list
for m in list_d:
@@ -560,7 +593,7 @@ class ExpressionNice(Expression):
if CoordFunctionSymb._omit_fargs:
list_f = []
- list_functions(self, list_f)
+ _list_functions(self, list_f)
for m in list_f:
d = d.replace(m[1] + m[2], m[1])
@@ -572,7 +605,7 @@ class ExpressionNice(Expression):
r"""
LaTeX representation of the object.
- EXAMPLES::
+ EXAMPLE::
sage: var('x y z')
(x, y, z)
@@ -589,92 +622,17 @@ class ExpressionNice(Expression):
sage: latex(ExpressionNice(fun))
y {\left(z - \frac{\partial\,h}{\partial z}\right)}^{2} + x \frac{\partial^2\,f}{\partial x\partial y}
- A check for a case when function variables are functions too:
- D[1](f)(x, g(x,y)) should render as \frac{\partial\,f}{\partial g}
-
- sage: var('x y')
- (x, y)
- sage: f = function('f', x, y)
- sage: g = function('g', x, f)
- sage: fun = (g.diff(x))*x - x^2*f.diff(x,y)
- sage: fun
- -x^2*D[0, 1](f)(x, y) + (D[0](f)(x, y)*D[1](g)(x, f(x, y)) + D[0](g)(x, f(x, y)))*x
- sage: from sage.manifolds.utilities import ExpressionNice
- sage: ExpressionNice(fun)
- -x^2*d^2(f)/dxdy + (d(f)/dx*d(g)/df + d(g)/dx)*x
- sage: latex(ExpressionNice(fun))
- -x^{2} \frac{\partial^2\,f}{\partial x\partial y} + {\left(\frac{\partial\,f}{\partial x} \frac{\partial\,g}{\partial f} + \frac{\partial\,g}{\partial x}\right)} x
-
-
- Multiple differentiation over the same variable is grouped for brevity:
- D[0, 0](f)(x) should render as \frac{\partial^2\,f}{\partial x^2}
-
- sage: var('x y')
- (x, y)
- sage: f = function('f', x, y)
- sage: fun = f.diff(x,x,y,y,x)*x
- sage: fun
- x*D[0, 0, 0, 1, 1](f)(x, y)
- sage: from sage.manifolds.utilities import ExpressionNice
- sage: ExpressionNice(fun)
- x*d^5(f)/dx^3dy^2
- sage: latex(ExpressionNice(fun))
- x \frac{\partial^5\,f}{\partial x^3\partial y^2}
- sage: f = function('f', x, y, latex_name=r"{\cal F}")
- sage: fun = f.diff(x,x,y,y,x)*x
- sage: latex(ExpressionNice(fun))
- x \frac{\partial^5\,{\cal F}}{\partial x^3\partial y^2}
-
- If diff operator is raised to some power, put brackets around:
- D[1](f)(x, y)^2 should render as (d(f)/dy)^2
+ Testing the behavior if no latex_name of the function is given::
- sage: var('x y')
- (x, y)
- sage: f = function('f', x, y)
- sage: fun = f.diff(y)^2
- sage: fun
- D[1](f)(x, y)^2
- sage: from sage.manifolds.utilities import ExpressionNice
- sage: ExpressionNice(fun)
- (d(f)/dy)^2
- sage: latex(ExpressionNice(fun))
- \left(\frac{\partial\,f}{\partial y}\right)^{2}
-
- omit_function_args() test:
-
- sage: var('x y')
- (x, y)
- sage: f = function('f', x, y, latex_name=r"{\cal F}")
- sage: fun = f*f.diff(y)^2
- sage: fun
- f(x, y)*D[1](f)(x, y)^2
- sage: from sage.manifolds.utilities import ExpressionNice
- sage: omit_function_args(True)
- sage: latex(ExpressionNice(fun))
- {\cal F} \left(\frac{\partial\,{\cal F}}{\partial y}\right)^{2}
- sage: omit_function_args(False) # bring back the default behavior
-
- Testing the behavior if no latex_name of the function is given:
-
- sage: var('x y')
- (x, y)
sage: f = function('f_x', x, y)
sage: fun = f.diff(y)
- sage: fun
- D[1](f_x)(x, y)
- sage: from sage.manifolds.utilities import ExpressionNice
sage: latex(ExpressionNice(fun))
\frac{\partial\,f_{x}}{\partial y}
If latex_name, it should be used in LaTeX output:
- sage: var('x y')
- (x, y)
sage: f = function('f_x', x, y, latex_name=r"{\cal F}")
sage: fun = f.diff(y)
- sage: fun
- D[1](f_x)(x, y)
- sage: from sage.manifolds.utilities import ExpressionNice
sage: latex(ExpressionNice(fun))
\frac{\partial\,{\cal F}}{\partial y}
@@ -689,7 +647,7 @@ class ExpressionNice(Expression):
# find all occurences of diff
list_d = []
- list_derivarives(self, list_d)
+ _list_derivatives(self, list_d)
for m in list_d:
@@ -730,7 +688,7 @@ class ExpressionNice(Expression):
if CoordFunctionSymb._omit_fargs:
list_f = []
- list_functions(self, list_f)
+ _list_functions(self, list_f)
for m in list_f:
d = d.replace(str(m[3]) + str(m[4]), str(m[3]))
@@ -738,37 +696,38 @@ class ExpressionNice(Expression):
return d
-def list_derivarives(ex, list_d, exponent=0):
+def _list_derivatives(ex, list_d, exponent=0):
r"""
- Function to find the occurences of FDerivativeOperator in the expression;
- inspired by http://ask.sagemath.org/question/10256/how-can-extract-different-terms-from-a-symbolic-expression/?answer=26136#post-id-26136
+ Function to find the occurences of FDerivativeOperator in a symbolic
+ expression; inspired by http://ask.sagemath.org/question/10256/how-can-extract-different-terms-from-a-symbolic-expression/?answer=26136#post-id-26136
INPUT:
- ``ex`` -- symbolic expression to be analyzed
- - ``exponent`` -- (optional) exponent of FDerivativeOperator, passed to a next level in the expression tree
+ - ``exponent`` -- (optional) exponent of FDerivativeOperator, passed to a
+ next level in the expression tree
OUTPUT:
- - ``list_d`` -- tuple containing the details of FDerivativeOperator found, in a following order:
+ - ``list_d`` -- tuple containing the details of FDerivativeOperator found,
+ in the following order:
- 1. operator
- 2. function name
- 3. LaTeX function name
- 4. parameter set
- 5. operands
- 6. exponent (if found, else 0)
+ 1. operator
+ 2. function name
+ 3. LaTeX function name
+ 4. parameter set
+ 5. operands
+ 6. exponent (if found, else 0)
TESTS::
sage: f = function('f_x', x, latex_name=r"{\cal F}")
sage: df = f.diff(x)^2
- sage: from sage.manifolds.utilities import list_derivarives
+ sage: from sage.manifolds.utilities import _list_derivatives
sage: list_d = []
- sage: list_derivarives(df, list_d)
+ sage: _list_derivatives(df, list_d)
sage: list_d
[(D[0](f_x)(x), 'f_x', {\cal F}, [0], [x], 2)]
-
"""
op = ex.operator()
@@ -797,12 +756,13 @@ def list_derivarives(ex, list_d, exponent=0):
list_d.append((ex, function, latex_function, parameter_set, operands, exponent))
for operand in operands:
- list_derivarives(operand, list_d, exponent)
+ _list_derivatives(operand, list_d, exponent)
-def list_functions(ex, list_f):
+def _list_functions(ex, list_f):
r"""
- Function to find the occurences of symbolic functions in the expression.
+ Function to find the occurences of symbolic functions in a symbolic
+ expression.
INPUT:
@@ -810,13 +770,14 @@ def list_functions(ex, list_f):
OUTPUT:
- - ``list_f`` -- tuple containing the details of a symbolic function found, in a following order:
+ - ``list_f`` -- tuple containing the details of a symbolic function found,
+ in the following order:
- 1. operator
- 2. function name
- 3. arguments
- 4. LaTeX version of function name
- 5. LaTeX version of arguments
+ 1. operator
+ 2. function name
+ 3. arguments
+ 4. LaTeX version of function name
+ 5. LaTeX version of arguments
TESTS::
@@ -825,9 +786,9 @@ def list_functions(ex, list_f):
sage: f = function('f', x, y, latex_name=r"{\cal F}")
sage: g = function('g_x', x, y)
sage: d = sin(x)*g.diff(x)*x*f - x^2*f.diff(x,y)/g
- sage: from sage.manifolds.utilities import list_functions
+ sage: from sage.manifolds.utilities import _list_functions
sage: list_f = []
- sage: list_functions(d, list_f)
+ sage: _list_functions(d, list_f)
sage: list_f
[(f, 'f', '(x, y)', {\cal F}, \left(x, y\right)), (g_x, 'g_x', '(x, y)', 'g_{x}', \left(x, y\right))]
@@ -858,7 +819,7 @@ def list_functions(ex, list_f):
list_f.append((op, repr_function, repr_args, latex_function, latex_args))
for operand in operands:
- list_functions(operand, list_f)
+ _list_functions(operand, list_f)
def nice_derivatives(status):