Coordinate calculus methods¶
The class CalculusMethod governs the calculus methods (symbolic and
numerical) used for coordinate computations on manifolds.
AUTHORS:
Marco Mancini (2017): initial version
Eric Gourgoulhon (2019): add
set_simplify_function()and various accessors
- class sage.manifolds.calculus_method.CalculusMethod(current=None, base_field_type='real')[source]¶
Bases:
SageObjectControl of calculus backends used on coordinate charts of manifolds.
This class stores the possible calculus methods and permits to switch between them, as well as to change the simplifying functions associated with them. For the moment, only two calculus backends are implemented:
Sage’s symbolic engine (Pynac + Maxima), implemented via the Symbolic Ring
SRSymPy engine, denoted
sympyhereafter
INPUT:
current– (default:None) string defining the calculus method that will be considered as the active one, until it is changed byset(); must be one of'SR': Sage’s default symbolic engine (Symbolic Ring)'sympy': SymPyNone: the default calculus method ('SR')
base_field_type– (default:'real') base field type of the manifold (cf.base_field_type())
EXAMPLES:
sage: from sage.manifolds.calculus_method import CalculusMethod sage: cm = CalculusMethod()
>>> from sage.all import * >>> from sage.manifolds.calculus_method import CalculusMethod >>> cm = CalculusMethod()
In the display, the currently active method is pointed out with a star:
sage: cm Available calculus methods (* = current): - SR (default) (*) - sympy
>>> from sage.all import * >>> cm Available calculus methods (* = current): - SR (default) (*) - sympy
It can be changed with
set():sage: cm.set('sympy') sage: cm Available calculus methods (* = current): - SR (default) - sympy (*)
>>> from sage.all import * >>> cm.set('sympy') >>> cm Available calculus methods (* = current): - SR (default) - sympy (*)
while
reset()brings back to the default:sage: cm.reset() sage: cm Available calculus methods (* = current): - SR (default) (*) - sympy
>>> from sage.all import * >>> cm.reset() >>> cm Available calculus methods (* = current): - SR (default) (*) - sympy
See
simplify_function()for the default simplification algorithms associated with each calculus method andset_simplify_function()for introducing a new simplification algorithm.- current()[source]¶
Return the active calculus method as a string.
OUTPUT:
String defining the calculus method; one of
'SR'– Sage’s default symbolic engine (Symbolic Ring)'sympy'– SymPy
EXAMPLES:
sage: from sage.manifolds.calculus_method import CalculusMethod sage: cm = CalculusMethod(); cm Available calculus methods (* = current): - SR (default) (*) - sympy sage: cm.current() 'SR' sage: cm.set('sympy') sage: cm.current() 'sympy'
>>> from sage.all import * >>> from sage.manifolds.calculus_method import CalculusMethod >>> cm = CalculusMethod(); cm Available calculus methods (* = current): - SR (default) (*) - sympy >>> cm.current() 'SR' >>> cm.set('sympy') >>> cm.current() 'sympy'
- is_trivial_zero(expression, method=None)[source]¶
Check if an expression is trivially equal to zero without any simplification.
INPUT:
expression– expressionmethod– (default:None) string defining the calculus method to use; ifNonethe current calculus method ofselfis used
OUTPUT:
Trueis expression is trivially zero,FalseelsewhereEXAMPLES:
sage: from sage.manifolds.calculus_method import CalculusMethod sage: cm = CalculusMethod(base_field_type='real') sage: f = sin(x) - sin(x) sage: cm.is_trivial_zero(f) True sage: cm.is_trivial_zero(f._sympy_(), method='sympy') True
>>> from sage.all import * >>> from sage.manifolds.calculus_method import CalculusMethod >>> cm = CalculusMethod(base_field_type='real') >>> f = sin(x) - sin(x) >>> cm.is_trivial_zero(f) True >>> cm.is_trivial_zero(f._sympy_(), method='sympy') True
sage: f = sin(x)^2 + cos(x)^2 - 1 sage: cm.is_trivial_zero(f) False sage: cm.is_trivial_zero(f._sympy_(), method='sympy') False
>>> from sage.all import * >>> f = sin(x)**Integer(2) + cos(x)**Integer(2) - Integer(1) >>> cm.is_trivial_zero(f) False >>> cm.is_trivial_zero(f._sympy_(), method='sympy') False
- reset()[source]¶
Set the current calculus method to the default one.
EXAMPLES:
sage: from sage.manifolds.calculus_method import CalculusMethod sage: cm = CalculusMethod(base_field_type='complex') sage: cm Available calculus methods (* = current): - SR (default) (*) - sympy sage: cm.set('sympy') sage: cm Available calculus methods (* = current): - SR (default) - sympy (*) sage: cm.reset() sage: cm Available calculus methods (* = current): - SR (default) (*) - sympy
>>> from sage.all import * >>> from sage.manifolds.calculus_method import CalculusMethod >>> cm = CalculusMethod(base_field_type='complex') >>> cm Available calculus methods (* = current): - SR (default) (*) - sympy >>> cm.set('sympy') >>> cm Available calculus methods (* = current): - SR (default) - sympy (*) >>> cm.reset() >>> cm Available calculus methods (* = current): - SR (default) (*) - sympy
- set(method)[source]¶
Set the currently active calculus method.
method– string defining the calculus method
EXAMPLES:
sage: from sage.manifolds.calculus_method import CalculusMethod sage: cm = CalculusMethod(base_field_type='complex') sage: cm Available calculus methods (* = current): - SR (default) (*) - sympy sage: cm.set('sympy') sage: cm Available calculus methods (* = current): - SR (default) - sympy (*) sage: cm.set('lala') Traceback (most recent call last): ... NotImplementedError: method lala not implemented
>>> from sage.all import * >>> from sage.manifolds.calculus_method import CalculusMethod >>> cm = CalculusMethod(base_field_type='complex') >>> cm Available calculus methods (* = current): - SR (default) (*) - sympy >>> cm.set('sympy') >>> cm Available calculus methods (* = current): - SR (default) - sympy (*) >>> cm.set('lala') Traceback (most recent call last): ... NotImplementedError: method lala not implemented
- set_simplify_function(simplifying_func, method=None)[source]¶
Set the simplifying function associated to a given calculus method.
INPUT:
simplifying_func– either the string'default'for restoring the default simplifying function or a functionfof a single argumentexprsuch thatf(expr)returns an object of the same type asexpr(hopefully the simplified version ofexpr), this type beingExpressionifmethod='SR'a SymPy type if
method='sympy'
method– (default:None) string defining the calculus method for whichsimplifying_funcis provided; must be one of'SR': Sage’s default symbolic engine (Symbolic Ring)'sympy': SymPyNone: the currently active calculus method ofselfis assumed
EXAMPLES:
On a real manifold, the default simplifying function is
simplify_chain_real()when the calculus method isSR:sage: from sage.manifolds.calculus_method import CalculusMethod sage: cm = CalculusMethod(base_field_type='real'); cm Available calculus methods (* = current): - SR (default) (*) - sympy sage: cm.simplify_function() is \ ....: sage.manifolds.utilities.simplify_chain_real True
>>> from sage.all import * >>> from sage.manifolds.calculus_method import CalculusMethod >>> cm = CalculusMethod(base_field_type='real'); cm Available calculus methods (* = current): - SR (default) (*) - sympy >>> cm.simplify_function() is sage.manifolds.utilities.simplify_chain_real True
Let us change it to
simplify():sage: cm.set_simplify_function(simplify) sage: cm.simplify_function() is simplify True
>>> from sage.all import * >>> cm.set_simplify_function(simplify) >>> cm.simplify_function() is simplify True
Since
SRis the current calculus method, the above is equivalent to:sage: cm.set_simplify_function(simplify, method='SR') sage: cm.simplify_function(method='SR') is simplify True
>>> from sage.all import * >>> cm.set_simplify_function(simplify, method='SR') >>> cm.simplify_function(method='SR') is simplify True
We revert to the default simplifying function by:
sage: cm.set_simplify_function('default')
>>> from sage.all import * >>> cm.set_simplify_function('default')
Then we are back to:
sage: cm.simplify_function() is \ ....: sage.manifolds.utilities.simplify_chain_real True
>>> from sage.all import * >>> cm.simplify_function() is sage.manifolds.utilities.simplify_chain_real True
- simplify(expression, method=None)[source]¶
Apply the simplifying function associated with a given calculus method to a symbolic expression.
INPUT:
expression– symbolic expression to simplifymethod– (default:None) string defining the calculus method to use; must be one of'SR': Sage’s default symbolic engine (Symbolic Ring)'sympy': SymPyNone: the current calculus method ofselfis used
OUTPUT: the simplified version of
expressionEXAMPLES:
sage: M = Manifold(2, 'M', structure='topological') sage: X.<x, y> = M.chart() sage: f = x^2 + sin(x)^2 + cos(x)^2 sage: from sage.manifolds.calculus_method import CalculusMethod sage: cm = CalculusMethod(base_field_type='real') sage: cm.simplify(f) x^2 + 1
>>> from sage.all import * >>> M = Manifold(Integer(2), 'M', structure='topological') >>> X = M.chart(names=('x', 'y',)); (x, y,) = X._first_ngens(2) >>> f = x**Integer(2) + sin(x)**Integer(2) + cos(x)**Integer(2) >>> from sage.manifolds.calculus_method import CalculusMethod >>> cm = CalculusMethod(base_field_type='real') >>> cm.simplify(f) x^2 + 1
Using a weaker simplifying function, like
simplify(), does not succeed in this case:sage: cm.set_simplify_function(simplify) sage: cm.simplify(f) x^2 + cos(x)^2 + sin(x)^2
>>> from sage.all import * >>> cm.set_simplify_function(simplify) >>> cm.simplify(f) x^2 + cos(x)^2 + sin(x)^2
Back to the default simplifying function (
simplify_chain_real()in the present case):sage: cm.set_simplify_function('default') sage: cm.simplify(f) x^2 + 1
>>> from sage.all import * >>> cm.set_simplify_function('default') >>> cm.simplify(f) x^2 + 1
A
SRexpression, such asf, cannot be simplified when the current calculus method issympy:sage: cm.set('sympy') sage: cm.simplify(f) Traceback (most recent call last): ... AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'combsimp'...
>>> from sage.all import * >>> cm.set('sympy') >>> cm.simplify(f) Traceback (most recent call last): ... AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'combsimp'...
In the present case, one should either transform
fto a SymPy object:sage: cm.simplify(f._sympy_()) x**2 + 1
>>> from sage.all import * >>> cm.simplify(f._sympy_()) x**2 + 1
or force the calculus method to be
'SR':sage: cm.simplify(f, method='SR') x^2 + 1
>>> from sage.all import * >>> cm.simplify(f, method='SR') x^2 + 1
- simplify_function(method=None)[source]¶
Return the simplifying function associated to a given calculus method.
The simplifying function is that used in all computations involved with the calculus method.
INPUT:
method– (default:None) string defining the calculus method for whichsimplifying_funcis provided; must be one of'SR': Sage’s default symbolic engine (Symbolic Ring)'sympy': SymPyNone: the currently active calculus method ofselfis assumed
OUTPUT: the simplifying function
EXAMPLES:
sage: from sage.manifolds.calculus_method import CalculusMethod sage: cm = CalculusMethod() sage: cm Available calculus methods (* = current): - SR (default) (*) - sympy sage: cm.simplify_function() # random (memory address) <function simplify_chain_real at 0x7f958d5b6758>
>>> from sage.all import * >>> from sage.manifolds.calculus_method import CalculusMethod >>> cm = CalculusMethod() >>> cm Available calculus methods (* = current): - SR (default) (*) - sympy >>> cm.simplify_function() # random (memory address) <function simplify_chain_real at 0x7f958d5b6758>
The output stands for the function
simplify_chain_real():sage: cm.simplify_function() is \ ....: sage.manifolds.utilities.simplify_chain_real True
>>> from sage.all import * >>> cm.simplify_function() is sage.manifolds.utilities.simplify_chain_real True
Since
SRis the default calculus method, we have:sage: cm.simplify_function() is cm.simplify_function(method='SR') True
>>> from sage.all import * >>> cm.simplify_function() is cm.simplify_function(method='SR') True
The simplifying function associated with
sympyissimplify_chain_real_sympy():sage: cm.simplify_function(method='sympy') # random (memory address) <function simplify_chain_real_sympy at 0x7f0b35a578c0> sage: cm.simplify_function(method='sympy') is \ ....: sage.manifolds.utilities.simplify_chain_real_sympy True
>>> from sage.all import * >>> cm.simplify_function(method='sympy') # random (memory address) <function simplify_chain_real_sympy at 0x7f0b35a578c0> >>> cm.simplify_function(method='sympy') is sage.manifolds.utilities.simplify_chain_real_sympy True
On complex manifolds, the simplifying functions are
simplify_chain_generic()andsimplify_chain_generic_sympy()for respectivelySRandsympy:sage: cmc = CalculusMethod(base_field_type='complex') sage: cmc.simplify_function(method='SR') is \ ....: sage.manifolds.utilities.simplify_chain_generic True sage: cmc.simplify_function(method='sympy') is \ ....: sage.manifolds.utilities.simplify_chain_generic_sympy True
>>> from sage.all import * >>> cmc = CalculusMethod(base_field_type='complex') >>> cmc.simplify_function(method='SR') is sage.manifolds.utilities.simplify_chain_generic True >>> cmc.simplify_function(method='sympy') is sage.manifolds.utilities.simplify_chain_generic_sympy True
Note that the simplifying functions can be customized via
set_simplify_function().