Symbolic Expressions

RELATIONAL EXPRESSIONS:

We create a relational expression:

sage: x = var('x')
sage: eqn = (x-1)^2 <= x^2 - 2*x + 3
sage: eqn.subs(x == 5)
16 <= 18
>>> from sage.all import *
>>> x = var('x')
>>> eqn = (x-Integer(1))**Integer(2) <= x**Integer(2) - Integer(2)*x + Integer(3)
>>> eqn.subs(x == Integer(5))
16 <= 18

Notice that squaring the relation squares both sides.

sage: eqn^2
(x - 1)^4 <= (x^2 - 2*x + 3)^2
sage: eqn.expand()
x^2 - 2*x + 1 <= x^2 - 2*x + 3
>>> from sage.all import *
>>> eqn**Integer(2)
(x - 1)^4 <= (x^2 - 2*x + 3)^2
>>> eqn.expand()
x^2 - 2*x + 1 <= x^2 - 2*x + 3

This can transform a true relation into a false one:

sage: eqn = SR(-5) < SR(-3); eqn
-5 < -3
sage: bool(eqn)
True
sage: eqn^2
25 < 9
sage: bool(eqn^2)
False
>>> from sage.all import *
>>> eqn = SR(-Integer(5)) < SR(-Integer(3)); eqn
-5 < -3
>>> bool(eqn)
True
>>> eqn**Integer(2)
25 < 9
>>> bool(eqn**Integer(2))
False

We can do arithmetic with relations:

sage: e = x+1 <= x-2
sage: e + 2
x + 3 <= x
sage: e - 1
x <= x - 3
sage: e*(-1)
-x - 1 <= -x + 2
sage: (-2)*e
-2*x - 2 <= -2*x + 4
sage: e*5
5*x + 5 <= 5*x - 10
sage: e/5
1/5*x + 1/5 <= 1/5*x - 2/5
sage: 5/e
5/(x + 1) <= 5/(x - 2)
sage: e/(-2)
-1/2*x - 1/2 <= -1/2*x + 1
sage: -2/e
-2/(x + 1) <= -2/(x - 2)
>>> from sage.all import *
>>> e = x+Integer(1) <= x-Integer(2)
>>> e + Integer(2)
x + 3 <= x
>>> e - Integer(1)
x <= x - 3
>>> e*(-Integer(1))
-x - 1 <= -x + 2
>>> (-Integer(2))*e
-2*x - 2 <= -2*x + 4
>>> e*Integer(5)
5*x + 5 <= 5*x - 10
>>> e/Integer(5)
1/5*x + 1/5 <= 1/5*x - 2/5
>>> Integer(5)/e
5/(x + 1) <= 5/(x - 2)
>>> e/(-Integer(2))
-1/2*x - 1/2 <= -1/2*x + 1
>>> -Integer(2)/e
-2/(x + 1) <= -2/(x - 2)

We can even add together two relations, as long as the operators are the same:

sage: (x^3 + x <= x - 17)  + (-x <= x - 10)
x^3 <= 2*x - 27
>>> from sage.all import *
>>> (x**Integer(3) + x <= x - Integer(17))  + (-x <= x - Integer(10))
x^3 <= 2*x - 27

Here they are not:

sage: (x^3 + x <= x - 17)  + (-x >= x - 10)
Traceback (most recent call last):
...
TypeError: incompatible relations
>>> from sage.all import *
>>> (x**Integer(3) + x <= x - Integer(17))  + (-x >= x - Integer(10))
Traceback (most recent call last):
...
TypeError: incompatible relations

ARBITRARY SAGE ELEMENTS:

You can work symbolically with any Sage data type. This can lead to nonsense if the data type is strange, e.g., an element of a finite field (at present).

We mix Singular variables with symbolic variables:

sage: R.<u,v> = QQ[]
sage: var('a,b,c')
(a, b, c)
sage: expand((u + v + a + b + c)^2)
a^2 + 2*a*b + b^2 + 2*a*c + 2*b*c + c^2 + 2*a*u + 2*b*u + 2*c*u + u^2 + 2*a*v + 2*b*v + 2*c*v + 2*u*v + v^2
>>> from sage.all import *
>>> R = QQ['u, v']; (u, v,) = R._first_ngens(2)
>>> var('a,b,c')
(a, b, c)
>>> expand((u + v + a + b + c)**Integer(2))
a^2 + 2*a*b + b^2 + 2*a*c + 2*b*c + c^2 + 2*a*u + 2*b*u + 2*c*u + u^2 + 2*a*v + 2*b*v + 2*c*v + 2*u*v + v^2
class sage.symbolic.expression.E[source]

Bases: Expression

Dummy class to represent base of the natural logarithm.

The base of the natural logarithm e is not a constant in GiNaC/Sage. It is represented by exp(1).

This class provides a dummy object that behaves well under addition, multiplication, etc. and on exponentiation calls the function exp.

EXAMPLES:

The constant defined at the top level is just exp(1):

sage: e.operator()
exp
sage: e.operands()
[1]
>>> from sage.all import *
>>> e.operator()
exp
>>> e.operands()
[1]

Arithmetic works:

sage: e + 2
e + 2
sage: 2 + e
e + 2
sage: 2*e
2*e
sage: e*2
2*e
sage: x*e
x*e
sage: var('a,b')
(a, b)
sage: t = e^(a+b); t
e^(a + b)
sage: t.operands()
[a + b]
>>> from sage.all import *
>>> e + Integer(2)
e + 2
>>> Integer(2) + e
e + 2
>>> Integer(2)*e
2*e
>>> e*Integer(2)
2*e
>>> x*e
x*e
>>> var('a,b')
(a, b)
>>> t = e**(a+b); t
e^(a + b)
>>> t.operands()
[a + b]

Numeric evaluation, conversion to other systems, and pickling works as expected. Note that these are properties of the exp() function, not this class:

sage: RR(e)
2.71828182845905
sage: R = RealField(200); R
Real Field with 200 bits of precision
sage: R(e)
2.7182818284590452353602874713526624977572470936999595749670
sage: em = 1 + e^(1-e); em
e^(-e + 1) + 1
sage: R(em)
1.1793740787340171819619895873183164984596816017589156131574
sage: maxima(e).float()
2.718281828459045
sage: t = mathematica(e)               # optional - mathematica
sage: t                                # optional - mathematica
E
sage: float(t)                         # optional - mathematica
2.718281828459045...

sage: loads(dumps(e))
e

sage: float(e)
2.718281828459045...
sage: e.__float__()
2.718281828459045...
sage: e._mpfr_(RealField(100))
2.7182818284590452353602874714
sage: e._real_double_(RDF)   # abs tol 5e-16
2.718281828459045
sage: import sympy                                                          # needs sympy
sage: sympy.E == e  # indirect doctest                                      # needs sympy
True
>>> from sage.all import *
>>> RR(e)
2.71828182845905
>>> R = RealField(Integer(200)); R
Real Field with 200 bits of precision
>>> R(e)
2.7182818284590452353602874713526624977572470936999595749670
>>> em = Integer(1) + e**(Integer(1)-e); em
e^(-e + 1) + 1
>>> R(em)
1.1793740787340171819619895873183164984596816017589156131574
>>> maxima(e).float()
2.718281828459045
>>> t = mathematica(e)               # optional - mathematica
>>> t                                # optional - mathematica
E
>>> float(t)                         # optional - mathematica
2.718281828459045...

>>> loads(dumps(e))
e

>>> float(e)
2.718281828459045...
>>> e.__float__()
2.718281828459045...
>>> e._mpfr_(RealField(Integer(100)))
2.7182818284590452353602874714
>>> e._real_double_(RDF)   # abs tol 5e-16
2.718281828459045
>>> import sympy                                                          # needs sympy
>>> sympy.E == e  # indirect doctest                                      # needs sympy
True
class sage.symbolic.expression.Expression[source]

Bases: Expression

Nearly all expressions are created by calling new_Expression_from_*, but we need to make sure this at least does not leave self._gobj uninitialized and segfault.

Order(hold=False)[source]

Return the order of the expression, as in big oh notation.

OUTPUT: a symbolic expression

EXAMPLES:

sage: n = var('n')
sage: t = (17*n^3).Order(); t
Order(n^3)
sage: t.derivative(n)
Order(n^2)
>>> from sage.all import *
>>> n = var('n')
>>> t = (Integer(17)*n**Integer(3)).Order(); t
Order(n^3)
>>> t.derivative(n)
Order(n^2)

To prevent automatic evaluation use the hold argument:

sage: (17*n^3).Order(hold=True)
Order(17*n^3)
>>> from sage.all import *
>>> (Integer(17)*n**Integer(3)).Order(hold=True)
Order(17*n^3)
WZ_certificate(n, k)[source]

Return the Wilf-Zeilberger certificate for this hypergeometric summand in n, k.

To prove the identity \(\sum_k F(n,k)=\textrm{const}\) it suffices to show that \(F(n+1,k)-F(n,k)=G(n,k+1)-G(n,k),\) with \(G=RF\) and \(R\) the WZ certificate.

EXAMPLES:

To show that \(\sum_k \binom{n}{k} = 2^n\) do:

sage: _ = var('k n')
sage: F(n,k) = binomial(n,k) / 2^n
sage: c = F(n,k).WZ_certificate(n,k); c
1/2*k/(k - n - 1)
sage: G(n,k) = c * F(n,k); G
(n, k) |--> 1/2*k*binomial(n, k)/(2^n*(k - n - 1))
sage: (F(n+1,k) - F(n,k) - G(n,k+1) + G(n,k)).simplify_full()
0
>>> from sage.all import *
>>> _ = var('k n')
>>> __tmp__=var("n,k"); F = symbolic_expression(binomial(n,k) / Integer(2)**n).function(n,k)
>>> c = F(n,k).WZ_certificate(n,k); c
1/2*k/(k - n - 1)
>>> __tmp__=var("n,k"); G = symbolic_expression(c * F(n,k)).function(n,k); G
(n, k) |--> 1/2*k*binomial(n, k)/(2^n*(k - n - 1))
>>> (F(n+Integer(1),k) - F(n,k) - G(n,k+Integer(1)) + G(n,k)).simplify_full()
0
abs(hold=False)[source]

Return the absolute value of this expression.

EXAMPLES:

sage: var('x, y')
(x, y)
sage: (x+y).abs()
abs(x + y)
>>> from sage.all import *
>>> var('x, y')
(x, y)
>>> (x+y).abs()
abs(x + y)

Using the hold parameter it is possible to prevent automatic evaluation:

sage: SR(-5).abs(hold=True)
abs(-5)
>>> from sage.all import *
>>> SR(-Integer(5)).abs(hold=True)
abs(-5)

To then evaluate again, we use unhold():

sage: a = SR(-5).abs(hold=True); a.unhold()
5
>>> from sage.all import *
>>> a = SR(-Integer(5)).abs(hold=True); a.unhold()
5
add(hold=False, *args)[source]

Return the sum of the current expression and the given arguments.

To prevent automatic evaluation use the hold argument.

EXAMPLES:

sage: x.add(x)
2*x
sage: x.add(x, hold=True)
x + x
sage: x.add(x, (2+x), hold=True)
(x + 2) + x + x
sage: x.add(x, (2+x), x, hold=True)
(x + 2) + x + x + x
sage: x.add(x, (2+x), x, 2*x, hold=True)
(x + 2) + 2*x + x + x + x
>>> from sage.all import *
>>> x.add(x)
2*x
>>> x.add(x, hold=True)
x + x
>>> x.add(x, (Integer(2)+x), hold=True)
(x + 2) + x + x
>>> x.add(x, (Integer(2)+x), x, hold=True)
(x + 2) + x + x + x
>>> x.add(x, (Integer(2)+x), x, Integer(2)*x, hold=True)
(x + 2) + 2*x + x + x + x

To then evaluate again, we use unhold():

sage: a = x.add(x, hold=True); a.unhold()
2*x
>>> from sage.all import *
>>> a = x.add(x, hold=True); a.unhold()
2*x
add_to_both_sides(x)[source]

Return a relation obtained by adding x to both sides of this relation.

EXAMPLES:

sage: var('x y z')
(x, y, z)
sage: eqn = x^2 + y^2 + z^2 <= 1
sage: eqn.add_to_both_sides(-z^2)
x^2 + y^2 <= -z^2 + 1
sage: eqn.add_to_both_sides(I)
x^2 + y^2 + z^2 + I <= (I + 1)
>>> from sage.all import *
>>> var('x y z')
(x, y, z)
>>> eqn = x**Integer(2) + y**Integer(2) + z**Integer(2) <= Integer(1)
>>> eqn.add_to_both_sides(-z**Integer(2))
x^2 + y^2 <= -z^2 + 1
>>> eqn.add_to_both_sides(I)
x^2 + y^2 + z^2 + I <= (I + 1)
arccos(hold=False)[source]

Return the arc cosine of self.

EXAMPLES:

sage: x.arccos()
arccos(x)
sage: SR(1).arccos()
0
sage: SR(1/2).arccos()
1/3*pi
sage: SR(0.4).arccos()
1.15927948072741
sage: plot(lambda x: SR(x).arccos(), -1,1)                                  # needs sage.plot
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> x.arccos()
arccos(x)
>>> SR(Integer(1)).arccos()
0
>>> SR(Integer(1)/Integer(2)).arccos()
1/3*pi
>>> SR(RealNumber('0.4')).arccos()
1.15927948072741
>>> plot(lambda x: SR(x).arccos(), -Integer(1),Integer(1))                                  # needs sage.plot
Graphics object consisting of 1 graphics primitive

To prevent automatic evaluation use the hold argument:

sage: SR(1).arccos(hold=True)
arccos(1)
>>> from sage.all import *
>>> SR(Integer(1)).arccos(hold=True)
arccos(1)

This also works using functional notation:

sage: arccos(1, hold=True)
arccos(1)
sage: arccos(1)
0
>>> from sage.all import *
>>> arccos(Integer(1), hold=True)
arccos(1)
>>> arccos(Integer(1))
0

To then evaluate again, we use unhold():

sage: a = SR(1).arccos(hold=True); a.unhold()
0
>>> from sage.all import *
>>> a = SR(Integer(1)).arccos(hold=True); a.unhold()
0
arccosh(hold=False)[source]

Return the inverse hyperbolic cosine of self.

EXAMPLES:

sage: x.arccosh()
arccosh(x)
sage: SR(0).arccosh()
1/2*I*pi
sage: SR(1/2).arccosh()
arccosh(1/2)
sage: SR(CDF(1/2)).arccosh() #  rel tol 1e-15
1.0471975511965976*I
sage: z = maxima('acosh(0.5)')
sage: z.real(), z.imag()  # abs tol 1e-15
(0.0, 1.047197551196598)
>>> from sage.all import *
>>> x.arccosh()
arccosh(x)
>>> SR(Integer(0)).arccosh()
1/2*I*pi
>>> SR(Integer(1)/Integer(2)).arccosh()
arccosh(1/2)
>>> SR(CDF(Integer(1)/Integer(2))).arccosh() #  rel tol 1e-15
1.0471975511965976*I
>>> z = maxima('acosh(0.5)')
>>> z.real(), z.imag()  # abs tol 1e-15
(0.0, 1.047197551196598)

To prevent automatic evaluation use the hold argument:

sage: SR(-1).arccosh()
I*pi
sage: SR(-1).arccosh(hold=True)
arccosh(-1)
>>> from sage.all import *
>>> SR(-Integer(1)).arccosh()
I*pi
>>> SR(-Integer(1)).arccosh(hold=True)
arccosh(-1)

This also works using functional notation:

sage: arccosh(-1,hold=True)
arccosh(-1)
sage: arccosh(-1)
I*pi
>>> from sage.all import *
>>> arccosh(-Integer(1),hold=True)
arccosh(-1)
>>> arccosh(-Integer(1))
I*pi

To then evaluate again, we use unhold():

sage: a = SR(-1).arccosh(hold=True); a.unhold()
I*pi
>>> from sage.all import *
>>> a = SR(-Integer(1)).arccosh(hold=True); a.unhold()
I*pi
arcsin(hold=False)[source]

Return the arcsin of x, i.e., the number y between -pi and pi such that sin(y) == x.

EXAMPLES:

sage: x.arcsin()
arcsin(x)
sage: SR(0.5).arcsin()
1/6*pi
sage: SR(0.999).arcsin()
1.52607123962616
sage: SR(1/3).arcsin()
arcsin(1/3)
sage: SR(-1/3).arcsin()
-arcsin(1/3)
>>> from sage.all import *
>>> x.arcsin()
arcsin(x)
>>> SR(RealNumber('0.5')).arcsin()
1/6*pi
>>> SR(RealNumber('0.999')).arcsin()
1.52607123962616
>>> SR(Integer(1)/Integer(3)).arcsin()
arcsin(1/3)
>>> SR(-Integer(1)/Integer(3)).arcsin()
-arcsin(1/3)

To prevent automatic evaluation use the hold argument:

sage: SR(0).arcsin()
0
sage: SR(0).arcsin(hold=True)
arcsin(0)
>>> from sage.all import *
>>> SR(Integer(0)).arcsin()
0
>>> SR(Integer(0)).arcsin(hold=True)
arcsin(0)

This also works using functional notation:

sage: arcsin(0,hold=True)
arcsin(0)
sage: arcsin(0)
0
>>> from sage.all import *
>>> arcsin(Integer(0),hold=True)
arcsin(0)
>>> arcsin(Integer(0))
0

To then evaluate again, we use unhold():

sage: a = SR(0).arcsin(hold=True); a.unhold()
0
>>> from sage.all import *
>>> a = SR(Integer(0)).arcsin(hold=True); a.unhold()
0
arcsinh(hold=False)[source]

Return the inverse hyperbolic sine of self.

EXAMPLES:

sage: x.arcsinh()
arcsinh(x)
sage: SR(0).arcsinh()
0
sage: SR(1).arcsinh()
arcsinh(1)
sage: SR(1.0).arcsinh()
0.881373587019543
sage: maxima('asinh(2.0)')
1.4436354751788...
>>> from sage.all import *
>>> x.arcsinh()
arcsinh(x)
>>> SR(Integer(0)).arcsinh()
0
>>> SR(Integer(1)).arcsinh()
arcsinh(1)
>>> SR(RealNumber('1.0')).arcsinh()
0.881373587019543
>>> maxima('asinh(2.0)')
1.4436354751788...

Sage automatically applies certain identities:

sage: SR(3/2).arcsinh().cosh()
1/2*sqrt(13)
>>> from sage.all import *
>>> SR(Integer(3)/Integer(2)).arcsinh().cosh()
1/2*sqrt(13)

To prevent automatic evaluation use the hold argument:

sage: SR(-2).arcsinh()
-arcsinh(2)
sage: SR(-2).arcsinh(hold=True)
arcsinh(-2)
>>> from sage.all import *
>>> SR(-Integer(2)).arcsinh()
-arcsinh(2)
>>> SR(-Integer(2)).arcsinh(hold=True)
arcsinh(-2)

This also works using functional notation:

sage: arcsinh(-2,hold=True)
arcsinh(-2)
sage: arcsinh(-2)
-arcsinh(2)
>>> from sage.all import *
>>> arcsinh(-Integer(2),hold=True)
arcsinh(-2)
>>> arcsinh(-Integer(2))
-arcsinh(2)

To then evaluate again, we use unhold():

sage: a = SR(-2).arcsinh(hold=True); a.unhold()
-arcsinh(2)
>>> from sage.all import *
>>> a = SR(-Integer(2)).arcsinh(hold=True); a.unhold()
-arcsinh(2)
arctan(hold=False)[source]

Return the arc tangent of self.

EXAMPLES:

sage: x = var('x')
sage: x.arctan()
arctan(x)
sage: SR(1).arctan()
1/4*pi
sage: SR(1/2).arctan()
arctan(1/2)
sage: SR(0.5).arctan()
0.463647609000806
sage: plot(lambda x: SR(x).arctan(), -20,20)                                # needs sage.plot
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> x = var('x')
>>> x.arctan()
arctan(x)
>>> SR(Integer(1)).arctan()
1/4*pi
>>> SR(Integer(1)/Integer(2)).arctan()
arctan(1/2)
>>> SR(RealNumber('0.5')).arctan()
0.463647609000806
>>> plot(lambda x: SR(x).arctan(), -Integer(20),Integer(20))                                # needs sage.plot
Graphics object consisting of 1 graphics primitive

To prevent automatic evaluation use the hold argument:

sage: SR(1).arctan(hold=True)
arctan(1)
>>> from sage.all import *
>>> SR(Integer(1)).arctan(hold=True)
arctan(1)

This also works using functional notation:

sage: arctan(1, hold=True)
arctan(1)
sage: arctan(1)
1/4*pi
>>> from sage.all import *
>>> arctan(Integer(1), hold=True)
arctan(1)
>>> arctan(Integer(1))
1/4*pi

To then evaluate again, we use unhold():

sage: a = SR(1).arctan(hold=True); a.unhold()
1/4*pi
>>> from sage.all import *
>>> a = SR(Integer(1)).arctan(hold=True); a.unhold()
1/4*pi
arctan2(x, hold=False)[source]

Return the inverse of the 2-variable tan function on self and x.

EXAMPLES:

sage: var('x,y')
(x, y)
sage: x.arctan2(y)
arctan2(x, y)
sage: SR(1/2).arctan2(1/2)
1/4*pi
sage: maxima.eval('atan2(1/2,1/2)')
'%pi/4'

sage: SR(-0.7).arctan2(SR(-0.6))
-2.27942259892257
>>> from sage.all import *
>>> var('x,y')
(x, y)
>>> x.arctan2(y)
arctan2(x, y)
>>> SR(Integer(1)/Integer(2)).arctan2(Integer(1)/Integer(2))
1/4*pi
>>> maxima.eval('atan2(1/2,1/2)')
'%pi/4'

>>> SR(-RealNumber('0.7')).arctan2(SR(-RealNumber('0.6')))
-2.27942259892257

To prevent automatic evaluation use the hold argument:

sage: SR(1/2).arctan2(1/2, hold=True)
arctan2(1/2, 1/2)
>>> from sage.all import *
>>> SR(Integer(1)/Integer(2)).arctan2(Integer(1)/Integer(2), hold=True)
arctan2(1/2, 1/2)

This also works using functional notation:

sage: arctan2(1,2,hold=True)
arctan2(1, 2)
sage: arctan2(1,2)
arctan(1/2)
>>> from sage.all import *
>>> arctan2(Integer(1),Integer(2),hold=True)
arctan2(1, 2)
>>> arctan2(Integer(1),Integer(2))
arctan(1/2)

To then evaluate again, we use unhold():

sage: a = SR(1/2).arctan2(1/2, hold=True); a.unhold()
1/4*pi
>>> from sage.all import *
>>> a = SR(Integer(1)/Integer(2)).arctan2(Integer(1)/Integer(2), hold=True); a.unhold()
1/4*pi
arctanh(hold=False)[source]

Return the inverse hyperbolic tangent of self.

EXAMPLES:

sage: x.arctanh()
arctanh(x)
sage: SR(0).arctanh()
0
sage: SR(1/2).arctanh()
1/2*log(3)
sage: SR(0.5).arctanh()
0.549306144334055
sage: SR(0.5).arctanh().tanh()
0.500000000000000
sage: maxima('atanh(0.5)')  # abs tol 2e-16
0.5493061443340548
>>> from sage.all import *
>>> x.arctanh()
arctanh(x)
>>> SR(Integer(0)).arctanh()
0
>>> SR(Integer(1)/Integer(2)).arctanh()
1/2*log(3)
>>> SR(RealNumber('0.5')).arctanh()
0.549306144334055
>>> SR(RealNumber('0.5')).arctanh().tanh()
0.500000000000000
>>> maxima('atanh(0.5)')  # abs tol 2e-16
0.5493061443340548

To prevent automatic evaluation use the hold argument:

sage: SR(-1/2).arctanh()
-1/2*log(3)
sage: SR(-1/2).arctanh(hold=True)
arctanh(-1/2)
>>> from sage.all import *
>>> SR(-Integer(1)/Integer(2)).arctanh()
-1/2*log(3)
>>> SR(-Integer(1)/Integer(2)).arctanh(hold=True)
arctanh(-1/2)

This also works using functional notation:

sage: arctanh(-1/2,hold=True)
arctanh(-1/2)
sage: arctanh(-1/2)
-1/2*log(3)
>>> from sage.all import *
>>> arctanh(-Integer(1)/Integer(2),hold=True)
arctanh(-1/2)
>>> arctanh(-Integer(1)/Integer(2))
-1/2*log(3)

To then evaluate again, we use unhold():

sage: a = SR(-1/2).arctanh(hold=True); a.unhold()
-1/2*log(3)
>>> from sage.all import *
>>> a = SR(-Integer(1)/Integer(2)).arctanh(hold=True); a.unhold()
-1/2*log(3)
args()[source]

EXAMPLES:

sage: x,y = var('x,y')
sage: f = x + y
sage: f.arguments()
(x, y)

sage: g = f.function(x)
sage: g.arguments()
(x,)
>>> from sage.all import *
>>> x,y = var('x,y')
>>> f = x + y
>>> f.arguments()
(x, y)

>>> g = f.function(x)
>>> g.arguments()
(x,)
arguments()[source]

EXAMPLES:

sage: x,y = var('x,y')
sage: f = x + y
sage: f.arguments()
(x, y)

sage: g = f.function(x)
sage: g.arguments()
(x,)
>>> from sage.all import *
>>> x,y = var('x,y')
>>> f = x + y
>>> f.arguments()
(x, y)

>>> g = f.function(x)
>>> g.arguments()
(x,)
assume()[source]

Assume that this equation holds. This is relevant for symbolic integration, among other things.

EXAMPLES: We call the assume method to assume that \(x>2\):

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

bool returns True below if the inequality is definitely known to be true.

sage: bool(x > 0)
True
sage: bool(x < 0)
False
>>> from sage.all import *
>>> bool(x > Integer(0))
True
>>> bool(x < Integer(0))
False

This may or may not be True, so bool returns False:

sage: bool(x > 3)
False
>>> from sage.all import *
>>> bool(x > Integer(3))
False

If you make inconsistent or meaningless assumptions, Sage will let you know:

sage: forget()
sage: assume(x<0)
sage: assume(x>0)
Traceback (most recent call last):
...
ValueError: Assumption is inconsistent
sage: assumptions()
[x < 0]
sage: forget()
>>> from sage.all import *
>>> forget()
>>> assume(x<Integer(0))
>>> assume(x>Integer(0))
Traceback (most recent call last):
...
ValueError: Assumption is inconsistent
>>> assumptions()
[x < 0]
>>> forget()
binomial(k, hold=False)[source]

Return binomial coefficient “self choose k”.

OUTPUT: a symbolic expression

EXAMPLES:

sage: var('x, y')
(x, y)
sage: SR(5).binomial(SR(3))
10
sage: x.binomial(SR(3))
1/6*(x - 1)*(x - 2)*x
sage: x.binomial(y)
binomial(x, y)
>>> from sage.all import *
>>> var('x, y')
(x, y)
>>> SR(Integer(5)).binomial(SR(Integer(3)))
10
>>> x.binomial(SR(Integer(3)))
1/6*(x - 1)*(x - 2)*x
>>> x.binomial(y)
binomial(x, y)

To prevent automatic evaluation use the hold argument:

sage: x.binomial(3, hold=True)
binomial(x, 3)
sage: SR(5).binomial(3, hold=True)
binomial(5, 3)
>>> from sage.all import *
>>> x.binomial(Integer(3), hold=True)
binomial(x, 3)
>>> SR(Integer(5)).binomial(Integer(3), hold=True)
binomial(5, 3)

To then evaluate again, we use unhold():

sage: a = SR(5).binomial(3, hold=True); a.unhold()
10
>>> from sage.all import *
>>> a = SR(Integer(5)).binomial(Integer(3), hold=True); a.unhold()
10

The hold parameter is also supported in functional notation:

sage: binomial(5,3, hold=True)
binomial(5, 3)
>>> from sage.all import *
>>> binomial(Integer(5),Integer(3), hold=True)
binomial(5, 3)
canonicalize_radical()[source]

Choose a canonical branch of the given expression.

The square root, cube root, natural log, etc. functions are multi-valued. The canonicalize_radical() method will choose one of these values based on a heuristic.

For example, sqrt(x^2) has two values: x, and -x. The canonicalize_radical() function will choose one of them, consistently, based on the behavior of the expression as x tends to positive infinity. The solution chosen is the one which exhibits this same behavior. Since sqrt(x^2) approaches positive infinity as x does, the solution chosen is x (which also tends to positive infinity).

Warning

As shown in the examples below, a canonical form is not always returned, i.e., two mathematically identical expressions might be converted to different expressions.

Assumptions are not taken into account during the transformation. This may result in a branch choice inconsistent with your assumptions.

ALGORITHM:

This uses the Maxima radcan() command. From the Maxima documentation:

Simplifies an expression, which can contain logs, exponentials, and radicals, by converting it into a form which is canonical over a large class of expressions and a given ordering of variables; that is, all functionally equivalent forms are mapped into a unique form. For a somewhat larger class of expressions, radcan produces a regular form. Two equivalent expressions in this class do not necessarily have the same appearance, but their difference can be simplified by radcan to zero.

For some expressions radcan is quite time consuming. This is the cost of exploring certain relationships among the components of the expression for simplifications based on factoring and partial fraction expansions of exponents.

EXAMPLES:

canonicalize_radical() can perform some of the same manipulations as log_expand():

sage: y = SR.symbol('y')
sage: f = log(x*y)
sage: f.log_expand()
log(x) + log(y)
sage: f.canonicalize_radical()
log(x) + log(y)
>>> from sage.all import *
>>> y = SR.symbol('y')
>>> f = log(x*y)
>>> f.log_expand()
log(x) + log(y)
>>> f.canonicalize_radical()
log(x) + log(y)

And also handles some exponential functions:

sage: f = (e^x-1)/(1+e^(x/2))
sage: f.canonicalize_radical()
e^(1/2*x) - 1
>>> from sage.all import *
>>> f = (e**x-Integer(1))/(Integer(1)+e**(x/Integer(2)))
>>> f.canonicalize_radical()
e^(1/2*x) - 1

It can also be used to change the base of a logarithm when the arguments to log() are positive real numbers:

sage: f = log(8)/log(2)
sage: f.canonicalize_radical()
3
>>> from sage.all import *
>>> f = log(Integer(8))/log(Integer(2))
>>> f.canonicalize_radical()
3

sage: a = SR.symbol('a')
sage: f = (log(x+x^2)-log(x))^a/log(1+x)^(a/2)
sage: f.canonicalize_radical()
log(x + 1)^(1/2*a)
>>> from sage.all import *
>>> a = SR.symbol('a')
>>> f = (log(x+x**Integer(2))-log(x))**a/log(Integer(1)+x)**(a/Integer(2))
>>> f.canonicalize_radical()
log(x + 1)^(1/2*a)

The simplest example of counter-intuitive behavior is what happens when we take the square root of a square:

sage: sqrt(x^2).canonicalize_radical()
x
>>> from sage.all import *
>>> sqrt(x**Integer(2)).canonicalize_radical()
x

If you don’t want this kind of “simplification,” don’t use canonicalize_radical().

This behavior can also be triggered when the expression under the radical is not given explicitly as a square:

sage: sqrt(x^2 - 2*x + 1).canonicalize_radical()
x - 1
>>> from sage.all import *
>>> sqrt(x**Integer(2) - Integer(2)*x + Integer(1)).canonicalize_radical()
x - 1

Another place where this can become confusing is with logarithms of complex numbers. Suppose x is complex with x == r*e^(I*t) (r real). Then log(x) is log(r) + I*(t + 2*k*pi) for some integer k.

Calling canonicalize_radical() will choose a branch, eliminating the solutions for all choices of k but one. Simplified by hand, the expression below is (1/2)*log(2) + I*pi*k for integer k. However, canonicalize_radical() will take each log expression, and choose one particular solution, dropping the other. When the results are subtracted, we’re left with no imaginary part:

sage: f = (1/2)*log(2*x) + (1/2)*log(1/x)
sage: f.canonicalize_radical()
1/2*log(2)
>>> from sage.all import *
>>> f = (Integer(1)/Integer(2))*log(Integer(2)*x) + (Integer(1)/Integer(2))*log(Integer(1)/x)
>>> f.canonicalize_radical()
1/2*log(2)

Naturally the result is wrong for some choices of x:

sage: f(x = -1)
I*pi + 1/2*log(2)
>>> from sage.all import *
>>> f(x = -Integer(1))
I*pi + 1/2*log(2)

The example below shows two expressions e1 and e2 which are “simplified” to different expressions, while their difference is “simplified” to zero; thus canonicalize_radical() does not return a canonical form:

sage: e1 = 1/(sqrt(5)+sqrt(2))
sage: e2 = (sqrt(5)-sqrt(2))/3
sage: e1.canonicalize_radical()
1/(sqrt(5) + sqrt(2))
sage: e2.canonicalize_radical()
1/3*sqrt(5) - 1/3*sqrt(2)
sage: (e1-e2).canonicalize_radical()
0
>>> from sage.all import *
>>> e1 = Integer(1)/(sqrt(Integer(5))+sqrt(Integer(2)))
>>> e2 = (sqrt(Integer(5))-sqrt(Integer(2)))/Integer(3)
>>> e1.canonicalize_radical()
1/(sqrt(5) + sqrt(2))
>>> e2.canonicalize_radical()
1/3*sqrt(5) - 1/3*sqrt(2)
>>> (e1-e2).canonicalize_radical()
0

The issue reported in Issue #3520 is a case where canonicalize_radical() causes a numerical integral to be calculated incorrectly:

sage: f1 = sqrt(25 - x) * sqrt( 1 + 1/(4*(25-x)) )
sage: f2 = f1.canonicalize_radical()
sage: numerical_integral(f1.real(), 0, 1)[0] # abs tol 1e-10
4.974852579915647
sage: numerical_integral(f2.real(), 0, 1)[0] # abs tol 1e-10
-4.974852579915647
>>> from sage.all import *
>>> f1 = sqrt(Integer(25) - x) * sqrt( Integer(1) + Integer(1)/(Integer(4)*(Integer(25)-x)) )
>>> f2 = f1.canonicalize_radical()
>>> numerical_integral(f1.real(), Integer(0), Integer(1))[Integer(0)] # abs tol 1e-10
4.974852579915647
>>> numerical_integral(f2.real(), Integer(0), Integer(1))[Integer(0)] # abs tol 1e-10
-4.974852579915647
coefficient(s, n=1)[source]

Return the coefficient of \(s^n\) in this symbolic expression.

INPUT:

  • s – expression

  • n – expression, default 1

OUTPUT: a symbolic expression. The coefficient of \(s^n\)

Sometimes it may be necessary to expand or factor first, since this is not done automatically.

EXAMPLES:

sage: var('x,y,a')
(x, y, a)
sage: f = 100 + a*x + x^3*sin(x*y) + x*y + x/y + 2*sin(x*y)/x; f
x^3*sin(x*y) + a*x + x*y + x/y + 2*sin(x*y)/x + 100
sage: f.collect(x)
x^3*sin(x*y) + (a + y + 1/y)*x + 2*sin(x*y)/x + 100
sage: f.coefficient(x,0)
100
sage: f.coefficient(x,-1)
2*sin(x*y)
sage: f.coefficient(x,1)
a + y + 1/y
sage: f.coefficient(x,2)
0
sage: f.coefficient(x,3)
sin(x*y)
sage: f.coefficient(x^3)
sin(x*y)
sage: f.coefficient(sin(x*y))
x^3 + 2/x
sage: f.collect(sin(x*y))
a*x + x*y + (x^3 + 2/x)*sin(x*y) + x/y + 100

sage: var('a, x, y, z')
(a, x, y, z)
sage: f = (a*sqrt(2))*x^2 + sin(y)*x^(1/2) + z^z
sage: f.coefficient(sin(y))
sqrt(x)
sage: f.coefficient(x^2)
sqrt(2)*a
sage: f.coefficient(x^(1/2))
sin(y)
sage: f.coefficient(1)
0
sage: f.coefficient(x, 0)
z^z
>>> from sage.all import *
>>> var('x,y,a')
(x, y, a)
>>> f = Integer(100) + a*x + x**Integer(3)*sin(x*y) + x*y + x/y + Integer(2)*sin(x*y)/x; f
x^3*sin(x*y) + a*x + x*y + x/y + 2*sin(x*y)/x + 100
>>> f.collect(x)
x^3*sin(x*y) + (a + y + 1/y)*x + 2*sin(x*y)/x + 100
>>> f.coefficient(x,Integer(0))
100
>>> f.coefficient(x,-Integer(1))
2*sin(x*y)
>>> f.coefficient(x,Integer(1))
a + y + 1/y
>>> f.coefficient(x,Integer(2))
0
>>> f.coefficient(x,Integer(3))
sin(x*y)
>>> f.coefficient(x**Integer(3))
sin(x*y)
>>> f.coefficient(sin(x*y))
x^3 + 2/x
>>> f.collect(sin(x*y))
a*x + x*y + (x^3 + 2/x)*sin(x*y) + x/y + 100

>>> var('a, x, y, z')
(a, x, y, z)
>>> f = (a*sqrt(Integer(2)))*x**Integer(2) + sin(y)*x**(Integer(1)/Integer(2)) + z**z
>>> f.coefficient(sin(y))
sqrt(x)
>>> f.coefficient(x**Integer(2))
sqrt(2)*a
>>> f.coefficient(x**(Integer(1)/Integer(2)))
sin(y)
>>> f.coefficient(Integer(1))
0
>>> f.coefficient(x, Integer(0))
z^z

Any coefficient can be queried:

sage: (x^2 + 3*x^pi).coefficient(x, pi)
3
sage: (2^x + 5*x^x).coefficient(x, x)
5
>>> from sage.all import *
>>> (x**Integer(2) + Integer(3)*x**pi).coefficient(x, pi)
3
>>> (Integer(2)**x + Integer(5)*x**x).coefficient(x, x)
5
coefficients(x=None, sparse=True)[source]

Return the coefficients of this symbolic expression as a polynomial in x.

INPUT:

  • x – (optional) variable

OUTPUT: depending on the value of sparse,

  • A list of pairs (expr, n), where expr is a symbolic expression and n is a power (sparse=True, default)

  • A list of expressions where the n-th element is the coefficient of x^n when self is seen as polynomial in x (sparse=False).

EXAMPLES:

sage: var('x, y, a')
(x, y, a)
sage: p = x^3 - (x-3)*(x^2+x) + 1
sage: p.coefficients()
[[1, 0], [3, 1], [2, 2]]
sage: p.coefficients(sparse=False)
[1, 3, 2]
sage: p = x - x^3 + 5/7*x^5
sage: p.coefficients()
[[1, 1], [-1, 3], [5/7, 5]]
sage: p.coefficients(sparse=False)
[0, 1, 0, -1, 0, 5/7]
sage: p = expand((x-a*sqrt(2))^2 + x + 1); p
-2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1
sage: p.coefficients(a)
[[x^2 + x + 1, 0], [-2*sqrt(2)*x, 1], [2, 2]]
sage: p.coefficients(a, sparse=False)
[x^2 + x + 1, -2*sqrt(2)*x, 2]
sage: p.coefficients(x)
[[2*a^2 + 1, 0], [-2*sqrt(2)*a + 1, 1], [1, 2]]
sage: p.coefficients(x, sparse=False)
[2*a^2 + 1, -2*sqrt(2)*a + 1, 1]
>>> from sage.all import *
>>> var('x, y, a')
(x, y, a)
>>> p = x**Integer(3) - (x-Integer(3))*(x**Integer(2)+x) + Integer(1)
>>> p.coefficients()
[[1, 0], [3, 1], [2, 2]]
>>> p.coefficients(sparse=False)
[1, 3, 2]
>>> p = x - x**Integer(3) + Integer(5)/Integer(7)*x**Integer(5)
>>> p.coefficients()
[[1, 1], [-1, 3], [5/7, 5]]
>>> p.coefficients(sparse=False)
[0, 1, 0, -1, 0, 5/7]
>>> p = expand((x-a*sqrt(Integer(2)))**Integer(2) + x + Integer(1)); p
-2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1
>>> p.coefficients(a)
[[x^2 + x + 1, 0], [-2*sqrt(2)*x, 1], [2, 2]]
>>> p.coefficients(a, sparse=False)
[x^2 + x + 1, -2*sqrt(2)*x, 2]
>>> p.coefficients(x)
[[2*a^2 + 1, 0], [-2*sqrt(2)*a + 1, 1], [1, 2]]
>>> p.coefficients(x, sparse=False)
[2*a^2 + 1, -2*sqrt(2)*a + 1, 1]
collect(s)[source]

Collect the coefficients of s into a group.

INPUT:

  • s – the symbol whose coefficients will be collected

OUTPUT:

A new expression, equivalent to the original one, with the coefficients of s grouped.

Note

The expression is not expanded or factored before the grouping takes place. For best results, call expand() on the expression before collect().

EXAMPLES:

In the first term of \(f\), \(x\) has a coefficient of \(4y\). In the second term, \(x\) has a coefficient of \(z\). Therefore, if we collect those coefficients, \(x\) will have a coefficient of \(4y+z\):

sage: x,y,z = var('x,y,z')
sage: f = 4*x*y + x*z + 20*y^2 + 21*y*z + 4*z^2 + x^2*y^2*z^2
sage: f.collect(x)
x^2*y^2*z^2 + x*(4*y + z) + 20*y^2 + 21*y*z + 4*z^2
>>> from sage.all import *
>>> x,y,z = var('x,y,z')
>>> f = Integer(4)*x*y + x*z + Integer(20)*y**Integer(2) + Integer(21)*y*z + Integer(4)*z**Integer(2) + x**Integer(2)*y**Integer(2)*z**Integer(2)
>>> f.collect(x)
x^2*y^2*z^2 + x*(4*y + z) + 20*y^2 + 21*y*z + 4*z^2

Here we do the same thing for \(y\) and \(z\); however, note that we do not factor the \(y^{2}\) and \(z^{2}\) terms before collecting coefficients:

sage: f.collect(y)
(x^2*z^2 + 20)*y^2 + (4*x + 21*z)*y + x*z + 4*z^2
sage: f.collect(z)
(x^2*y^2 + 4)*z^2 + 4*x*y + 20*y^2 + (x + 21*y)*z
>>> from sage.all import *
>>> f.collect(y)
(x^2*z^2 + 20)*y^2 + (4*x + 21*z)*y + x*z + 4*z^2
>>> f.collect(z)
(x^2*y^2 + 4)*z^2 + 4*x*y + 20*y^2 + (x + 21*y)*z

The terms are collected, whether the expression is expanded or not:

sage: f = (x + y)*(x - z)
sage: f.collect(x)
x^2 + x*(y - z) - y*z
sage: f.expand().collect(x)
x^2 + x*(y - z) - y*z
>>> from sage.all import *
>>> f = (x + y)*(x - z)
>>> f.collect(x)
x^2 + x*(y - z) - y*z
>>> f.expand().collect(x)
x^2 + x*(y - z) - y*z
collect_common_factors()[source]

This function does not perform a full factorization but only looks for factors which are already explicitly present.

Polynomials can often be brought into a more compact form by collecting common factors from the terms of sums. This is accomplished by this function.

EXAMPLES:

sage: var('x')
x
sage: (x/(x^2 + x)).collect_common_factors()
1/(x + 1)

sage: var('a,b,c,x,y')
(a, b, c, x, y)
sage: (a*x+a*y).collect_common_factors()
a*(x + y)
sage: (a*x^2+2*a*x*y+a*y^2).collect_common_factors()
(x^2 + 2*x*y + y^2)*a
sage: (a*(b*(a+c)*x+b*((a+c)*x+(a+c)*y)*y)).collect_common_factors()
((x + y)*y + x)*(a + c)*a*b
>>> from sage.all import *
>>> var('x')
x
>>> (x/(x**Integer(2) + x)).collect_common_factors()
1/(x + 1)

>>> var('a,b,c,x,y')
(a, b, c, x, y)
>>> (a*x+a*y).collect_common_factors()
a*(x + y)
>>> (a*x**Integer(2)+Integer(2)*a*x*y+a*y**Integer(2)).collect_common_factors()
(x^2 + 2*x*y + y^2)*a
>>> (a*(b*(a+c)*x+b*((a+c)*x+(a+c)*y)*y)).collect_common_factors()
((x + y)*y + x)*(a + c)*a*b
combine(deep=False)[source]

Return a simplified version of this symbolic expression by combining all toplevel terms with the same denominator into a single term.

Please use the keyword deep=True to apply the process recursively.

EXAMPLES:

sage: var('x, y, a, b, c')
(x, y, a, b, c)
sage: f = x*(x-1)/(x^2 - 7) + y^2/(x^2-7) + 1/(x+1) + b/a + c/a; f
(x - 1)*x/(x^2 - 7) + y^2/(x^2 - 7) + b/a + c/a + 1/(x + 1)
sage: f.combine()
((x - 1)*x + y^2)/(x^2 - 7) + (b + c)/a + 1/(x + 1)
sage: (1/x + 1/x^2 + (x+1)/x).combine()
(x + 2)/x + 1/x^2
sage: ex = 1/x + ((x + 1)/x - 1/x)/x^2 + (x+1)/x; ex
(x + 1)/x + 1/x + ((x + 1)/x - 1/x)/x^2
sage: ex.combine()
(x + 2)/x + ((x + 1)/x - 1/x)/x^2
sage: ex.combine(deep=True)
(x + 2)/x + 1/x^2
sage: (1+sin((x + 1)/x - 1/x)).combine(deep=True)
sin(1) + 1
>>> from sage.all import *
>>> var('x, y, a, b, c')
(x, y, a, b, c)
>>> f = x*(x-Integer(1))/(x**Integer(2) - Integer(7)) + y**Integer(2)/(x**Integer(2)-Integer(7)) + Integer(1)/(x+Integer(1)) + b/a + c/a; f
(x - 1)*x/(x^2 - 7) + y^2/(x^2 - 7) + b/a + c/a + 1/(x + 1)
>>> f.combine()
((x - 1)*x + y^2)/(x^2 - 7) + (b + c)/a + 1/(x + 1)
>>> (Integer(1)/x + Integer(1)/x**Integer(2) + (x+Integer(1))/x).combine()
(x + 2)/x + 1/x^2
>>> ex = Integer(1)/x + ((x + Integer(1))/x - Integer(1)/x)/x**Integer(2) + (x+Integer(1))/x; ex
(x + 1)/x + 1/x + ((x + 1)/x - 1/x)/x^2
>>> ex.combine()
(x + 2)/x + ((x + 1)/x - 1/x)/x^2
>>> ex.combine(deep=True)
(x + 2)/x + 1/x^2
>>> (Integer(1)+sin((x + Integer(1))/x - Integer(1)/x)).combine(deep=True)
sin(1) + 1
conjugate(hold=False)[source]

Return the complex conjugate of this symbolic expression.

EXAMPLES:

sage: a = 1 + 2*I
sage: a.conjugate()
-2*I + 1
sage: a = sqrt(2) + 3^(1/3)*I; a
sqrt(2) + I*3^(1/3)
sage: a.conjugate()
sqrt(2) - I*3^(1/3)

sage: SR(CDF.0).conjugate()
-1.0*I
sage: x.conjugate()
conjugate(x)
sage: SR(RDF(1.5)).conjugate()
1.5
sage: SR(float(1.5)).conjugate()
1.5
sage: SR(I).conjugate()
-I
sage: ( 1+I  + (2-3*I)*x).conjugate()
(3*I + 2)*conjugate(x) - I + 1
>>> from sage.all import *
>>> a = Integer(1) + Integer(2)*I
>>> a.conjugate()
-2*I + 1
>>> a = sqrt(Integer(2)) + Integer(3)**(Integer(1)/Integer(3))*I; a
sqrt(2) + I*3^(1/3)
>>> a.conjugate()
sqrt(2) - I*3^(1/3)

>>> SR(CDF.gen(0)).conjugate()
-1.0*I
>>> x.conjugate()
conjugate(x)
>>> SR(RDF(RealNumber('1.5'))).conjugate()
1.5
>>> SR(float(RealNumber('1.5'))).conjugate()
1.5
>>> SR(I).conjugate()
-I
>>> ( Integer(1)+I  + (Integer(2)-Integer(3)*I)*x).conjugate()
(3*I + 2)*conjugate(x) - I + 1

Using the hold parameter it is possible to prevent automatic evaluation:

sage: SR(I).conjugate(hold=True)
conjugate(I)
>>> from sage.all import *
>>> SR(I).conjugate(hold=True)
conjugate(I)

This also works in functional notation:

sage: conjugate(I)
-I
sage: conjugate(I,hold=True)
conjugate(I)
>>> from sage.all import *
>>> conjugate(I)
-I
>>> conjugate(I,hold=True)
conjugate(I)

To then evaluate again, we use unhold():

sage: a = SR(I).conjugate(hold=True); a.unhold()
-I
>>> from sage.all import *
>>> a = SR(I).conjugate(hold=True); a.unhold()
-I
content(s)[source]

Return the content of this expression when considered as a polynomial in s.

See also unit(), primitive_part(), and unit_content_primitive().

INPUT:

  • s – a symbolic expression

OUTPUT:

The content part of a polynomial as a symbolic expression. It is defined as the gcd of the coefficients.

Warning

The expression is considered to be a univariate polynomial in s. The output is different from the content() method provided by multivariate polynomial rings in Sage.

EXAMPLES:

sage: (2*x+4).content(x)
2
sage: (2*x+1).content(x)
1
sage: (2*x+1/2).content(x)
1/2
sage: var('y')
y
sage: (2*x + 4*sin(y)).content(sin(y))
2
>>> from sage.all import *
>>> (Integer(2)*x+Integer(4)).content(x)
2
>>> (Integer(2)*x+Integer(1)).content(x)
1
>>> (Integer(2)*x+Integer(1)/Integer(2)).content(x)
1/2
>>> var('y')
y
>>> (Integer(2)*x + Integer(4)*sin(y)).content(sin(y))
2
contradicts(soln)[source]

Return True if this relation is violated by the given variable assignment(s).

EXAMPLES:

sage: (x<3).contradicts(x==0)
False
sage: (x<3).contradicts(x==3)
True
sage: (x<=3).contradicts(x==3)
False
sage: y = var('y')
sage: (x<y).contradicts(x==30)
False
sage: (x<y).contradicts({x: 30, y: 20})
True
>>> from sage.all import *
>>> (x<Integer(3)).contradicts(x==Integer(0))
False
>>> (x<Integer(3)).contradicts(x==Integer(3))
True
>>> (x<=Integer(3)).contradicts(x==Integer(3))
False
>>> y = var('y')
>>> (x<y).contradicts(x==Integer(30))
False
>>> (x<y).contradicts({x: Integer(30), y: Integer(20)})
True
convert(target=None)[source]

Call the convert function in the units package. For symbolic variables that are not units, this function just returns the variable.

INPUT:

  • self – the symbolic expression converting from

  • target – (default: None) the symbolic expression converting to

OUTPUT: a symbolic expression

EXAMPLES:

sage: units.length.foot.convert()
381/1250*meter
sage: units.mass.kilogram.convert(units.mass.pound)
100000000/45359237*pound
>>> from sage.all import *
>>> units.length.foot.convert()
381/1250*meter
>>> units.mass.kilogram.convert(units.mass.pound)
100000000/45359237*pound

We do not get anything new by converting an ordinary symbolic variable:

sage: a = var('a')
sage: a - a.convert()
0
>>> from sage.all import *
>>> a = var('a')
>>> a - a.convert()
0

Raises ValueError if self and target are not convertible:

sage: units.mass.kilogram.convert(units.length.foot)
Traceback (most recent call last):
...
ValueError: Incompatible units
sage: (units.length.meter^2).convert(units.length.foot)
Traceback (most recent call last):
...
ValueError: Incompatible units
>>> from sage.all import *
>>> units.mass.kilogram.convert(units.length.foot)
Traceback (most recent call last):
...
ValueError: Incompatible units
>>> (units.length.meter**Integer(2)).convert(units.length.foot)
Traceback (most recent call last):
...
ValueError: Incompatible units

Recognizes derived unit relationships to base units and other derived units:

sage: (units.length.foot/units.time.second^2).convert(units.acceleration.galileo)
762/25*galileo
sage: (units.mass.kilogram*units.length.meter/units.time.second^2).convert(units.force.newton)
newton
sage: (units.length.foot^3).convert(units.area.acre*units.length.inch)
1/3630*(acre*inch)
sage: (units.charge.coulomb).convert(units.current.ampere*units.time.second)
(ampere*second)
sage: (units.pressure.pascal*units.si_prefixes.kilo).convert(units.pressure.pounds_per_square_inch)
1290320000000/8896443230521*pounds_per_square_inch
>>> from sage.all import *
>>> (units.length.foot/units.time.second**Integer(2)).convert(units.acceleration.galileo)
762/25*galileo
>>> (units.mass.kilogram*units.length.meter/units.time.second**Integer(2)).convert(units.force.newton)
newton
>>> (units.length.foot**Integer(3)).convert(units.area.acre*units.length.inch)
1/3630*(acre*inch)
>>> (units.charge.coulomb).convert(units.current.ampere*units.time.second)
(ampere*second)
>>> (units.pressure.pascal*units.si_prefixes.kilo).convert(units.pressure.pounds_per_square_inch)
1290320000000/8896443230521*pounds_per_square_inch

For decimal answers multiply by 1.0:

sage: (units.pressure.pascal*units.si_prefixes.kilo).convert(units.pressure.pounds_per_square_inch)*1.0
0.145037737730209*pounds_per_square_inch
>>> from sage.all import *
>>> (units.pressure.pascal*units.si_prefixes.kilo).convert(units.pressure.pounds_per_square_inch)*RealNumber('1.0')
0.145037737730209*pounds_per_square_inch

Converting temperatures works as well:

sage: s = 68*units.temperature.fahrenheit
sage: s.convert(units.temperature.celsius)
20*celsius
sage: s.convert()
293.150000000000*kelvin
>>> from sage.all import *
>>> s = Integer(68)*units.temperature.fahrenheit
>>> s.convert(units.temperature.celsius)
20*celsius
>>> s.convert()
293.150000000000*kelvin

Trying to multiply temperatures by another unit then converting raises a ValueError:

sage: wrong = 50*units.temperature.celsius*units.length.foot
sage: wrong.convert()
Traceback (most recent call last):
...
ValueError: cannot convert
>>> from sage.all import *
>>> wrong = Integer(50)*units.temperature.celsius*units.length.foot
>>> wrong.convert()
Traceback (most recent call last):
...
ValueError: cannot convert
cos(hold=False)[source]

Return the cosine of self.

EXAMPLES:

sage: var('x, y')
(x, y)
sage: cos(x^2 + y^2)
cos(x^2 + y^2)
sage: cos(sage.symbolic.constants.pi)
-1
sage: cos(SR(1))
cos(1)
sage: cos(SR(RealField(150)(1)))
0.54030230586813971740093660744297660373231042
>>> from sage.all import *
>>> var('x, y')
(x, y)
>>> cos(x**Integer(2) + y**Integer(2))
cos(x^2 + y^2)
>>> cos(sage.symbolic.constants.pi)
-1
>>> cos(SR(Integer(1)))
cos(1)
>>> cos(SR(RealField(Integer(150))(Integer(1))))
0.54030230586813971740093660744297660373231042

In order to get a numeric approximation use .n():

sage: SR(RR(1)).cos().n()
0.540302305868140
sage: SR(float(1)).cos().n()
0.540302305868140
>>> from sage.all import *
>>> SR(RR(Integer(1))).cos().n()
0.540302305868140
>>> SR(float(Integer(1))).cos().n()
0.540302305868140

To prevent automatic evaluation use the hold argument:

sage: pi.cos()
-1
sage: pi.cos(hold=True)
cos(pi)
>>> from sage.all import *
>>> pi.cos()
-1
>>> pi.cos(hold=True)
cos(pi)

This also works using functional notation:

sage: cos(pi,hold=True)
cos(pi)
sage: cos(pi)
-1
>>> from sage.all import *
>>> cos(pi,hold=True)
cos(pi)
>>> cos(pi)
-1

To then evaluate again, we use unhold():

sage: a = pi.cos(hold=True); a.unhold()
-1
>>> from sage.all import *
>>> a = pi.cos(hold=True); a.unhold()
-1
cosh(hold=False)[source]

Return cosh of self.

We have \(\cosh(x) = (e^{x} + e^{-x})/2\).

EXAMPLES:

sage: x.cosh()
cosh(x)
sage: SR(1).cosh()
cosh(1)
sage: SR(0).cosh()
1
sage: SR(1.0).cosh()
1.54308063481524
sage: maxima('cosh(1.0)')
1.54308063481524...
sage: SR(1.00000000000000000000000000).cosh()
1.5430806348152437784779056
sage: SR(RIF(1)).cosh()
1.543080634815244?
>>> from sage.all import *
>>> x.cosh()
cosh(x)
>>> SR(Integer(1)).cosh()
cosh(1)
>>> SR(Integer(0)).cosh()
1
>>> SR(RealNumber('1.0')).cosh()
1.54308063481524
>>> maxima('cosh(1.0)')
1.54308063481524...
>>> SR(RealNumber('1.00000000000000000000000000')).cosh()
1.5430806348152437784779056
>>> SR(RIF(Integer(1))).cosh()
1.543080634815244?

To prevent automatic evaluation use the hold argument:

sage: arcsinh(x).cosh()
sqrt(x^2 + 1)
sage: arcsinh(x).cosh(hold=True)
cosh(arcsinh(x))
>>> from sage.all import *
>>> arcsinh(x).cosh()
sqrt(x^2 + 1)
>>> arcsinh(x).cosh(hold=True)
cosh(arcsinh(x))

This also works using functional notation:

sage: cosh(arcsinh(x),hold=True)
cosh(arcsinh(x))
sage: cosh(arcsinh(x))
sqrt(x^2 + 1)
>>> from sage.all import *
>>> cosh(arcsinh(x),hold=True)
cosh(arcsinh(x))
>>> cosh(arcsinh(x))
sqrt(x^2 + 1)

To then evaluate again, we use unhold():

sage: a = arcsinh(x).cosh(hold=True); a.unhold()
sqrt(x^2 + 1)
>>> from sage.all import *
>>> a = arcsinh(x).cosh(hold=True); a.unhold()
sqrt(x^2 + 1)
csgn(hold=False)[source]

Return the sign of self, which is -1 if self < 0, 0 if self == 0, and 1 if self > 0, or unevaluated when self is a nonconstant symbolic expression.

If self is not real, return the complex half-plane (left or right) in which the number lies. If self is pure imaginary, return the sign of the imaginary part of self.

EXAMPLES:

sage: x = var('x')
sage: SR(-2).csgn()
-1
sage: SR(0.0).csgn()
0
sage: SR(10).csgn()
1
sage: x.csgn()
csgn(x)
sage: SR(CDF.0).csgn()
1
sage: SR(I).csgn()
1
sage: SR(-I).csgn()
-1
sage: SR(1+I).csgn()
1
sage: SR(1-I).csgn()
1
sage: SR(-1+I).csgn()
-1
sage: SR(-1-I).csgn()
-1
>>> from sage.all import *
>>> x = var('x')
>>> SR(-Integer(2)).csgn()
-1
>>> SR(RealNumber('0.0')).csgn()
0
>>> SR(Integer(10)).csgn()
1
>>> x.csgn()
csgn(x)
>>> SR(CDF.gen(0)).csgn()
1
>>> SR(I).csgn()
1
>>> SR(-I).csgn()
-1
>>> SR(Integer(1)+I).csgn()
1
>>> SR(Integer(1)-I).csgn()
1
>>> SR(-Integer(1)+I).csgn()
-1
>>> SR(-Integer(1)-I).csgn()
-1

Using the hold parameter it is possible to prevent automatic evaluation:

sage: SR(I).csgn(hold=True)
csgn(I)
>>> from sage.all import *
>>> SR(I).csgn(hold=True)
csgn(I)
decl_assume(decl)[source]
decl_forget(decl)[source]
default_variable()[source]

Return the default variable, which is by definition the first variable in self, or \(x\) if there are no variables in self. The result is cached.

EXAMPLES:

sage: sqrt(2).default_variable()
x
sage: x, theta, a = var('x, theta, a')
sage: f = x^2 + theta^3 - a^x
sage: f.default_variable()
a
>>> from sage.all import *
>>> sqrt(Integer(2)).default_variable()
x
>>> x, theta, a = var('x, theta, a')
>>> f = x**Integer(2) + theta**Integer(3) - a**x
>>> f.default_variable()
a

Note that this is the first variable, not the first argument:

sage: f(theta, a, x) = a + theta^3
sage: f.default_variable()
a
sage: f.variables()
(a, theta)
sage: f.arguments()
(theta, a, x)
>>> from sage.all import *
>>> __tmp__=var("theta,a,x"); f = symbolic_expression(a + theta**Integer(3)).function(theta,a,x)
>>> f.default_variable()
a
>>> f.variables()
(a, theta)
>>> f.arguments()
(theta, a, x)
degree(s)[source]

Return the exponent of the highest power of s in self.

OUTPUT: integer

EXAMPLES:

sage: var('x,y,a')
(x, y, a)
sage: f = 100 + a*x + x^3*sin(x*y) + x*y + x/y^10 + 2*sin(x*y)/x; f
x^3*sin(x*y) + a*x + x*y + 2*sin(x*y)/x + x/y^10 + 100
sage: f.degree(x)
3
sage: f.degree(y)
1
sage: f.degree(sin(x*y))
1
sage: (x^-3+y).degree(x)
0
sage: (1/x+1/x**2).degree(x)
-1
>>> from sage.all import *
>>> var('x,y,a')
(x, y, a)
>>> f = Integer(100) + a*x + x**Integer(3)*sin(x*y) + x*y + x/y**Integer(10) + Integer(2)*sin(x*y)/x; f
x^3*sin(x*y) + a*x + x*y + 2*sin(x*y)/x + x/y^10 + 100
>>> f.degree(x)
3
>>> f.degree(y)
1
>>> f.degree(sin(x*y))
1
>>> (x**-Integer(3)+y).degree(x)
0
>>> (Integer(1)/x+Integer(1)/x**Integer(2)).degree(x)
-1
demoivre(force=False)[source]

Return this symbolic expression with complex exponentials (optionally all exponentials) replaced by (at least partially) trigonometric/hyperbolic expressions.

EXAMPLES:

sage: x, a, b = SR.var("x, a, b")
sage: exp(a + I*b).demoivre()
(cos(b) + I*sin(b))*e^a
sage: exp(I*x).demoivre()
cos(x) + I*sin(x)
sage: exp(x).demoivre()
e^x
sage: exp(x).demoivre(force=True)
cosh(x) + sinh(x)
>>> from sage.all import *
>>> x, a, b = SR.var("x, a, b")
>>> exp(a + I*b).demoivre()
(cos(b) + I*sin(b))*e^a
>>> exp(I*x).demoivre()
cos(x) + I*sin(x)
>>> exp(x).demoivre()
e^x
>>> exp(x).demoivre(force=True)
cosh(x) + sinh(x)
denominator(normalize=True)[source]

Return the denominator of this symbolic expression.

INPUT:

  • normalize – boolean (default: True)

If normalize is True, the expression is first normalized to have it as a fraction before getting the denominator.

If normalize is False, the expression is kept and if it is not a quotient, then this will just return 1.

EXAMPLES:

sage: x, y, z, theta = var('x, y, z, theta')
sage: f = (sqrt(x) + sqrt(y) + sqrt(z))/(x^10 - y^10 - sqrt(theta))
sage: f.numerator()
sqrt(x) + sqrt(y) + sqrt(z)
sage: f.denominator()
x^10 - y^10 - sqrt(theta)

sage: f.numerator(normalize=False)
(sqrt(x) + sqrt(y) + sqrt(z))
sage: f.denominator(normalize=False)
x^10 - y^10 - sqrt(theta)

sage: y = var('y')
sage: g = x + y/(x + 2); g
x + y/(x + 2)
sage: g.numerator(normalize=False)
x + y/(x + 2)
sage: g.denominator(normalize=False)
1
>>> from sage.all import *
>>> x, y, z, theta = var('x, y, z, theta')
>>> f = (sqrt(x) + sqrt(y) + sqrt(z))/(x**Integer(10) - y**Integer(10) - sqrt(theta))
>>> f.numerator()
sqrt(x) + sqrt(y) + sqrt(z)
>>> f.denominator()
x^10 - y^10 - sqrt(theta)

>>> f.numerator(normalize=False)
(sqrt(x) + sqrt(y) + sqrt(z))
>>> f.denominator(normalize=False)
x^10 - y^10 - sqrt(theta)

>>> y = var('y')
>>> g = x + y/(x + Integer(2)); g
x + y/(x + 2)
>>> g.numerator(normalize=False)
x + y/(x + 2)
>>> g.denominator(normalize=False)
1
derivative(*args)[source]

Return the derivative of this expressions with respect to the variables supplied in args.

Multiple variables and iteration counts may be supplied; see documentation for the global derivative() function for more details.

See also

This is implemented in the _derivative method (see the source code).

EXAMPLES:

sage: var("x y")
(x, y)
sage: t = (x^2+y)^2
sage: t.derivative(x)
4*(x^2 + y)*x
sage: t.derivative(x, 2)
12*x^2 + 4*y
sage: t.derivative(x, 2, y)
4
sage: t.derivative(y)
2*x^2 + 2*y
>>> from sage.all import *
>>> var("x y")
(x, y)
>>> t = (x**Integer(2)+y)**Integer(2)
>>> t.derivative(x)
4*(x^2 + y)*x
>>> t.derivative(x, Integer(2))
12*x^2 + 4*y
>>> t.derivative(x, Integer(2), y)
4
>>> t.derivative(y)
2*x^2 + 2*y

If the function depends on only one variable, you may omit the variable. Giving just a number (for the order of the derivative) also works:

sage: f(x) = x^3 + sin(x)
sage: f.derivative()
x |--> 3*x^2 + cos(x)
sage: f.derivative(2)
x |--> 6*x - sin(x)
>>> from sage.all import *
>>> __tmp__=var("x"); f = symbolic_expression(x**Integer(3) + sin(x)).function(x)
>>> f.derivative()
x |--> 3*x^2 + cos(x)
>>> f.derivative(Integer(2))
x |--> 6*x - sin(x)

Some expressions can’t be cleanly differentiated by the chain rule:

sage: _ = var('x', domain='real')
sage: _ = var('w z')
sage: (x^z).conjugate().diff(x)
conjugate(x^(z - 1))*conjugate(z)
sage: (w^z).conjugate().diff(w)
w^(z - 1)*z*D[0](conjugate)(w^z)
sage: atanh(x).real_part().diff(x)
-1/(x^2 - 1)
sage: atanh(x).imag_part().diff(x)
0
sage: atanh(w).real_part().diff(w)
-D[0](real_part)(arctanh(w))/(w^2 - 1)
sage: atanh(w).imag_part().diff(w)
-D[0](imag_part)(arctanh(w))/(w^2 - 1)
sage: abs(log(x)).diff(x)
1/2*(conjugate(log(x))/x + log(x)/x)/abs(log(x))
sage: abs(log(z)).diff(z)
1/2*(conjugate(log(z))/z + log(z)/conjugate(z))/abs(log(z))
sage: forget()

sage: t = sin(x+y^2)*tan(x*y)
sage: t.derivative(x)
(tan(x*y)^2 + 1)*y*sin(y^2 + x) + cos(y^2 + x)*tan(x*y)
sage: t.derivative(y)
(tan(x*y)^2 + 1)*x*sin(y^2 + x) + 2*y*cos(y^2 + x)*tan(x*y)
>>> from sage.all import *
>>> _ = var('x', domain='real')
>>> _ = var('w z')
>>> (x**z).conjugate().diff(x)
conjugate(x^(z - 1))*conjugate(z)
>>> (w**z).conjugate().diff(w)
w^(z - 1)*z*D[0](conjugate)(w^z)
>>> atanh(x).real_part().diff(x)
-1/(x^2 - 1)
>>> atanh(x).imag_part().diff(x)
0
>>> atanh(w).real_part().diff(w)
-D[0](real_part)(arctanh(w))/(w^2 - 1)
>>> atanh(w).imag_part().diff(w)
-D[0](imag_part)(arctanh(w))/(w^2 - 1)
>>> abs(log(x)).diff(x)
1/2*(conjugate(log(x))/x + log(x)/x)/abs(log(x))
>>> abs(log(z)).diff(z)
1/2*(conjugate(log(z))/z + log(z)/conjugate(z))/abs(log(z))
>>> forget()

>>> t = sin(x+y**Integer(2))*tan(x*y)
>>> t.derivative(x)
(tan(x*y)^2 + 1)*y*sin(y^2 + x) + cos(y^2 + x)*tan(x*y)
>>> t.derivative(y)
(tan(x*y)^2 + 1)*x*sin(y^2 + x) + 2*y*cos(y^2 + x)*tan(x*y)

sage: h = sin(x)/cos(x)
sage: derivative(h,x,x,x)
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
sage: derivative(h,x,3)
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
>>> from sage.all import *
>>> h = sin(x)/cos(x)
>>> derivative(h,x,x,x)
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
>>> derivative(h,x,Integer(3))
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2

sage: var('x, y')
(x, y)
sage: u = (sin(x) + cos(y))*(cos(x) - sin(y))
sage: derivative(u,x,y)
-cos(x)*cos(y) + sin(x)*sin(y)
sage: f = ((x^2+1)/(x^2-1))^(1/4)
sage: g = derivative(f, x); g # this is a complex expression
-1/2*((x^2 + 1)*x/(x^2 - 1)^2 - x/(x^2 - 1))/((x^2 + 1)/(x^2 - 1))^(3/4)
sage: g.factor()
-x/((x + 1)^2*(x - 1)^2*((x^2 + 1)/(x^2 - 1))^(3/4))
>>> from sage.all import *
>>> var('x, y')
(x, y)
>>> u = (sin(x) + cos(y))*(cos(x) - sin(y))
>>> derivative(u,x,y)
-cos(x)*cos(y) + sin(x)*sin(y)
>>> f = ((x**Integer(2)+Integer(1))/(x**Integer(2)-Integer(1)))**(Integer(1)/Integer(4))
>>> g = derivative(f, x); g # this is a complex expression
-1/2*((x^2 + 1)*x/(x^2 - 1)^2 - x/(x^2 - 1))/((x^2 + 1)/(x^2 - 1))^(3/4)
>>> g.factor()
-x/((x + 1)^2*(x - 1)^2*((x^2 + 1)/(x^2 - 1))^(3/4))

sage: y = var('y')
sage: f = y^(sin(x))
sage: derivative(f, x)
y^sin(x)*cos(x)*log(y)
>>> from sage.all import *
>>> y = var('y')
>>> f = y**(sin(x))
>>> derivative(f, x)
y^sin(x)*cos(x)*log(y)

sage: g(x) = sqrt(5-2*x)
sage: g_3 = derivative(g, x, 3); g_3(2)
-3
>>> from sage.all import *
>>> __tmp__=var("x"); g = symbolic_expression(sqrt(Integer(5)-Integer(2)*x)).function(x)
>>> g_3 = derivative(g, x, Integer(3)); g_3(Integer(2))
-3

sage: f = x*e^(-x)
sage: derivative(f, 100)
x*e^(-x) - 100*e^(-x)
>>> from sage.all import *
>>> f = x*e**(-x)
>>> derivative(f, Integer(100))
x*e^(-x) - 100*e^(-x)

sage: g = 1/(sqrt((x^2-1)*(x+5)^6))
sage: derivative(g, x)
-((x + 5)^6*x + 3*(x^2 - 1)*(x + 5)^5)/((x^2 - 1)*(x + 5)^6)^(3/2)
>>> from sage.all import *
>>> g = Integer(1)/(sqrt((x**Integer(2)-Integer(1))*(x+Integer(5))**Integer(6)))
>>> derivative(g, x)
-((x + 5)^6*x + 3*(x^2 - 1)*(x + 5)^5)/((x^2 - 1)*(x + 5)^6)^(3/2)
diff(*args)[source]

Return the derivative of this expressions with respect to the variables supplied in args.

Multiple variables and iteration counts may be supplied; see documentation for the global derivative() function for more details.

See also

This is implemented in the _derivative method (see the source code).

EXAMPLES:

sage: var("x y")
(x, y)
sage: t = (x^2+y)^2
sage: t.derivative(x)
4*(x^2 + y)*x
sage: t.derivative(x, 2)
12*x^2 + 4*y
sage: t.derivative(x, 2, y)
4
sage: t.derivative(y)
2*x^2 + 2*y
>>> from sage.all import *
>>> var("x y")
(x, y)
>>> t = (x**Integer(2)+y)**Integer(2)
>>> t.derivative(x)
4*(x^2 + y)*x
>>> t.derivative(x, Integer(2))
12*x^2 + 4*y
>>> t.derivative(x, Integer(2), y)
4
>>> t.derivative(y)
2*x^2 + 2*y

If the function depends on only one variable, you may omit the variable. Giving just a number (for the order of the derivative) also works:

sage: f(x) = x^3 + sin(x)
sage: f.derivative()
x |--> 3*x^2 + cos(x)
sage: f.derivative(2)
x |--> 6*x - sin(x)
>>> from sage.all import *
>>> __tmp__=var("x"); f = symbolic_expression(x**Integer(3) + sin(x)).function(x)
>>> f.derivative()
x |--> 3*x^2 + cos(x)
>>> f.derivative(Integer(2))
x |--> 6*x - sin(x)

Some expressions can’t be cleanly differentiated by the chain rule:

sage: _ = var('x', domain='real')
sage: _ = var('w z')
sage: (x^z).conjugate().diff(x)
conjugate(x^(z - 1))*conjugate(z)
sage: (w^z).conjugate().diff(w)
w^(z - 1)*z*D[0](conjugate)(w^z)
sage: atanh(x).real_part().diff(x)
-1/(x^2 - 1)
sage: atanh(x).imag_part().diff(x)
0
sage: atanh(w).real_part().diff(w)
-D[0](real_part)(arctanh(w))/(w^2 - 1)
sage: atanh(w).imag_part().diff(w)
-D[0](imag_part)(arctanh(w))/(w^2 - 1)
sage: abs(log(x)).diff(x)
1/2*(conjugate(log(x))/x + log(x)/x)/abs(log(x))
sage: abs(log(z)).diff(z)
1/2*(conjugate(log(z))/z + log(z)/conjugate(z))/abs(log(z))
sage: forget()

sage: t = sin(x+y^2)*tan(x*y)
sage: t.derivative(x)
(tan(x*y)^2 + 1)*y*sin(y^2 + x) + cos(y^2 + x)*tan(x*y)
sage: t.derivative(y)
(tan(x*y)^2 + 1)*x*sin(y^2 + x) + 2*y*cos(y^2 + x)*tan(x*y)
>>> from sage.all import *
>>> _ = var('x', domain='real')
>>> _ = var('w z')
>>> (x**z).conjugate().diff(x)
conjugate(x^(z - 1))*conjugate(z)
>>> (w**z).conjugate().diff(w)
w^(z - 1)*z*D[0](conjugate)(w^z)
>>> atanh(x).real_part().diff(x)
-1/(x^2 - 1)
>>> atanh(x).imag_part().diff(x)
0
>>> atanh(w).real_part().diff(w)
-D[0](real_part)(arctanh(w))/(w^2 - 1)
>>> atanh(w).imag_part().diff(w)
-D[0](imag_part)(arctanh(w))/(w^2 - 1)
>>> abs(log(x)).diff(x)
1/2*(conjugate(log(x))/x + log(x)/x)/abs(log(x))
>>> abs(log(z)).diff(z)
1/2*(conjugate(log(z))/z + log(z)/conjugate(z))/abs(log(z))
>>> forget()

>>> t = sin(x+y**Integer(2))*tan(x*y)
>>> t.derivative(x)
(tan(x*y)^2 + 1)*y*sin(y^2 + x) + cos(y^2 + x)*tan(x*y)
>>> t.derivative(y)
(tan(x*y)^2 + 1)*x*sin(y^2 + x) + 2*y*cos(y^2 + x)*tan(x*y)

sage: h = sin(x)/cos(x)
sage: derivative(h,x,x,x)
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
sage: derivative(h,x,3)
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
>>> from sage.all import *
>>> h = sin(x)/cos(x)
>>> derivative(h,x,x,x)
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
>>> derivative(h,x,Integer(3))
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2

sage: var('x, y')
(x, y)
sage: u = (sin(x) + cos(y))*(cos(x) - sin(y))
sage: derivative(u,x,y)
-cos(x)*cos(y) + sin(x)*sin(y)
sage: f = ((x^2+1)/(x^2-1))^(1/4)
sage: g = derivative(f, x); g # this is a complex expression
-1/2*((x^2 + 1)*x/(x^2 - 1)^2 - x/(x^2 - 1))/((x^2 + 1)/(x^2 - 1))^(3/4)
sage: g.factor()
-x/((x + 1)^2*(x - 1)^2*((x^2 + 1)/(x^2 - 1))^(3/4))
>>> from sage.all import *
>>> var('x, y')
(x, y)
>>> u = (sin(x) + cos(y))*(cos(x) - sin(y))
>>> derivative(u,x,y)
-cos(x)*cos(y) + sin(x)*sin(y)
>>> f = ((x**Integer(2)+Integer(1))/(x**Integer(2)-Integer(1)))**(Integer(1)/Integer(4))
>>> g = derivative(f, x); g # this is a complex expression
-1/2*((x^2 + 1)*x/(x^2 - 1)^2 - x/(x^2 - 1))/((x^2 + 1)/(x^2 - 1))^(3/4)
>>> g.factor()
-x/((x + 1)^2*(x - 1)^2*((x^2 + 1)/(x^2 - 1))^(3/4))

sage: y = var('y')
sage: f = y^(sin(x))
sage: derivative(f, x)
y^sin(x)*cos(x)*log(y)
>>> from sage.all import *
>>> y = var('y')
>>> f = y**(sin(x))
>>> derivative(f, x)
y^sin(x)*cos(x)*log(y)

sage: g(x) = sqrt(5-2*x)
sage: g_3 = derivative(g, x, 3); g_3(2)
-3
>>> from sage.all import *
>>> __tmp__=var("x"); g = symbolic_expression(sqrt(Integer(5)-Integer(2)*x)).function(x)
>>> g_3 = derivative(g, x, Integer(3)); g_3(Integer(2))
-3

sage: f = x*e^(-x)
sage: derivative(f, 100)
x*e^(-x) - 100*e^(-x)
>>> from sage.all import *
>>> f = x*e**(-x)
>>> derivative(f, Integer(100))
x*e^(-x) - 100*e^(-x)

sage: g = 1/(sqrt((x^2-1)*(x+5)^6))
sage: derivative(g, x)
-((x + 5)^6*x + 3*(x^2 - 1)*(x + 5)^5)/((x^2 - 1)*(x + 5)^6)^(3/2)
>>> from sage.all import *
>>> g = Integer(1)/(sqrt((x**Integer(2)-Integer(1))*(x+Integer(5))**Integer(6)))
>>> derivative(g, x)
-((x + 5)^6*x + 3*(x^2 - 1)*(x + 5)^5)/((x^2 - 1)*(x + 5)^6)^(3/2)
differentiate(*args)[source]

Return the derivative of this expressions with respect to the variables supplied in args.

Multiple variables and iteration counts may be supplied; see documentation for the global derivative() function for more details.

See also

This is implemented in the _derivative method (see the source code).

EXAMPLES:

sage: var("x y")
(x, y)
sage: t = (x^2+y)^2
sage: t.derivative(x)
4*(x^2 + y)*x
sage: t.derivative(x, 2)
12*x^2 + 4*y
sage: t.derivative(x, 2, y)
4
sage: t.derivative(y)
2*x^2 + 2*y
>>> from sage.all import *
>>> var("x y")
(x, y)
>>> t = (x**Integer(2)+y)**Integer(2)
>>> t.derivative(x)
4*(x^2 + y)*x
>>> t.derivative(x, Integer(2))
12*x^2 + 4*y
>>> t.derivative(x, Integer(2), y)
4
>>> t.derivative(y)
2*x^2 + 2*y

If the function depends on only one variable, you may omit the variable. Giving just a number (for the order of the derivative) also works:

sage: f(x) = x^3 + sin(x)
sage: f.derivative()
x |--> 3*x^2 + cos(x)
sage: f.derivative(2)
x |--> 6*x - sin(x)
>>> from sage.all import *
>>> __tmp__=var("x"); f = symbolic_expression(x**Integer(3) + sin(x)).function(x)
>>> f.derivative()
x |--> 3*x^2 + cos(x)
>>> f.derivative(Integer(2))
x |--> 6*x - sin(x)

Some expressions can’t be cleanly differentiated by the chain rule:

sage: _ = var('x', domain='real')
sage: _ = var('w z')
sage: (x^z).conjugate().diff(x)
conjugate(x^(z - 1))*conjugate(z)
sage: (w^z).conjugate().diff(w)
w^(z - 1)*z*D[0](conjugate)(w^z)
sage: atanh(x).real_part().diff(x)
-1/(x^2 - 1)
sage: atanh(x).imag_part().diff(x)
0
sage: atanh(w).real_part().diff(w)
-D[0](real_part)(arctanh(w))/(w^2 - 1)
sage: atanh(w).imag_part().diff(w)
-D[0](imag_part)(arctanh(w))/(w^2 - 1)
sage: abs(log(x)).diff(x)
1/2*(conjugate(log(x))/x + log(x)/x)/abs(log(x))
sage: abs(log(z)).diff(z)
1/2*(conjugate(log(z))/z + log(z)/conjugate(z))/abs(log(z))
sage: forget()

sage: t = sin(x+y^2)*tan(x*y)
sage: t.derivative(x)
(tan(x*y)^2 + 1)*y*sin(y^2 + x) + cos(y^2 + x)*tan(x*y)
sage: t.derivative(y)
(tan(x*y)^2 + 1)*x*sin(y^2 + x) + 2*y*cos(y^2 + x)*tan(x*y)
>>> from sage.all import *
>>> _ = var('x', domain='real')
>>> _ = var('w z')
>>> (x**z).conjugate().diff(x)
conjugate(x^(z - 1))*conjugate(z)
>>> (w**z).conjugate().diff(w)
w^(z - 1)*z*D[0](conjugate)(w^z)
>>> atanh(x).real_part().diff(x)
-1/(x^2 - 1)
>>> atanh(x).imag_part().diff(x)
0
>>> atanh(w).real_part().diff(w)
-D[0](real_part)(arctanh(w))/(w^2 - 1)
>>> atanh(w).imag_part().diff(w)
-D[0](imag_part)(arctanh(w))/(w^2 - 1)
>>> abs(log(x)).diff(x)
1/2*(conjugate(log(x))/x + log(x)/x)/abs(log(x))
>>> abs(log(z)).diff(z)
1/2*(conjugate(log(z))/z + log(z)/conjugate(z))/abs(log(z))
>>> forget()

>>> t = sin(x+y**Integer(2))*tan(x*y)
>>> t.derivative(x)
(tan(x*y)^2 + 1)*y*sin(y^2 + x) + cos(y^2 + x)*tan(x*y)
>>> t.derivative(y)
(tan(x*y)^2 + 1)*x*sin(y^2 + x) + 2*y*cos(y^2 + x)*tan(x*y)

sage: h = sin(x)/cos(x)
sage: derivative(h,x,x,x)
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
sage: derivative(h,x,3)
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
>>> from sage.all import *
>>> h = sin(x)/cos(x)
>>> derivative(h,x,x,x)
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2
>>> derivative(h,x,Integer(3))
8*sin(x)^2/cos(x)^2 + 6*sin(x)^4/cos(x)^4 + 2

sage: var('x, y')
(x, y)
sage: u = (sin(x) + cos(y))*(cos(x) - sin(y))
sage: derivative(u,x,y)
-cos(x)*cos(y) + sin(x)*sin(y)
sage: f = ((x^2+1)/(x^2-1))^(1/4)
sage: g = derivative(f, x); g # this is a complex expression
-1/2*((x^2 + 1)*x/(x^2 - 1)^2 - x/(x^2 - 1))/((x^2 + 1)/(x^2 - 1))^(3/4)
sage: g.factor()
-x/((x + 1)^2*(x - 1)^2*((x^2 + 1)/(x^2 - 1))^(3/4))
>>> from sage.all import *
>>> var('x, y')
(x, y)
>>> u = (sin(x) + cos(y))*(cos(x) - sin(y))
>>> derivative(u,x,y)
-cos(x)*cos(y) + sin(x)*sin(y)
>>> f = ((x**Integer(2)+Integer(1))/(x**Integer(2)-Integer(1)))**(Integer(1)/Integer(4))
>>> g = derivative(f, x); g # this is a complex expression
-1/2*((x^2 + 1)*x/(x^2 - 1)^2 - x/(x^2 - 1))/((x^2 + 1)/(x^2 - 1))^(3/4)
>>> g.factor()
-x/((x + 1)^2*(x - 1)^2*((x^2 + 1)/(x^2 - 1))^(3/4))

sage: y = var('y')
sage: f = y^(sin(x))
sage: derivative(f, x)
y^sin(x)*cos(x)*log(y)
>>> from sage.all import *
>>> y = var('y')
>>> f = y**(sin(x))
>>> derivative(f, x)
y^sin(x)*cos(x)*log(y)

sage: g(x) = sqrt(5-2*x)
sage: g_3 = derivative(g, x, 3); g_3(2)
-3
>>> from sage.all import *
>>> __tmp__=var("x"); g = symbolic_expression(sqrt(Integer(5)-Integer(2)*x)).function(x)
>>> g_3 = derivative(g, x, Integer(3)); g_3(Integer(2))
-3

sage: f = x*e^(-x)
sage: derivative(f, 100)
x*e^(-x) - 100*e^(-x)
>>> from sage.all import *
>>> f = x*e**(-x)
>>> derivative(f, Integer(100))
x*e^(-x) - 100*e^(-x)

sage: g = 1/(sqrt((x^2-1)*(x+5)^6))
sage: derivative(g, x)
-((x + 5)^6*x + 3*(x^2 - 1)*(x + 5)^5)/((x^2 - 1)*(x + 5)^6)^(3/2)
>>> from sage.all import *
>>> g = Integer(1)/(sqrt((x**Integer(2)-Integer(1))*(x+Integer(5))**Integer(6)))
>>> derivative(g, x)
-((x + 5)^6*x + 3*(x^2 - 1)*(x + 5)^5)/((x^2 - 1)*(x + 5)^6)^(3/2)
distribute(recursive=True)[source]

Distribute some indexed operators over similar operators in order to allow further groupings or simplifications.

Implemented cases (so far):

  • Symbolic sum of a sum ==> sum of symbolic sums

  • Integral (definite or not) of a sum ==> sum of integrals.

  • Symbolic product of a product ==> product of symbolic products.

INPUT:

  • recursive – (default: True) the distribution proceeds along the subtrees of the expression

AUTHORS:

  • Emmanuel Charpentier, Ralf Stephan (05-2017)

divide_both_sides(x, checksign=None)[source]

Return a relation obtained by dividing both sides of this relation by x.

Note

The checksign keyword argument is currently ignored and is included for backward compatibility reasons only.

EXAMPLES:

sage: theta = var('theta')
sage: eqn =   (x^3 + theta < sin(x*theta))
sage: eqn.divide_both_sides(theta, checksign=False)
(x^3 + theta)/theta < sin(theta*x)/theta
sage: eqn.divide_both_sides(theta)
(x^3 + theta)/theta < sin(theta*x)/theta
sage: eqn/theta
(x^3 + theta)/theta < sin(theta*x)/theta
>>> from sage.all import *
>>> theta = var('theta')
>>> eqn =   (x**Integer(3) + theta < sin(x*theta))
>>> eqn.divide_both_sides(theta, checksign=False)
(x^3 + theta)/theta < sin(theta*x)/theta
>>> eqn.divide_both_sides(theta)
(x^3 + theta)/theta < sin(theta*x)/theta
>>> eqn/theta
(x^3 + theta)/theta < sin(theta*x)/theta
exp(hold=False)[source]

Return exponential function of self, i.e., \(e\) to the power of self.

EXAMPLES:

sage: x.exp()
e^x
sage: SR(0).exp()
1
sage: SR(1/2).exp()
e^(1/2)
sage: SR(0.5).exp()
1.64872127070013
sage: math.exp(0.5)
1.6487212707001282

sage: SR(0.5).exp().log()
0.500000000000000
sage: (pi*I).exp()
-1
>>> from sage.all import *
>>> x.exp()
e^x
>>> SR(Integer(0)).exp()
1
>>> SR(Integer(1)/Integer(2)).exp()
e^(1/2)
>>> SR(RealNumber('0.5')).exp()
1.64872127070013
>>> math.exp(RealNumber('0.5'))
1.6487212707001282

>>> SR(RealNumber('0.5')).exp().log()
0.500000000000000
>>> (pi*I).exp()
-1

To prevent automatic evaluation use the hold argument:

sage: (pi*I).exp(hold=True)
e^(I*pi)
>>> from sage.all import *
>>> (pi*I).exp(hold=True)
e^(I*pi)

This also works using functional notation:

sage: exp(I*pi,hold=True)
e^(I*pi)
sage: exp(I*pi)
-1
>>> from sage.all import *
>>> exp(I*pi,hold=True)
e^(I*pi)
>>> exp(I*pi)
-1

To then evaluate again, we use unhold():

sage: a = (pi*I).exp(hold=True); a.unhold()
-1
>>> from sage.all import *
>>> a = (pi*I).exp(hold=True); a.unhold()
-1
expand(side=None)[source]

Expand this symbolic expression. Products of sums and exponentiated sums are multiplied out, numerators of rational expressions which are sums are split into their respective terms, and multiplications are distributed over addition at all levels.

EXAMPLES:

We expand the expression \((x-y)^5\) using both method and functional notation.

sage: x,y = var('x,y')
sage: a = (x-y)^5
sage: a.expand()
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5
sage: expand(a)
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5
>>> from sage.all import *
>>> x,y = var('x,y')
>>> a = (x-y)**Integer(5)
>>> a.expand()
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5
>>> expand(a)
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5

We expand some other expressions:

sage: expand((x-1)^3/(y-1))
x^3/(y - 1) - 3*x^2/(y - 1) + 3*x/(y - 1) - 1/(y - 1)
sage: expand((x+sin((x+y)^2))^2)
x^2 + 2*x*sin(x^2 + 2*x*y + y^2) + sin(x^2 + 2*x*y + y^2)^2
>>> from sage.all import *
>>> expand((x-Integer(1))**Integer(3)/(y-Integer(1)))
x^3/(y - 1) - 3*x^2/(y - 1) + 3*x/(y - 1) - 1/(y - 1)
>>> expand((x+sin((x+y)**Integer(2)))**Integer(2))
x^2 + 2*x*sin(x^2 + 2*x*y + y^2) + sin(x^2 + 2*x*y + y^2)^2

Observe that expand() also expands function arguments:

sage: f(x) = function('f')(x)
sage: fx = f(x*(x+1)); fx
f((x + 1)*x)
sage: fx.expand()
f(x^2 + x)
>>> from sage.all import *
>>> __tmp__=var("x"); f = symbolic_expression(function('f')(x)).function(x)
>>> fx = f(x*(x+Integer(1))); fx
f((x + 1)*x)
>>> fx.expand()
f(x^2 + x)

We can expand individual sides of a relation:

sage: a = (16*x-13)^2 == (3*x+5)^2/2
sage: a.expand()
256*x^2 - 416*x + 169 == 9/2*x^2 + 15*x + 25/2
sage: a.expand('left')
256*x^2 - 416*x + 169 == 1/2*(3*x + 5)^2
sage: a.expand('right')
(16*x - 13)^2 == 9/2*x^2 + 15*x + 25/2
>>> from sage.all import *
>>> a = (Integer(16)*x-Integer(13))**Integer(2) == (Integer(3)*x+Integer(5))**Integer(2)/Integer(2)
>>> a.expand()
256*x^2 - 416*x + 169 == 9/2*x^2 + 15*x + 25/2
>>> a.expand('left')
256*x^2 - 416*x + 169 == 1/2*(3*x + 5)^2
>>> a.expand('right')
(16*x - 13)^2 == 9/2*x^2 + 15*x + 25/2
expand_log(algorithm='products')[source]

Simplify symbolic expression, which can contain logs.

Expands logarithms of powers, logarithms of products and logarithms of quotients. The option algorithm specifies which expression types should be expanded.

INPUT:

  • self – expression to be simplified

  • algorithm – (default: 'products') governs which expression is expanded. Possible values are

    • 'nothing' (no expansion),

    • 'powers' (log(a^r) is expanded),

    • 'products' (like ‘powers’ and also log(a*b) are expanded),

    • 'all' (all possible expansion).

    See also examples below.

DETAILS: This uses the Maxima simplifier and sets logexpand option for this simplifier. From the Maxima documentation: “Logexpand:true causes log(a^b) to become b*log(a). If it is set to all, log(a*b) will also simplify to log(a)+log(b). If it is set to super, then log(a/b) will also simplify to log(a)-log(b) for rational numbers a/b, a#1. (log(1/b), for integer b, always simplifies.) If it is set to false, all of these simplifications will be turned off. “

ALIAS: log_expand() and expand_log() are the same

EXAMPLES:

By default powers and products (and quotients) are expanded, but not quotients of integers:

sage: (log(3/4*x^pi)).log_expand()
pi*log(x) + log(3/4)
>>> from sage.all import *
>>> (log(Integer(3)/Integer(4)*x**pi)).log_expand()
pi*log(x) + log(3/4)

To expand also log(3/4) use algorithm='all':

sage: (log(3/4*x^pi)).log_expand('all')
pi*log(x) + log(3) - 2*log(2)
>>> from sage.all import *
>>> (log(Integer(3)/Integer(4)*x**pi)).log_expand('all')
pi*log(x) + log(3) - 2*log(2)

To expand only the power use algorithm='powers'.:

sage: (log(x^6)).log_expand('powers')
6*log(x)
>>> from sage.all import *
>>> (log(x**Integer(6))).log_expand('powers')
6*log(x)

The expression log((3*x)^6) is not expanded with algorithm='powers', since it is converted into product first:

sage: (log((3*x)^6)).log_expand('powers')
log(729*x^6)
>>> from sage.all import *
>>> (log((Integer(3)*x)**Integer(6))).log_expand('powers')
log(729*x^6)

This shows that the option algorithm from the previous call has no influence to future calls (we changed some default Maxima flag, and have to ensure that this flag has been restored):

sage: (log(3/4*x^pi)).log_expand()
pi*log(x) + log(3/4)

sage: (log(3/4*x^pi)).log_expand('all')
pi*log(x) + log(3) - 2*log(2)

sage: (log(3/4*x^pi)).log_expand()
pi*log(x) + log(3/4)
>>> from sage.all import *
>>> (log(Integer(3)/Integer(4)*x**pi)).log_expand()
pi*log(x) + log(3/4)

>>> (log(Integer(3)/Integer(4)*x**pi)).log_expand('all')
pi*log(x) + log(3) - 2*log(2)

>>> (log(Integer(3)/Integer(4)*x**pi)).log_expand()
pi*log(x) + log(3/4)

AUTHORS:

  • Robert Marik (11-2009)

expand_rational(side=None)[source]

Expand this symbolic expression. Products of sums and exponentiated sums are multiplied out, numerators of rational expressions which are sums are split into their respective terms, and multiplications are distributed over addition at all levels.

EXAMPLES:

We expand the expression \((x-y)^5\) using both method and functional notation.

sage: x,y = var('x,y')
sage: a = (x-y)^5
sage: a.expand()
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5
sage: expand(a)
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5
>>> from sage.all import *
>>> x,y = var('x,y')
>>> a = (x-y)**Integer(5)
>>> a.expand()
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5
>>> expand(a)
x^5 - 5*x^4*y + 10*x^3*y^2 - 10*x^2*y^3 + 5*x*y^4 - y^5

We expand some other expressions:

sage: expand((x-1)^3/(y-1))
x^3/(y - 1) - 3*x^2/(y - 1) + 3*x/(y - 1) - 1/(y - 1)
sage: expand((x+sin((x+y)^2))^2)
x^2 + 2*x*sin(x^2 + 2*x*y + y^2) + sin(x^2 + 2*x*y + y^2)^2
>>> from sage.all import *
>>> expand((x-Integer(1))**Integer(3)/(y-Integer(1)))
x^3/(y - 1) - 3*x^2/(y - 1) + 3*x/(y - 1) - 1/(y - 1)
>>> expand((x+sin((x+y)**Integer(2)))**Integer(2))
x^2 + 2*x*sin(x^2 + 2*x*y + y^2) + sin(x^2 + 2*x*y + y^2)^2

Observe that expand() also expands function arguments:

sage: f(x) = function('f')(x)
sage: fx = f(x*(x+1)); fx
f((x + 1)*x)
sage: fx.expand()
f(x^2 + x)
>>> from sage.all import *
>>> __tmp__=var("x"); f = symbolic_expression(function('f')(x)).function(x)
>>> fx = f(x*(x+Integer(1))); fx
f((x + 1)*x)
>>> fx.expand()
f(x^2 + x)

We can expand individual sides of a relation:

sage: a = (16*x-13)^2 == (3*x+5)^2/2
sage: a.expand()
256*x^2 - 416*x + 169 == 9/2*x^2 + 15*x + 25/2
sage: a.expand('left')
256*x^2 - 416*x + 169 == 1/2*(3*x + 5)^2
sage: a.expand('right')
(16*x - 13)^2 == 9/2*x^2 + 15*x + 25/2
>>> from sage.all import *
>>> a = (Integer(16)*x-Integer(13))**Integer(2) == (Integer(3)*x+Integer(5))**Integer(2)/Integer(2)
>>> a.expand()
256*x^2 - 416*x + 169 == 9/2*x^2 + 15*x + 25/2
>>> a.expand('left')
256*x^2 - 416*x + 169 == 1/2*(3*x + 5)^2
>>> a.expand('right')
(16*x - 13)^2 == 9/2*x^2 + 15*x + 25/2
expand_sum()[source]

For every symbolic sum in the given expression, try to expand it, symbolically or numerically.

While symbolic sum expressions with constant limits are evaluated immediately on the command line, unevaluated sums of this kind can result from, e.g., substitution of limit variables.

INPUT:

  • self – symbolic expression

EXAMPLES:

sage: (k,n) = var('k,n')
sage: ex = sum(abs(-k*k+n),k,1,n)(n=8); ex
sum(abs(-k^2 + 8), k, 1, 8)
sage: ex.expand_sum()
162
sage: f(x,k) = sum((2/n)*(sin(n*x)*(-1)^(n+1)), n, 1, k)
sage: f(x,2)
-2*sum((-1)^n*sin(n*x)/n, n, 1, 2)
sage: f(x,2).expand_sum()
-sin(2*x) + 2*sin(x)
>>> from sage.all import *
>>> (k,n) = var('k,n')
>>> ex = sum(abs(-k*k+n),k,Integer(1),n)(n=Integer(8)); ex
sum(abs(-k^2 + 8), k, 1, 8)
>>> ex.expand_sum()
162
>>> __tmp__=var("x,k"); f = symbolic_expression(sum((Integer(2)/n)*(sin(n*x)*(-Integer(1))**(n+Integer(1))), n, Integer(1), k)).function(x,k)
>>> f(x,Integer(2))
-2*sum((-1)^n*sin(n*x)/n, n, 1, 2)
>>> f(x,Integer(2)).expand_sum()
-sin(2*x) + 2*sin(x)

We can use this to do floating-point approximation as well:

sage: (k,n) = var('k,n')
sage: f(n)=sum(sqrt(abs(-k*k+n)),k,1,n)
sage: f(n=8)
sum(sqrt(abs(-k^2 + 8)), k, 1, 8)
sage: f(8).expand_sum()
sqrt(41) + sqrt(17) + 2*sqrt(14) + 3*sqrt(7) + 2*sqrt(2) + 3
sage: f(8).expand_sum().n()
31.7752256945384
>>> from sage.all import *
>>> (k,n) = var('k,n')
>>> __tmp__=var("n"); f = symbolic_expression(sum(sqrt(abs(-k*k+n)),k,Integer(1),n)).function(n)
>>> f(n=Integer(8))
sum(sqrt(abs(-k^2 + 8)), k, 1, 8)
>>> f(Integer(8)).expand_sum()
sqrt(41) + sqrt(17) + 2*sqrt(14) + 3*sqrt(7) + 2*sqrt(2) + 3
>>> f(Integer(8)).expand_sum().n()
31.7752256945384

See Issue #9424 for making the following no longer raise an error:

sage: f(8).n()
31.7752256945384
>>> from sage.all import *
>>> f(Integer(8)).n()
31.7752256945384
expand_trig(full=False, half_angles=False, plus=True, times=True)[source]

Expand trigonometric and hyperbolic functions of sums of angles and of multiple angles occurring in self.

For best results, self should already be expanded.

INPUT:

  • full – boolean (default: False); to enhance user control of simplification, this function expands only one level at a time by default, expanding sums of angles or multiple angles. To obtain full expansion into sines and cosines immediately, set the optional parameter full to True.

  • half_angles – boolean (default: False); if True, causes half-angles to be simplified away

  • plus – boolean (default: True); controls the sum rule. Expansion of sums (e.g. \(\sin(x + y)\)) will take place only if plus is True.

  • times – boolean (default: True); controls the product rule, expansion of products (e.g. \(\sin(2 x)\)) will take place only if times is True.

OUTPUT: a symbolic expression

EXAMPLES:

sage: sin(5*x).expand_trig()
5*cos(x)^4*sin(x) - 10*cos(x)^2*sin(x)^3 + sin(x)^5
sage: cos(2*x + var('y')).expand_trig()
cos(2*x)*cos(y) - sin(2*x)*sin(y)
>>> from sage.all import *
>>> sin(Integer(5)*x).expand_trig()
5*cos(x)^4*sin(x) - 10*cos(x)^2*sin(x)^3 + sin(x)^5
>>> cos(Integer(2)*x + var('y')).expand_trig()
cos(2*x)*cos(y) - sin(2*x)*sin(y)

We illustrate various options to this function:

sage: f = sin(sin(3*cos(2*x))*x)
sage: f.expand_trig()
sin((3*cos(cos(2*x))^2*sin(cos(2*x)) - sin(cos(2*x))^3)*x)
sage: f.expand_trig(full=True)
sin((3*(cos(cos(x)^2)*cos(sin(x)^2)
      + sin(cos(x)^2)*sin(sin(x)^2))^2*(cos(sin(x)^2)*sin(cos(x)^2)
                                         - cos(cos(x)^2)*sin(sin(x)^2))
      - (cos(sin(x)^2)*sin(cos(x)^2) - cos(cos(x)^2)*sin(sin(x)^2))^3)*x)
sage: sin(2*x).expand_trig(times=False)
sin(2*x)
sage: sin(2*x).expand_trig(times=True)
2*cos(x)*sin(x)
sage: sin(2 + x).expand_trig(plus=False)
sin(x + 2)
sage: sin(2 + x).expand_trig(plus=True)
cos(x)*sin(2) + cos(2)*sin(x)
sage: sin(x/2).expand_trig(half_angles=False)
sin(1/2*x)
sage: sin(x/2).expand_trig(half_angles=True)
(-1)^floor(1/2*x/pi)*sqrt(-1/2*cos(x) + 1/2)
>>> from sage.all import *
>>> f = sin(sin(Integer(3)*cos(Integer(2)*x))*x)
>>> f.expand_trig()
sin((3*cos(cos(2*x))^2*sin(cos(2*x)) - sin(cos(2*x))^3)*x)
>>> f.expand_trig(full=True)
sin((3*(cos(cos(x)^2)*cos(sin(x)^2)
      + sin(cos(x)^2)*sin(sin(x)^2))^2*(cos(sin(x)^2)*sin(cos(x)^2)
                                         - cos(cos(x)^2)*sin(sin(x)^2))
      - (cos(sin(x)^2)*sin(cos(x)^2) - cos(cos(x)^2)*sin(sin(x)^2))^3)*x)
>>> sin(Integer(2)*x).expand_trig(times=False)
sin(2*x)
>>> sin(Integer(2)*x).expand_trig(times=True)
2*cos(x)*sin(x)
>>> sin(Integer(2) + x).expand_trig(plus=False)
sin(x + 2)
>>> sin(Integer(2) + x).expand_trig(plus=True)
cos(x)*sin(2) + cos(2)*sin(x)
>>> sin(x/Integer(2)).expand_trig(half_angles=False)
sin(1/2*x)
>>> sin(x/Integer(2)).expand_trig(half_angles=True)
(-1)^floor(1/2*x/pi)*sqrt(-1/2*cos(x) + 1/2)

If the expression contains terms which are factored, we expand first:

sage: (x, k1, k2) = var('x, k1, k2')
sage: cos((k1-k2)*x).expand().expand_trig()
cos(k1*x)*cos(k2*x) + sin(k1*x)*sin(k2*x)
>>> from sage.all import *
>>> (x, k1, k2) = var('x, k1, k2')
>>> cos((k1-k2)*x).expand().expand_trig()
cos(k1*x)*cos(k2*x) + sin(k1*x)*sin(k2*x)

ALIAS:

trig_expand() and expand_trig() are the same

exponentialize()[source]

Return this symbolic expression with all circular and hyperbolic functions replaced by their respective exponential expressions.

EXAMPLES:

sage: x = SR.var("x")
sage: sin(x).exponentialize()
-1/2*I*e^(I*x) + 1/2*I*e^(-I*x)
sage: sec(x).exponentialize()
2/(e^(I*x) + e^(-I*x))
sage: tan(x).exponentialize()
(-I*e^(I*x) + I*e^(-I*x))/(e^(I*x) + e^(-I*x))
sage: sinh(x).exponentialize()
-1/2*e^(-x) + 1/2*e^x
sage: sech(x).exponentialize()
2/(e^(-x) + e^x)
sage: tanh(x).exponentialize()
-(e^(-x) - e^x)/(e^(-x) + e^x)
>>> from sage.all import *
>>> x = SR.var("x")
>>> sin(x).exponentialize()
-1/2*I*e^(I*x) + 1/2*I*e^(-I*x)
>>> sec(x).exponentialize()
2/(e^(I*x) + e^(-I*x))
>>> tan(x).exponentialize()
(-I*e^(I*x) + I*e^(-I*x))/(e^(I*x) + e^(-I*x))
>>> sinh(x).exponentialize()
-1/2*e^(-x) + 1/2*e^x
>>> sech(x).exponentialize()
2/(e^(-x) + e^x)
>>> tanh(x).exponentialize()
-(e^(-x) - e^x)/(e^(-x) + e^x)
factor(dontfactor=None)[source]

Factor the expression, containing any number of variables or functions, into factors irreducible over the integers.

INPUT:

  • self – a symbolic expression

  • dontfactor – list (default: []); a list of variables with respect to which factoring is not to occur. Factoring also will not take place with respect to any variables which are less important (using the variable ordering assumed for CRE form) than those on the ‘dontfactor’ list.

EXAMPLES:

sage: x,y,z = var('x, y, z')
sage: (x^3-y^3).factor()
(x^2 + x*y + y^2)*(x - y)
sage: factor(-8*y - 4*x + z^2*(2*y + x))
(x + 2*y)*(z + 2)*(z - 2)
sage: f = -1 - 2*x - x^2 + y^2 + 2*x*y^2 + x^2*y^2
sage: F = factor(f/(36*(1 + 2*y + y^2)), dontfactor=[x]); F
1/36*(x^2 + 2*x + 1)*(y - 1)/(y + 1)
>>> from sage.all import *
>>> x,y,z = var('x, y, z')
>>> (x**Integer(3)-y**Integer(3)).factor()
(x^2 + x*y + y^2)*(x - y)
>>> factor(-Integer(8)*y - Integer(4)*x + z**Integer(2)*(Integer(2)*y + x))
(x + 2*y)*(z + 2)*(z - 2)
>>> f = -Integer(1) - Integer(2)*x - x**Integer(2) + y**Integer(2) + Integer(2)*x*y**Integer(2) + x**Integer(2)*y**Integer(2)
>>> F = factor(f/(Integer(36)*(Integer(1) + Integer(2)*y + y**Integer(2))), dontfactor=[x]); F
1/36*(x^2 + 2*x + 1)*(y - 1)/(y + 1)

If you are factoring a polynomial with rational coefficients (and dontfactor is empty) the factorization is done using Singular instead of Maxima, so the following is very fast instead of dreadfully slow:

sage: var('x,y')
(x, y)
sage: (x^99 + y^99).factor()
(x^60 + x^57*y^3 - x^51*y^9 - x^48*y^12 + x^42*y^18 + x^39*y^21 -
x^33*y^27 - x^30*y^30 - x^27*y^33 + x^21*y^39 + x^18*y^42 -
x^12*y^48 - x^9*y^51 + x^3*y^57 + y^60)*(x^20 + x^19*y -
x^17*y^3 - x^16*y^4 + x^14*y^6 + x^13*y^7 - x^11*y^9 -
x^10*y^10 - x^9*y^11 + x^7*y^13 + x^6*y^14 - x^4*y^16 -
x^3*y^17 + x*y^19 + y^20)*(x^10 - x^9*y + x^8*y^2 - x^7*y^3 +
x^6*y^4 - x^5*y^5 + x^4*y^6 - x^3*y^7 + x^2*y^8 - x*y^9 +
y^10)*(x^6 - x^3*y^3 + y^6)*(x^2 - x*y + y^2)*(x + y)
>>> from sage.all import *
>>> var('x,y')
(x, y)
>>> (x**Integer(99) + y**Integer(99)).factor()
(x^60 + x^57*y^3 - x^51*y^9 - x^48*y^12 + x^42*y^18 + x^39*y^21 -
x^33*y^27 - x^30*y^30 - x^27*y^33 + x^21*y^39 + x^18*y^42 -
x^12*y^48 - x^9*y^51 + x^3*y^57 + y^60)*(x^20 + x^19*y -
x^17*y^3 - x^16*y^4 + x^14*y^6 + x^13*y^7 - x^11*y^9 -
x^10*y^10 - x^9*y^11 + x^7*y^13 + x^6*y^14 - x^4*y^16 -
x^3*y^17 + x*y^19 + y^20)*(x^10 - x^9*y + x^8*y^2 - x^7*y^3 +
x^6*y^4 - x^5*y^5 + x^4*y^6 - x^3*y^7 + x^2*y^8 - x*y^9 +
y^10)*(x^6 - x^3*y^3 + y^6)*(x^2 - x*y + y^2)*(x + y)
factor_list(dontfactor=None)[source]

Return a list of the factors of self, as computed by the factor command.

INPUT:

  • self – a symbolic expression

  • dontfactor – see docs for factor()

Note

If you already have a factored expression and just want to get at the individual factors, use the _factor_list method instead.

EXAMPLES:

sage: var('x, y, z')
(x, y, z)
sage: f = x^3-y^3
sage: f.factor()
(x^2 + x*y + y^2)*(x - y)
>>> from sage.all import *
>>> var('x, y, z')
(x, y, z)
>>> f = x**Integer(3)-y**Integer(3)
>>> f.factor()
(x^2 + x*y + y^2)*(x - y)

Notice that the -1 factor is separated out:

sage: f.factor_list()
[(x^2 + x*y + y^2, 1), (x - y, 1)]
>>> from sage.all import *
>>> f.factor_list()
[(x^2 + x*y + y^2, 1), (x - y, 1)]

We factor a fairly straightforward expression:

sage: factor(-8*y - 4*x + z^2*(2*y + x)).factor_list()
[(x + 2*y, 1), (z + 2, 1), (z - 2, 1)]
>>> from sage.all import *
>>> factor(-Integer(8)*y - Integer(4)*x + z**Integer(2)*(Integer(2)*y + x)).factor_list()
[(x + 2*y, 1), (z + 2, 1), (z - 2, 1)]

A more complicated example:

sage: var('x, u, v')
(x, u, v)
sage: f = expand((2*u*v^2-v^2-4*u^3)^2 * (-u)^3 * (x-sin(x))^3)
sage: f.factor()
-(4*u^3 - 2*u*v^2 + v^2)^2*u^3*(x - sin(x))^3
sage: g = f.factor_list(); g
[(4*u^3 - 2*u*v^2 + v^2, 2), (u, 3), (x - sin(x), 3), (-1, 1)]
>>> from sage.all import *
>>> var('x, u, v')
(x, u, v)
>>> f = expand((Integer(2)*u*v**Integer(2)-v**Integer(2)-Integer(4)*u**Integer(3))**Integer(2) * (-u)**Integer(3) * (x-sin(x))**Integer(3))
>>> f.factor()
-(4*u^3 - 2*u*v^2 + v^2)^2*u^3*(x - sin(x))^3
>>> g = f.factor_list(); g
[(4*u^3 - 2*u*v^2 + v^2, 2), (u, 3), (x - sin(x), 3), (-1, 1)]

This function also works for quotients:

sage: f = -1 - 2*x - x^2 + y^2 + 2*x*y^2 + x^2*y^2
sage: g = f/(36*(1 + 2*y + y^2)); g
1/36*(x^2*y^2 + 2*x*y^2 - x^2 + y^2 - 2*x - 1)/(y^2 + 2*y + 1)
sage: g.factor(dontfactor=[x])
1/36*(x^2 + 2*x + 1)*(y - 1)/(y + 1)
sage: g.factor_list(dontfactor=[x])
[(x^2 + 2*x + 1, 1), (y + 1, -1), (y - 1, 1), (1/36, 1)]
>>> from sage.all import *
>>> f = -Integer(1) - Integer(2)*x - x**Integer(2) + y**Integer(2) + Integer(2)*x*y**Integer(2) + x**Integer(2)*y**Integer(2)
>>> g = f/(Integer(36)*(Integer(1) + Integer(2)*y + y**Integer(2))); g
1/36*(x^2*y^2 + 2*x*y^2 - x^2 + y^2 - 2*x - 1)/(y^2 + 2*y + 1)
>>> g.factor(dontfactor=[x])
1/36*(x^2 + 2*x + 1)*(y - 1)/(y + 1)
>>> g.factor_list(dontfactor=[x])
[(x^2 + 2*x + 1, 1), (y + 1, -1), (y - 1, 1), (1/36, 1)]

This example also illustrates that the exponents do not have to be integers:

sage: f = x^(2*sin(x)) * (x-1)^(sqrt(2)*x); f
(x - 1)^(sqrt(2)*x)*x^(2*sin(x))
sage: f.factor_list()
[(x - 1, sqrt(2)*x), (x, 2*sin(x))]
>>> from sage.all import *
>>> f = x**(Integer(2)*sin(x)) * (x-Integer(1))**(sqrt(Integer(2))*x); f
(x - 1)^(sqrt(2)*x)*x^(2*sin(x))
>>> f.factor_list()
[(x - 1, sqrt(2)*x), (x, 2*sin(x))]
factorial(hold=False)[source]

Return the factorial of self.

OUTPUT: a symbolic expression

EXAMPLES:

sage: var('x, y')
(x, y)
sage: SR(5).factorial()
120
sage: x.factorial()
factorial(x)
sage: (x^2+y^3).factorial()
factorial(y^3 + x^2)
>>> from sage.all import *
>>> var('x, y')
(x, y)
>>> SR(Integer(5)).factorial()
120
>>> x.factorial()
factorial(x)
>>> (x**Integer(2)+y**Integer(3)).factorial()
factorial(y^3 + x^2)

To prevent automatic evaluation use the hold argument:

sage: SR(5).factorial(hold=True)
factorial(5)
>>> from sage.all import *
>>> SR(Integer(5)).factorial(hold=True)
factorial(5)

This also works using functional notation:

sage: factorial(5,hold=True)
factorial(5)
sage: factorial(5)
120
>>> from sage.all import *
>>> factorial(Integer(5),hold=True)
factorial(5)
>>> factorial(Integer(5))
120

To then evaluate again, we use unhold():

sage: a = SR(5).factorial(hold=True); a.unhold()
120
>>> from sage.all import *
>>> a = SR(Integer(5)).factorial(hold=True); a.unhold()
120
factorial_simplify()[source]

Simplify by combining expressions with factorials, and by expanding binomials into factorials.

ALIAS: factorial_simplify and simplify_factorial are the same

EXAMPLES:

Some examples are relatively clear:

sage: var('n,k')
(n, k)
sage: f = factorial(n+1)/factorial(n); f
factorial(n + 1)/factorial(n)
sage: f.simplify_factorial()
n + 1
>>> from sage.all import *
>>> var('n,k')
(n, k)
>>> f = factorial(n+Integer(1))/factorial(n); f
factorial(n + 1)/factorial(n)
>>> f.simplify_factorial()
n + 1

sage: f = factorial(n)*(n+1); f
(n + 1)*factorial(n)
sage: simplify(f)
(n + 1)*factorial(n)
sage: f.simplify_factorial()
factorial(n + 1)
>>> from sage.all import *
>>> f = factorial(n)*(n+Integer(1)); f
(n + 1)*factorial(n)
>>> simplify(f)
(n + 1)*factorial(n)
>>> f.simplify_factorial()
factorial(n + 1)

sage: f = binomial(n, k)*factorial(k)*factorial(n-k); f
binomial(n, k)*factorial(k)*factorial(-k + n)
sage: f.simplify_factorial()
factorial(n)
>>> from sage.all import *
>>> f = binomial(n, k)*factorial(k)*factorial(n-k); f
binomial(n, k)*factorial(k)*factorial(-k + n)
>>> f.simplify_factorial()
factorial(n)

A more complicated example, which needs further processing:

sage: f = factorial(x)/factorial(x-2)/2 + factorial(x+1)/factorial(x)/2; f
1/2*factorial(x + 1)/factorial(x) + 1/2*factorial(x)/factorial(x - 2)
sage: g = f.simplify_factorial(); g
1/2*(x - 1)*x + 1/2*x + 1/2
sage: g.simplify_rational()
1/2*x^2 + 1/2
>>> from sage.all import *
>>> f = factorial(x)/factorial(x-Integer(2))/Integer(2) + factorial(x+Integer(1))/factorial(x)/Integer(2); f
1/2*factorial(x + 1)/factorial(x) + 1/2*factorial(x)/factorial(x - 2)
>>> g = f.simplify_factorial(); g
1/2*(x - 1)*x + 1/2*x + 1/2
>>> g.simplify_rational()
1/2*x^2 + 1/2
find(pattern)[source]

Find all occurrences of the given pattern in this expression.

Note that once a subexpression matches the pattern, the search does not extend to subexpressions of it.

EXAMPLES:

sage: var('x,y,z,a,b')
(x, y, z, a, b)
sage: w0 = SR.wild(0); w1 = SR.wild(1)

sage: (sin(x)*sin(y)).find(sin(w0))
[sin(y), sin(x)]

sage: ((sin(x)+sin(y))*(a+b)).expand().find(sin(w0))
[sin(y), sin(x)]

sage: (1+x+x^2+x^3).find(x)
[x]
sage: (1+x+x^2+x^3).find(x^w0)
[x^2, x^3]

sage: (1+x+x^2+x^3).find(y)
[]

# subexpressions of a match are not listed
sage: ((x^y)^z).find(w0^w1)
[(x^y)^z]
>>> from sage.all import *
>>> var('x,y,z,a,b')
(x, y, z, a, b)
>>> w0 = SR.wild(Integer(0)); w1 = SR.wild(Integer(1))

>>> (sin(x)*sin(y)).find(sin(w0))
[sin(y), sin(x)]

>>> ((sin(x)+sin(y))*(a+b)).expand().find(sin(w0))
[sin(y), sin(x)]

>>> (Integer(1)+x+x**Integer(2)+x**Integer(3)).find(x)
[x]
>>> (Integer(1)+x+x**Integer(2)+x**Integer(3)).find(x**w0)
[x^2, x^3]

>>> (Integer(1)+x+x**Integer(2)+x**Integer(3)).find(y)
[]

# subexpressions of a match are not listed
>>> ((x**y)**z).find(w0**w1)
[(x^y)^z]
find_local_maximum(a, b, var=None, tol=1.48e-08, maxfun=500, imaginary_tolerance=1e-08)[source]

Numerically find a local maximum of the expression self on the interval [a,b] (or [b,a]) along with the point at which the maximum is attained.

See the documentation for find_local_minimum() for more details.

EXAMPLES:

sage: f = x*cos(x)
sage: f.find_local_maximum(0,5)                                             # needs scipy
(0.5610963381910451, 0.8603335890...)
sage: f.find_local_maximum(0,5, tol=0.1, maxfun=10)                         # needs scipy
(0.561090323458081..., 0.857926501456...)
>>> from sage.all import *
>>> f = x*cos(x)
>>> f.find_local_maximum(Integer(0),Integer(5))                                             # needs scipy
(0.5610963381910451, 0.8603335890...)
>>> f.find_local_maximum(Integer(0),Integer(5), tol=RealNumber('0.1'), maxfun=Integer(10))                         # needs scipy
(0.561090323458081..., 0.857926501456...)
find_local_minimum(a, b, var=None, tol=1.48e-08, maxfun=500, imaginary_tolerance=1e-08)[source]

Numerically find a local minimum of the expression self on the interval [a,b] (or [b,a]) and the point at which it attains that minimum. Note that self must be a function of (at most) one variable.

INPUT:

  • a – real number; left endpoint of interval on which to minimize

  • b – real number; right endpoint of interval on which to minimize

  • var – variable (default: first variable in self); the variable in self to maximize over

  • tol – positive real (default: 1.48e-08); the convergence tolerance

  • maxfun – natural number (default: 500); maximum function evaluations

  • imaginary_tolerance – (default: 1e-8) if an imaginary number arises (due, for example, to numerical issues), this tolerance specifies how large it has to be in magnitude before we raise an error. In other words, imaginary parts smaller than this are ignored when we are expecting a real answer.

OUTPUT:

A tuple (minval, x), where

  • minval – float; the minimum value that self takes on in the interval [a,b]

  • x – float; the point at which self takes on the minimum value

EXAMPLES:

sage: # needs scipy
sage: f = x*cos(x)
sage: f.find_local_minimum(1, 5)
(-3.288371395590..., 3.4256184695...)
sage: f.find_local_minimum(1, 5, tol=1e-3)
(-3.288371361890..., 3.4257507903...)
sage: f.find_local_minimum(1, 5, tol=1e-2, maxfun=10)
(-3.288370845983..., 3.4250840220...)
sage: show(f.plot(0, 20))                                                   # needs sage.plot
sage: f.find_local_minimum(1, 15)
(-9.477294259479..., 9.5293344109...)
>>> from sage.all import *
>>> # needs scipy
>>> f = x*cos(x)
>>> f.find_local_minimum(Integer(1), Integer(5))
(-3.288371395590..., 3.4256184695...)
>>> f.find_local_minimum(Integer(1), Integer(5), tol=RealNumber('1e-3'))
(-3.288371361890..., 3.4257507903...)
>>> f.find_local_minimum(Integer(1), Integer(5), tol=RealNumber('1e-2'), maxfun=Integer(10))
(-3.288370845983..., 3.4250840220...)
>>> show(f.plot(Integer(0), Integer(20)))                                                   # needs sage.plot
>>> f.find_local_minimum(Integer(1), Integer(15))
(-9.477294259479..., 9.5293344109...)

ALGORITHM:

Uses sage.numerical.optimize.find_local_minimum().

AUTHORS:

  • William Stein (2007-12-07)

find_root(a, b, var=None, xtol=1e-12, rtol=8.881784197001252e-16, maxiter=100, full_output=False, imaginary_tolerance=1e-08)[source]

Numerically find a root of self on the closed interval [a,b] (or [b,a]) if possible, where self is a function in one variable. Note: this function only works in fixed (machine) precision, it is not possible to get arbitrary precision approximations with it.

INPUT:

  • a, b – endpoints of the interval

  • var – (optional) variable

  • xtol, rtol – the routine converges when a root is known to lie within xtol of the value return. Should be nonnegative. The routine modifies this to take into account the relative precision of doubles.

  • maxiter – integer; if convergence is not achieved in maxiter iterations, an error is raised. Must be nonnegative.

  • full_output – boolean (default: False); if True, also return object that contains information about convergence

  • imaginary_tolerance – (default: 1e-8) if an imaginary number arises (due, for example, to numerical issues), this tolerance specifies how large it has to be in magnitude before we raise an error. In other words, imaginary parts smaller than this are ignored when we are expecting a real answer.

EXAMPLES:

Note that in this example both f(-2) and f(3) are positive, yet we still find a root in that interval:

sage: # needs scipy
sage: f = x^2 - 1
sage: f.find_root(-2, 3)
1.0
sage: f.find_root(-2, 3, x)
1.0
sage: z, result = f.find_root(-2, 3, full_output=True)
sage: result.converged
True
sage: result.flag
'converged'
sage: result.function_calls
11
sage: result.iterations
10
sage: result.root
1.0
>>> from sage.all import *
>>> # needs scipy
>>> f = x**Integer(2) - Integer(1)
>>> f.find_root(-Integer(2), Integer(3))
1.0
>>> f.find_root(-Integer(2), Integer(3), x)
1.0
>>> z, result = f.find_root(-Integer(2), Integer(3), full_output=True)
>>> result.converged
True
>>> result.flag
'converged'
>>> result.function_calls
11
>>> result.iterations
10
>>> result.root
1.0

More examples:

sage: (sin(x) + exp(x)).find_root(-10, 10)                                  # needs scipy
-0.588532743981862...
sage: sin(x).find_root(-1,1)                                                # needs scipy
0.0
>>> from sage.all import *
>>> (sin(x) + exp(x)).find_root(-Integer(10), Integer(10))                                  # needs scipy
-0.588532743981862...
>>> sin(x).find_root(-Integer(1),Integer(1))                                                # needs scipy
0.0

This example was fixed along with Issue #4942 - there was an error in the example pi is a root for tan(x), but an asymptote to 1/tan(x) added an example to show handling of both cases:

sage: (tan(x)).find_root(3,3.5)                                             # needs scipy
3.1415926535...
sage: (1/tan(x)).find_root(3, 3.5)                                          # needs scipy
Traceback (most recent call last):
...
NotImplementedError: Brent's method failed to find a zero for f on the interval
>>> from sage.all import *
>>> (tan(x)).find_root(Integer(3),RealNumber('3.5'))                                             # needs scipy
3.1415926535...
>>> (Integer(1)/tan(x)).find_root(Integer(3), RealNumber('3.5'))                                          # needs scipy
Traceback (most recent call last):
...
NotImplementedError: Brent's method failed to find a zero for f on the interval

An example with a square root:

sage: f = 1 + x + sqrt(x+2); f.find_root(-2,10)                             # needs scipy
-1.618033988749895
>>> from sage.all import *
>>> f = Integer(1) + x + sqrt(x+Integer(2)); f.find_root(-Integer(2),Integer(10))                             # needs scipy
-1.618033988749895

Some examples that Ted Kosan came up with:

sage: t = var('t')
sage: v = 0.004*(9600*e^(-(1200*t)) - 2400*e^(-(300*t)))
sage: v.find_root(0, 0.002)                                                 # needs scipy
0.001540327067911417...
>>> from sage.all import *
>>> t = var('t')
>>> v = RealNumber('0.004')*(Integer(9600)*e**(-(Integer(1200)*t)) - Integer(2400)*e**(-(Integer(300)*t)))
>>> v.find_root(Integer(0), RealNumber('0.002'))                                                 # needs scipy
0.001540327067911417...

With this expression, we can see there is a zero very close to the origin:

sage: a = .004*(8*e^(-(300*t)) - 8*e^(-(1200*t)))*(720000*e^(-(300*t)) - 11520000*e^(-(1200*t))) +.004*(9600*e^(-(1200*t)) - 2400*e^(-(300*t)))^2
sage: show(plot(a, 0, .002), xmin=0, xmax=.002)                             # needs sage.plot
>>> from sage.all import *
>>> a = RealNumber('.004')*(Integer(8)*e**(-(Integer(300)*t)) - Integer(8)*e**(-(Integer(1200)*t)))*(Integer(720000)*e**(-(Integer(300)*t)) - Integer(11520000)*e**(-(Integer(1200)*t))) +RealNumber('.004')*(Integer(9600)*e**(-(Integer(1200)*t)) - Integer(2400)*e**(-(Integer(300)*t)))**Integer(2)
>>> show(plot(a, Integer(0), RealNumber('.002')), xmin=Integer(0), xmax=RealNumber('.002'))                             # needs sage.plot

It is easy to approximate with find_root:

sage: a.find_root(0,0.002)                                                  # needs scipy
0.0004110514049349...
>>> from sage.all import *
>>> a.find_root(Integer(0),RealNumber('0.002'))                                                  # needs scipy
0.0004110514049349...

Using solve takes more effort, and even then gives only a solution with free (integer) variables:

sage: a.solve(t)
[]
sage: b = a.canonicalize_radical(); b
(46080.0*e^(1800*t) - 576000.0*e^(900*t) + 737280.0)*e^(-2400*t)
sage: b.solve(t)
[]
sage: b.solve(t, to_poly_solve=True)
[t == 1/450*I*pi*z... + 1/900*log(-3/4*sqrt(41) + 25/4),
 t == 1/450*I*pi*z... + 1/900*log(3/4*sqrt(41) + 25/4)]
sage: n(1/900*log(-3/4*sqrt(41) + 25/4))
0.000411051404934985
>>> from sage.all import *
>>> a.solve(t)
[]
>>> b = a.canonicalize_radical(); b
(46080.0*e^(1800*t) - 576000.0*e^(900*t) + 737280.0)*e^(-2400*t)
>>> b.solve(t)
[]
>>> b.solve(t, to_poly_solve=True)
[t == 1/450*I*pi*z... + 1/900*log(-3/4*sqrt(41) + 25/4),
 t == 1/450*I*pi*z... + 1/900*log(3/4*sqrt(41) + 25/4)]
>>> n(Integer(1)/Integer(900)*log(-Integer(3)/Integer(4)*sqrt(Integer(41)) + Integer(25)/Integer(4)))
0.000411051404934985

We illustrate that root finding is only implemented in one dimension:

sage: x, y = var('x,y')
sage: (x-y).find_root(-2,2)
Traceback (most recent call last):
...
NotImplementedError: root finding currently only implemented in 1 dimension.
>>> from sage.all import *
>>> x, y = var('x,y')
>>> (x-y).find_root(-Integer(2),Integer(2))
Traceback (most recent call last):
...
NotImplementedError: root finding currently only implemented in 1 dimension.
forget()[source]

Forget the given constraint.

EXAMPLES:

sage: var('x,y')
(x, y)
sage: forget()
sage: assume(x>0, y < 2)
sage: assumptions()
[x > 0, y < 2]
sage: forget(y < 2)
sage: assumptions()
[x > 0]
>>> from sage.all import *
>>> var('x,y')
(x, y)
>>> forget()
>>> assume(x>Integer(0), y < Integer(2))
>>> assumptions()
[x > 0, y < 2]
>>> forget(y < Integer(2))
>>> assumptions()
[x > 0]
fraction(base_ring)[source]

Return this expression as element of the algebraic fraction field over the base ring given.

EXAMPLES:

sage: fr = (1/x).fraction(ZZ); fr
1/x
sage: parent(fr)
Fraction Field of Univariate Polynomial Ring in x over Integer Ring
sage: parent(((pi+sqrt(2)/x).fraction(SR)))
Fraction Field of Univariate Polynomial Ring in x over Symbolic Ring
sage: parent(((pi+sqrt(2))/x).fraction(SR))
Fraction Field of Univariate Polynomial Ring in x over Symbolic Ring
sage: y = var('y')
sage: fr = ((3*x^5 - 5*y^5)^7/(x*y)).fraction(GF(7)); fr
(3*x^35 + 2*y^35)/(x*y)
sage: parent(fr)
Fraction Field of Multivariate Polynomial Ring in x, y over Finite Field of size 7
>>> from sage.all import *
>>> fr = (Integer(1)/x).fraction(ZZ); fr
1/x
>>> parent(fr)
Fraction Field of Univariate Polynomial Ring in x over Integer Ring
>>> parent(((pi+sqrt(Integer(2))/x).fraction(SR)))
Fraction Field of Univariate Polynomial Ring in x over Symbolic Ring
>>> parent(((pi+sqrt(Integer(2)))/x).fraction(SR))
Fraction Field of Univariate Polynomial Ring in x over Symbolic Ring
>>> y = var('y')
>>> fr = ((Integer(3)*x**Integer(5) - Integer(5)*y**Integer(5))**Integer(7)/(x*y)).fraction(GF(Integer(7))); fr
(3*x^35 + 2*y^35)/(x*y)
>>> parent(fr)
Fraction Field of Multivariate Polynomial Ring in x, y over Finite Field of size 7
free_variables()[source]

Return sorted tuple of unbound variables that occur in this expression.

EXAMPLES:

sage: (x,y,z) = var('x,y,z')
sage: (x+y).free_variables()
(x, y)
sage: (2*x).free_variables()
(x,)
sage: (x^y).free_variables()
(x, y)
sage: sin(x+y^z).free_variables()
(x, y, z)
sage: _ = function('f')
sage: e = limit( f(x,y), x=0 ); e
limit(f(x, y), x, 0)
sage: e.free_variables()
(y,)
>>> from sage.all import *
>>> (x,y,z) = var('x,y,z')
>>> (x+y).free_variables()
(x, y)
>>> (Integer(2)*x).free_variables()
(x,)
>>> (x**y).free_variables()
(x, y)
>>> sin(x+y**z).free_variables()
(x, y, z)
>>> _ = function('f')
>>> e = limit( f(x,y), x=Integer(0) ); e
limit(f(x, y), x, 0)
>>> e.free_variables()
(y,)
full_simplify()[source]

Apply simplify_factorial(), simplify_rectform(), simplify_trig(), simplify_rational(), and then expand_sum() to self (in that order).

ALIAS: simplify_full and full_simplify are the same.

EXAMPLES:

sage: f = sin(x)^2 + cos(x)^2
sage: f.simplify_full()
1
>>> from sage.all import *
>>> f = sin(x)**Integer(2) + cos(x)**Integer(2)
>>> f.simplify_full()
1

sage: f = sin(x/(x^2 + x))
sage: f.simplify_full()
sin(1/(x + 1))
>>> from sage.all import *
>>> f = sin(x/(x**Integer(2) + x))
>>> f.simplify_full()
sin(1/(x + 1))

sage: var('n,k')
(n, k)
sage: f = binomial(n,k)*factorial(k)*factorial(n-k)
sage: f.simplify_full()
factorial(n)
>>> from sage.all import *
>>> var('n,k')
(n, k)
>>> f = binomial(n,k)*factorial(k)*factorial(n-k)
>>> f.simplify_full()
factorial(n)
function(*args)[source]

Return a callable symbolic expression with the given variables.

EXAMPLES:

We will use several symbolic variables in the examples below:

sage: var('x, y, z, t, a, w, n')
(x, y, z, t, a, w, n)
>>> from sage.all import *
>>> var('x, y, z, t, a, w, n')
(x, y, z, t, a, w, n)

sage: u = sin(x) + x*cos(y)
sage: g = u.function(x,y)
sage: g(x,y)
x*cos(y) + sin(x)
sage: g(t,z)
t*cos(z) + sin(t)
sage: g(x^2, x^y)
x^2*cos(x^y) + sin(x^2)
>>> from sage.all import *
>>> u = sin(x) + x*cos(y)
>>> g = u.function(x,y)
>>> g(x,y)
x*cos(y) + sin(x)
>>> g(t,z)
t*cos(z) + sin(t)
>>> g(x**Integer(2), x**y)
x^2*cos(x^y) + sin(x^2)

sage: f = (x^2 + sin(a*w)).function(a,x,w); f
(a, x, w) |--> x^2 + sin(a*w)
sage: f(1,2,3)
sin(3) + 4
>>> from sage.all import *
>>> f = (x**Integer(2) + sin(a*w)).function(a,x,w); f
(a, x, w) |--> x^2 + sin(a*w)
>>> f(Integer(1),Integer(2),Integer(3))
sin(3) + 4

Using the function() method we can obtain the above function \(f\), but viewed as a function of different variables:

sage: h = f.function(w,a); h
(w, a) |--> x^2 + sin(a*w)
>>> from sage.all import *
>>> h = f.function(w,a); h
(w, a) |--> x^2 + sin(a*w)

This notation also works:

sage: h(w,a) = f
sage: h
(w, a) |--> x^2 + sin(a*w)
>>> from sage.all import *
>>> __tmp__=var("w,a"); h = symbolic_expression(f).function(w,a)
>>> h
(w, a) |--> x^2 + sin(a*w)

You can even make a symbolic expression \(f\) into a function by writing f(x,y) = f:

sage: f = x^n + y^n; f
x^n + y^n
sage: f(x,y) = f
sage: f
(x, y) |--> x^n + y^n
sage: f(2,3)
3^n + 2^n
>>> from sage.all import *
>>> f = x**n + y**n; f
x^n + y^n
>>> __tmp__=var("x,y"); f = symbolic_expression(f).function(x,y)
>>> f
(x, y) |--> x^n + y^n
>>> f(Integer(2),Integer(3))
3^n + 2^n
gamma(hold=False)[source]

Return the Gamma function evaluated at self.

EXAMPLES:

sage: x = var('x')
sage: x.gamma()
gamma(x)
sage: SR(2).gamma()
1
sage: SR(10).gamma()
362880
sage: SR(10.0r).gamma()  # For ARM: rel tol 2e-15
362880.0
sage: SR(CDF(1,1)).gamma()
0.49801566811835607 - 0.15494982830181067*I
>>> from sage.all import *
>>> x = var('x')
>>> x.gamma()
gamma(x)
>>> SR(Integer(2)).gamma()
1
>>> SR(Integer(10)).gamma()
362880
>>> SR(10.0).gamma()  # For ARM: rel tol 2e-15
362880.0
>>> SR(CDF(Integer(1),Integer(1))).gamma()
0.49801566811835607 - 0.15494982830181067*I

sage: gp('gamma(1+I)')
0.4980156681183560427136911175 - 0.1549498283018106851249551305*I # 32-bit
0.49801566811835604271369111746219809195 - 0.15494982830181068512495513048388660520*I # 64-bit
>>> from sage.all import *
>>> gp('gamma(1+I)')
0.4980156681183560427136911175 - 0.1549498283018106851249551305*I # 32-bit
0.49801566811835604271369111746219809195 - 0.15494982830181068512495513048388660520*I # 64-bit

We plot the familiar plot of this log-convex function:

sage: plot(gamma(x), -6, 4).show(ymin=-3, ymax=3)                           # needs sage.plot
>>> from sage.all import *
>>> plot(gamma(x), -Integer(6), Integer(4)).show(ymin=-Integer(3), ymax=Integer(3))                           # needs sage.plot

To prevent automatic evaluation use the hold argument:

sage: SR(1/2).gamma()
sqrt(pi)
sage: SR(1/2).gamma(hold=True)
gamma(1/2)
>>> from sage.all import *
>>> SR(Integer(1)/Integer(2)).gamma()
sqrt(pi)
>>> SR(Integer(1)/Integer(2)).gamma(hold=True)
gamma(1/2)

This also works using functional notation:

sage: gamma(1/2, hold=True)
gamma(1/2)
sage: gamma(1/2)
sqrt(pi)
>>> from sage.all import *
>>> gamma(Integer(1)/Integer(2), hold=True)
gamma(1/2)
>>> gamma(Integer(1)/Integer(2))
sqrt(pi)

To then evaluate again, we use unhold():

sage: a = SR(1/2).gamma(hold=True); a.unhold()
sqrt(pi)
>>> from sage.all import *
>>> a = SR(Integer(1)/Integer(2)).gamma(hold=True); a.unhold()
sqrt(pi)
gamma_normalize()[source]

Return the expression with any gamma functions that have a common base converted to that base.

Additionally the expression is normalized so any fractions can be simplified through cancellation.

EXAMPLES:

sage: m,n = var('m n', domain='integer')
sage: (gamma(n+2)/gamma(n)).gamma_normalize()
(n + 1)*n
sage: (gamma(n+2)*gamma(n)).gamma_normalize()
(n + 1)*n*gamma(n)^2
sage: (gamma(n+2)*gamma(m-1)/gamma(n)/gamma(m+1)).gamma_normalize()
(n + 1)*n/((m - 1)*m)
>>> from sage.all import *
>>> m,n = var('m n', domain='integer')
>>> (gamma(n+Integer(2))/gamma(n)).gamma_normalize()
(n + 1)*n
>>> (gamma(n+Integer(2))*gamma(n)).gamma_normalize()
(n + 1)*n*gamma(n)^2
>>> (gamma(n+Integer(2))*gamma(m-Integer(1))/gamma(n)/gamma(m+Integer(1))).gamma_normalize()
(n + 1)*n/((m - 1)*m)

Check that Issue #22826 is fixed:

sage: _ = var('n')
sage: (n-1).gcd(n+1)
1
sage: ex = (n-1)^2*gamma(2*n+5)/gamma(n+3) + gamma(2*n+3)/gamma(n+1)
sage: ex.gamma_normalize()
(4*n^3 - 2*n^2 - 7*n + 7)*gamma(2*n + 3)/((n + 1)*gamma(n + 1))
>>> from sage.all import *
>>> _ = var('n')
>>> (n-Integer(1)).gcd(n+Integer(1))
1
>>> ex = (n-Integer(1))**Integer(2)*gamma(Integer(2)*n+Integer(5))/gamma(n+Integer(3)) + gamma(Integer(2)*n+Integer(3))/gamma(n+Integer(1))
>>> ex.gamma_normalize()
(4*n^3 - 2*n^2 - 7*n + 7)*gamma(2*n + 3)/((n + 1)*gamma(n + 1))
gcd(b)[source]

Return the symbolic gcd of self and b.

Note that the polynomial GCD is unique up to the multiplication by an invertible constant. The following examples make sure all results are caught.

EXAMPLES:

sage: var('x,y')
(x, y)
sage: SR(10).gcd(SR(15))
5
sage: (x^3 - 1).gcd(x-1) / (x-1) in QQ
True
sage: (x^3 - 1).gcd(x^2+x+1) / (x^2+x+1) in QQ
True
sage: (x^3 - x^2*pi + x^2 - pi^2).gcd(x-pi) / (x-pi) in QQ
True
sage: gcd(sin(x)^2 + sin(x), sin(x)^2 - 1) / (sin(x) + 1) in QQ
True
sage: gcd(x^3 - y^3, x-y) / (x-y) in QQ
True
sage: gcd(x^100-y^100, x^10-y^10) / (x^10-y^10) in QQ
True
sage: r = gcd(expand( (x^2+17*x+3/7*y)*(x^5 - 17*y + 2/3) ), expand((x^13+17*x+3/7*y)*(x^5 - 17*y + 2/3)) )
sage: r / (x^5 - 17*y + 2/3) in QQ
True
>>> from sage.all import *
>>> var('x,y')
(x, y)
>>> SR(Integer(10)).gcd(SR(Integer(15)))
5
>>> (x**Integer(3) - Integer(1)).gcd(x-Integer(1)) / (x-Integer(1)) in QQ
True
>>> (x**Integer(3) - Integer(1)).gcd(x**Integer(2)+x+Integer(1)) / (x**Integer(2)+x+Integer(1)) in QQ
True
>>> (x**Integer(3) - x**Integer(2)*pi + x**Integer(2) - pi**Integer(2)).gcd(x-pi) / (x-pi) in QQ
True
>>> gcd(sin(x)**Integer(2) + sin(x), sin(x)**Integer(2) - Integer(1)) / (sin(x) + Integer(1)) in QQ
True
>>> gcd(x**Integer(3) - y**Integer(3), x-y) / (x-y) in QQ
True
>>> gcd(x**Integer(100)-y**Integer(100), x**Integer(10)-y**Integer(10)) / (x**Integer(10)-y**Integer(10)) in QQ
True
>>> r = gcd(expand( (x**Integer(2)+Integer(17)*x+Integer(3)/Integer(7)*y)*(x**Integer(5) - Integer(17)*y + Integer(2)/Integer(3)) ), expand((x**Integer(13)+Integer(17)*x+Integer(3)/Integer(7)*y)*(x**Integer(5) - Integer(17)*y + Integer(2)/Integer(3))) )
>>> r / (x**Integer(5) - Integer(17)*y + Integer(2)/Integer(3)) in QQ
True

Embedded Sage objects of all kinds get basic support. Note that full algebraic GCD is not implemented yet:

sage: gcd(I - I*x, x^2 - 1)
x - 1
sage: gcd(I + I*x, x^2 - 1)
x + 1
sage: alg = SR(QQbar(sqrt(2) + I*sqrt(3)))
sage: gcd(alg + alg*x, x^2 - 1)  # known bug (Issue #28489)
x + 1
sage: gcd(alg - alg*x, x^2 - 1)  # known bug (Issue #28489)
x - 1
sage: sqrt2 = SR(QQbar(sqrt(2)))
sage: gcd(sqrt2 + x, x^2 - 2)    # known bug
1
>>> from sage.all import *
>>> gcd(I - I*x, x**Integer(2) - Integer(1))
x - 1
>>> gcd(I + I*x, x**Integer(2) - Integer(1))
x + 1
>>> alg = SR(QQbar(sqrt(Integer(2)) + I*sqrt(Integer(3))))
>>> gcd(alg + alg*x, x**Integer(2) - Integer(1))  # known bug (Issue #28489)
x + 1
>>> gcd(alg - alg*x, x**Integer(2) - Integer(1))  # known bug (Issue #28489)
x - 1
>>> sqrt2 = SR(QQbar(sqrt(Integer(2))))
>>> gcd(sqrt2 + x, x**Integer(2) - Integer(2))    # known bug
1
gosper_sum(*args)[source]

Return the summation of this hypergeometric expression using Gosper’s algorithm.

INPUT:

  • a symbolic expression that may contain rational functions, powers, factorials, gamma function terms, binomial coefficients, and Pochhammer symbols that are rational-linear in their arguments

  • the main variable and, optionally, summation limits

EXAMPLES:

sage: a,b,k,m,n = var('a b k m n')
sage: SR(1).gosper_sum(n)
n
sage: SR(1).gosper_sum(n,5,8)
4
sage: n.gosper_sum(n)
1/2*(n - 1)*n
sage: n.gosper_sum(n,0,5)
15
sage: n.gosper_sum(n,0,m)
1/2*(m + 1)*m
sage: n.gosper_sum(n,a,b)
-1/2*(a + b)*(a - b - 1)
>>> from sage.all import *
>>> a,b,k,m,n = var('a b k m n')
>>> SR(Integer(1)).gosper_sum(n)
n
>>> SR(Integer(1)).gosper_sum(n,Integer(5),Integer(8))
4
>>> n.gosper_sum(n)
1/2*(n - 1)*n
>>> n.gosper_sum(n,Integer(0),Integer(5))
15
>>> n.gosper_sum(n,Integer(0),m)
1/2*(m + 1)*m
>>> n.gosper_sum(n,a,b)
-1/2*(a + b)*(a - b - 1)

sage: (factorial(m + n)/factorial(n)).gosper_sum(n)
n*factorial(m + n)/((m + 1)*factorial(n))
sage: (binomial(m + n, n)).gosper_sum(n)
n*binomial(m + n, n)/(m + 1)
sage: (binomial(m + n, n)).gosper_sum(n, 0, a)
(a + m + 1)*binomial(a + m, a)/(m + 1)
sage: (binomial(m + n, n)).gosper_sum(n, 0, 5)
1/120*(m + 6)*(m + 5)*(m + 4)*(m + 3)*(m + 2)
sage: (rising_factorial(a,n)/rising_factorial(b,n)).gosper_sum(n)
(b + n - 1)*gamma(a + n)*gamma(b)/((a - b + 1)*gamma(a)*gamma(b + n))
sage: factorial(n).gosper_term(n)
Traceback (most recent call last):
...
ValueError: expression not Gosper-summable
>>> from sage.all import *
>>> (factorial(m + n)/factorial(n)).gosper_sum(n)
n*factorial(m + n)/((m + 1)*factorial(n))
>>> (binomial(m + n, n)).gosper_sum(n)
n*binomial(m + n, n)/(m + 1)
>>> (binomial(m + n, n)).gosper_sum(n, Integer(0), a)
(a + m + 1)*binomial(a + m, a)/(m + 1)
>>> (binomial(m + n, n)).gosper_sum(n, Integer(0), Integer(5))
1/120*(m + 6)*(m + 5)*(m + 4)*(m + 3)*(m + 2)
>>> (rising_factorial(a,n)/rising_factorial(b,n)).gosper_sum(n)
(b + n - 1)*gamma(a + n)*gamma(b)/((a - b + 1)*gamma(a)*gamma(b + n))
>>> factorial(n).gosper_term(n)
Traceback (most recent call last):
...
ValueError: expression not Gosper-summable
gosper_term(n)[source]

Return Gosper’s hypergeometric term for self.

Suppose f``=``self is a hypergeometric term such that:

\[s_n = \sum_{k=0}^{n-1} f_k\]

and \(f_k\) doesn’t depend on \(n\). Return a hypergeometric term \(g_n\) such that \(g_{n+1} - g_n = f_n\).

EXAMPLES:

sage: _ = var('n')
sage: SR(1).gosper_term(n)
n
sage: n.gosper_term(n)
1/2*(n^2 - n)/n
sage: (n*factorial(n)).gosper_term(n)
1/n
sage: factorial(n).gosper_term(n)
Traceback (most recent call last):
...
ValueError: expression not Gosper-summable
>>> from sage.all import *
>>> _ = var('n')
>>> SR(Integer(1)).gosper_term(n)
n
>>> n.gosper_term(n)
1/2*(n^2 - n)/n
>>> (n*factorial(n)).gosper_term(n)
1/n
>>> factorial(n).gosper_term(n)
Traceback (most recent call last):
...
ValueError: expression not Gosper-summable
gradient(variables=None)[source]

Compute the gradient of a symbolic function.

This function returns a vector whose components are the derivatives of the original function with respect to the arguments of the original function. Alternatively, you can specify the variables as a list.

EXAMPLES:

sage: x,y = var('x y')
sage: f = x^2+y^2
sage: f.gradient()
(2*x, 2*y)
sage: g(x,y) = x^2+y^2
sage: g.gradient()
(x, y) |--> (2*x, 2*y)
sage: n = var('n')
sage: f(x,y) = x^n+y^n
sage: f.gradient()
(x, y) |--> (n*x^(n - 1), n*y^(n - 1))
sage: f.gradient([y,x])
(x, y) |--> (n*y^(n - 1), n*x^(n - 1))
>>> from sage.all import *
>>> x,y = var('x y')
>>> f = x**Integer(2)+y**Integer(2)
>>> f.gradient()
(2*x, 2*y)
>>> __tmp__=var("x,y"); g = symbolic_expression(x**Integer(2)+y**Integer(2)).function(x,y)
>>> g.gradient()
(x, y) |--> (2*x, 2*y)
>>> n = var('n')
>>> __tmp__=var("x,y"); f = symbolic_expression(x**n+y**n).function(x,y)
>>> f.gradient()
(x, y) |--> (n*x^(n - 1), n*y^(n - 1))
>>> f.gradient([y,x])
(x, y) |--> (n*y^(n - 1), n*x^(n - 1))

See also

gradient() of scalar fields on Euclidean spaces (and more generally pseudo-Riemannian manifolds), in particular for computing the gradient in curvilinear coordinates.

half_angle()[source]

Replace all occurrences of trigonometric (or hyperbolic) functions by rational fractions of the (hyperbolic) tangent of half the original argument.

This can help highlight the algebraic structure of an expression, which can be useful e.g. for integration.

This method has no direct relation with the half_angles argument of the trig_expand() method.

EXAMPLES:

sage: x, t = var("x, t")
sage: cos(x).half_angle().subs(tan(x/2) == t)
-(t^2 - 1)/(t^2 + 1)
>>> from sage.all import *
>>> x, t = var("x, t")
>>> cos(x).half_angle().subs(tan(x/Integer(2)) == t)
-(t^2 - 1)/(t^2 + 1)

Note that this structure highlighting works better after expansion:

sage: x, t = var("x, t")
sage: a = (cos(3*x)/(4-cos(x)))
sage: b = a.trig_expand()
sage: a.half_angle().subs(tan(x/2) == t).simplify_full()
(2*(t^2 + 1)*cos(3/2*x)^2 - t^2 - 1)/(5*t^2 + 3)
sage: b.half_angle().subs(tan(x/2) == t).simplify_full()
-(t^6 - 15*t^4 + 15*t^2 - 1)/(5*t^6 + 13*t^4 + 11*t^2 + 3)
>>> from sage.all import *
>>> x, t = var("x, t")
>>> a = (cos(Integer(3)*x)/(Integer(4)-cos(x)))
>>> b = a.trig_expand()
>>> a.half_angle().subs(tan(x/Integer(2)) == t).simplify_full()
(2*(t^2 + 1)*cos(3/2*x)^2 - t^2 - 1)/(5*t^2 + 3)
>>> b.half_angle().subs(tan(x/Integer(2)) == t).simplify_full()
-(t^6 - 15*t^4 + 15*t^2 - 1)/(5*t^6 + 13*t^4 + 11*t^2 + 3)
has(pattern)[source]

EXAMPLES:

sage: var('x,y,a'); w0 = SR.wild(); w1 = SR.wild()
(x, y, a)
sage: (x*sin(x + y + 2*a)).has(y)
True
>>> from sage.all import *
>>> var('x,y,a'); w0 = SR.wild(); w1 = SR.wild()
(x, y, a)
>>> (x*sin(x + y + Integer(2)*a)).has(y)
True

Here “x+y” is not a subexpression of “x+y+2*a” (which has the subexpressions “x”, “y” and “2*a”):

sage: (x*sin(x + y + 2*a)).has(x+y)
False
sage: (x*sin(x + y + 2*a)).has(x + y + w0)
True
>>> from sage.all import *
>>> (x*sin(x + y + Integer(2)*a)).has(x+y)
False
>>> (x*sin(x + y + Integer(2)*a)).has(x + y + w0)
True

The following fails because “2*(x+y)” automatically gets converted to “2*x+2*y” of which “x+y” is not a subexpression:

sage: (x*sin(2*(x+y) + 2*a)).has(x+y)
False
>>> from sage.all import *
>>> (x*sin(Integer(2)*(x+y) + Integer(2)*a)).has(x+y)
False

Although x^1==x and x^0==1, neither “x” nor “1” are actually of the form “x^something”:

sage: (x+1).has(x^w0)
False
>>> from sage.all import *
>>> (x+Integer(1)).has(x**w0)
False

Here is another possible pitfall, where the first expression matches because the term “-x” has the form “(-1)*x” in GiNaC. To check whether a polynomial contains a linear term you should use the coeff() function instead.

sage: (4*x^2 - x + 3).has(w0*x)
True
sage: (4*x^2 + x + 3).has(w0*x)
False
sage: (4*x^2 + x + 3).has(x)
True
sage: (4*x^2 - x + 3).coefficient(x,1)
-1
sage: (4*x^2 + x + 3).coefficient(x,1)
1
>>> from sage.all import *
>>> (Integer(4)*x**Integer(2) - x + Integer(3)).has(w0*x)
True
>>> (Integer(4)*x**Integer(2) + x + Integer(3)).has(w0*x)
False
>>> (Integer(4)*x**Integer(2) + x + Integer(3)).has(x)
True
>>> (Integer(4)*x**Integer(2) - x + Integer(3)).coefficient(x,Integer(1))
-1
>>> (Integer(4)*x**Integer(2) + x + Integer(3)).coefficient(x,Integer(1))
1
has_wild()[source]

Return True if this expression contains a wildcard.

EXAMPLES:

sage: (1 + x^2).has_wild()
False
sage: (SR.wild(0) + x^2).has_wild()
True
sage: SR.wild(0).has_wild()
True
>>> from sage.all import *
>>> (Integer(1) + x**Integer(2)).has_wild()
False
>>> (SR.wild(Integer(0)) + x**Integer(2)).has_wild()
True
>>> SR.wild(Integer(0)).has_wild()
True
hessian()[source]

Compute the hessian of a function. This returns a matrix components are the 2nd partial derivatives of the original function.

EXAMPLES:

sage: x,y = var('x y')
sage: f = x^2+y^2
sage: f.hessian()
[2 0]
[0 2]
sage: g(x,y) = x^2+y^2
sage: g.hessian()
[(x, y) |--> 2 (x, y) |--> 0]
[(x, y) |--> 0 (x, y) |--> 2]
>>> from sage.all import *
>>> x,y = var('x y')
>>> f = x**Integer(2)+y**Integer(2)
>>> f.hessian()
[2 0]
[0 2]
>>> __tmp__=var("x,y"); g = symbolic_expression(x**Integer(2)+y**Integer(2)).function(x,y)
>>> g.hessian()
[(x, y) |--> 2 (x, y) |--> 0]
[(x, y) |--> 0 (x, y) |--> 2]
horner(x)[source]

Rewrite this expression as a polynomial in Horner form in x.

EXAMPLES:

sage: add((i+1)*x^i for i in range(5)).horner(x)
(((5*x + 4)*x + 3)*x + 2)*x + 1

sage: x, y, z = SR.var('x,y,z')
sage: (x^5 + y*cos(x) + z^3 + (x + y)^2 + y^x).horner(x)
z^3 + ((x^3 + 1)*x + 2*y)*x + y^2 + y*cos(x) + y^x

sage: expr = sin(5*x).expand_trig(); expr
5*cos(x)^4*sin(x) - 10*cos(x)^2*sin(x)^3 + sin(x)^5
sage: expr.horner(sin(x))
(5*cos(x)^4 - (10*cos(x)^2 - sin(x)^2)*sin(x)^2)*sin(x)
sage: expr.horner(cos(x))
sin(x)^5 + 5*(cos(x)^2*sin(x) - 2*sin(x)^3)*cos(x)^2
>>> from sage.all import *
>>> add((i+Integer(1))*x**i for i in range(Integer(5))).horner(x)
(((5*x + 4)*x + 3)*x + 2)*x + 1

>>> x, y, z = SR.var('x,y,z')
>>> (x**Integer(5) + y*cos(x) + z**Integer(3) + (x + y)**Integer(2) + y**x).horner(x)
z^3 + ((x^3 + 1)*x + 2*y)*x + y^2 + y*cos(x) + y^x

>>> expr = sin(Integer(5)*x).expand_trig(); expr
5*cos(x)^4*sin(x) - 10*cos(x)^2*sin(x)^3 + sin(x)^5
>>> expr.horner(sin(x))
(5*cos(x)^4 - (10*cos(x)^2 - sin(x)^2)*sin(x)^2)*sin(x)
>>> expr.horner(cos(x))
sin(x)^5 + 5*(cos(x)^2*sin(x) - 2*sin(x)^3)*cos(x)^2
hypergeometric_simplify(algorithm='maxima')[source]

Simplify an expression containing hypergeometric or confluent hypergeometric functions.

INPUT:

  • algorithm – (default: 'maxima') the algorithm to use for for simplification. Implemented are 'maxima', which uses Maxima’s hgfred function, and 'sage', which uses an algorithm implemented in the hypergeometric module

ALIAS: hypergeometric_simplify() and simplify_hypergeometric() are the same

EXAMPLES:

sage: hypergeometric((5, 4), (4, 1, 2, 3),
....:                x).simplify_hypergeometric()
1/144*x^2*hypergeometric((), (3, 4), x) +...
1/3*x*hypergeometric((), (2, 3), x) + hypergeometric((), (1, 2), x)
sage: (2*hypergeometric((), (), x)).simplify_hypergeometric()
2*e^x
sage: (nest(lambda y: hypergeometric([y], [1], x), 3, 1)  # not tested, unstable
....:  .simplify_hypergeometric())
laguerre(-laguerre(-e^x, x), x)
sage: (nest(lambda y: hypergeometric([y], [1], x), 3, 1)  # not tested, unstable
....:  .simplify_hypergeometric(algorithm='sage'))
hypergeometric((hypergeometric((e^x,), (1,), x),), (1,), x)
sage: hypergeometric_M(1, 3, x).simplify_hypergeometric()
-2*((x + 1)*e^(-x) - 1)*e^x/x^2
sage: (2 * hypergeometric_U(1, 3, x)).simplify_hypergeometric()
2*(x + 1)/x^2
>>> from sage.all import *
>>> hypergeometric((Integer(5), Integer(4)), (Integer(4), Integer(1), Integer(2), Integer(3)),
...                x).simplify_hypergeometric()
1/144*x^2*hypergeometric((), (3, 4), x) +...
1/3*x*hypergeometric((), (2, 3), x) + hypergeometric((), (1, 2), x)
>>> (Integer(2)*hypergeometric((), (), x)).simplify_hypergeometric()
2*e^x
>>> (nest(lambda y: hypergeometric([y], [Integer(1)], x), Integer(3), Integer(1))  # not tested, unstable
...  .simplify_hypergeometric())
laguerre(-laguerre(-e^x, x), x)
>>> (nest(lambda y: hypergeometric([y], [Integer(1)], x), Integer(3), Integer(1))  # not tested, unstable
...  .simplify_hypergeometric(algorithm='sage'))
hypergeometric((hypergeometric((e^x,), (1,), x),), (1,), x)
>>> hypergeometric_M(Integer(1), Integer(3), x).simplify_hypergeometric()
-2*((x + 1)*e^(-x) - 1)*e^x/x^2
>>> (Integer(2) * hypergeometric_U(Integer(1), Integer(3), x)).simplify_hypergeometric()
2*(x + 1)/x^2
imag(hold=False)[source]

Return the imaginary part of this symbolic expression.

EXAMPLES:

sage: sqrt(-2).imag_part()
sqrt(2)
>>> from sage.all import *
>>> sqrt(-Integer(2)).imag_part()
sqrt(2)

We simplify \(\ln(\exp(z))\) to \(z\). This should only be for \(-\pi<{\rm Im}(z)<=\pi\), but Maxima does not have a symbolic imaginary part function, so we cannot use assume to assume that first:

sage: z = var('z')
sage: f = log(exp(z))
sage: f
log(e^z)
sage: f.simplify()
z
sage: forget()
>>> from sage.all import *
>>> z = var('z')
>>> f = log(exp(z))
>>> f
log(e^z)
>>> f.simplify()
z
>>> forget()

A more symbolic example:

sage: var('a, b')
(a, b)
sage: f = log(a + b*I)
sage: f.imag_part()
arctan2(imag_part(a) + real_part(b), -imag_part(b) + real_part(a))
>>> from sage.all import *
>>> var('a, b')
(a, b)
>>> f = log(a + b*I)
>>> f.imag_part()
arctan2(imag_part(a) + real_part(b), -imag_part(b) + real_part(a))

Using the hold parameter it is possible to prevent automatic evaluation:

sage: SR(I).imag_part()
1
sage: SR(I).imag_part(hold=True)
imag_part(I)
>>> from sage.all import *
>>> SR(I).imag_part()
1
>>> SR(I).imag_part(hold=True)
imag_part(I)

This also works using functional notation:

sage: imag_part(I, hold=True)
imag_part(I)
sage: imag_part(SR(I))
1
>>> from sage.all import *
>>> imag_part(I, hold=True)
imag_part(I)
>>> imag_part(SR(I))
1

To then evaluate again, we use unhold():

sage: a = SR(I).imag_part(hold=True); a.unhold()
1
>>> from sage.all import *
>>> a = SR(I).imag_part(hold=True); a.unhold()
1
imag_part(hold=False)[source]

Return the imaginary part of this symbolic expression.

EXAMPLES:

sage: sqrt(-2).imag_part()
sqrt(2)
>>> from sage.all import *
>>> sqrt(-Integer(2)).imag_part()
sqrt(2)

We simplify \(\ln(\exp(z))\) to \(z\). This should only be for \(-\pi<{\rm Im}(z)<=\pi\), but Maxima does not have a symbolic imaginary part function, so we cannot use assume to assume that first:

sage: z = var('z')
sage: f = log(exp(z))
sage: f
log(e^z)
sage: f.simplify()
z
sage: forget()
>>> from sage.all import *
>>> z = var('z')
>>> f = log(exp(z))
>>> f
log(e^z)
>>> f.simplify()
z
>>> forget()

A more symbolic example:

sage: var('a, b')
(a, b)
sage: f = log(a + b*I)
sage: f.imag_part()
arctan2(imag_part(a) + real_part(b), -imag_part(b) + real_part(a))
>>> from sage.all import *
>>> var('a, b')
(a, b)
>>> f = log(a + b*I)
>>> f.imag_part()
arctan2(imag_part(a) + real_part(b), -imag_part(b) + real_part(a))

Using the hold parameter it is possible to prevent automatic evaluation:

sage: SR(I).imag_part()
1
sage: SR(I).imag_part(hold=True)
imag_part(I)
>>> from sage.all import *
>>> SR(I).imag_part()
1
>>> SR(I).imag_part(hold=True)
imag_part(I)

This also works using functional notation:

sage: imag_part(I, hold=True)
imag_part(I)
sage: imag_part(SR(I))
1
>>> from sage.all import *
>>> imag_part(I, hold=True)
imag_part(I)
>>> imag_part(SR(I))
1

To then evaluate again, we use unhold():

sage: a = SR(I).imag_part(hold=True); a.unhold()
1
>>> from sage.all import *
>>> a = SR(I).imag_part(hold=True); a.unhold()
1
implicit_derivative(Y, X, n=1)[source]

Return the \(n\)-th derivative of \(Y\) with respect to \(X\) given implicitly by this expression.

INPUT:

  • Y – the dependent variable of the implicit expression

  • X – the independent variable with respect to which the derivative is taken

  • n – (default: 1) the order of the derivative

EXAMPLES:

sage: var('x, y')
(x, y)
sage: f = cos(x)*sin(y)
sage: f.implicit_derivative(y, x)
sin(x)*sin(y)/(cos(x)*cos(y))
sage: g = x*y^2
sage: g.implicit_derivative(y, x, 3)
-1/4*(y + 2*y/x)/x^2 + 1/4*(2*y^2/x - y^2/x^2)/(x*y) - 3/4*y/x^3
>>> from sage.all import *
>>> var('x, y')
(x, y)
>>> f = cos(x)*sin(y)
>>> f.implicit_derivative(y, x)
sin(x)*sin(y)/(cos(x)*cos(y))
>>> g = x*y**Integer(2)
>>> g.implicit_derivative(y, x, Integer(3))
-1/4*(y + 2*y/x)/x^2 + 1/4*(2*y^2/x - y^2/x^2)/(x*y) - 3/4*y/x^3

It is an error to not include an independent variable term in the expression:

sage: (cos(x)*sin(x)).implicit_derivative(y, x)
Traceback (most recent call last):
...
ValueError: Expression cos(x)*sin(x) contains no y terms
>>> from sage.all import *
>>> (cos(x)*sin(x)).implicit_derivative(y, x)
Traceback (most recent call last):
...
ValueError: Expression cos(x)*sin(x) contains no y terms
integral(*args, **kwds)[source]

Compute the integral of self.

Please see sage.symbolic.integration.integral.integrate() for more details.

EXAMPLES:

sage: sin(x).integral(x,0,3)
-cos(3) + 1
sage: sin(x).integral(x)
-cos(x)
>>> from sage.all import *
>>> sin(x).integral(x,Integer(0),Integer(3))
-cos(3) + 1
>>> sin(x).integral(x)
-cos(x)
integrate(*args, **kwds)[source]

Compute the integral of self.

Please see sage.symbolic.integration.integral.integrate() for more details.

EXAMPLES:

sage: sin(x).integral(x,0,3)
-cos(3) + 1
sage: sin(x).integral(x)
-cos(x)
>>> from sage.all import *
>>> sin(x).integral(x,Integer(0),Integer(3))
-cos(3) + 1
>>> sin(x).integral(x)
-cos(x)
inverse_laplace(t, s)[source]

Return inverse Laplace transform of self.

See sage.calculus.calculus.inverse_laplace

EXAMPLES:

sage: var('w, m')
(w, m)
sage: f = (1/(w^2+10)).inverse_laplace(w, m); f
1/10*sqrt(10)*sin(sqrt(10)*m)
>>> from sage.all import *
>>> var('w, m')
(w, m)
>>> f = (Integer(1)/(w**Integer(2)+Integer(10))).inverse_laplace(w, m); f
1/10*sqrt(10)*sin(sqrt(10)*m)
is_algebraic()[source]

Return True if this expression is known to be algebraic.

EXAMPLES:

sage: sqrt(2).is_algebraic()
True
sage: (5*sqrt(2)).is_algebraic()
True
sage: (sqrt(2) + 2^(1/3) - 1).is_algebraic()
True
sage: (I*golden_ratio + sqrt(2)).is_algebraic()
True
sage: (sqrt(2) + pi).is_algebraic()
False
sage: SR(QQ(2/3)).is_algebraic()
True
sage: SR(1.2).is_algebraic()
False

sage: complex_root_of(x^3 - x^2 - x - 1, 0).is_algebraic()
True
>>> from sage.all import *
>>> sqrt(Integer(2)).is_algebraic()
True
>>> (Integer(5)*sqrt(Integer(2))).is_algebraic()
True
>>> (sqrt(Integer(2)) + Integer(2)**(Integer(1)/Integer(3)) - Integer(1)).is_algebraic()
True
>>> (I*golden_ratio + sqrt(Integer(2))).is_algebraic()
True
>>> (sqrt(Integer(2)) + pi).is_algebraic()
False
>>> SR(QQ(Integer(2)/Integer(3))).is_algebraic()
True
>>> SR(RealNumber('1.2')).is_algebraic()
False

>>> complex_root_of(x**Integer(3) - x**Integer(2) - x - Integer(1), Integer(0)).is_algebraic()
True
is_callable()[source]

Return True if self is a callable symbolic expression.

EXAMPLES:

sage: var('a x y z')
(a, x, y, z)
sage: f(x, y) = a + 2*x + 3*y + z
sage: f.is_callable()
True
sage: (a+2*x).is_callable()
False
>>> from sage.all import *
>>> var('a x y z')
(a, x, y, z)
>>> __tmp__=var("x,y"); f = symbolic_expression(a + Integer(2)*x + Integer(3)*y + z).function(x,y)
>>> f.is_callable()
True
>>> (a+Integer(2)*x).is_callable()
False
is_constant()[source]

Return whether this symbolic expression is a constant.

A symbolic expression is constant if it does not contain any variables.

EXAMPLES:

sage: pi.is_constant()
True
sage: SR(1).is_constant()
True
sage: SR(2).is_constant()
True
sage: log(2).is_constant()
True
sage: SR(I).is_constant()
True
sage: x.is_constant()
False
>>> from sage.all import *
>>> pi.is_constant()
True
>>> SR(Integer(1)).is_constant()
True
>>> SR(Integer(2)).is_constant()
True
>>> log(Integer(2)).is_constant()
True
>>> SR(I).is_constant()
True
>>> x.is_constant()
False
is_exact()[source]

Return True if this expression only contains exact numerical coefficients.

EXAMPLES:

sage: x, y = var('x, y')
sage: (x+y-1).is_exact()
True
sage: (x+y-1.9).is_exact()
False
sage: x.is_exact()
True
sage: pi.is_exact()
True
sage: (sqrt(x-y) - 2*x + 1).is_exact()
True
sage: ((x-y)^0.5 - 2*x + 1).is_exact()
False
>>> from sage.all import *
>>> x, y = var('x, y')
>>> (x+y-Integer(1)).is_exact()
True
>>> (x+y-RealNumber('1.9')).is_exact()
False
>>> x.is_exact()
True
>>> pi.is_exact()
True
>>> (sqrt(x-y) - Integer(2)*x + Integer(1)).is_exact()
True
>>> ((x-y)**RealNumber('0.5') - Integer(2)*x + Integer(1)).is_exact()
False
is_infinity()[source]

Return True if self is an infinite expression.

EXAMPLES:

sage: SR(oo).is_infinity()
True
sage: x.is_infinity()
False
>>> from sage.all import *
>>> SR(oo).is_infinity()
True
>>> x.is_infinity()
False
is_integer()[source]

Return True if this expression is known to be an integer.

EXAMPLES:

sage: SR(5).is_integer()
True
>>> from sage.all import *
>>> SR(Integer(5)).is_integer()
True
is_negative()[source]

Return True if this expression is known to be negative.

EXAMPLES:

sage: SR(-5).is_negative()
True
>>> from sage.all import *
>>> SR(-Integer(5)).is_negative()
True

Check if we can correctly deduce negativity of mul objects:

sage: t0 = SR.symbol("t0", domain='positive')
sage: t0.is_negative()
False
sage: (-t0).is_negative()
True
sage: (-pi).is_negative()
True
>>> from sage.all import *
>>> t0 = SR.symbol("t0", domain='positive')
>>> t0.is_negative()
False
>>> (-t0).is_negative()
True
>>> (-pi).is_negative()
True

Assumptions on symbols are handled correctly:

sage: y = var('y')
sage: assume(y < 0)
sage: y.is_positive()
False
sage: y.is_negative()
True
sage: forget()
>>> from sage.all import *
>>> y = var('y')
>>> assume(y < Integer(0))
>>> y.is_positive()
False
>>> y.is_negative()
True
>>> forget()
is_negative_infinity()[source]

Return True if self is a negative infinite expression.

EXAMPLES:

sage: SR(oo).is_negative_infinity()
False
sage: SR(-oo).is_negative_infinity()
True
sage: x.is_negative_infinity()
False
>>> from sage.all import *
>>> SR(oo).is_negative_infinity()
False
>>> SR(-oo).is_negative_infinity()
True
>>> x.is_negative_infinity()
False
is_numeric()[source]

A Pynac numeric is an object you can do arithmetic with that is not a symbolic variable, function, or constant. Return True if this expression only consists of a numeric object.

EXAMPLES:

sage: SR(1).is_numeric()
True
sage: x.is_numeric()
False
sage: pi.is_numeric()
False
sage: sin(x).is_numeric()
False
>>> from sage.all import *
>>> SR(Integer(1)).is_numeric()
True
>>> x.is_numeric()
False
>>> pi.is_numeric()
False
>>> sin(x).is_numeric()
False
is_polynomial(var)[source]

Return True if self is a polynomial in the given variable.

EXAMPLES:

sage: var('x,y,z')
(x, y, z)
sage: t = x^2 + y; t
x^2 + y
sage: t.is_polynomial(x)
True
sage: t.is_polynomial(y)
True
sage: t.is_polynomial(z)
True

sage: t = sin(x) + y; t
y + sin(x)
sage: t.is_polynomial(x)
False
sage: t.is_polynomial(y)
True
sage: t.is_polynomial(sin(x))
True
>>> from sage.all import *
>>> var('x,y,z')
(x, y, z)
>>> t = x**Integer(2) + y; t
x^2 + y
>>> t.is_polynomial(x)
True
>>> t.is_polynomial(y)
True
>>> t.is_polynomial(z)
True

>>> t = sin(x) + y; t
y + sin(x)
>>> t.is_polynomial(x)
False
>>> t.is_polynomial(y)
True
>>> t.is_polynomial(sin(x))
True
is_positive()[source]

Return True if this expression is known to be positive.

EXAMPLES:

sage: t0 = SR.symbol("t0", domain='positive')
sage: t0.is_positive()
True
sage: t0.is_negative()
False
sage: t0.is_real()
True
sage: t1 = SR.symbol("t1", domain='positive')
sage: (t0*t1).is_positive()
True
sage: (t0 + t1).is_positive()
True
sage: (t0*x).is_positive()
False
>>> from sage.all import *
>>> t0 = SR.symbol("t0", domain='positive')
>>> t0.is_positive()
True
>>> t0.is_negative()
False
>>> t0.is_real()
True
>>> t1 = SR.symbol("t1", domain='positive')
>>> (t0*t1).is_positive()
True
>>> (t0 + t1).is_positive()
True
>>> (t0*x).is_positive()
False

sage: forget()
sage: assume(x>0)
sage: x.is_positive()
True
sage: cosh(x).is_positive()
True
sage: f = function('f')(x)
sage: assume(f>0)
sage: f.is_positive()
True
sage: forget()
>>> from sage.all import *
>>> forget()
>>> assume(x>Integer(0))
>>> x.is_positive()
True
>>> cosh(x).is_positive()
True
>>> f = function('f')(x)
>>> assume(f>Integer(0))
>>> f.is_positive()
True
>>> forget()
is_positive_infinity()[source]

Return True if self is a positive infinite expression.

EXAMPLES:

sage: SR(oo).is_positive_infinity()
True
sage: SR(-oo).is_positive_infinity()
False
sage: x.is_infinity()
False
>>> from sage.all import *
>>> SR(oo).is_positive_infinity()
True
>>> SR(-oo).is_positive_infinity()
False
>>> x.is_infinity()
False
is_rational_expression()[source]

Return True if this expression if a rational expression, i.e., a quotient of polynomials.

EXAMPLES:

sage: var('x y z')
(x, y, z)
sage: ((x + y + z)/(1 + x^2)).is_rational_expression()
True