Conversion of symbolic expressions to other types

This module provides routines for converting new symbolic expressions to other types. Primarily, it provides a class Converter which will walk the expression tree and make calls to methods overridden by subclasses.

class sage.symbolic.expression_conversions.Converter(use_fake_div=False)[source]

Bases: object

If use_fake_div is set to True, then the converter will try to replace expressions whose operator is operator.mul with the corresponding expression whose operator is operator.truediv.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import Converter
sage: c = Converter(use_fake_div=True)
sage: c.use_fake_div
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import Converter
>>> c = Converter(use_fake_div=True)
>>> c.use_fake_div
True
arithmetic(ex, operator)[source]

The input to this method is a symbolic expression and the infix operator corresponding to that expression. Typically, one will convert all of the arguments and then perform the operation afterward.

composition(ex, operator)[source]

The input to this method is a symbolic expression and its operator. This method will get called when you have a symbolic function application.

derivative(ex, operator)[source]

The input to this method is a symbolic expression which corresponds to a relation.

get_fake_div(ex)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import Converter
sage: c = Converter(use_fake_div=True)
sage: c.get_fake_div(sin(x)/x)
FakeExpression([sin(x), x], <built-in function truediv>)
sage: c.get_fake_div(-1*sin(x))
FakeExpression([sin(x)], <built-in function neg>)
sage: c.get_fake_div(-x)
FakeExpression([x], <built-in function neg>)
sage: c.get_fake_div((2*x^3+2*x-1)/((x-2)*(x+1)))
FakeExpression([2*x^3 + 2*x - 1, FakeExpression([x + 1, x - 2], <built-in function mul>)], <built-in function truediv>)
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import Converter
>>> c = Converter(use_fake_div=True)
>>> c.get_fake_div(sin(x)/x)
FakeExpression([sin(x), x], <built-in function truediv>)
>>> c.get_fake_div(-Integer(1)*sin(x))
FakeExpression([sin(x)], <built-in function neg>)
>>> c.get_fake_div(-x)
FakeExpression([x], <built-in function neg>)
>>> c.get_fake_div((Integer(2)*x**Integer(3)+Integer(2)*x-Integer(1))/((x-Integer(2))*(x+Integer(1))))
FakeExpression([2*x^3 + 2*x - 1, FakeExpression([x + 1, x - 2], <built-in function mul>)], <built-in function truediv>)

Check if Issue #8056 is fixed, i.e., if numerator is 1.:

sage: c.get_fake_div(1/pi/x)
FakeExpression([1, FakeExpression([pi, x], <built-in function mul>)], <built-in function truediv>)
>>> from sage.all import *
>>> c.get_fake_div(Integer(1)/pi/x)
FakeExpression([1, FakeExpression([pi, x], <built-in function mul>)], <built-in function truediv>)
pyobject(ex, obj)[source]

The input to this method is the result of calling pyobject() on a symbolic expression.

Note

Note that if a constant such as pi is encountered in the expression tree, its corresponding pyobject which is an instance of sage.symbolic.constants.Pi will be passed into this method. One cannot do arithmetic using such an object.

relation(ex, operator)[source]

The input to this method is a symbolic expression which corresponds to a relation.

symbol(ex)[source]

The input to this method is a symbolic expression which corresponds to a single variable. For example, this method could be used to return a generator for a polynomial ring.

class sage.symbolic.expression_conversions.DeMoivre(ex, force=False)[source]

Bases: ExpressionTreeWalker

A class that walks a symbolic expression tree and replaces occurences of complex exponentials (optionally, all exponentials) by their respective trigonometric expressions.

INPUT:

  • force – boolean (default: False); replace \(\exp(x)\) with \(\cosh(x) + \sinh(x)\)

EXAMPLES:

sage: a, b = SR.var("a, b")
sage: from sage.symbolic.expression_conversions import DeMoivre
sage: d = DeMoivre(e^a)
sage: d(e^(a+I*b))
(cos(b) + I*sin(b))*e^a
>>> from sage.all import *
>>> a, b = SR.var("a, b")
>>> from sage.symbolic.expression_conversions import DeMoivre
>>> d = DeMoivre(e**a)
>>> d(e**(a+I*b))
(cos(b) + I*sin(b))*e^a
composition(ex, op)[source]

Return the composition of self with ex by op.

EXAMPLES:

sage: x, a, b = SR.var('x, a, b')
sage: from sage.symbolic.expression_conversions import DeMoivre
sage: p = exp(x)
sage: s = DeMoivre(p)
sage: q = exp(a+I*b)
sage: s.composition(q, q.operator())
(cos(b) + I*sin(b))*e^a
>>> from sage.all import *
>>> x, a, b = SR.var('x, a, b')
>>> from sage.symbolic.expression_conversions import DeMoivre
>>> p = exp(x)
>>> s = DeMoivre(p)
>>> q = exp(a+I*b)
>>> s.composition(q, q.operator())
(cos(b) + I*sin(b))*e^a
class sage.symbolic.expression_conversions.Exponentialize(ex)[source]

Bases: ExpressionTreeWalker

A class that walks a symbolic expression tree and replace circular and hyperbolic functions by their respective exponential expressions.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import Exponentialize
sage: d = Exponentialize(sin(x))
sage: d(sin(x))
-1/2*I*e^(I*x) + 1/2*I*e^(-I*x)
sage: d(cosh(x))
1/2*e^(-x) + 1/2*e^x
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import Exponentialize
>>> d = Exponentialize(sin(x))
>>> d(sin(x))
-1/2*I*e^(I*x) + 1/2*I*e^(-I*x)
>>> d(cosh(x))
1/2*e^(-x) + 1/2*e^x
CircDict = {sinh: x |--> -1/2*e^(-x) + 1/2*e^x, cosh: x |--> 1/2*e^(-x) + 1/2*e^x, tanh: x |--> -(e^(-x) - e^x)/(e^(-x) + e^x), coth: x |--> -(e^(-x) + e^x)/(e^(-x) - e^x), sech: x |--> 2/(e^(-x) + e^x), csch: x |--> -2/(e^(-x) - e^x), sin: x |--> -1/2*I*e^(I*x) + 1/2*I*e^(-I*x), cos: x |--> 1/2*e^(I*x) + 1/2*e^(-I*x), tan: x |--> (-I*e^(I*x) + I*e^(-I*x))/(e^(I*x) + e^(-I*x)), cot: x |--> (I*e^(I*x) + I*e^(-I*x))/(e^(I*x) - e^(-I*x)), sec: x |--> 2/(e^(I*x) + e^(-I*x)), csc: x |--> 2*I/(e^(I*x) - e^(-I*x))}
Circs = [sin, cos, sec, csc, tan, cot, sinh, cosh, sech, csch, tanh, coth]
I = I[source]
Integer[source]

alias of Integer

SR = Symbolic Ring[source]
composition(ex, op)[source]

Return the composition of self with ex by op.

EXAMPLES:

sage: x = SR.var("x")
sage: from sage.symbolic.expression_conversions import Exponentialize
sage: p = x
sage: s = Exponentialize(p)
sage: q = sin(x)
sage: s.composition(q, q.operator())
-1/2*I*e^(I*x) + 1/2*I*e^(-I*x)
>>> from sage.all import *
>>> x = SR.var("x")
>>> from sage.symbolic.expression_conversions import Exponentialize
>>> p = x
>>> s = Exponentialize(p)
>>> q = sin(x)
>>> s.composition(q, q.operator())
-1/2*I*e^(I*x) + 1/2*I*e^(-I*x)
cos = cos[source]
cosh = cosh[source]
cot = cot[source]
coth = coth[source]
csc = csc[source]
csch = csch[source]
e = e[source]
exp = exp[source]
function(s, **kwds)[source]

Create a formal symbolic function with the name s.

INPUT:

  • nargs=0 – number of arguments the function accepts, defaults to variable number of arguments, or 0

  • latex_name – name used when printing in latex mode

  • conversions – dictionary specifying names of this function in other systems, this is used by the interfaces internally during conversion

  • eval_func – method used for automatic evaluation

  • evalf_func – method used for numeric evaluation

  • evalf_params_first – boolean to indicate if parameters should be evaluated numerically before calling the custom evalf function

  • conjugate_func – method used for complex conjugation

  • real_part_func – method used when taking real parts

  • imag_part_func – method used when taking imaginary parts

  • derivative_func – method to be used for (partial) derivation This method should take a keyword argument deriv_param specifying the index of the argument to differentiate w.r.t

  • tderivative_func – method to be used for derivatives

  • power_func – method used when taking powers This method should take a keyword argument power_param specifying the exponent

  • series_func – method used for series expansion This method should expect keyword arguments - order – order for the expansion to be computed - var – variable to expand w.r.t. - at – expand at this value

  • print_func – method for custom printing

  • print_latex_func – method for custom printing in latex mode

Note that custom methods must be instance methods, i.e., expect the instance of the symbolic function as the first argument.

Note

The new function is both returned and automatically injected into the global namespace. If you use this function in library code, it is better to use sage.symbolic.function_factory.function, since it will not touch the global namespace.

EXAMPLES:

We create a formal function called supersin

sage: function('supersin')
supersin
>>> from sage.all import *
>>> function('supersin')
supersin

We can immediately use supersin in symbolic expressions:

sage: y, z, A = var('y z A')
sage: supersin(y+z) + A^3
A^3 + supersin(y + z)
>>> from sage.all import *
>>> y, z, A = var('y z A')
>>> supersin(y+z) + A**Integer(3)
A^3 + supersin(y + z)

We can define other functions in terms of supersin:

sage: g(x,y) = supersin(x)^2 + sin(y/2)
sage: g
(x, y) |--> supersin(x)^2 + sin(1/2*y)
sage: g.diff(y)
(x, y) |--> 1/2*cos(1/2*y)
sage: k = g.diff(x); k
(x, y) |--> 2*supersin(x)*diff(supersin(x), x)
>>> from sage.all import *
>>> __tmp__=var("x,y"); g = symbolic_expression(supersin(x)**Integer(2) + sin(y/Integer(2))).function(x,y)
>>> g
(x, y) |--> supersin(x)^2 + sin(1/2*y)
>>> g.diff(y)
(x, y) |--> 1/2*cos(1/2*y)
>>> k = g.diff(x); k
(x, y) |--> 2*supersin(x)*diff(supersin(x), x)

We create a formal function of one variable, write down an expression that involves first and second derivatives, and extract off coefficients:

sage: r, kappa = var('r,kappa')
sage: psi = function('psi', nargs=1)(r); psi
psi(r)
sage: g = 1/r^2*(2*r*psi.derivative(r,1) + r^2*psi.derivative(r,2)); g
(r^2*diff(psi(r), r, r) + 2*r*diff(psi(r), r))/r^2
sage: g.expand()
2*diff(psi(r), r)/r + diff(psi(r), r, r)
sage: g.coefficient(psi.derivative(r,2))
1
sage: g.coefficient(psi.derivative(r,1))
2/r
>>> from sage.all import *
>>> r, kappa = var('r,kappa')
>>> psi = function('psi', nargs=Integer(1))(r); psi
psi(r)
>>> g = Integer(1)/r**Integer(2)*(Integer(2)*r*psi.derivative(r,Integer(1)) + r**Integer(2)*psi.derivative(r,Integer(2))); g
(r^2*diff(psi(r), r, r) + 2*r*diff(psi(r), r))/r^2
>>> g.expand()
2*diff(psi(r), r)/r + diff(psi(r), r, r)
>>> g.coefficient(psi.derivative(r,Integer(2)))
1
>>> g.coefficient(psi.derivative(r,Integer(1)))
2/r

Custom typesetting of symbolic functions in LaTeX, either using latex_name keyword:

sage: function('riemann', latex_name='\\mathcal{R}')
riemann
sage: latex(riemann(x))
\mathcal{R}\left(x\right)
>>> from sage.all import *
>>> function('riemann', latex_name='\\mathcal{R}')
riemann
>>> latex(riemann(x))
\mathcal{R}\left(x\right)

or passing a custom callable function that returns a latex expression:

sage: mu,nu = var('mu,nu')
sage: def my_latex_print(self, *args): return "\\psi_{%s}"%(', '.join(map(latex, args)))
sage: function('psi', print_latex_func=my_latex_print)
psi
sage: latex(psi(mu,nu))
\psi_{\mu, \nu}
>>> from sage.all import *
>>> mu,nu = var('mu,nu')
>>> def my_latex_print(self, *args): return "\\psi_{%s}"%(', '.join(map(latex, args)))
>>> function('psi', print_latex_func=my_latex_print)
psi
>>> latex(psi(mu,nu))
\psi_{\mu, \nu}

Defining custom methods for automatic or numeric evaluation, derivation, conjugation, etc. is supported:

sage: def ev(self, x): return 2*x
sage: foo = function("foo", nargs=1, eval_func=ev)
sage: foo(x)
2*x
sage: foo = function("foo", nargs=1, eval_func=lambda self, x: 5)
sage: foo(x)
5
sage: def ef(self, x): pass
sage: bar = function("bar", nargs=1, eval_func=ef)
sage: bar(x)
bar(x)

sage: def evalf_f(self, x, parent=None, algorithm=None): return 6
sage: foo = function("foo", nargs=1, evalf_func=evalf_f)
sage: foo(x)
foo(x)
sage: foo(x).n()
6

sage: foo = function("foo", nargs=1, conjugate_func=ev)
sage: foo(x).conjugate()
2*x

sage: def deriv(self, *args, **kwds): print("{} {}".format(args, kwds)); return args[kwds['diff_param']]^2
sage: foo = function("foo", nargs=2, derivative_func=deriv)
sage: foo(x,y).derivative(y)
(x, y) {'diff_param': 1}
y^2

sage: def pow(self, x, power_param=None): print("{} {}".format(x, power_param)); return x*power_param
sage: foo = function("foo", nargs=1, power_func=pow)
sage: foo(y)^(x+y)
y x + y
(x + y)*y

sage: from pprint import pformat
sage: def expand(self, *args, **kwds):
....:     print("{} {}".format(args, pformat(kwds)))
....:     return sum(args[0]^i for i in range(kwds['order']))
sage: foo = function("foo", nargs=1, series_func=expand)
sage: foo(y).series(y, 5)
(y,) {'at': 0, 'options': 0, 'order': 5, 'var': y}
y^4 + y^3 + y^2 + y + 1

sage: def my_print(self, *args):
....:     return "my args are: " + ', '.join(map(repr, args))
sage: foo = function('t', nargs=2, print_func=my_print)
sage: foo(x,y^z)
my args are: x, y^z

sage: latex(foo(x,y^z))
t\left(x, y^{z}\right)
sage: foo = function('t', nargs=2, print_latex_func=my_print)
sage: foo(x,y^z)
t(x, y^z)
sage: latex(foo(x,y^z))
my args are: x, y^z
sage: foo = function('t', nargs=2, latex_name='foo')
sage: latex(foo(x,y^z))
foo\left(x, y^{z}\right)
>>> from sage.all import *
>>> def ev(self, x): return Integer(2)*x
>>> foo = function("foo", nargs=Integer(1), eval_func=ev)
>>> foo(x)
2*x
>>> foo = function("foo", nargs=Integer(1), eval_func=lambda self, x: Integer(5))
>>> foo(x)
5
>>> def ef(self, x): pass
>>> bar = function("bar", nargs=Integer(1), eval_func=ef)
>>> bar(x)
bar(x)

>>> def evalf_f(self, x, parent=None, algorithm=None): return Integer(6)
>>> foo = function("foo", nargs=Integer(1), evalf_func=evalf_f)
>>> foo(x)
foo(x)
>>> foo(x).n()
6

>>> foo = function("foo", nargs=Integer(1), conjugate_func=ev)
>>> foo(x).conjugate()
2*x

>>> def deriv(self, *args, **kwds): print("{} {}".format(args, kwds)); return args[kwds['diff_param']]**Integer(2)
>>> foo = function("foo", nargs=Integer(2), derivative_func=deriv)
>>> foo(x,y).derivative(y)
(x, y) {'diff_param': 1}
y^2

>>> def pow(self, x, power_param=None): print("{} {}".format(x, power_param)); return x*power_param
>>> foo = function("foo", nargs=Integer(1), power_func=pow)
>>> foo(y)**(x+y)
y x + y
(x + y)*y

>>> from pprint import pformat
>>> def expand(self, *args, **kwds):
...     print("{} {}".format(args, pformat(kwds)))
...     return sum(args[Integer(0)]**i for i in range(kwds['order']))
>>> foo = function("foo", nargs=Integer(1), series_func=expand)
>>> foo(y).series(y, Integer(5))
(y,) {'at': 0, 'options': 0, 'order': 5, 'var': y}
y^4 + y^3 + y^2 + y + 1

>>> def my_print(self, *args):
...     return "my args are: " + ', '.join(map(repr, args))
>>> foo = function('t', nargs=Integer(2), print_func=my_print)
>>> foo(x,y**z)
my args are: x, y^z

>>> latex(foo(x,y**z))
t\left(x, y^{z}\right)
>>> foo = function('t', nargs=Integer(2), print_latex_func=my_print)
>>> foo(x,y**z)
t(x, y^z)
>>> latex(foo(x,y**z))
my args are: x, y^z
>>> foo = function('t', nargs=Integer(2), latex_name='foo')
>>> latex(foo(x,y**z))
foo\left(x, y^{z}\right)

Chain rule:

sage: def print_args(self, *args, **kwds): print("args: {}".format(args)); print("kwds: {}".format(kwds)); return args[0]
sage: foo = function('t', nargs=2, tderivative_func=print_args)
sage: foo(x,x).derivative(x)
args: (x, x)
kwds: {'diff_param': x}
x
sage: foo = function('t', nargs=2, derivative_func=print_args)
sage: foo(x,x).derivative(x)
args: (x, x)
kwds: {'diff_param': 0}
args: (x, x)
kwds: {'diff_param': 1}
2*x
>>> from sage.all import *
>>> def print_args(self, *args, **kwds): print("args: {}".format(args)); print("kwds: {}".format(kwds)); return args[Integer(0)]
>>> foo = function('t', nargs=Integer(2), tderivative_func=print_args)
>>> foo(x,x).derivative(x)
args: (x, x)
kwds: {'diff_param': x}
x
>>> foo = function('t', nargs=Integer(2), derivative_func=print_args)
>>> foo(x,x).derivative(x)
args: (x, x)
kwds: {'diff_param': 0}
args: (x, x)
kwds: {'diff_param': 1}
2*x

Since Sage 4.0, basic arithmetic with unevaluated functions is no longer supported:

sage: x = var('x')
sage: f = function('f')
sage: 2*f
Traceback (most recent call last):
...
TypeError: unsupported operand parent(s) for *: 'Integer Ring' and '<class 'sage.symbolic.function_factory...NewSymbolicFunction'>'
>>> from sage.all import *
>>> x = var('x')
>>> f = function('f')
>>> Integer(2)*f
Traceback (most recent call last):
...
TypeError: unsupported operand parent(s) for *: 'Integer Ring' and '<class 'sage.symbolic.function_factory...NewSymbolicFunction'>'

You now need to evaluate the function in order to do the arithmetic:

sage: 2*f(x)
2*f(x)
>>> from sage.all import *
>>> Integer(2)*f(x)
2*f(x)

Since Sage 4.0, you need to use substitute_function() to replace all occurrences of a function with another:

sage: var('a, b')
(a, b)
sage: cr = function('cr')
sage: f = cr(a)
sage: g = f.diff(a).integral(b)
sage: g
b*diff(cr(a), a)
sage: g.substitute_function(cr, cos)
-b*sin(a)

sage: g.substitute_function(cr, (sin(x) + cos(x)).function(x))
b*(cos(a) - sin(a))
>>> from sage.all import *
>>> var('a, b')
(a, b)
>>> cr = function('cr')
>>> f = cr(a)
>>> g = f.diff(a).integral(b)
>>> g
b*diff(cr(a), a)
>>> g.substitute_function(cr, cos)
-b*sin(a)

>>> g.substitute_function(cr, (sin(x) + cos(x)).function(x))
b*(cos(a) - sin(a))
half = 1/2[source]
sec = sec[source]
sech = sech[source]
sin = sin[source]
sinh = sinh[source]
tan = tan[source]
tanh = tanh[source]
two = 2[source]
x = x[source]
class sage.symbolic.expression_conversions.ExpressionTreeWalker(ex)[source]

Bases: Converter

A class that walks the tree. Mainly for subclassing.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
sage: from sage.symbolic.random_tests import random_expr
sage: ex = sin(atan(0,hold=True)+hypergeometric((1,),(1,),x))
sage: s = ExpressionTreeWalker(ex)
sage: bool(s() == ex)
True
sage: set_random_seed(0)  # random_expr is unstable
sage: foo = random_expr(20, nvars=2)
sage: s = ExpressionTreeWalker(foo)
sage: bool(s() == foo)
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import ExpressionTreeWalker
>>> from sage.symbolic.random_tests import random_expr
>>> ex = sin(atan(Integer(0),hold=True)+hypergeometric((Integer(1),),(Integer(1),),x))
>>> s = ExpressionTreeWalker(ex)
>>> bool(s() == ex)
True
>>> set_random_seed(Integer(0))  # random_expr is unstable
>>> foo = random_expr(Integer(20), nvars=Integer(2))
>>> s = ExpressionTreeWalker(foo)
>>> bool(s() == foo)
True
arithmetic(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
sage: foo = function('foo')
sage: f = x*foo(x) + pi/foo(x)
sage: s = ExpressionTreeWalker(f)
sage: bool(s.arithmetic(f, f.operator()) == f)
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import ExpressionTreeWalker
>>> foo = function('foo')
>>> f = x*foo(x) + pi/foo(x)
>>> s = ExpressionTreeWalker(f)
>>> bool(s.arithmetic(f, f.operator()) == f)
True
composition(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
sage: foo = function('foo')
sage: f = foo(atan2(0, 0, hold=True))
sage: s = ExpressionTreeWalker(f)
sage: bool(s.composition(f, f.operator()) == f)
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import ExpressionTreeWalker
>>> foo = function('foo')
>>> f = foo(atan2(Integer(0), Integer(0), hold=True))
>>> s = ExpressionTreeWalker(f)
>>> bool(s.composition(f, f.operator()) == f)
True
derivative(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
sage: foo = function('foo')
sage: f = foo(x).diff(x)
sage: s = ExpressionTreeWalker(f)
sage: bool(s.derivative(f, f.operator()) == f)
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import ExpressionTreeWalker
>>> foo = function('foo')
>>> f = foo(x).diff(x)
>>> s = ExpressionTreeWalker(f)
>>> bool(s.derivative(f, f.operator()) == f)
True
pyobject(ex, obj)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
sage: f = SR(2)
sage: s = ExpressionTreeWalker(f)
sage: bool(s.pyobject(f, f.pyobject()) == f.pyobject())
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import ExpressionTreeWalker
>>> f = SR(Integer(2))
>>> s = ExpressionTreeWalker(f)
>>> bool(s.pyobject(f, f.pyobject()) == f.pyobject())
True
relation(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
sage: foo = function('foo')
sage: eq = foo(x) == x
sage: s = ExpressionTreeWalker(eq)
sage: s.relation(eq, eq.operator()) == eq
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import ExpressionTreeWalker
>>> foo = function('foo')
>>> eq = foo(x) == x
>>> s = ExpressionTreeWalker(eq)
>>> s.relation(eq, eq.operator()) == eq
True
symbol(ex)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
sage: s = ExpressionTreeWalker(x)
sage: bool(s.symbol(x) == x)
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import ExpressionTreeWalker
>>> s = ExpressionTreeWalker(x)
>>> bool(s.symbol(x) == x)
True
tuple(ex)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
sage: foo = function('foo')
sage: f = hypergeometric((1,2,3,),(x,),x)
sage: s = ExpressionTreeWalker(f)
sage: bool(s() == f)
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import ExpressionTreeWalker
>>> foo = function('foo')
>>> f = hypergeometric((Integer(1),Integer(2),Integer(3),),(x,),x)
>>> s = ExpressionTreeWalker(f)
>>> bool(s() == f)
True
class sage.symbolic.expression_conversions.FakeExpression(operands, operator)[source]

Bases: object

Pynac represents \(x/y\) as \(xy^{-1}\). Often, tree-walkers would prefer to see divisions instead of multiplications and negative exponents. To allow for this (since Pynac internally doesn’t have division at all), there is a possibility to pass use_fake_div=True; this will rewrite an Expression into a mixture of Expression and FakeExpression nodes, where the FakeExpression nodes are used to represent divisions. These nodes are intended to act sufficiently like Expression nodes that tree-walkers won’t care about the difference.

operands()[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import FakeExpression
sage: import operator; x,y = var('x,y')
sage: f = FakeExpression([x, y], operator.truediv)
sage: f.operands()
[x, y]
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import FakeExpression
>>> import operator; x,y = var('x,y')
>>> f = FakeExpression([x, y], operator.truediv)
>>> f.operands()
[x, y]
operator()[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import FakeExpression
sage: import operator; x,y = var('x,y')
sage: f = FakeExpression([x, y], operator.truediv)
sage: f.operator()
<built-in function truediv>
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import FakeExpression
>>> import operator; x,y = var('x,y')
>>> f = FakeExpression([x, y], operator.truediv)
>>> f.operator()
<built-in function truediv>
pyobject()[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import FakeExpression
sage: import operator; x,y = var('x,y')
sage: f = FakeExpression([x, y], operator.truediv)
sage: f.pyobject()
Traceback (most recent call last):
...
TypeError: self must be a numeric expression
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import FakeExpression
>>> import operator; x,y = var('x,y')
>>> f = FakeExpression([x, y], operator.truediv)
>>> f.pyobject()
Traceback (most recent call last):
...
TypeError: self must be a numeric expression
class sage.symbolic.expression_conversions.FastCallableConverter(ex, etb)[source]

Bases: Converter

EXAMPLES:

sage: from sage.symbolic.expression_conversions import FastCallableConverter
sage: from sage.ext.fast_callable import ExpressionTreeBuilder
sage: etb = ExpressionTreeBuilder(vars=['x'])
sage: f = FastCallableConverter(x+2, etb)
sage: f.ex
x + 2
sage: f.etb
<sage.ext.fast_callable.ExpressionTreeBuilder object at 0x...>
sage: f.use_fake_div
True
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import FastCallableConverter
>>> from sage.ext.fast_callable import ExpressionTreeBuilder
>>> etb = ExpressionTreeBuilder(vars=['x'])
>>> f = FastCallableConverter(x+Integer(2), etb)
>>> f.ex
x + 2
>>> f.etb
<sage.ext.fast_callable.ExpressionTreeBuilder object at 0x...>
>>> f.use_fake_div
True
arithmetic(ex, operator)[source]

EXAMPLES:

sage: from sage.ext.fast_callable import ExpressionTreeBuilder
sage: etb = ExpressionTreeBuilder(vars=['x','y'])
sage: var('x,y')
(x, y)
sage: (x+y)._fast_callable_(etb)
add(v_0, v_1)
sage: (-x)._fast_callable_(etb)
neg(v_0)
sage: (x+y+x^2)._fast_callable_(etb)
add(add(ipow(v_0, 2), v_0), v_1)
>>> from sage.all import *
>>> from sage.ext.fast_callable import ExpressionTreeBuilder
>>> etb = ExpressionTreeBuilder(vars=['x','y'])
>>> var('x,y')
(x, y)
>>> (x+y)._fast_callable_(etb)
add(v_0, v_1)
>>> (-x)._fast_callable_(etb)
neg(v_0)
>>> (x+y+x**Integer(2))._fast_callable_(etb)
add(add(ipow(v_0, 2), v_0), v_1)
composition(ex, function)[source]

Given an ExpressionTreeBuilder, return an Expression representing this value.

EXAMPLES:

sage: from sage.ext.fast_callable import ExpressionTreeBuilder
sage: etb = ExpressionTreeBuilder(vars=['x','y'])
sage: x,y = var('x,y')
sage: sin(sqrt(x+y))._fast_callable_(etb)
sin(sqrt(add(v_0, v_1)))
sage: arctan2(x,y)._fast_callable_(etb)
{arctan2}(v_0, v_1)
>>> from sage.all import *
>>> from sage.ext.fast_callable import ExpressionTreeBuilder
>>> etb = ExpressionTreeBuilder(vars=['x','y'])
>>> x,y = var('x,y')
>>> sin(sqrt(x+y))._fast_callable_(etb)
sin(sqrt(add(v_0, v_1)))
>>> arctan2(x,y)._fast_callable_(etb)
{arctan2}(v_0, v_1)
pyobject(ex, obj)[source]

EXAMPLES:

sage: from sage.ext.fast_callable import ExpressionTreeBuilder
sage: etb = ExpressionTreeBuilder(vars=['x'])
sage: pi._fast_callable_(etb)
pi
sage: etb = ExpressionTreeBuilder(vars=['x'], domain=RDF)
sage: pi._fast_callable_(etb)
3.141592653589793
>>> from sage.all import *
>>> from sage.ext.fast_callable import ExpressionTreeBuilder
>>> etb = ExpressionTreeBuilder(vars=['x'])
>>> pi._fast_callable_(etb)
pi
>>> etb = ExpressionTreeBuilder(vars=['x'], domain=RDF)
>>> pi._fast_callable_(etb)
3.141592653589793
relation(ex, operator)[source]

EXAMPLES:

sage: ff = fast_callable(x == 2, vars=['x'])
sage: ff(2)
0
sage: ff(4)
2
sage: ff = fast_callable(x < 2, vars=['x'])
Traceback (most recent call last):
...
NotImplementedError
>>> from sage.all import *
>>> ff = fast_callable(x == Integer(2), vars=['x'])
>>> ff(Integer(2))
0
>>> ff(Integer(4))
2
>>> ff = fast_callable(x < Integer(2), vars=['x'])
Traceback (most recent call last):
...
NotImplementedError
symbol(ex)[source]

Given an ExpressionTreeBuilder, return an Expression representing this value.

EXAMPLES:

sage: from sage.ext.fast_callable import ExpressionTreeBuilder
sage: etb = ExpressionTreeBuilder(vars=['x','y'])
sage: x, y, z = var('x,y,z')
sage: x._fast_callable_(etb)
v_0
sage: y._fast_callable_(etb)
v_1
sage: z._fast_callable_(etb)
Traceback (most recent call last):
...
ValueError: Variable 'z' not found...
>>> from sage.all import *
>>> from sage.ext.fast_callable import ExpressionTreeBuilder
>>> etb = ExpressionTreeBuilder(vars=['x','y'])
>>> x, y, z = var('x,y,z')
>>> x._fast_callable_(etb)
v_0
>>> y._fast_callable_(etb)
v_1
>>> z._fast_callable_(etb)
Traceback (most recent call last):
...
ValueError: Variable 'z' not found...
tuple(ex)[source]

Given a symbolic tuple, return its elements as a Python list.

EXAMPLES:

sage: from sage.ext.fast_callable import ExpressionTreeBuilder
sage: etb = ExpressionTreeBuilder(vars=['x'])
sage: SR._force_pyobject((2, 3, x^2))._fast_callable_(etb)
[2, 3, x^2]
>>> from sage.all import *
>>> from sage.ext.fast_callable import ExpressionTreeBuilder
>>> etb = ExpressionTreeBuilder(vars=['x'])
>>> SR._force_pyobject((Integer(2), Integer(3), x**Integer(2)))._fast_callable_(etb)
[2, 3, x^2]
class sage.symbolic.expression_conversions.FriCASConverter[source]

Bases: InterfaceInit

Convert any expression to FriCAS.

EXAMPLES:

sage: var('x,y')
(x, y)
sage: f = exp(x^2) - arcsin(pi+x)/y
sage: f._fricas_()                                                      # optional - fricas
     2
    x
y %e   - asin(x + %pi)
----------------------
           y
>>> from sage.all import *
>>> var('x,y')
(x, y)
>>> f = exp(x**Integer(2)) - arcsin(pi+x)/y
>>> f._fricas_()                                                      # optional - fricas
     2
    x
y %e   - asin(x + %pi)
----------------------
           y
derivative(ex, operator)[source]

Convert the derivative of self in FriCAS.

INPUT:

  • ex – a symbolic expression

  • operator – operator

Note that ex.operator() == operator.

EXAMPLES:

sage: var('x,y,z')
(x, y, z)
sage: f = function("F")
sage: f(x)._fricas_()                                               # optional - fricas
F(x)
sage: diff(f(x,y,z), x, z, x)._fricas_()                            # optional - fricas
F      (x,y,z)
 ,1,1,3
>>> from sage.all import *
>>> var('x,y,z')
(x, y, z)
>>> f = function("F")
>>> f(x)._fricas_()                                               # optional - fricas
F(x)
>>> diff(f(x,y,z), x, z, x)._fricas_()                            # optional - fricas
F      (x,y,z)
 ,1,1,3

Check that Issue #25838 is fixed:

sage: var('x')
x
sage: F = function('F')
sage: integrate(F(x), x, algorithm='fricas')                        # optional - fricas
integral(F(x), x)

sage: integrate(diff(F(x), x)*sin(F(x)), x, algorithm='fricas')     # optional - fricas
-cos(F(x))
>>> from sage.all import *
>>> var('x')
x
>>> F = function('F')
>>> integrate(F(x), x, algorithm='fricas')                        # optional - fricas
integral(F(x), x)

>>> integrate(diff(F(x), x)*sin(F(x)), x, algorithm='fricas')     # optional - fricas
-cos(F(x))

Check that Issue #27310 is fixed:

sage: f = function("F")
sage: var("y")
y
sage: ex = (diff(f(x,y), x, x, y)).subs(y=x+y); ex
D[0, 0, 1](F)(x, x + y)
sage: fricas(ex)                                                    # optional - fricas
F      (x,y + x)
 ,1,1,2
>>> from sage.all import *
>>> f = function("F")
>>> var("y")
y
>>> ex = (diff(f(x,y), x, x, y)).subs(y=x+y); ex
D[0, 0, 1](F)(x, x + y)
>>> fricas(ex)                                                    # optional - fricas
F      (x,y + x)
 ,1,1,2
pyobject(ex, obj)[source]

Return a string which, when evaluated by FriCAS, returns the object as an expression.

We explicitly add the coercion to the FriCAS domains \(Expression Integer\) and \(Expression Complex Integer\) to make sure that elements of the symbolic ring are translated to these. In particular, this is needed for integration, see Issue #28641 and Issue #28647.

EXAMPLES:

sage: 2._fricas_().domainOf()                                       # optional - fricas
PositiveInteger...

sage: (-1/2)._fricas_().domainOf()                                  # optional - fricas
Fraction(Integer...)

sage: SR(2)._fricas_().domainOf()                                   # optional - fricas
Expression(Integer...)

sage: (sqrt(2))._fricas_().domainOf()                               # optional - fricas
Expression(Integer...)

sage: pi._fricas_().domainOf()                                      # optional - fricas
Pi...

sage: asin(pi)._fricas_()                                           # optional - fricas
asin(%pi)

sage: I._fricas_().domainOf()                                   # optional - fricas
Complex(Integer...)

sage: SR(I)._fricas_().domainOf()                                   # optional - fricas
Expression(Complex(Integer...))

sage: ex = (I+sqrt(2)+2)
sage: ex._fricas_().domainOf()                                      # optional - fricas
Expression(Complex(Integer...))

sage: ex._fricas_()^2                                               # optional - fricas
           +-+
(4 + 2 %i)\|2  + 5 + 4 %i

sage: (ex^2)._fricas_()                                             # optional - fricas
           +-+
(4 + 2 %i)\|2  + 5 + 4 %i
>>> from sage.all import *
>>> Integer(2)._fricas_().domainOf()                                       # optional - fricas
PositiveInteger...

>>> (-Integer(1)/Integer(2))._fricas_().domainOf()                                  # optional - fricas
Fraction(Integer...)

>>> SR(Integer(2))._fricas_().domainOf()                                   # optional - fricas
Expression(Integer...)

>>> (sqrt(Integer(2)))._fricas_().domainOf()                               # optional - fricas
Expression(Integer...)

>>> pi._fricas_().domainOf()                                      # optional - fricas
Pi...

>>> asin(pi)._fricas_()                                           # optional - fricas
asin(%pi)

>>> I._fricas_().domainOf()                                   # optional - fricas
Complex(Integer...)

>>> SR(I)._fricas_().domainOf()                                   # optional - fricas
Expression(Complex(Integer...))

>>> ex = (I+sqrt(Integer(2))+Integer(2))
>>> ex._fricas_().domainOf()                                      # optional - fricas
Expression(Complex(Integer...))

>>> ex._fricas_()**Integer(2)                                               # optional - fricas
           +-+
(4 + 2 %i)\|2  + 5 + 4 %i

>>> (ex**Integer(2))._fricas_()                                             # optional - fricas
           +-+
(4 + 2 %i)\|2  + 5 + 4 %i
symbol(ex)[source]

Convert the argument, which is a symbol, to FriCAS.

In this case, we do not return an \(Expression Integer\), because FriCAS frequently requires elements of domain \(Symbol\) or \(Variable\) as arguments, for example to \(integrate\). Moreover, FriCAS is able to do the conversion itself, whenever the argument should be interpreted as a symbolic expression.

EXAMPLES:

sage: x._fricas_().domainOf()                                       # optional - fricas
Variable(x)

sage: (x^2)._fricas_().domainOf()                                   # optional - fricas
Expression(Integer...)

sage: (2*x)._fricas_().integrate(x)                                 # optional - fricas
 2
x
>>> from sage.all import *
>>> x._fricas_().domainOf()                                       # optional - fricas
Variable(x)

>>> (x**Integer(2))._fricas_().domainOf()                                   # optional - fricas
Expression(Integer...)

>>> (Integer(2)*x)._fricas_().integrate(x)                                 # optional - fricas
 2
x
class sage.symbolic.expression_conversions.HalfAngle(ex)[source]

Bases: ExpressionTreeWalker

A class that walks a symbolic expression tree, replacing each occurrence of a trigonometric or hyperbolic function by its expression as a rational fraction in the (hyperbolic) tangent of half the original argument.

Halves = [sin, cos, tan, csc, sec, cot, sinh, cosh, tanh, csch, sech, coth]
HalvesDict = {sinh: x |--> -2*tanh(1/2*x)/(tanh(1/2*x)^2 - 1), cosh: x |--> -(tanh(1/2*x)^2 + 1)/(tanh(1/2*x)^2 - 1), tanh: x |--> 2*tanh(1/2*x)/(tanh(1/2*x)^2 + 1), coth: x |--> 1/2*(tanh(1/2*x)^2 + 1)/tanh(1/2*x), sech: x |--> -(tanh(1/2*x)^2 - 1)/(tanh(1/2*x)^2 + 1), csch: x |--> -1/2*(tanh(1/2*x)^2 - 1)/tanh(1/2*x), sin: x |--> 2*tan(1/2*x)/(tan(1/2*x)^2 + 1), cos: x |--> -(tan(1/2*x)^2 - 1)/(tan(1/2*x)^2 + 1), tan: x |--> -2*tan(1/2*x)/(tan(1/2*x)^2 - 1), cot: x |--> -1/2*(tan(1/2*x)^2 - 1)/tan(1/2*x), sec: x |--> -(tan(1/2*x)^2 + 1)/(tan(1/2*x)^2 - 1), csc: x |--> 1/2*(tan(1/2*x)^2 + 1)/tan(1/2*x)}
Integer[source]

alias of Integer

SR = Symbolic Ring[source]
composition(ex, op)[source]

Compose.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import HalfAngle
sage: x, t = SR.var("x, t")
sage: a = HalfAngle(cos(3*x)/(4-cos(x)).trig_expand())()
sage: a.subs(tan(x/2) == t).simplify_full()
(2*(t^2 + 1)*cos(3/2*x)^2 - t^2 - 1)/(5*t^2 + 3)
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import HalfAngle
>>> x, t = SR.var("x, t")
>>> a = HalfAngle(cos(Integer(3)*x)/(Integer(4)-cos(x)).trig_expand())()
>>> a.subs(tan(x/Integer(2)) == t).simplify_full()
(2*(t^2 + 1)*cos(3/2*x)^2 - t^2 - 1)/(5*t^2 + 3)
cos = cos[source]
cosh = cosh[source]
cot = cot[source]
coth = coth[source]
csc = csc[source]
csch = csch[source]
function(s, **kwds)[source]

Create a formal symbolic function with the name s.

INPUT:

  • nargs=0 – number of arguments the function accepts, defaults to variable number of arguments, or 0

  • latex_name – name used when printing in latex mode

  • conversions – dictionary specifying names of this function in other systems, this is used by the interfaces internally during conversion

  • eval_func – method used for automatic evaluation

  • evalf_func – method used for numeric evaluation

  • evalf_params_first – boolean to indicate if parameters should be evaluated numerically before calling the custom evalf function

  • conjugate_func – method used for complex conjugation

  • real_part_func – method used when taking real parts

  • imag_part_func – method used when taking imaginary parts

  • derivative_func – method to be used for (partial) derivation This method should take a keyword argument deriv_param specifying the index of the argument to differentiate w.r.t

  • tderivative_func – method to be used for derivatives

  • power_func – method used when taking powers This method should take a keyword argument power_param specifying the exponent

  • series_func – method used for series expansion This method should expect keyword arguments - order – order for the expansion to be computed - var – variable to expand w.r.t. - at – expand at this value

  • print_func – method for custom printing

  • print_latex_func – method for custom printing in latex mode

Note that custom methods must be instance methods, i.e., expect the instance of the symbolic function as the first argument.

Note

The new function is both returned and automatically injected into the global namespace. If you use this function in library code, it is better to use sage.symbolic.function_factory.function, since it will not touch the global namespace.

EXAMPLES:

We create a formal function called supersin

sage: function('supersin')
supersin
>>> from sage.all import *
>>> function('supersin')
supersin

We can immediately use supersin in symbolic expressions:

sage: y, z, A = var('y z A')
sage: supersin(y+z) + A^3
A^3 + supersin(y + z)
>>> from sage.all import *
>>> y, z, A = var('y z A')
>>> supersin(y+z) + A**Integer(3)
A^3 + supersin(y + z)

We can define other functions in terms of supersin:

sage: g(x,y) = supersin(x)^2 + sin(y/2)
sage: g
(x, y) |--> supersin(x)^2 + sin(1/2*y)
sage: g.diff(y)
(x, y) |--> 1/2*cos(1/2*y)
sage: k = g.diff(x); k
(x, y) |--> 2*supersin(x)*diff(supersin(x), x)
>>> from sage.all import *
>>> __tmp__=var("x,y"); g = symbolic_expression(supersin(x)**Integer(2) + sin(y/Integer(2))).function(x,y)
>>> g
(x, y) |--> supersin(x)^2 + sin(1/2*y)
>>> g.diff(y)
(x, y) |--> 1/2*cos(1/2*y)
>>> k = g.diff(x); k
(x, y) |--> 2*supersin(x)*diff(supersin(x), x)

We create a formal function of one variable, write down an expression that involves first and second derivatives, and extract off coefficients:

sage: r, kappa = var('r,kappa')
sage: psi = function('psi', nargs=1)(r); psi
psi(r)
sage: g = 1/r^2*(2*r*psi.derivative(r,1) + r^2*psi.derivative(r,2)); g
(r^2*diff(psi(r), r, r) + 2*r*diff(psi(r), r))/r^2
sage: g.expand()
2*diff(psi(r), r)/r + diff(psi(r), r, r)
sage: g.coefficient(psi.derivative(r,2))
1
sage: g.coefficient(psi.derivative(r,1))
2/r
>>> from sage.all import *
>>> r, kappa = var('r,kappa')
>>> psi = function('psi', nargs=Integer(1))(r); psi
psi(r)
>>> g = Integer(1)/r**Integer(2)*(Integer(2)*r*psi.derivative(r,Integer(1)) + r**Integer(2)*psi.derivative(r,Integer(2))); g
(r^2*diff(psi(r), r, r) + 2*r*diff(psi(r), r))/r^2
>>> g.expand()
2*diff(psi(r), r)/r + diff(psi(r), r, r)
>>> g.coefficient(psi.derivative(r,Integer(2)))
1
>>> g.coefficient(psi.derivative(r,Integer(1)))
2/r

Custom typesetting of symbolic functions in LaTeX, either using latex_name keyword:

sage: function('riemann', latex_name='\\mathcal{R}')
riemann
sage: latex(riemann(x))
\mathcal{R}\left(x\right)
>>> from sage.all import *
>>> function('riemann', latex_name='\\mathcal{R}')
riemann
>>> latex(riemann(x))
\mathcal{R}\left(x\right)

or passing a custom callable function that returns a latex expression:

sage: mu,nu = var('mu,nu')
sage: def my_latex_print(self, *args): return "\\psi_{%s}"%(', '.join(map(latex, args)))
sage: function('psi', print_latex_func=my_latex_print)
psi
sage: latex(psi(mu,nu))
\psi_{\mu, \nu}
>>> from sage.all import *
>>> mu,nu = var('mu,nu')
>>> def my_latex_print(self, *args): return "\\psi_{%s}"%(', '.join(map(latex, args)))
>>> function('psi', print_latex_func=my_latex_print)
psi
>>> latex(psi(mu,nu))
\psi_{\mu, \nu}

Defining custom methods for automatic or numeric evaluation, derivation, conjugation, etc. is supported:

sage: def ev(self, x): return 2*x
sage: foo = function("foo", nargs=1, eval_func=ev)
sage: foo(x)
2*x
sage: foo = function("foo", nargs=1, eval_func=lambda self, x: 5)
sage: foo(x)
5
sage: def ef(self, x): pass
sage: bar = function("bar", nargs=1, eval_func=ef)
sage: bar(x)
bar(x)

sage: def evalf_f(self, x, parent=None, algorithm=None): return 6
sage: foo = function("foo", nargs=1, evalf_func=evalf_f)
sage: foo(x)
foo(x)
sage: foo(x).n()
6

sage: foo = function("foo", nargs=1, conjugate_func=ev)
sage: foo(x).conjugate()
2*x

sage: def deriv(self, *args, **kwds): print("{} {}".format(args, kwds)); return args[kwds['diff_param']]^2
sage: foo = function("foo", nargs=2, derivative_func=deriv)
sage: foo(x,y).derivative(y)
(x, y) {'diff_param': 1}
y^2

sage: def pow(self, x, power_param=None): print("{} {}".format(x, power_param)); return x*power_param
sage: foo = function("foo", nargs=1, power_func=pow)
sage: foo(y)^(x+y)
y x + y
(x + y)*y

sage: from pprint import pformat
sage: def expand(self, *args, **kwds):
....:     print("{} {}".format(args, pformat(kwds)))
....:     return sum(args[0]^i for i in range(kwds['order']))
sage: foo = function("foo", nargs=1, series_func=expand)
sage: foo(y).series(y, 5)
(y,) {'at': 0, 'options': 0, 'order': 5, 'var': y}
y^4 + y^3 + y^2 + y + 1

sage: def my_print(self, *args):
....:     return "my args are: " + ', '.join(map(repr, args))
sage: foo = function('t', nargs=2, print_func=my_print)
sage: foo(x,y^z)
my args are: x, y^z

sage: latex(foo(x,y^z))
t\left(x, y^{z}\right)
sage: foo = function('t', nargs=2, print_latex_func=my_print)
sage: foo(x,y^z)
t(x, y^z)
sage: latex(foo(x,y^z))
my args are: x, y^z
sage: foo = function('t', nargs=2, latex_name='foo')
sage: latex(foo(x,y^z))
foo\left(x, y^{z}\right)
>>> from sage.all import *
>>> def ev(self, x): return Integer(2)*x
>>> foo = function("foo", nargs=Integer(1), eval_func=ev)
>>> foo(x)
2*x
>>> foo = function("foo", nargs=Integer(1), eval_func=lambda self, x: Integer(5))
>>> foo(x)
5
>>> def ef(self, x): pass
>>> bar = function("bar", nargs=Integer(1), eval_func=ef)
>>> bar(x)
bar(x)

>>> def evalf_f(self, x, parent=None, algorithm=None): return Integer(6)
>>> foo = function("foo", nargs=Integer(1), evalf_func=evalf_f)
>>> foo(x)
foo(x)
>>> foo(x).n()
6

>>> foo = function("foo", nargs=Integer(1), conjugate_func=ev)
>>> foo(x).conjugate()
2*x

>>> def deriv(self, *args, **kwds): print("{} {}".format(args, kwds)); return args[kwds['diff_param']]**Integer(2)
>>> foo = function("foo", nargs=Integer(2), derivative_func=deriv)
>>> foo(x,y).derivative(y)
(x, y) {'diff_param': 1}
y^2

>>> def pow(self, x, power_param=None): print("{} {}".format(x, power_param)); return x*power_param
>>> foo = function("foo", nargs=Integer(1), power_func=pow)
>>> foo(y)**(x+y)
y x + y
(x + y)*y

>>> from pprint import pformat
>>> def expand(self, *args, **kwds):
...     print("{} {}".format(args, pformat(kwds)))
...     return sum(args[Integer(0)]**i for i in range(kwds['order']))
>>> foo = function("foo", nargs=Integer(1), series_func=expand)
>>> foo(y).series(y, Integer(5))
(y,) {'at': 0, 'options': 0, 'order': 5, 'var': y}
y^4 + y^3 + y^2 + y + 1

>>> def my_print(self, *args):
...     return "my args are: " + ', '.join(map(repr, args))
>>> foo = function('t', nargs=Integer(2), print_func=my_print)
>>> foo(x,y**z)
my args are: x, y^z

>>> latex(foo(x,y**z))
t\left(x, y^{z}\right)
>>> foo = function('t', nargs=Integer(2), print_latex_func=my_print)
>>> foo(x,y**z)
t(x, y^z)
>>> latex(foo(x,y**z))
my args are: x, y^z
>>> foo = function('t', nargs=Integer(2), latex_name='foo')
>>> latex(foo(x,y**z))
foo\left(x, y^{z}\right)

Chain rule:

sage: def print_args(self, *args, **kwds): print("args: {}".format(args)); print("kwds: {}".format(kwds)); return args[0]
sage: foo = function('t', nargs=2, tderivative_func=print_args)
sage: foo(x,x).derivative(x)
args: (x, x)
kwds: {'diff_param': x}
x
sage: foo = function('t', nargs=2, derivative_func=print_args)
sage: foo(x,x).derivative(x)
args: (x, x)
kwds: {'diff_param': 0}
args: (x, x)
kwds: {'diff_param': 1}
2*x
>>> from sage.all import *
>>> def print_args(self, *args, **kwds): print("args: {}".format(args)); print("kwds: {}".format(kwds)); return args[Integer(0)]
>>> foo = function('t', nargs=Integer(2), tderivative_func=print_args)
>>> foo(x,x).derivative(x)
args: (x, x)
kwds: {'diff_param': x}
x
>>> foo = function('t', nargs=Integer(2), derivative_func=print_args)
>>> foo(x,x).derivative(x)
args: (x, x)
kwds: {'diff_param': 0}
args: (x, x)
kwds: {'diff_param': 1}
2*x

Since Sage 4.0, basic arithmetic with unevaluated functions is no longer supported:

sage: x = var('x')
sage: f = function('f')
sage: 2*f
Traceback (most recent call last):
...
TypeError: unsupported operand parent(s) for *: 'Integer Ring' and '<class 'sage.symbolic.function_factory...NewSymbolicFunction'>'
>>> from sage.all import *
>>> x = var('x')
>>> f = function('f')
>>> Integer(2)*f
Traceback (most recent call last):
...
TypeError: unsupported operand parent(s) for *: 'Integer Ring' and '<class 'sage.symbolic.function_factory...NewSymbolicFunction'>'

You now need to evaluate the function in order to do the arithmetic:

sage: 2*f(x)
2*f(x)
>>> from sage.all import *
>>> Integer(2)*f(x)
2*f(x)

Since Sage 4.0, you need to use substitute_function() to replace all occurrences of a function with another:

sage: var('a, b')
(a, b)
sage: cr = function('cr')
sage: f = cr(a)
sage: g = f.diff(a).integral(b)
sage: g
b*diff(cr(a), a)
sage: g.substitute_function(cr, cos)
-b*sin(a)

sage: g.substitute_function(cr, (sin(x) + cos(x)).function(x))
b*(cos(a) - sin(a))
>>> from sage.all import *
>>> var('a, b')
(a, b)
>>> cr = function('cr')
>>> f = cr(a)
>>> g = f.diff(a).integral(b)
>>> g
b*diff(cr(a), a)
>>> g.substitute_function(cr, cos)
-b*sin(a)

>>> g.substitute_function(cr, (sin(x) + cos(x)).function(x))
b*(cos(a) - sin(a))
half = 1/2[source]
halfx = 1/2*x[source]
one = 1[source]
sec = sec[source]
sech = sech[source]
sin = sin[source]
sinh = sinh[source]
tan = tan[source]
tanh = tanh[source]
two = 2[source]
x = x[source]
class sage.symbolic.expression_conversions.HoldRemover(ex, exclude=None)[source]

Bases: ExpressionTreeWalker

A class that walks the tree and evaluates every operator that is not in a given list of exceptions.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import HoldRemover
sage: ex = sin(pi*cos(0, hold=True), hold=True); ex
sin(pi*cos(0))
sage: h = HoldRemover(ex)
sage: h()
0
sage: h = HoldRemover(ex, [sin])
sage: h()
sin(pi)
sage: h = HoldRemover(ex, [cos])
sage: h()
sin(pi*cos(0))
sage: ex = atan2(0, 0, hold=True) + hypergeometric([1,2], [3,4], 0, hold=True)
sage: h = HoldRemover(ex, [atan2])
sage: h()
arctan2(0, 0) + 1
sage: h = HoldRemover(ex, [hypergeometric])
sage: h()
NaN + hypergeometric((1, 2), (3, 4), 0)
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import HoldRemover
>>> ex = sin(pi*cos(Integer(0), hold=True), hold=True); ex
sin(pi*cos(0))
>>> h = HoldRemover(ex)
>>> h()
0
>>> h = HoldRemover(ex, [sin])
>>> h()
sin(pi)
>>> h = HoldRemover(ex, [cos])
>>> h()
sin(pi*cos(0))
>>> ex = atan2(Integer(0), Integer(0), hold=True) + hypergeometric([Integer(1),Integer(2)], [Integer(3),Integer(4)], Integer(0), hold=True)
>>> h = HoldRemover(ex, [atan2])
>>> h()
arctan2(0, 0) + 1
>>> h = HoldRemover(ex, [hypergeometric])
>>> h()
NaN + hypergeometric((1, 2), (3, 4), 0)
composition(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import HoldRemover
sage: ex = sin(pi*cos(0, hold=True), hold=True); ex
sin(pi*cos(0))
sage: h = HoldRemover(ex)
sage: h()
0
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import HoldRemover
>>> ex = sin(pi*cos(Integer(0), hold=True), hold=True); ex
sin(pi*cos(0))
>>> h = HoldRemover(ex)
>>> h()
0
class sage.symbolic.expression_conversions.InterfaceInit(interface)[source]

Bases: Converter

EXAMPLES:

sage: from sage.symbolic.expression_conversions import InterfaceInit
sage: m = InterfaceInit(maxima)
sage: a = pi + 2
sage: m(a)
'(%pi)+(2)'
sage: m(sin(a))
'sin((%pi)+(2))'
sage: m(exp(x^2) + pi + 2)
'(%pi)+(exp((_SAGE_VAR_x)^(2)))+(2)'
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import InterfaceInit
>>> m = InterfaceInit(maxima)
>>> a = pi + Integer(2)
>>> m(a)
'(%pi)+(2)'
>>> m(sin(a))
'sin((%pi)+(2))'
>>> m(exp(x**Integer(2)) + pi + Integer(2))
'(%pi)+(exp((_SAGE_VAR_x)^(2)))+(2)'
arithmetic(ex, operator)[source]

EXAMPLES:

sage: import operator
sage: from sage.symbolic.expression_conversions import InterfaceInit
sage: m = InterfaceInit(maxima)
sage: m.arithmetic(x+2, sage.symbolic.operators.add_vararg)
'(_SAGE_VAR_x)+(2)'
>>> from sage.all import *
>>> import operator
>>> from sage.symbolic.expression_conversions import InterfaceInit
>>> m = InterfaceInit(maxima)
>>> m.arithmetic(x+Integer(2), sage.symbolic.operators.add_vararg)
'(_SAGE_VAR_x)+(2)'
composition(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import InterfaceInit
sage: m = InterfaceInit(maxima)
sage: m.composition(sin(x), sin)
'sin(_SAGE_VAR_x)'
sage: m.composition(ceil(x), ceil)
'ceiling(_SAGE_VAR_x)'

sage: m = InterfaceInit(mathematica)
sage: m.composition(sin(x), sin)
'Sin[x]'
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import InterfaceInit
>>> m = InterfaceInit(maxima)
>>> m.composition(sin(x), sin)
'sin(_SAGE_VAR_x)'
>>> m.composition(ceil(x), ceil)
'ceiling(_SAGE_VAR_x)'

>>> m = InterfaceInit(mathematica)
>>> m.composition(sin(x), sin)
'Sin[x]'
derivative(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import InterfaceInit
sage: m = InterfaceInit(maxima)
sage: f = function('f')
sage: a = f(x).diff(x); a
diff(f(x), x)
sage: print(m.derivative(a, a.operator()))
diff('f(_SAGE_VAR_x), _SAGE_VAR_x, 1)
sage: b = f(x).diff(x, x)
sage: print(m.derivative(b, b.operator()))
diff('f(_SAGE_VAR_x), _SAGE_VAR_x, 2)
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import InterfaceInit
>>> m = InterfaceInit(maxima)
>>> f = function('f')
>>> a = f(x).diff(x); a
diff(f(x), x)
>>> print(m.derivative(a, a.operator()))
diff('f(_SAGE_VAR_x), _SAGE_VAR_x, 1)
>>> b = f(x).diff(x, x)
>>> print(m.derivative(b, b.operator()))
diff('f(_SAGE_VAR_x), _SAGE_VAR_x, 2)

We can also convert expressions where the argument is not just a variable, but the result is an “at” expression using temporary variables:

sage: y = var('y')
sage: t = (f(x*y).diff(x))/y
sage: t
D[0](f)(x*y)
sage: m.derivative(t, t.operator())
"at(diff('f(_SAGE_VAR__symbol0), _SAGE_VAR__symbol0, 1), [_SAGE_VAR__symbol0 = (_SAGE_VAR_x)*(_SAGE_VAR_y)])"
>>> from sage.all import *
>>> y = var('y')
>>> t = (f(x*y).diff(x))/y
>>> t
D[0](f)(x*y)
>>> m.derivative(t, t.operator())
"at(diff('f(_SAGE_VAR__symbol0), _SAGE_VAR__symbol0, 1), [_SAGE_VAR__symbol0 = (_SAGE_VAR_x)*(_SAGE_VAR_y)])"
pyobject(ex, obj)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import InterfaceInit
sage: ii = InterfaceInit(gp)
sage: f = 2+SR(I)
sage: ii.pyobject(f, f.pyobject())
'I + 2'

sage: ii.pyobject(SR(2), 2)
'2'

sage: ii.pyobject(pi, pi.pyobject())
'Pi'
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import InterfaceInit
>>> ii = InterfaceInit(gp)
>>> f = Integer(2)+SR(I)
>>> ii.pyobject(f, f.pyobject())
'I + 2'

>>> ii.pyobject(SR(Integer(2)), Integer(2))
'2'

>>> ii.pyobject(pi, pi.pyobject())
'Pi'
relation(ex, operator)[source]

EXAMPLES:

sage: import operator
sage: from sage.symbolic.expression_conversions import InterfaceInit
sage: m = InterfaceInit(maxima)
sage: m.relation(x==3, operator.eq)
'_SAGE_VAR_x = 3'
sage: m.relation(x==3, operator.lt)
'_SAGE_VAR_x < 3'
>>> from sage.all import *
>>> import operator
>>> from sage.symbolic.expression_conversions import InterfaceInit
>>> m = InterfaceInit(maxima)
>>> m.relation(x==Integer(3), operator.eq)
'_SAGE_VAR_x = 3'
>>> m.relation(x==Integer(3), operator.lt)
'_SAGE_VAR_x < 3'
symbol(ex)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import InterfaceInit
sage: m = InterfaceInit(maxima)
sage: m.symbol(x)
'_SAGE_VAR_x'
sage: f(x) = x
sage: m.symbol(f)
'_SAGE_VAR_x'
sage: ii = InterfaceInit(gp)
sage: ii.symbol(x)
'x'
sage: g = InterfaceInit(giac)
sage: g.symbol(x)
'sageVARx'
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import InterfaceInit
>>> m = InterfaceInit(maxima)
>>> m.symbol(x)
'_SAGE_VAR_x'
>>> __tmp__=var("x"); f = symbolic_expression(x).function(x)
>>> m.symbol(f)
'_SAGE_VAR_x'
>>> ii = InterfaceInit(gp)
>>> ii.symbol(x)
'x'
>>> g = InterfaceInit(giac)
>>> g.symbol(x)
'sageVARx'
tuple(ex)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import InterfaceInit
sage: m = InterfaceInit(maxima)
sage: t = SR._force_pyobject((3, 4, e^x))
sage: m.tuple(t)
'[3,4,exp(_SAGE_VAR_x)]'
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import InterfaceInit
>>> m = InterfaceInit(maxima)
>>> t = SR._force_pyobject((Integer(3), Integer(4), e**x))
>>> m.tuple(t)
'[3,4,exp(_SAGE_VAR_x)]'
class sage.symbolic.expression_conversions.LaurentPolynomialConverter(ex, base_ring=None, ring=None)[source]

Bases: PolynomialConverter

A converter from symbolic expressions to Laurent polynomials.

See laurent_polynomial() for details.

class sage.symbolic.expression_conversions.PolynomialConverter(ex, base_ring=None, ring=None)[source]

Bases: Converter

A converter from symbolic expressions to polynomials.

See polynomial() for details.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import PolynomialConverter
sage: x, y = var('x,y')
sage: p = PolynomialConverter(x+y, base_ring=QQ)
sage: p.base_ring
Rational Field
sage: p.ring
Multivariate Polynomial Ring in x, y over Rational Field

sage: p = PolynomialConverter(x, base_ring=QQ)
sage: p.base_ring
Rational Field
sage: p.ring
Univariate Polynomial Ring in x over Rational Field

sage: p = PolynomialConverter(x, ring=QQ['x,y'])
sage: p.base_ring
Rational Field
sage: p.ring
Multivariate Polynomial Ring in x, y over Rational Field

sage: p = PolynomialConverter(x+y, ring=QQ['x'])
Traceback (most recent call last):
...
TypeError: y is not a variable of Univariate Polynomial Ring in x over Rational Field
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import PolynomialConverter
>>> x, y = var('x,y')
>>> p = PolynomialConverter(x+y, base_ring=QQ)
>>> p.base_ring
Rational Field
>>> p.ring
Multivariate Polynomial Ring in x, y over Rational Field

>>> p = PolynomialConverter(x, base_ring=QQ)
>>> p.base_ring
Rational Field
>>> p.ring
Univariate Polynomial Ring in x over Rational Field

>>> p = PolynomialConverter(x, ring=QQ['x,y'])
>>> p.base_ring
Rational Field
>>> p.ring
Multivariate Polynomial Ring in x, y over Rational Field

>>> p = PolynomialConverter(x+y, ring=QQ['x'])
Traceback (most recent call last):
...
TypeError: y is not a variable of Univariate Polynomial Ring in x over Rational Field
arithmetic(ex, operator)[source]

EXAMPLES:

sage: import operator
sage: from sage.symbolic.expression_conversions import PolynomialConverter

sage: x, y = var('x, y')
sage: p = PolynomialConverter(x, base_ring=RR)
sage: p.arithmetic(pi+e, operator.add)
5.85987448204884
sage: p.arithmetic(x^2, operator.pow)
x^2

sage: p = PolynomialConverter(x+y, base_ring=RR)
sage: p.arithmetic(x*y+y^2, operator.add)
x*y + y^2

sage: p = PolynomialConverter(y^(3/2), ring=SR['x'])
sage: p.arithmetic(y^(3/2), operator.pow)
y^(3/2)
sage: _.parent()
Symbolic Ring
>>> from sage.all import *
>>> import operator
>>> from sage.symbolic.expression_conversions import PolynomialConverter

>>> x, y = var('x, y')
>>> p = PolynomialConverter(x, base_ring=RR)
>>> p.arithmetic(pi+e, operator.add)
5.85987448204884
>>> p.arithmetic(x**Integer(2), operator.pow)
x^2

>>> p = PolynomialConverter(x+y, base_ring=RR)
>>> p.arithmetic(x*y+y**Integer(2), operator.add)
x*y + y^2

>>> p = PolynomialConverter(y**(Integer(3)/Integer(2)), ring=SR['x'])
>>> p.arithmetic(y**(Integer(3)/Integer(2)), operator.pow)
y^(3/2)
>>> _.parent()
Symbolic Ring
composition(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import PolynomialConverter
sage: a = sin(2)
sage: p = PolynomialConverter(a*x, base_ring=RR)
sage: p.composition(a, a.operator())
0.909297426825682
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import PolynomialConverter
>>> a = sin(Integer(2))
>>> p = PolynomialConverter(a*x, base_ring=RR)
>>> p.composition(a, a.operator())
0.909297426825682
pyobject(ex, obj)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import PolynomialConverter
sage: p = PolynomialConverter(x, base_ring=QQ)
sage: f = SR(2)
sage: p.pyobject(f, f.pyobject())
2
sage: _.parent()
Rational Field
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import PolynomialConverter
>>> p = PolynomialConverter(x, base_ring=QQ)
>>> f = SR(Integer(2))
>>> p.pyobject(f, f.pyobject())
2
>>> _.parent()
Rational Field
relation(ex, op)[source]

EXAMPLES:

sage: import operator
sage: from sage.symbolic.expression_conversions import PolynomialConverter

sage: x, y = var('x, y')
sage: p = PolynomialConverter(x, base_ring=RR)

sage: p.relation(x==3, operator.eq)
x - 3.00000000000000
sage: p.relation(x==3, operator.lt)
Traceback (most recent call last):
...
ValueError: Unable to represent as a polynomial

sage: p = PolynomialConverter(x - y, base_ring=QQ)
sage: p.relation(x^2 - y^3 + 1 == x^3, operator.eq)
-x^3 - y^3 + x^2 + 1
>>> from sage.all import *
>>> import operator
>>> from sage.symbolic.expression_conversions import PolynomialConverter

>>> x, y = var('x, y')
>>> p = PolynomialConverter(x, base_ring=RR)

>>> p.relation(x==Integer(3), operator.eq)
x - 3.00000000000000
>>> p.relation(x==Integer(3), operator.lt)
Traceback (most recent call last):
...
ValueError: Unable to represent as a polynomial

>>> p = PolynomialConverter(x - y, base_ring=QQ)
>>> p.relation(x**Integer(2) - y**Integer(3) + Integer(1) == x**Integer(3), operator.eq)
-x^3 - y^3 + x^2 + 1
symbol(ex)[source]

Return a variable in the polynomial ring.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import PolynomialConverter
sage: p = PolynomialConverter(x, base_ring=QQ)
sage: p.symbol(x)
x
sage: _.parent()
Univariate Polynomial Ring in x over Rational Field
sage: y = var('y')
sage: p = PolynomialConverter(x*y, ring=SR['x'])
sage: p.symbol(y)
y
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import PolynomialConverter
>>> p = PolynomialConverter(x, base_ring=QQ)
>>> p.symbol(x)
x
>>> _.parent()
Univariate Polynomial Ring in x over Rational Field
>>> y = var('y')
>>> p = PolynomialConverter(x*y, ring=SR['x'])
>>> p.symbol(y)
y
class sage.symbolic.expression_conversions.RingConverter(R, subs_dict=None)[source]

Bases: Converter

A class to convert expressions to other rings.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import RingConverter
sage: R = RingConverter(RIF, subs_dict={x:2})
sage: R.ring
Real Interval Field with 53 bits of precision
sage: R.subs_dict
{x: 2}
sage: R(pi+e)
5.85987448204884?
sage: loads(dumps(R))
<sage.symbolic.expression_conversions.RingConverter object at 0x...>
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import RingConverter
>>> R = RingConverter(RIF, subs_dict={x:Integer(2)})
>>> R.ring
Real Interval Field with 53 bits of precision
>>> R.subs_dict
{x: 2}
>>> R(pi+e)
5.85987448204884?
>>> loads(dumps(R))
<sage.symbolic.expression_conversions.RingConverter object at 0x...>
arithmetic(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import RingConverter
sage: P.<z> = ZZ[]
sage: R = RingConverter(P, subs_dict={x:z})
sage: a = 2*x^2 + x + 3
sage: R(a)
2*z^2 + z + 3
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import RingConverter
>>> P = ZZ['z']; (z,) = P._first_ngens(1)
>>> R = RingConverter(P, subs_dict={x:z})
>>> a = Integer(2)*x**Integer(2) + x + Integer(3)
>>> R(a)
2*z^2 + z + 3
composition(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import RingConverter
sage: R = RingConverter(RIF)
sage: R(cos(2))
-0.4161468365471424?
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import RingConverter
>>> R = RingConverter(RIF)
>>> R(cos(Integer(2)))
-0.4161468365471424?
pyobject(ex, obj)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import RingConverter
sage: R = RingConverter(RIF)
sage: R(SR(5/2))
2.5000000000000000?
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import RingConverter
>>> R = RingConverter(RIF)
>>> R(SR(Integer(5)/Integer(2)))
2.5000000000000000?
symbol(ex)[source]

All symbols appearing in the expression must either appear in subs_dict or be convertible by the ring’s element constructor in order for the conversion to be successful.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import RingConverter
sage: R = RingConverter(RIF, subs_dict={x:2})
sage: R(x+pi)
5.141592653589794?

sage: R = RingConverter(RIF)
sage: R(x+pi)
Traceback (most recent call last):
...
TypeError: unable to simplify to a real interval approximation

sage: R = RingConverter(QQ['x'])
sage: R(x^2+x)
x^2 + x
sage: R(x^2+x).parent()
Univariate Polynomial Ring in x over Rational Field
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import RingConverter
>>> R = RingConverter(RIF, subs_dict={x:Integer(2)})
>>> R(x+pi)
5.141592653589794?

>>> R = RingConverter(RIF)
>>> R(x+pi)
Traceback (most recent call last):
...
TypeError: unable to simplify to a real interval approximation

>>> R = RingConverter(QQ['x'])
>>> R(x**Integer(2)+x)
x^2 + x
>>> R(x**Integer(2)+x).parent()
Univariate Polynomial Ring in x over Rational Field
class sage.symbolic.expression_conversions.SubstituteFunction(ex, *args)[source]

Bases: ExpressionTreeWalker

A class that walks the tree and replaces occurrences of a function with another.

EXAMPLES:

sage: from sage.symbolic.expression_conversions import SubstituteFunction
sage: foo = function('foo'); bar = function('bar')
sage: s = SubstituteFunction(foo(x), {foo: bar})
sage: s(1/foo(foo(x)) + foo(2))
1/bar(bar(x)) + bar(2)
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import SubstituteFunction
>>> foo = function('foo'); bar = function('bar')
>>> s = SubstituteFunction(foo(x), {foo: bar})
>>> s(Integer(1)/foo(foo(x)) + foo(Integer(2)))
1/bar(bar(x)) + bar(2)
composition(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import SubstituteFunction
sage: foo = function('foo'); bar = function('bar')
sage: s = SubstituteFunction(foo(x), {foo: bar})
sage: f = foo(x)
sage: s.composition(f, f.operator())
bar(x)
sage: f = foo(foo(x))
sage: s.composition(f, f.operator())
bar(bar(x))
sage: f = sin(foo(x))
sage: s.composition(f, f.operator())
sin(bar(x))
sage: f = foo(sin(x))
sage: s.composition(f, f.operator())
bar(sin(x))
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import SubstituteFunction
>>> foo = function('foo'); bar = function('bar')
>>> s = SubstituteFunction(foo(x), {foo: bar})
>>> f = foo(x)
>>> s.composition(f, f.operator())
bar(x)
>>> f = foo(foo(x))
>>> s.composition(f, f.operator())
bar(bar(x))
>>> f = sin(foo(x))
>>> s.composition(f, f.operator())
sin(bar(x))
>>> f = foo(sin(x))
>>> s.composition(f, f.operator())
bar(sin(x))
derivative(ex, operator)[source]

EXAMPLES:

sage: from sage.symbolic.expression_conversions import SubstituteFunction
sage: foo = function('foo'); bar = function('bar')
sage: s = SubstituteFunction(foo(x), {foo: bar})
sage: f = foo(x).diff(x)
sage: s.derivative(f, f.operator())
diff(bar(x), x)
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import SubstituteFunction
>>> foo = function('foo'); bar = function('bar')
>>> s = SubstituteFunction(foo(x), {foo: bar})
>>> f = foo(x).diff(x)
>>> s.derivative(f, f.operator())
diff(bar(x), x)
sage.symbolic.expression_conversions.fast_callable(ex, etb)[source]

Given an ExpressionTreeBuilder etb, return an Expression representing the symbolic expression ex.

EXAMPLES:

sage: from sage.ext.fast_callable import ExpressionTreeBuilder
sage: etb = ExpressionTreeBuilder(vars=['x','y'])
sage: x,y = var('x,y')
sage: f = y+2*x^2
sage: f._fast_callable_(etb)
add(mul(ipow(v_0, 2), 2), v_1)

sage: f = (2*x^3+2*x-1)/((x-2)*(x+1))
sage: f._fast_callable_(etb)
div(add(add(mul(ipow(v_0, 3), 2), mul(v_0, 2)), -1), mul(add(v_0, 1), add(v_0, -2)))
>>> from sage.all import *
>>> from sage.ext.fast_callable import ExpressionTreeBuilder
>>> etb = ExpressionTreeBuilder(vars=['x','y'])
>>> x,y = var('x,y')
>>> f = y+Integer(2)*x**Integer(2)
>>> f._fast_callable_(etb)
add(mul(ipow(v_0, 2), 2), v_1)

>>> f = (Integer(2)*x**Integer(3)+Integer(2)*x-Integer(1))/((x-Integer(2))*(x+Integer(1)))
>>> f._fast_callable_(etb)
div(add(add(mul(ipow(v_0, 3), 2), mul(v_0, 2)), -1), mul(add(v_0, 1), add(v_0, -2)))
sage.symbolic.expression_conversions.laurent_polynomial(ex, base_ring=None, ring=None)[source]

Return a Laurent polynomial from the symbolic expression ex.

INPUT:

  • ex – a symbolic expression

  • base_ring, ring – either a base_ring or a Laurent polynomial ring can be specified for the parent of result. If just a base_ring is given, then the variables of the base_ring will be the variables of the expression ex.

OUTPUT: a Laurent polynomial

EXAMPLES:

sage: from sage.symbolic.expression_conversions import laurent_polynomial
sage: f = x^2 + 2/x
sage: laurent_polynomial(f, base_ring=QQ)
2*x^-1 + x^2
sage: _.parent()
Univariate Laurent Polynomial Ring in x over Rational Field

sage: laurent_polynomial(f, ring=LaurentPolynomialRing(QQ, 'x, y'))
x^2 + 2*x^-1
sage: _.parent()
Multivariate Laurent Polynomial Ring in x, y over Rational Field

sage: x, y = var('x, y')
sage: laurent_polynomial(x + 1/y^2, ring=LaurentPolynomialRing(QQ, 'x, y'))
x + y^-2
sage: _.parent()
Multivariate Laurent Polynomial Ring in x, y over Rational Field
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import laurent_polynomial
>>> f = x**Integer(2) + Integer(2)/x
>>> laurent_polynomial(f, base_ring=QQ)
2*x^-1 + x^2
>>> _.parent()
Univariate Laurent Polynomial Ring in x over Rational Field

>>> laurent_polynomial(f, ring=LaurentPolynomialRing(QQ, 'x, y'))
x^2 + 2*x^-1
>>> _.parent()
Multivariate Laurent Polynomial Ring in x, y over Rational Field

>>> x, y = var('x, y')
>>> laurent_polynomial(x + Integer(1)/y**Integer(2), ring=LaurentPolynomialRing(QQ, 'x, y'))
x + y^-2
>>> _.parent()
Multivariate Laurent Polynomial Ring in x, y over Rational Field
sage.symbolic.expression_conversions.polynomial(ex, base_ring=None, ring=None)[source]

Return a polynomial from the symbolic expression ex.

INPUT:

  • ex – a symbolic expression

  • base_ring, ring – either a base_ring or a polynomial ring can be specified for the parent of result. If just a base_ring is given, then the variables of the base_ring will be the variables of the expression ex.

OUTPUT: a polynomial

EXAMPLES:

sage: from sage.symbolic.expression_conversions import polynomial
sage: f = x^2 + 2
sage: polynomial(f, base_ring=QQ)
x^2 + 2
sage: _.parent()
Univariate Polynomial Ring in x over Rational Field

sage: polynomial(f, ring=QQ['x,y'])
x^2 + 2
sage: _.parent()
Multivariate Polynomial Ring in x, y over Rational Field

sage: x, y = var('x, y')
sage: polynomial(x + y^2, ring=QQ['x,y'])
y^2 + x
sage: _.parent()
Multivariate Polynomial Ring in x, y over Rational Field

sage: s,t = var('s,t')
sage: expr = t^2-2*s*t+1
sage: expr.polynomial(None,ring=SR['t'])
t^2 - 2*s*t + 1
sage: _.parent()
Univariate Polynomial Ring in t over Symbolic Ring

sage: polynomial(x*y, ring=SR['x'])
y*x

sage: polynomial(y - sqrt(x), ring=SR['y'])
y - sqrt(x)
sage: _.list()
[-sqrt(x), 1]
>>> from sage.all import *
>>> from sage.symbolic.expression_conversions import polynomial
>>> f = x**Integer(2) + Integer(2)
>>> polynomial(f, base_ring=QQ)
x^2 + 2
>>> _.parent()
Univariate Polynomial Ring in x over Rational Field

>>> polynomial(f, ring=QQ['x,y'])
x^2 + 2
>>> _.parent()
Multivariate Polynomial Ring in x, y over Rational Field

>>> x, y = var('x, y')
>>> polynomial(x + y**Integer(2), ring=QQ['x,y'])
y^2 + x
>>> _.parent()
Multivariate Polynomial Ring in x, y over Rational Field

>>> s,t = var('s,t')
>>> expr = t**Integer(2)-Integer(2)*s*t+Integer(1)
>>> expr.polynomial(None,ring=SR['t'])
t^2 - 2*s*t + 1
>>> _.parent()
Univariate Polynomial Ring in t over Symbolic Ring

>>> polynomial(x*y, ring=SR['x'])
y*x

>>> polynomial(y - sqrt(x), ring=SR['y'])
y - sqrt(x)
>>> _.list()
[-sqrt(x), 1]

The polynomials can have arbitrary (constant) coefficients so long as they coerce into the base ring:

sage: polynomial(2^sin(2)*x^2 + exp(3), base_ring=RR)
1.87813065119873*x^2 + 20.0855369231877
>>> from sage.all import *
>>> polynomial(Integer(2)**sin(Integer(2))*x**Integer(2) + exp(Integer(3)), base_ring=RR)
1.87813065119873*x^2 + 20.0855369231877