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
x = var('x') eqn = (x-1)^2 <= x^2 - 2*x + 3 eqn.subs(x == 5)
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
eqn^2 eqn.expand()
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
eqn = SR(-5) < SR(-3); eqn bool(eqn) eqn^2 bool(eqn^2)
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)
e = x+1 <= x-2 e + 2 e - 1 e*(-1) (-2)*e e*5 e/5 5/e e/(-2) -2/e
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
(x^3 + x <= x - 17) + (-x <= x - 10)
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
(x^3 + x <= x - 17) + (-x >= x - 10)
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
R.<u,v> = QQ[] var('a,b,c') expand((u + v + a + b + c)^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 byexp(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]
e.operator() e.operands()
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]
e + 2 2 + e 2*e e*2 x*e var('a,b') t = e^(a+b); t t.operands()
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
RR(e) R = RealField(200); R R(e) em = 1 + e^(1-e); em R(em) maxima(e).float() t = mathematica(e) # optional - mathematica t # optional - mathematica float(t) # optional - mathematica loads(dumps(e)) float(e) e.__float__() e._mpfr_(RealField(100)) e._real_double_(RDF) # abs tol 5e-16 import sympy # needs sympy sympy.E == e # indirect doctest # needs sympy
- 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)
n = var('n') t = (17*n^3).Order(); t t.derivative(n)
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)
(17*n^3).Order(hold=True)
- 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
_ = var('k n') F(n,k) = binomial(n,k) / 2^n c = F(n,k).WZ_certificate(n,k); c G(n,k) = c * F(n,k); G (F(n+1,k) - F(n,k) - G(n,k+1) + G(n,k)).simplify_full()
- 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)
var('x, y') (x+y).abs()
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)
SR(-5).abs(hold=True)
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
a = SR(-5).abs(hold=True); a.unhold()
- 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
x.add(x) x.add(x, hold=True) x.add(x, (2+x), hold=True) x.add(x, (2+x), x, hold=True) x.add(x, (2+x), x, 2*x, hold=True)
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
a = x.add(x, hold=True); a.unhold()
- 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)
var('x y z') eqn = x^2 + y^2 + z^2 <= 1 eqn.add_to_both_sides(-z^2) eqn.add_to_both_sides(I)
- 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
x.arccos() SR(1).arccos() SR(1/2).arccos() SR(0.4).arccos() plot(lambda x: SR(x).arccos(), -1,1) # needs sage.plot
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)
SR(1).arccos(hold=True)
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
arccos(1, hold=True) arccos(1)
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
a = SR(1).arccos(hold=True); a.unhold()
- 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)
x.arccosh() SR(0).arccosh() SR(1/2).arccosh() SR(CDF(1/2)).arccosh() # rel tol 1e-15 z = maxima('acosh(0.5)') z.real(), z.imag() # abs tol 1e-15
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)
SR(-1).arccosh() SR(-1).arccosh(hold=True)
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
arccosh(-1,hold=True) arccosh(-1)
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
a = SR(-1).arccosh(hold=True); a.unhold()
- 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)
x.arcsin() SR(0.5).arcsin() SR(0.999).arcsin() SR(1/3).arcsin() SR(-1/3).arcsin()
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)
SR(0).arcsin() SR(0).arcsin(hold=True)
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
arcsin(0,hold=True) arcsin(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
a = SR(0).arcsin(hold=True); a.unhold()
- 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...
x.arcsinh() SR(0).arcsinh() SR(1).arcsinh() SR(1.0).arcsinh() maxima('asinh(2.0)')
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)
SR(3/2).arcsinh().cosh()
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)
SR(-2).arcsinh() SR(-2).arcsinh(hold=True)
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)
arcsinh(-2,hold=True) 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)
a = SR(-2).arcsinh(hold=True); a.unhold()
- 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
x = var('x') x.arctan() SR(1).arctan() SR(1/2).arctan() SR(0.5).arctan() plot(lambda x: SR(x).arctan(), -20,20) # needs sage.plot
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)
SR(1).arctan(hold=True)
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
arctan(1, hold=True) arctan(1)
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
a = SR(1).arctan(hold=True); a.unhold()
- arctan2(x, hold=False)[source]¶
Return the inverse of the 2-variable tan function on
self
andx
.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
var('x,y') x.arctan2(y) SR(1/2).arctan2(1/2) maxima.eval('atan2(1/2,1/2)') SR(-0.7).arctan2(SR(-0.6))
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)
SR(1/2).arctan2(1/2, hold=True)
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)
arctan2(1,2,hold=True) arctan2(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
a = SR(1/2).arctan2(1/2, hold=True); a.unhold()
- 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
x.arctanh() SR(0).arctanh() SR(1/2).arctanh() SR(0.5).arctanh() SR(0.5).arctanh().tanh() maxima('atanh(0.5)') # abs tol 2e-16
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)
SR(-1/2).arctanh() SR(-1/2).arctanh(hold=True)
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)
arctanh(-1/2,hold=True) arctanh(-1/2)
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)
a = SR(-1/2).arctanh(hold=True); a.unhold()
- 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,)
x,y = var('x,y') f = x + y f.arguments() g = f.function(x) g.arguments()
- 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,)
x,y = var('x,y') f = x + y f.arguments() g = f.function(x) g.arguments()
- 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()
(x > 2).assume()
bool
returnsTrue
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
bool(x > 0) bool(x < 0)
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
bool(x > 3)
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()
forget() assume(x<0) assume(x>0) assumptions() 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)
var('x, y') SR(5).binomial(SR(3)) x.binomial(SR(3)) x.binomial(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)
x.binomial(3, hold=True) SR(5).binomial(3, hold=True)
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
a = SR(5).binomial(3, hold=True); a.unhold()
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)
binomial(5,3, hold=True)
- 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
. Thecanonicalize_radical()
function will choose one of them, consistently, based on the behavior of the expression asx
tends to positive infinity. The solution chosen is the one which exhibits this same behavior. Sincesqrt(x^2)
approaches positive infinity asx
does, the solution chosen isx
(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 aslog_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)
y = SR.symbol('y') f = log(x*y) f.log_expand() f.canonicalize_radical()
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
f = (e^x-1)/(1+e^(x/2)) f.canonicalize_radical()
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
f = log(8)/log(2) f.canonicalize_radical()
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)
a = SR.symbol('a') f = (log(x+x^2)-log(x))^a/log(1+x)^(a/2) f.canonicalize_radical()
>>> 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)
a = SR.symbol('a') f = (log(x+x^2)-log(x))^a/log(1+x)^(a/2) f.canonicalize_radical()
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
sqrt(x^2).canonicalize_radical()
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
sqrt(x^2 - 2*x + 1).canonicalize_radical()
Another place where this can become confusing is with logarithms of complex numbers. Suppose
x
is complex withx == r*e^(I*t)
(r
real). Thenlog(x)
islog(r) + I*(t + 2*k*pi)
for some integerk
.Calling
canonicalize_radical()
will choose a branch, eliminating the solutions for all choices ofk
but one. Simplified by hand, the expression below is(1/2)*log(2) + I*pi*k
for integerk
. 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)
f = (1/2)*log(2*x) + (1/2)*log(1/x) f.canonicalize_radical()
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)
f(x = -1)
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
e1 = 1/(sqrt(5)+sqrt(2)) e2 = (sqrt(5)-sqrt(2))/3 e1.canonicalize_radical() e2.canonicalize_radical() (e1-e2).canonicalize_radical()
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
f1 = sqrt(25 - x) * sqrt( 1 + 1/(4*(25-x)) ) f2 = f1.canonicalize_radical() numerical_integral(f1.real(), 0, 1)[0] # abs tol 1e-10 numerical_integral(f2.real(), 0, 1)[0] # abs tol 1e-10
- coefficient(s, n=1)[source]¶
Return the coefficient of \(s^n\) in this symbolic expression.
INPUT:
s
– expressionn
– 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
var('x,y,a') f = 100 + a*x + x^3*sin(x*y) + x*y + x/y + 2*sin(x*y)/x; f f.collect(x) f.coefficient(x,0) f.coefficient(x,-1) f.coefficient(x,1) f.coefficient(x,2) f.coefficient(x,3) f.coefficient(x^3) f.coefficient(sin(x*y)) f.collect(sin(x*y)) var('a, x, y, z') f = (a*sqrt(2))*x^2 + sin(y)*x^(1/2) + z^z f.coefficient(sin(y)) f.coefficient(x^2) f.coefficient(x^(1/2)) f.coefficient(1) f.coefficient(x, 0)
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
(x^2 + 3*x^pi).coefficient(x, pi) (2^x + 5*x^x).coefficient(x, x)
- 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)
, whereexpr
is a symbolic expression andn
is a power (sparse=True
, default)A list of expressions where the
n
-th element is the coefficient ofx^n
whenself
is seen as polynomial inx
(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]
var('x, y, a') p = x^3 - (x-3)*(x^2+x) + 1 p.coefficients() p.coefficients(sparse=False) p = x - x^3 + 5/7*x^5 p.coefficients() p.coefficients(sparse=False) p = expand((x-a*sqrt(2))^2 + x + 1); p p.coefficients(a) p.coefficients(a, sparse=False) p.coefficients(x) p.coefficients(x, sparse=False)
- 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 beforecollect()
.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
x,y,z = var('x,y,z') f = 4*x*y + x*z + 20*y^2 + 21*y*z + 4*z^2 + x^2*y^2*z^2 f.collect(x)
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
f.collect(y) f.collect(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
f = (x + y)*(x - z) f.collect(x) f.expand().collect(x)
- 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
var('x') (x/(x^2 + x)).collect_common_factors() var('a,b,c,x,y') (a*x+a*y).collect_common_factors() (a*x^2+2*a*x*y+a*y^2).collect_common_factors() (a*(b*(a+c)*x+b*((a+c)*x+(a+c)*y)*y)).collect_common_factors()
- 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
var('x, y, a, b, c') f = x*(x-1)/(x^2 - 7) + y^2/(x^2-7) + 1/(x+1) + b/a + c/a; f f.combine() (1/x + 1/x^2 + (x+1)/x).combine() ex = 1/x + ((x + 1)/x - 1/x)/x^2 + (x+1)/x; ex ex.combine() ex.combine(deep=True) (1+sin((x + 1)/x - 1/x)).combine(deep=True)
- 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
a = 1 + 2*I a.conjugate() a = sqrt(2) + 3^(1/3)*I; a a.conjugate() SR(CDF.0).conjugate() x.conjugate() SR(RDF(1.5)).conjugate() SR(float(1.5)).conjugate() SR(I).conjugate() ( 1+I + (2-3*I)*x).conjugate()
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)
SR(I).conjugate(hold=True)
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)
conjugate(I) conjugate(I,hold=True)
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
a = SR(I).conjugate(hold=True); a.unhold()
- content(s)[source]¶
Return the content of this expression when considered as a polynomial in
s
.See also
unit()
,primitive_part()
, andunit_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 thecontent()
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
(2*x+4).content(x) (2*x+1).content(x) (2*x+1/2).content(x) var('y') (2*x + 4*sin(y)).content(sin(y))
- 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
(x<3).contradicts(x==0) (x<3).contradicts(x==3) (x<=3).contradicts(x==3) y = var('y') (x<y).contradicts(x==30) (x<y).contradicts({x: 30, y: 20})
- 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 fromtarget
– (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
units.length.foot.convert() units.mass.kilogram.convert(units.mass.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
a = var('a') a - a.convert()
Raises
ValueError
ifself
andtarget
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
units.mass.kilogram.convert(units.length.foot) (units.length.meter^2).convert(units.length.foot)
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
(units.length.foot/units.time.second^2).convert(units.acceleration.galileo) (units.mass.kilogram*units.length.meter/units.time.second^2).convert(units.force.newton) (units.length.foot^3).convert(units.area.acre*units.length.inch) (units.charge.coulomb).convert(units.current.ampere*units.time.second) (units.pressure.pascal*units.si_prefixes.kilo).convert(units.pressure.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
(units.pressure.pascal*units.si_prefixes.kilo).convert(units.pressure.pounds_per_square_inch)*1.0
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
s = 68*units.temperature.fahrenheit s.convert(units.temperature.celsius) s.convert()
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
wrong = 50*units.temperature.celsius*units.length.foot wrong.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
var('x, y') cos(x^2 + y^2) cos(sage.symbolic.constants.pi) cos(SR(1)) cos(SR(RealField(150)(1)))
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
SR(RR(1)).cos().n() SR(float(1)).cos().n()
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)
pi.cos() pi.cos(hold=True)
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
cos(pi,hold=True) cos(pi)
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
a = pi.cos(hold=True); a.unhold()
- 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?
x.cosh() SR(1).cosh() SR(0).cosh() SR(1.0).cosh() maxima('cosh(1.0)') SR(1.00000000000000000000000000).cosh() SR(RIF(1)).cosh()
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))
arcsinh(x).cosh() arcsinh(x).cosh(hold=True)
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)
cosh(arcsinh(x),hold=True) cosh(arcsinh(x))
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)
a = arcsinh(x).cosh(hold=True); a.unhold()
- csgn(hold=False)[source]¶
Return the sign of
self
, which is -1 ifself < 0
, 0 ifself == 0
, and 1 ifself > 0
, or unevaluated whenself
is a nonconstant symbolic expression.If
self
is not real, return the complex half-plane (left or right) in which the number lies. Ifself
is pure imaginary, return the sign of the imaginary part ofself
.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
x = var('x') SR(-2).csgn() SR(0.0).csgn() SR(10).csgn() x.csgn() SR(CDF.0).csgn() SR(I).csgn() SR(-I).csgn() SR(1+I).csgn() SR(1-I).csgn() SR(-1+I).csgn() SR(-1-I).csgn()
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)
SR(I).csgn(hold=True)
- default_variable()[source]¶
Return the default variable, which is by definition the first variable in
self
, or \(x\) if there are no variables inself
. 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
sqrt(2).default_variable() x, theta, a = var('x, theta, a') f = x^2 + theta^3 - a^x f.default_variable()
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)
f(theta, a, x) = a + theta^3 f.default_variable() f.variables() f.arguments()
- degree(s)[source]¶
Return the exponent of the highest power of
s
inself
.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
var('x,y,a') f = 100 + a*x + x^3*sin(x*y) + x*y + x/y^10 + 2*sin(x*y)/x; f f.degree(x) f.degree(y) f.degree(sin(x*y)) (x^-3+y).degree(x) (1/x+1/x**2).degree(x)
- 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)
x, a, b = SR.var("x, a, b") exp(a + I*b).demoivre() exp(I*x).demoivre() exp(x).demoivre() exp(x).demoivre(force=True)
- denominator(normalize=True)[source]¶
Return the denominator of this symbolic expression.
INPUT:
normalize
– boolean (default:True
)
If
normalize
isTrue
, the expression is first normalized to have it as a fraction before getting the denominator.If
normalize
isFalse
, the expression is kept and if it is not a quotient, then this will just return 1.See also
normalize()
,numerator()
,numerator_denominator()
,combine()
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
x, y, z, theta = var('x, y, z, theta') f = (sqrt(x) + sqrt(y) + sqrt(z))/(x^10 - y^10 - sqrt(theta)) f.numerator() f.denominator() f.numerator(normalize=False) f.denominator(normalize=False) y = var('y') g = x + y/(x + 2); g g.numerator(normalize=False) g.denominator(normalize=False)
- 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
var("x y") t = (x^2+y)^2 t.derivative(x) t.derivative(x, 2) t.derivative(x, 2, y) t.derivative(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)
f(x) = x^3 + sin(x) f.derivative() f.derivative(2)
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)
_ = var('x', domain='real') _ = var('w z') (x^z).conjugate().diff(x) (w^z).conjugate().diff(w) atanh(x).real_part().diff(x) atanh(x).imag_part().diff(x) atanh(w).real_part().diff(w) atanh(w).imag_part().diff(w) abs(log(x)).diff(x) abs(log(z)).diff(z) forget() t = sin(x+y^2)*tan(x*y) t.derivative(x) t.derivative(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
h = sin(x)/cos(x) derivative(h,x,x,x) derivative(h,x,3)
>>> 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
h = sin(x)/cos(x) derivative(h,x,x,x) derivative(h,x,3)
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))
var('x, y') u = (sin(x) + cos(y))*(cos(x) - sin(y)) derivative(u,x,y) f = ((x^2+1)/(x^2-1))^(1/4) g = derivative(f, x); g # this is a complex expression g.factor()
>>> 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))
var('x, y') u = (sin(x) + cos(y))*(cos(x) - sin(y)) derivative(u,x,y) f = ((x^2+1)/(x^2-1))^(1/4) g = derivative(f, x); g # this is a complex expression g.factor()
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)
y = var('y') f = y^(sin(x)) derivative(f, x)
>>> from sage.all import * >>> y = var('y') >>> f = y**(sin(x)) >>> derivative(f, x) y^sin(x)*cos(x)*log(y)
y = var('y') f = y^(sin(x)) derivative(f, x)
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
g(x) = sqrt(5-2*x) g_3 = derivative(g, x, 3); g_3(2)
>>> 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
g(x) = sqrt(5-2*x) g_3 = derivative(g, x, 3); g_3(2)
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)
f = x*e^(-x) derivative(f, 100)
>>> from sage.all import * >>> f = x*e**(-x) >>> derivative(f, Integer(100)) x*e^(-x) - 100*e^(-x)
f = x*e^(-x) derivative(f, 100)
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)
g = 1/(sqrt((x^2-1)*(x+5)^6)) derivative(g, x)
>>> 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)
g = 1/(sqrt((x^2-1)*(x+5)^6)) derivative(g, x)
- 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
var("x y") t = (x^2+y)^2 t.derivative(x) t.derivative(x, 2) t.derivative(x, 2, y) t.derivative(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)
f(x) = x^3 + sin(x) f.derivative() f.derivative(2)
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)
_ = var('x', domain='real') _ = var('w z') (x^z).conjugate().diff(x) (w^z).conjugate().diff(w) atanh(x).real_part().diff(x) atanh(x).imag_part().diff(x) atanh(w).real_part().diff(w) atanh(w).imag_part().diff(w) abs(log(x)).diff(x) abs(log(z)).diff(z) forget() t = sin(x+y^2)*tan(x*y) t.derivative(x) t.derivative(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
h = sin(x)/cos(x) derivative(h,x,x,x) derivative(h,x,3)
>>> 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
h = sin(x)/cos(x) derivative(h,x,x,x) derivative(h,x,3)
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))
var('x, y') u = (sin(x) + cos(y))*(cos(x) - sin(y)) derivative(u,x,y) f = ((x^2+1)/(x^2-1))^(1/4) g = derivative(f, x); g # this is a complex expression g.factor()
>>> 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))
var('x, y') u = (sin(x) + cos(y))*(cos(x) - sin(y)) derivative(u,x,y) f = ((x^2+1)/(x^2-1))^(1/4) g = derivative(f, x); g # this is a complex expression g.factor()
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)
y = var('y') f = y^(sin(x)) derivative(f, x)
>>> from sage.all import * >>> y = var('y') >>> f = y**(sin(x)) >>> derivative(f, x) y^sin(x)*cos(x)*log(y)
y = var('y') f = y^(sin(x)) derivative(f, x)
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
g(x) = sqrt(5-2*x) g_3 = derivative(g, x, 3); g_3(2)
>>> 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
g(x) = sqrt(5-2*x) g_3 = derivative(g, x, 3); g_3(2)
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)
f = x*e^(-x) derivative(f, 100)
>>> from sage.all import * >>> f = x*e**(-x) >>> derivative(f, Integer(100)) x*e^(-x) - 100*e^(-x)
f = x*e^(-x) derivative(f, 100)
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)
g = 1/(sqrt((x^2-1)*(x+5)^6)) derivative(g, x)
>>> 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)
g = 1/(sqrt((x^2-1)*(x+5)^6)) derivative(g, x)
- 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
var("x y") t = (x^2+y)^2 t.derivative(x) t.derivative(x, 2) t.derivative(x, 2, y) t.derivative(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)
f(x) = x^3 + sin(x) f.derivative() f.derivative(2)
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)
_ = var('x', domain='real') _ = var('w z') (x^z).conjugate().diff(x) (w^z).conjugate().diff(w) atanh(x).real_part().diff(x) atanh(x).imag_part().diff(x) atanh(w).real_part().diff(w) atanh(w).imag_part().diff(w) abs(log(x)).diff(x) abs(log(z)).diff(z) forget() t = sin(x+y^2)*tan(x*y) t.derivative(x) t.derivative(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
h = sin(x)/cos(x) derivative(h,x,x,x) derivative(h,x,3)
>>> 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
h = sin(x)/cos(x) derivative(h,x,x,x) derivative(h,x,3)
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))
var('x, y') u = (sin(x) + cos(y))*(cos(x) - sin(y)) derivative(u,x,y) f = ((x^2+1)/(x^2-1))^(1/4) g = derivative(f, x); g # this is a complex expression g.factor()
>>> 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))
var('x, y') u = (sin(x) + cos(y))*(cos(x) - sin(y)) derivative(u,x,y) f = ((x^2+1)/(x^2-1))^(1/4) g = derivative(f, x); g # this is a complex expression g.factor()
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)
y = var('y') f = y^(sin(x)) derivative(f, x)
>>> from sage.all import * >>> y = var('y') >>> f = y**(sin(x)) >>> derivative(f, x) y^sin(x)*cos(x)*log(y)
y = var('y') f = y^(sin(x)) derivative(f, x)
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
g(x) = sqrt(5-2*x) g_3 = derivative(g, x, 3); g_3(2)
>>> 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
g(x) = sqrt(5-2*x) g_3 = derivative(g, x, 3); g_3(2)
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)
f = x*e^(-x) derivative(f, 100)
>>> from sage.all import * >>> f = x*e**(-x) >>> derivative(f, Integer(100)) x*e^(-x) - 100*e^(-x)
f = x*e^(-x) derivative(f, 100)
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)
g = 1/(sqrt((x^2-1)*(x+5)^6)) derivative(g, x)
>>> 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)
g = 1/(sqrt((x^2-1)*(x+5)^6)) derivative(g, x)
- 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
theta = var('theta') eqn = (x^3 + theta < sin(x*theta)) eqn.divide_both_sides(theta, checksign=False) eqn.divide_both_sides(theta) eqn/theta
- exp(hold=False)[source]¶
Return exponential function of
self
, i.e., \(e\) to the power ofself
.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
x.exp() SR(0).exp() SR(1/2).exp() SR(0.5).exp() math.exp(0.5) SR(0.5).exp().log() (pi*I).exp()
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)
(pi*I).exp(hold=True)
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
exp(I*pi,hold=True) exp(I*pi)
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
a = (pi*I).exp(hold=True); a.unhold()
- 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
x,y = var('x,y') a = (x-y)^5 a.expand() expand(a)
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
expand((x-1)^3/(y-1)) expand((x+sin((x+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)
f(x) = function('f')(x) fx = f(x*(x+1)); fx fx.expand()
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
a = (16*x-13)^2 == (3*x+5)^2/2 a.expand() a.expand('left') a.expand('right')
- 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 simplifiedalgorithm
– (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()
andexpand_log()
are the sameEXAMPLES:
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)
(log(3/4*x^pi)).log_expand()
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)
(log(3/4*x^pi)).log_expand('all')
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)
(log(x^6)).log_expand('powers')
The expression
log((3*x)^6)
is not expanded withalgorithm='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)
(log((3*x)^6)).log_expand('powers')
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)
(log(3/4*x^pi)).log_expand() (log(3/4*x^pi)).log_expand('all') (log(3/4*x^pi)).log_expand()
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
x,y = var('x,y') a = (x-y)^5 a.expand() expand(a)
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
expand((x-1)^3/(y-1)) expand((x+sin((x+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)
f(x) = function('f')(x) fx = f(x*(x+1)); fx fx.expand()
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
a = (16*x-13)^2 == (3*x+5)^2/2 a.expand() a.expand('left') a.expand('right')
- 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)
(k,n) = var('k,n') ex = sum(abs(-k*k+n),k,1,n)(n=8); ex ex.expand_sum() f(x,k) = sum((2/n)*(sin(n*x)*(-1)^(n+1)), n, 1, k) f(x,2) f(x,2).expand_sum()
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
(k,n) = var('k,n') f(n)=sum(sqrt(abs(-k*k+n)),k,1,n) f(n=8) f(8).expand_sum() f(8).expand_sum().n()
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
f(8).n()
- 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 toTrue
.half_angles
– boolean (default:False
); ifTrue
, causes half-angles to be simplified awayplus
– boolean (default:True
); controls the sum rule. Expansion of sums (e.g. \(\sin(x + y)\)) will take place only ifplus
isTrue
.times
– boolean (default:True
); controls the product rule, expansion of products (e.g. \(\sin(2 x)\)) will take place only iftimes
isTrue
.
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)
sin(5*x).expand_trig() cos(2*x + var('y')).expand_trig()
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)
f = sin(sin(3*cos(2*x))*x) f.expand_trig() f.expand_trig(full=True) sin(2*x).expand_trig(times=False) sin(2*x).expand_trig(times=True) sin(2 + x).expand_trig(plus=False) sin(2 + x).expand_trig(plus=True) sin(x/2).expand_trig(half_angles=False) sin(x/2).expand_trig(half_angles=True)
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)
(x, k1, k2) = var('x, k1, k2') cos((k1-k2)*x).expand().expand_trig()
ALIAS:
trig_expand()
andexpand_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)
x = SR.var("x") sin(x).exponentialize() sec(x).exponentialize() tan(x).exponentialize() sinh(x).exponentialize() sech(x).exponentialize() tanh(x).exponentialize()
- factor(dontfactor=None)[source]¶
Factor the expression, containing any number of variables or functions, into factors irreducible over the integers.
INPUT:
self
– a symbolic expressiondontfactor
– 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)
x,y,z = var('x, y, z') (x^3-y^3).factor() factor(-8*y - 4*x + z^2*(2*y + x)) f = -1 - 2*x - x^2 + y^2 + 2*x*y^2 + x^2*y^2 F = factor(f/(36*(1 + 2*y + y^2)), dontfactor=[x]); F
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)
var('x,y') (x^99 + y^99).factor()
- factor_list(dontfactor=None)[source]¶
Return a list of the factors of self, as computed by the factor command.
INPUT:
self
– a symbolic expressiondontfactor
– see docs forfactor()
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)
var('x, y, z') f = x^3-y^3 f.factor()
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)]
f.factor_list()
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)]
factor(-8*y - 4*x + z^2*(2*y + x)).factor_list()
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)]
var('x, u, v') f = expand((2*u*v^2-v^2-4*u^3)^2 * (-u)^3 * (x-sin(x))^3) f.factor() g = f.factor_list(); g
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)]
f = -1 - 2*x - x^2 + y^2 + 2*x*y^2 + x^2*y^2 g = f/(36*(1 + 2*y + y^2)); g g.factor(dontfactor=[x]) g.factor_list(dontfactor=[x])
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))]
f = x^(2*sin(x)) * (x-1)^(sqrt(2)*x); f f.factor_list()
- 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)
var('x, y') SR(5).factorial() x.factorial() (x^2+y^3).factorial()
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)
SR(5).factorial(hold=True)
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
factorial(5,hold=True) factorial(5)
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
a = SR(5).factorial(hold=True); a.unhold()
- 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
var('n,k') f = factorial(n+1)/factorial(n); f f.simplify_factorial()
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)
f = factorial(n)*(n+1); f simplify(f) f.simplify_factorial()
>>> 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)
f = factorial(n)*(n+1); f simplify(f) f.simplify_factorial()
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)
f = binomial(n, k)*factorial(k)*factorial(n-k); f f.simplify_factorial()
>>> 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)
f = binomial(n, k)*factorial(k)*factorial(n-k); f f.simplify_factorial()
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
f = factorial(x)/factorial(x-2)/2 + factorial(x+1)/factorial(x)/2; f g = f.simplify_factorial(); g g.simplify_rational()
- 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]
var('x,y,z,a,b') w0 = SR.wild(0); w1 = SR.wild(1) (sin(x)*sin(y)).find(sin(w0)) ((sin(x)+sin(y))*(a+b)).expand().find(sin(w0)) (1+x+x^2+x^3).find(x) (1+x+x^2+x^3).find(x^w0) (1+x+x^2+x^3).find(y) ((x^y)^z).find(w0^w1)
- 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...)
f = x*cos(x) f.find_local_maximum(0,5) # needs scipy f.find_local_maximum(0,5, tol=0.1, maxfun=10) # needs scipy
- 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 thatself
must be a function of (at most) one variable.INPUT:
a
– real number; left endpoint of interval on which to minimizeb
– real number; right endpoint of interval on which to minimizevar
– variable (default: first variable inself
); the variable inself
to maximize overtol
– positive real (default: 1.48e-08); the convergence tolerancemaxfun
– natural number (default: 500); maximum function evaluationsimaginary_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)
, whereminval
– float; the minimum value thatself
takes on in the interval[a,b]
x
– float; the point at whichself
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...)
# needs scipy f = x*cos(x) f.find_local_minimum(1, 5) f.find_local_minimum(1, 5, tol=1e-3) f.find_local_minimum(1, 5, tol=1e-2, maxfun=10) show(f.plot(0, 20)) # needs sage.plot f.find_local_minimum(1, 15)
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, whereself
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 intervalvar
– (optional) variablextol, rtol
– the routine converges when a root is known to lie withinxtol
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
); ifTrue
, also return object that contains information about convergenceimaginary_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
# needs scipy f = x^2 - 1 f.find_root(-2, 3) f.find_root(-2, 3, x) z, result = f.find_root(-2, 3, full_output=True) result.converged result.flag result.function_calls result.iterations result.root
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
(sin(x) + exp(x)).find_root(-10, 10) # needs scipy sin(x).find_root(-1,1) # needs scipy
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
(tan(x)).find_root(3,3.5) # needs scipy (1/tan(x)).find_root(3, 3.5) # needs scipy
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
f = 1 + x + sqrt(x+2); f.find_root(-2,10) # needs scipy
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...
t = var('t') v = 0.004*(9600*e^(-(1200*t)) - 2400*e^(-(300*t))) v.find_root(0, 0.002) # needs scipy
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
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 show(plot(a, 0, .002), xmin=0, xmax=.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...
a.find_root(0,0.002) # needs scipy
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
a.solve(t) b = a.canonicalize_radical(); b b.solve(t) b.solve(t, to_poly_solve=True) n(1/900*log(-3/4*sqrt(41) + 25/4))
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.
x, y = var('x,y') (x-y).find_root(-2,2)
- 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]
var('x,y') forget() assume(x>0, y < 2) assumptions() forget(y < 2) assumptions()
- 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
fr = (1/x).fraction(ZZ); fr parent(fr) parent(((pi+sqrt(2)/x).fraction(SR))) parent(((pi+sqrt(2))/x).fraction(SR)) y = var('y') fr = ((3*x^5 - 5*y^5)^7/(x*y)).fraction(GF(7)); fr parent(fr)
- 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,)
(x,y,z) = var('x,y,z') (x+y).free_variables() (2*x).free_variables() (x^y).free_variables() sin(x+y^z).free_variables() _ = function('f') e = limit( f(x,y), x=0 ); e e.free_variables()
- full_simplify()[source]¶
Apply
simplify_factorial()
,simplify_rectform()
,simplify_trig()
,simplify_rational()
, and thenexpand_sum()
toself
(in that order).ALIAS:
simplify_full
andfull_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
f = sin(x)^2 + cos(x)^2 f.simplify_full()
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))
f = sin(x/(x^2 + x)) f.simplify_full()
>>> from sage.all import * >>> f = sin(x/(x**Integer(2) + x)) >>> f.simplify_full() sin(1/(x + 1))
f = sin(x/(x^2 + x)) f.simplify_full()
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)
var('n,k') f = binomial(n,k)*factorial(k)*factorial(n-k) f.simplify_full()
>>> from sage.all import * >>> var('n,k') (n, k) >>> f = binomial(n,k)*factorial(k)*factorial(n-k) >>> f.simplify_full() factorial(n)
var('n,k') f = binomial(n,k)*factorial(k)*factorial(n-k) f.simplify_full()
- 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)
var('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)
u = sin(x) + x*cos(y) g = u.function(x,y) g(x,y) g(t,z) g(x^2, x^y)
>>> 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)
u = sin(x) + x*cos(y) g = u.function(x,y) g(x,y) g(t,z) g(x^2, x^y)
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
f = (x^2 + sin(a*w)).function(a,x,w); f f(1,2,3)
>>> 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
f = (x^2 + sin(a*w)).function(a,x,w); f f(1,2,3)
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)
h = f.function(w,a); h
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)
h(w,a) = f h
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
f = x^n + y^n; f f(x,y) = f f f(2,3)
- 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
x = var('x') x.gamma() SR(2).gamma() SR(10).gamma() SR(10.0r).gamma() # For ARM: rel tol 2e-15 SR(CDF(1,1)).gamma()
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
gp('gamma(1+I)')
>>> from sage.all import * >>> gp('gamma(1+I)') 0.4980156681183560427136911175 - 0.1549498283018106851249551305*I # 32-bit 0.49801566811835604271369111746219809195 - 0.15494982830181068512495513048388660520*I # 64-bit
gp('gamma(1+I)')
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
plot(gamma(x), -6, 4).show(ymin=-3, ymax=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)
SR(1/2).gamma() SR(1/2).gamma(hold=True)
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)
gamma(1/2, hold=True) gamma(1/2)
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)
a = SR(1/2).gamma(hold=True); a.unhold()
- 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)
m,n = var('m n', domain='integer') (gamma(n+2)/gamma(n)).gamma_normalize() (gamma(n+2)*gamma(n)).gamma_normalize() (gamma(n+2)*gamma(m-1)/gamma(n)/gamma(m+1)).gamma_normalize()
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))
_ = var('n') (n-1).gcd(n+1) ex = (n-1)^2*gamma(2*n+5)/gamma(n+3) + gamma(2*n+3)/gamma(n+1) ex.gamma_normalize()
- gcd(b)[source]¶
Return the symbolic gcd of
self
andb
.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
var('x,y') SR(10).gcd(SR(15)) (x^3 - 1).gcd(x-1) / (x-1) in QQ (x^3 - 1).gcd(x^2+x+1) / (x^2+x+1) in QQ (x^3 - x^2*pi + x^2 - pi^2).gcd(x-pi) / (x-pi) in QQ gcd(sin(x)^2 + sin(x), sin(x)^2 - 1) / (sin(x) + 1) in QQ gcd(x^3 - y^3, x-y) / (x-y) in QQ gcd(x^100-y^100, x^10-y^10) / (x^10-y^10) in QQ 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)) ) r / (x^5 - 17*y + 2/3) in QQ
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
gcd(I - I*x, x^2 - 1) gcd(I + I*x, x^2 - 1) alg = SR(QQbar(sqrt(2) + I*sqrt(3))) gcd(alg + alg*x, x^2 - 1) # known bug (Issue #28489) gcd(alg - alg*x, x^2 - 1) # known bug (Issue #28489) sqrt2 = SR(QQbar(sqrt(2))) gcd(sqrt2 + x, x^2 - 2) # known bug
- 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)
a,b,k,m,n = var('a b k m n') SR(1).gosper_sum(n) SR(1).gosper_sum(n,5,8) n.gosper_sum(n) n.gosper_sum(n,0,5) n.gosper_sum(n,0,m) n.gosper_sum(n,a,b)
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
(factorial(m + n)/factorial(n)).gosper_sum(n) (binomial(m + n, n)).gosper_sum(n) (binomial(m + n, n)).gosper_sum(n, 0, a) (binomial(m + n, n)).gosper_sum(n, 0, 5) (rising_factorial(a,n)/rising_factorial(b,n)).gosper_sum(n) factorial(n).gosper_term(n)
>>> 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
(factorial(m + n)/factorial(n)).gosper_sum(n) (binomial(m + n, n)).gosper_sum(n) (binomial(m + n, n)).gosper_sum(n, 0, a) (binomial(m + n, n)).gosper_sum(n, 0, 5) (rising_factorial(a,n)/rising_factorial(b,n)).gosper_sum(n) factorial(n).gosper_term(n)
- 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
_ = var('n') SR(1).gosper_term(n) n.gosper_term(n) (n*factorial(n)).gosper_term(n) factorial(n).gosper_term(n)
- 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))
x,y = var('x y') f = x^2+y^2 f.gradient() g(x,y) = x^2+y^2 g.gradient() n = var('n') f(x,y) = x^n+y^n f.gradient() f.gradient([y,x])
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 thetrig_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)
x, t = var("x, t") cos(x).half_angle().subs(tan(x/2) == t)
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)
x, t = var("x, t") a = (cos(3*x)/(4-cos(x))) b = a.trig_expand() a.half_angle().subs(tan(x/2) == t).simplify_full() b.half_angle().subs(tan(x/2) == t).simplify_full()
- 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
var('x,y,a'); w0 = SR.wild(); w1 = SR.wild() (x*sin(x + y + 2*a)).has(y)
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
(x*sin(x + y + 2*a)).has(x+y) (x*sin(x + y + 2*a)).has(x + y + w0)
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
(x*sin(2*(x+y) + 2*a)).has(x+y)
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
(x+1).has(x^w0)
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
(4*x^2 - x + 3).has(w0*x) (4*x^2 + x + 3).has(w0*x) (4*x^2 + x + 3).has(x) (4*x^2 - x + 3).coefficient(x,1) (4*x^2 + x + 3).coefficient(x,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
(1 + x^2).has_wild() (SR.wild(0) + x^2).has_wild() SR.wild(0).has_wild()
- 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]
x,y = var('x y') f = x^2+y^2 f.hessian() g(x,y) = x^2+y^2 g.hessian()
- 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
add((i+1)*x^i for i in range(5)).horner(x) x, y, z = SR.var('x,y,z') (x^5 + y*cos(x) + z^3 + (x + y)^2 + y^x).horner(x) expr = sin(5*x).expand_trig(); expr expr.horner(sin(x)) expr.horner(cos(x))
- 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’shgfred
function, and'sage'
, which uses an algorithm implemented in the hypergeometric module
ALIAS:
hypergeometric_simplify()
andsimplify_hypergeometric()
are the sameEXAMPLES:
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
hypergeometric((5, 4), (4, 1, 2, 3), x).simplify_hypergeometric() (2*hypergeometric((), (), x)).simplify_hypergeometric() (nest(lambda y: hypergeometric([y], [1], x), 3, 1) # not tested, unstable .simplify_hypergeometric()) (nest(lambda y: hypergeometric([y], [1], x), 3, 1) # not tested, unstable .simplify_hypergeometric(algorithm='sage')) hypergeometric_M(1, 3, x).simplify_hypergeometric() (2 * hypergeometric_U(1, 3, x)).simplify_hypergeometric()
- 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)
sqrt(-2).imag_part()
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()
z = var('z') f = log(exp(z)) f f.simplify() 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))
var('a, b') f = log(a + b*I) f.imag_part()
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)
SR(I).imag_part() SR(I).imag_part(hold=True)
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
imag_part(I, hold=True) imag_part(SR(I))
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
a = SR(I).imag_part(hold=True); a.unhold()
- 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)
sqrt(-2).imag_part()
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()
z = var('z') f = log(exp(z)) f f.simplify() 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))
var('a, b') f = log(a + b*I) f.imag_part()
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)
SR(I).imag_part() SR(I).imag_part(hold=True)
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
imag_part(I, hold=True) imag_part(SR(I))
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
a = SR(I).imag_part(hold=True); a.unhold()
- 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 expressionX
– the independent variable with respect to which the derivative is takenn
– (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
var('x, y') f = cos(x)*sin(y) f.implicit_derivative(y, x) g = x*y^2 g.implicit_derivative(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
(cos(x)*sin(x)).implicit_derivative(y, x)
- 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)
sin(x).integral(x,0,3) sin(x).integral(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)
sin(x).integral(x,0,3) sin(x).integral(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)
var('w, m') f = (1/(w^2+10)).inverse_laplace(w, m); f
- 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
sqrt(2).is_algebraic() (5*sqrt(2)).is_algebraic() (sqrt(2) + 2^(1/3) - 1).is_algebraic() (I*golden_ratio + sqrt(2)).is_algebraic() (sqrt(2) + pi).is_algebraic() SR(QQ(2/3)).is_algebraic() SR(1.2).is_algebraic() complex_root_of(x^3 - x^2 - x - 1, 0).is_algebraic()
- is_callable()[source]¶
Return
True
ifself
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
var('a x y z') f(x, y) = a + 2*x + 3*y + z f.is_callable() (a+2*x).is_callable()
- 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
pi.is_constant() SR(1).is_constant() SR(2).is_constant() log(2).is_constant() SR(I).is_constant() x.is_constant()
- 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
x, y = var('x, y') (x+y-1).is_exact() (x+y-1.9).is_exact() x.is_exact() pi.is_exact() (sqrt(x-y) - 2*x + 1).is_exact() ((x-y)^0.5 - 2*x + 1).is_exact()
- is_infinity()[source]¶
Return
True
ifself
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
SR(oo).is_infinity() x.is_infinity()
- 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
SR(5).is_integer()
- 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
SR(-5).is_negative()
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
t0 = SR.symbol("t0", domain='positive') t0.is_negative() (-t0).is_negative() (-pi).is_negative()
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()
y = var('y') assume(y < 0) y.is_positive() y.is_negative() forget()
- is_negative_infinity()[source]¶
Return
True
ifself
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
SR(oo).is_negative_infinity() SR(-oo).is_negative_infinity() x.is_negative_infinity()
- 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
SR(1).is_numeric() x.is_numeric() pi.is_numeric() sin(x).is_numeric()
- is_polynomial(var)[source]¶
Return
True
ifself
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
var('x,y,z') t = x^2 + y; t t.is_polynomial(x) t.is_polynomial(y) t.is_polynomial(z) t = sin(x) + y; t t.is_polynomial(x) t.is_polynomial(y) t.is_polynomial(sin(x))
- 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
t0 = SR.symbol("t0", domain='positive') t0.is_positive() t0.is_negative() t0.is_real() t1 = SR.symbol("t1", domain='positive') (t0*t1).is_positive() (t0 + t1).is_positive() (t0*x).is_positive()
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()
forget() assume(x>0) x.is_positive() cosh(x).is_positive() f = function('f')(x) assume(f>0) f.is_positive() 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()
forget() assume(x>0) x.is_positive() cosh(x).is_positive() f = function('f')(x) assume(f>0) f.is_positive() forget()
- is_positive_infinity()[source]¶
Return
True
ifself
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
SR(oo).is_positive_infinity() SR(-oo).is_positive_infinity() x.is_infinity()
- 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 sage: ((1 + x + y)^10).is_rational_expression() True sage: ((1/x + z)^5 - 1).is_rational_expression() True sage: (1/(x + y)).is_rational_expression() True sage: (exp(x) + 1).is_rational_expression() False sage: (sin(x*y) + z^3).is_rational_expression() False sage: (exp(x) + exp(-x)).is_rational_expression() False
>>> from sage.all import * >>> var('x y z') (x, y, z) >>> ((x + y + z)/(Integer(1) + x**Integer(2))).is_rational_expression() True >>> ((Integer(1) + x + y)**Integer(10)).is_rational_expression() True >>> ((Integer(1)/x + z)**Integer(5) - Integer(1)).is_rational_expression() True >>> (Integer(1)/(x + y)).is_rational_expression() True >>> (exp(x) + Integer(1)).is_rational_expression() False >>> (sin(x*y) + z**Integer(3)).is_rational_expression() False >>> (exp(x) + exp(-x)).is_rational_expression() False
var('x y z') ((x + y + z)/(1 + x^2)).is_rational_expression() ((1 + x + y)^10).is_rational_expression() ((1/x + z)^5 - 1).is_rational_expression() (1/(x + y)).is_rational_expression() (exp(x) + 1).is_rational_expression() (sin(x*y) + z^3).is_rational_expression() (exp(x) + exp(-x)).is_rational_expression()
- is_real()[source]¶
Return
True
if this expression is known to be a real number.EXAMPLES:
sage: t0 = SR.symbol("t0", domain='real') sage: t0.is_real() True sage: t0.is_positive() False sage: t1 = SR.symbol("t1", domain='positive') sage: (t0+t1).is_real() True sage: (t0+x).is_real() False sage: (t0*t1).is_real() True sage: t2 = SR.symbol("t2", domain='positive') sage: (t1**t2).is_real() True sage: (t0*x).is_real() False sage: (t0^t1).is_real() False sage: (t1^t2).is_real() True sage: gamma(pi).is_real() True sage: cosh(-3).is_real() True sage: cos(exp(-3) + log(2)).is_real() True sage: gamma(t1).is_real() True sage: (x^pi).is_real() False sage: (cos(exp(t0) + log(t1))^8).is_real() True sage: cos(I + 1).is_real() False sage: sin(2 - I).is_real() False sage: (2^t0).is_real() True
>>> from sage.all import * >>> t0 = SR.symbol("t0", domain='real') >>> t0.is_real() True >>> t0.is_positive() False >>> t1 = SR.symbol("t1", domain='positive') >>> (t0+t1).is_real() True >>> (t0+x).is_real() False >>> (t0*t1).is_real() True >>> t2 = SR.symbol("t2", domain='positive') >>> (t1**t2).is_real() True >>> (t0*x).is_real() False >>> (t0**t1).is_real() False >>> (t1**t2).is_real() True >>> gamma(pi).is_real() True >>> cosh(-Integer(3)).is_real() True >>> cos(exp(-Integer(3)) + log(Integer(2))).is_real() True >>> gamma(t1).is_real() True >>> (x**pi).is_real() False >>> (cos(exp(t0) + log(t1))**Integer(8)).is_real() True >>> cos(I + Integer(1)).is_real() False >>> sin(Integer(2) - I).is_real() False >>> (Integer(2)**t0).is_real() True
t0 = SR.symbol("t0", domain='real') t0.is_real() t0.is_positive() t1 = SR.symbol("t1", domain='positive') (t0+t1).is_real() (t0+x).is_real() (t0*t1).is_real() t2 = SR.symbol("t2", domain='positive') (t1**t2).is_real() (t0*x).is_real() (t0^t1).is_real() (t1^t2).is_real() gamma(pi).is_real() cosh(-3).is_real() cos(exp(-3) + log(2)).is_real() gamma(t1).is_real() (x^pi).is_real() (cos(exp(t0) + log(t1))^8).is_real() cos(I + 1).is_real() sin(2 - I).is_real() (2^t0).is_real()
The following is real, but we cannot deduce that.:
sage: (x*x.conjugate()).is_real() False
>>> from sage.all import * >>> (x*x.conjugate()).is_real() False
(x*x.conjugate()).is_real()
Assumption of real has the same effect as setting the domain:
sage: forget() sage: assume(x, 'real') sage: x.is_real() True sage: cosh(x).is_real() True sage: forget()
>>> from sage.all import * >>> forget() >>> assume(x, 'real') >>> x.is_real() True >>> cosh(x).is_real() True >>> forget()
forget() assume(x, 'real') x.is_real() cosh(x).is_real() forget()
The real domain is also set with the integer domain:
sage: SR.var('x', domain='integer').is_real() True
>>> from sage.all import * >>> SR.var('x', domain='integer').is_real() True
SR.var('x', domain='integer').is_real()
- is_relational()[source]¶
Return
True
ifself
is a relational expression.EXAMPLES:
sage: x = var('x') sage: eqn = (x-1)^2 == x^2 - 2*x + 3 sage: eqn.is_relational() True sage: sin(x).is_relational() False
>>> from sage.all import * >>> x = var('x') >>> eqn = (x-Integer(1))**Integer(2) == x**Integer(2) - Integer(2)*x + Integer(3) >>> eqn.is_relational() True >>> sin(x).is_relational() False
x = var('x') eqn = (x-1)^2 == x^2 - 2*x + 3 eqn.is_relational() sin(x).is_relational()
- is_square()[source]¶
Return
True
ifself
is the square of another symbolic expression.This is
True
for all constant, non-relational expressions (containing no variables or comparison), and not implemented otherwise.EXAMPLES:
sage: SR(4).is_square() True sage: SR(5).is_square() True sage: pi.is_square() True sage: x.is_square() Traceback (most recent call last): ... NotImplementedError: is_square() not implemented for non-constant or relational elements of Symbolic Ring sage: r = SR(4) == SR(5) sage: r.is_square() Traceback (most recent call last): ... NotImplementedError: is_square() not implemented for non-constant or relational elements of Symbolic Ring
>>> from sage.all import * >>> SR(Integer(4)).is_square() True >>> SR(Integer(5)).is_square() True >>> pi.is_square() True >>> x.is_square() Traceback (most recent call last): ... NotImplementedError: is_square() not implemented for non-constant or relational elements of Symbolic Ring >>> r = SR(Integer(4)) == SR(Integer(5)) >>> r.is_square() Traceback (most recent call last): ... NotImplementedError: is_square() not implemented for non-constant or relational elements of Symbolic Ring
SR(4).is_square() SR(5).is_square() pi.is_square() x.is_square() r = SR(4) == SR(5) r.is_square()
- is_symbol()[source]¶
Return
True
if this symbolic expression consists of only a symbol, i.e., a symbolic variable.EXAMPLES:
sage: x.is_symbol() True sage: var('y') y sage: y.is_symbol() True sage: (x*y).is_symbol() False sage: pi.is_symbol() False
>>> from sage.all import * >>> x.is_symbol() True >>> var('y') y >>> y.is_symbol() True >>> (x*y).is_symbol() False >>> pi.is_symbol() False
x.is_symbol() var('y') y.is_symbol() (x*y).is_symbol() pi.is_symbol()
sage: ((x*y)/y).is_symbol() True sage: (x^y).is_symbol() False
>>> from sage.all import * >>> ((x*y)/y).is_symbol() True >>> (x**y).is_symbol() False
((x*y)/y).is_symbol() (x^y).is_symbol()
>>> from sage.all import * >>> ((x*y)/y).is_symbol() True >>> (x**y).is_symbol() False
((x*y)/y).is_symbol() (x^y).is_symbol()
- is_terminating_series()[source]¶
Return
True
ifself
is a series without order term.A series is terminating if it can be represented exactly, without requiring an order term. You can explicitly request terminating series by setting the order to positive infinity.
OUTPUT: boolean; whether
self
was constructed byseries()
and has no order termEXAMPLES:
sage: (x^5+x^2+1).series(x, +oo) 1 + 1*x^2 + 1*x^5 sage: (x^5+x^2+1).series(x,+oo).is_terminating_series() True sage: SR(5).is_terminating_series() False sage: var('x') x sage: x.is_terminating_series() False sage: exp(x).series(x,10).is_terminating_series() False
>>> from sage.all import * >>> (x**Integer(5)+x**Integer(2)+Integer(1)).series(x, +oo) 1 + 1*x^2 + 1*x^5 >>> (x**Integer(5)+x**Integer(2)+Integer(1)).series(x,+oo).is_terminating_series() True >>> SR(Integer(5)).is_terminating_series() False >>> var('x') x >>> x.is_terminating_series() False >>> exp(x).series(x,Integer(10)).is_terminating_series() False
(x^5+x^2+1).series(x, +oo) (x^5+x^2+1).series(x,+oo).is_terminating_series() SR(5).is_terminating_series() var('x') x.is_terminating_series() exp(x).series(x,10).is_terminating_series()
- is_trivial_zero()[source]¶
Check if this expression is trivially equal to zero without any simplification.
This method is intended to be used in library code where trying to obtain a mathematically correct result by applying potentially expensive rewrite rules is not desirable.
EXAMPLES:
sage: SR(0).is_trivial_zero() True sage: SR(0.0).is_trivial_zero() True sage: SR(float(0.0)).is_trivial_zero() True sage: (SR(1)/2^1000).is_trivial_zero() False sage: SR(1./2^10000).is_trivial_zero() False
>>> from sage.all import * >>> SR(Integer(0)).is_trivial_zero() True >>> SR(RealNumber('0.0')).is_trivial_zero() True >>> SR(float(RealNumber('0.0'))).is_trivial_zero() True >>> (SR(Integer(1))/Integer(2)**Integer(1000)).is_trivial_zero() False >>> SR(RealNumber('1.')/Integer(2)**Integer(10000)).is_trivial_zero() False
SR(0).is_trivial_zero() SR(0.0).is_trivial_zero() SR(float(0.0)).is_trivial_zero() (SR(1)/2^1000).is_trivial_zero() SR(1./2^10000).is_trivial_zero()
The
is_zero()
method is more capable:sage: t = pi + (pi - 1)*pi - pi^2 sage: t.is_trivial_zero() False sage: t.is_zero() True sage: t = pi + x*pi + (pi - 1 - x)*pi - pi^2 sage: t.is_zero() True sage: u = sin(x)^2 + cos(x)^2 - 1 sage: u.is_trivial_zero() False sage: u.is_zero() True
>>> from sage.all import * >>> t = pi + (pi - Integer(1))*pi - pi**Integer(2) >>> t.is_trivial_zero() False >>> t.is_zero() True >>> t = pi + x*pi + (pi - Integer(1) - x)*pi - pi**Integer(2) >>> t.is_zero() True >>> u = sin(x)**Integer(2) + cos(x)**Integer(2) - Integer(1) >>> u.is_trivial_zero() False >>> u.is_zero() True
t = pi + (pi - 1)*pi - pi^2 t.is_trivial_zero() t.is_zero() t = pi + x*pi + (pi - 1 - x)*pi - pi^2 t.is_zero() u = sin(x)^2 + cos(x)^2 - 1 u.is_trivial_zero() u.is_zero()
- is_trivially_equal(other)[source]¶
Check if this expression is trivially equal to the argument expression, without any simplification.
Note that the expressions may still be subject to immediate evaluation.
This method is intended to be used in library code where trying to obtain a mathematically correct result by applying potentially expensive rewrite rules is not desirable.
EXAMPLES:
sage: (x^2).is_trivially_equal(x^2) True sage: ((x+1)^2 - 2*x - 1).is_trivially_equal(x^2) False sage: (x*(x+1)).is_trivially_equal((x+1)*x) True sage: (x^2 + x).is_trivially_equal((x+1)*x) False sage: ((x+1)*(x+1)).is_trivially_equal((x+1)^2) True sage: (x^2 + 2*x + 1).is_trivially_equal((x+1)^2) False sage: (x^-1).is_trivially_equal(1/x) True sage: (x/x^2).is_trivially_equal(1/x) True sage: ((x^2+x) / (x+1)).is_trivially_equal(1/x) False
>>> from sage.all import * >>> (x**Integer(2)).is_trivially_equal(x**Integer(2)) True >>> ((x+Integer(1))**Integer(2) - Integer(2)*x - Integer(1)).is_trivially_equal(x**Integer(2)) False >>> (x*(x+Integer(1))).is_trivially_equal((x+Integer(1))*x) True >>> (x**Integer(2) + x).is_trivially_equal((x+Integer(1))*x) False >>> ((x+Integer(1))*(x+Integer(1))).is_trivially_equal((x+Integer(1))**Integer(2)) True >>> (x**Integer(2) + Integer(2)*x + Integer(1)).is_trivially_equal((x+Integer(1))**Integer(2)) False >>> (x**-Integer(1)).is_trivially_equal(Integer(1)/x) True >>> (x/x**Integer(2)).is_trivially_equal(Integer(1)/x) True >>> ((x**Integer(2)+x) / (x+Integer(1))).is_trivially_equal(Integer(1)/x) False
(x^2).is_trivially_equal(x^2) ((x+1)^2 - 2*x - 1).is_trivially_equal(x^2) (x*(x+1)).is_trivially_equal((x+1)*x) (x^2 + x).is_trivially_equal((x+1)*x) ((x+1)*(x+1)).is_trivially_equal((x+1)^2) (x^2 + 2*x + 1).is_trivially_equal((x+1)^2) (x^-1).is_trivially_equal(1/x) (x/x^2).is_trivially_equal(1/x) ((x^2+x) / (x+1)).is_trivially_equal(1/x)
- is_unit()[source]¶
Return
True
if this expression is a unit of the symbolic ring.Note that a proof may be attempted to get the result. To avoid this use
(ex-1).is_trivial_zero()
.EXAMPLES:
sage: SR(1).is_unit() True sage: SR(-1).is_unit() True sage: SR(0).is_unit() False
>>> from sage.all import * >>> SR(Integer(1)).is_unit() True >>> SR(-Integer(1)).is_unit() True >>> SR(Integer(0)).is_unit() False
SR(1).is_unit() SR(-1).is_unit() SR(0).is_unit()
- iterator()[source]¶
Return an iterator over the operands of this expression.
EXAMPLES:
sage: x,y,z = var('x,y,z') sage: list((x+y+z).iterator()) [x, y, z] sage: list((x*y*z).iterator()) [x, y, z] sage: list((x^y*z*(x+y)).iterator()) [x + y, x^y, z]
>>> from sage.all import * >>> x,y,z = var('x,y,z') >>> list((x+y+z).iterator()) [x, y, z] >>> list((x*y*z).iterator()) [x, y, z] >>> list((x**y*z*(x+y)).iterator()) [x + y, x^y, z]
x,y,z = var('x,y,z') list((x+y+z).iterator()) list((x*y*z).iterator()) list((x^y*z*(x+y)).iterator())
Note that symbols, constants and numeric objects do not have operands, so the iterator function raises an error in these cases:
sage: x.iterator() Traceback (most recent call last): ... ValueError: expressions containing only a numeric coefficient, constant or symbol have no operands sage: pi.iterator() Traceback (most recent call last): ... ValueError: expressions containing only a numeric coefficient, constant or symbol have no operands sage: SR(5).iterator() Traceback (most recent call last): ... ValueError: expressions containing only a numeric coefficient, constant or symbol have no operands
>>> from sage.all import * >>> x.iterator() Traceback (most recent call last): ... ValueError: expressions containing only a numeric coefficient, constant or symbol have no operands >>> pi.iterator() Traceback (most recent call last): ... ValueError: expressions containing only a numeric coefficient, constant or symbol have no operands >>> SR(Integer(5)).iterator() Traceback (most recent call last): ... ValueError: expressions containing only a numeric coefficient, constant or symbol have no operands
x.iterator() pi.iterator() SR(5).iterator()
- laplace(t, s)[source]¶
Return Laplace transform of
self
.See
sage.calculus.calculus.laplace
EXAMPLES:
sage: var('x,s,z') (x, s, z) sage: (z + exp(x)).laplace(x, s) z/s + 1/(s - 1)
>>> from sage.all import * >>> var('x,s,z') (x, s, z) >>> (z + exp(x)).laplace(x, s) z/s + 1/(s - 1)
var('x,s,z') (z + exp(x)).laplace(x, s)
- laurent_polynomial(base_ring=None, ring=None)[source]¶
Return this symbolic expression as a Laurent polynomial over the given base ring, if possible.
INPUT:
base_ring
– (optional) the base ring for the polynomialring
– (optional) the parent for the polynomial
You can specify either the base ring (
base_ring
) you want the output Laurent polynomial to be over, or you can specify the full laurent polynomial ring (ring
) you want the output laurent polynomial to be an element of.EXAMPLES:
sage: f = x^2 -2/3/x + 1 sage: f.laurent_polynomial(QQ) -2/3*x^-1 + 1 + x^2 sage: f.laurent_polynomial(GF(19)) 12*x^-1 + 1 + x^2
>>> from sage.all import * >>> f = x**Integer(2) -Integer(2)/Integer(3)/x + Integer(1) >>> f.laurent_polynomial(QQ) -2/3*x^-1 + 1 + x^2 >>> f.laurent_polynomial(GF(Integer(19))) 12*x^-1 + 1 + x^2
f = x^2 -2/3/x + 1 f.laurent_polynomial(QQ) f.laurent_polynomial(GF(19))
- lcm(b)[source]¶
Return the lcm of
self
andb
.The lcm is computed from the gcd of
self
andb
implicitly from the relationself * b = gcd(self, b) * lcm(self, b)
.Note
In agreement with the convention in use for integers, if
self * b == 0
, thengcd(self, b) == max(self, b)
andlcm(self, b) == 0
.Note
Since the polynomial lcm is computed from the gcd, and the polynomial gcd is unique up to a constant factor (which can be negative), the polynomial lcm is unique up to a factor of -1.
EXAMPLES:
sage: var('x,y') (x, y) sage: SR(10).lcm(SR(15)) 30 sage: (x^3 - 1).lcm(x-1) x^3 - 1 sage: (x^3 - 1).lcm(x^2+x+1) x^3 - 1 sage: (x^3 - sage.symbolic.constants.pi).lcm(x-sage.symbolic.constants.pi) (pi - x^3)*(pi - x) sage: lcm(x^3 - y^3, x-y) / (x^3 - y^3) in [1,-1] True sage: lcm(x^100-y^100, x^10-y^10) / (x^100 - y^100) in [1,-1] True sage: a = expand( (x^2+17*x+3/7*y)*(x^5 - 17*y + 2/3) ) sage: b = expand((x^13+17*x+3/7*y)*(x^5 - 17*y + 2/3) ) sage: gcd(a,b) * lcm(a,b) / (a * b) in [1,-1] True
>>> from sage.all import * >>> var('x,y') (x, y) >>> SR(Integer(10)).lcm(SR(Integer(15))) 30 >>> (x**Integer(3) - Integer(1)).lcm(x-Integer(1)) x^3 - 1 >>> (x**Integer(3) - Integer(1)).lcm(x**Integer(2)+x+Integer(1)) x^3 - 1 >>> (x**Integer(3) - sage.symbolic.constants.pi).lcm(x-sage.symbolic.constants.pi) (pi - x^3)*(pi - x) >>> lcm(x**Integer(3) - y**Integer(3), x-y) / (x**Integer(3) - y**Integer(3)) in [Integer(1),-Integer(1)] True >>> lcm(x**Integer(100)-y**Integer(100), x**Integer(10)-y**Integer(10)) / (x**Integer(100) - y**Integer(100)) in [Integer(1),-Integer(1)] True >>> a = expand( (x**Integer(2)+Integer(17)*x+Integer(3)/Integer(7)*y)*(x**Integer(5) - Integer(17)*y + Integer(2)/Integer(3)) ) >>> b = expand((x**Integer(13)+Integer(17)*x+Integer(3)/Integer(7)*y)*(x**Integer(5) - Integer(17)*y + Integer(2)/Integer(3)) ) >>> gcd(a,b) * lcm(a,b) / (a * b) in [Integer(1),-Integer(1)] True
var('x,y') SR(10).lcm(SR(15)) (x^3 - 1).lcm(x-1) (x^3 - 1).lcm(x^2+x+1) (x^3 - sage.symbolic.constants.pi).lcm(x-sage.symbolic.constants.pi) lcm(x^3 - y^3, x-y) / (x^3 - y^3) in [1,-1] lcm(x^100-y^100, x^10-y^10) / (x^100 - y^100) in [1,-1] a = expand( (x^2+17*x+3/7*y)*(x^5 - 17*y + 2/3) ) b = expand((x^13+17*x+3/7*y)*(x^5 - 17*y + 2/3) ) gcd(a,b) * lcm(a,b) / (a * b) in [1,-1]
The result is not automatically simplified:
sage: ex = lcm(sin(x)^2 - 1, sin(x)^2 + sin(x)); ex (sin(x)^2 + sin(x))*(sin(x)^2 - 1)/(sin(x) + 1) sage: ex.simplify_full() sin(x)^3 - sin(x)
>>> from sage.all import * >>> ex = lcm(sin(x)**Integer(2) - Integer(1), sin(x)**Integer(2) + sin(x)); ex (sin(x)^2 + sin(x))*(sin(x)^2 - 1)/(sin(x) + 1) >>> ex.simplify_full() sin(x)^3 - sin(x)
ex = lcm(sin(x)^2 - 1, sin(x)^2 + sin(x)); ex ex.simplify_full()
- leading_coeff(s)[source]¶
Return the leading coefficient of
s
inself
.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.leading_coefficient(x) sin(x*y) sage: f.leading_coefficient(y) x sage: f.leading_coefficient(sin(x*y)) x^3 + 2/x
>>> 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.leading_coefficient(x) sin(x*y) >>> f.leading_coefficient(y) x >>> f.leading_coefficient(sin(x*y)) x^3 + 2/x
var('x,y,a') f = 100 + a*x + x^3*sin(x*y) + x*y + x/y + 2*sin(x*y)/x; f f.leading_coefficient(x) f.leading_coefficient(y) f.leading_coefficient(sin(x*y))
- leading_coefficient(s)[source]¶
Return the leading coefficient of
s
inself
.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.leading_coefficient(x) sin(x*y) sage: f.leading_coefficient(y) x sage: f.leading_coefficient(sin(x*y)) x^3 + 2/x
>>> 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.leading_coefficient(x) sin(x*y) >>> f.leading_coefficient(y) x >>> f.leading_coefficient(sin(x*y)) x^3 + 2/x
var('x,y,a') f = 100 + a*x + x^3*sin(x*y) + x*y + x/y + 2*sin(x*y)/x; f f.leading_coefficient(x) f.leading_coefficient(y) f.leading_coefficient(sin(x*y))
- left()[source]¶
If
self
is a relational expression, return the left hand side of the relation. Otherwise, raise aValueError
.EXAMPLES:
sage: x = var('x') sage: eqn = (x-1)^2 == x^2 - 2*x + 3 sage: eqn.left_hand_side() (x - 1)^2 sage: eqn.lhs() (x - 1)^2 sage: eqn.left() (x - 1)^2
>>> from sage.all import * >>> x = var('x') >>> eqn = (x-Integer(1))**Integer(2) == x**Integer(2) - Integer(2)*x + Integer(3) >>> eqn.left_hand_side() (x - 1)^2 >>> eqn.lhs() (x - 1)^2 >>> eqn.left() (x - 1)^2
x = var('x') eqn = (x-1)^2 == x^2 - 2*x + 3 eqn.left_hand_side() eqn.lhs() eqn.left()
- left_hand_side()[source]¶
If
self
is a relational expression, return the left hand side of the relation. Otherwise, raise aValueError
.EXAMPLES:
sage: x = var('x') sage: eqn = (x-1)^2 == x^2 - 2*x + 3 sage: eqn.left_hand_side() (x - 1)^2 sage: eqn.lhs() (x - 1)^2 sage: eqn.left() (x - 1)^2
>>> from sage.all import * >>> x = var('x') >>> eqn = (x-Integer(1))**Integer(2) == x**Integer(2) - Integer(2)*x + Integer(3) >>> eqn.left_hand_side() (x - 1)^2 >>> eqn.lhs() (x - 1)^2 >>> eqn.left() (x - 1)^2
x = var('x') eqn = (x-1)^2 == x^2 - 2*x + 3 eqn.left_hand_side() eqn.lhs() eqn.left()
- lhs()[source]¶
If
self
is a relational expression, return the left hand side of the relation. Otherwise, raise aValueError
.EXAMPLES:
sage: x = var('x') sage: eqn = (x-1)^2 == x^2 - 2*x + 3 sage: eqn.left_hand_side() (x - 1)^2 sage: eqn.lhs() (x - 1)^2 sage: eqn.left() (x - 1)^2
>>> from sage.all import * >>> x = var('x') >>> eqn = (x-Integer(1))**Integer(2) == x**Integer(2) - Integer(2)*x + Integer(3) >>> eqn.left_hand_side() (x - 1)^2 >>> eqn.lhs() (x - 1)^2 >>> eqn.left() (x - 1)^2
x = var('x') eqn = (x-1)^2 == x^2 - 2*x + 3 eqn.left_hand_side() eqn.lhs() eqn.left()
- limit(*args, **kwds)[source]¶
Return a symbolic limit.
See
sage.calculus.calculus.limit
EXAMPLES:
sage: (sin(x)/x).limit(x=0) 1
>>> from sage.all import * >>> (sin(x)/x).limit(x=Integer(0)) 1
(sin(x)/x).limit(x=0)
- list(x=None)[source]¶
Return the coefficients of this symbolic expression as a polynomial in x.
INPUT:
x
– (optional) variable
OUTPUT:
A list of expressions where the
n
-th element is the coefficient ofx^n
whenself
is seen as polynomial inx
.EXAMPLES:
sage: var('x, y, a') (x, y, a) sage: (x^5).list() [0, 0, 0, 0, 0, 1] sage: p = x - x^3 + 5/7*x^5 sage: p.list() [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.list(a) [x^2 + x + 1, -2*sqrt(2)*x, 2] sage: s = (1/(1-x)).series(x,6); s 1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6) sage: s.list() [1, 1, 1, 1, 1, 1]
>>> from sage.all import * >>> var('x, y, a') (x, y, a) >>> (x**Integer(5)).list() [0, 0, 0, 0, 0, 1] >>> p = x - x**Integer(3) + Integer(5)/Integer(7)*x**Integer(5) >>> p.list() [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.list(a) [x^2 + x + 1, -2*sqrt(2)*x, 2] >>> s = (Integer(1)/(Integer(1)-x)).series(x,Integer(6)); s 1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6) >>> s.list() [1, 1, 1, 1, 1, 1]
var('x, y, a') (x^5).list() p = x - x^3 + 5/7*x^5 p.list() p = expand((x-a*sqrt(2))^2 + x + 1); p p.list(a) s = (1/(1-x)).series(x,6); s s.list()
- log(b=None, hold=False)[source]¶
Return the logarithm of
self
.EXAMPLES:
sage: x, y = var('x, y') sage: x.log() log(x) sage: (x^y + y^x).log() log(x^y + y^x) sage: SR(0).log() -Infinity sage: SR(-1).log() I*pi sage: SR(1).log() 0 sage: SR(1/2).log() log(1/2) sage: SR(0.5).log() -0.693147180559945 sage: SR(0.5).log().exp() 0.500000000000000 sage: math.log(0.5) -0.6931471805599453 sage: plot(lambda x: SR(x).log(), 0.1,10) # needs sage.plot Graphics object consisting of 1 graphics primitive
>>> from sage.all import * >>> x, y = var('x, y') >>> x.log() log(x) >>> (x**y + y**x).log() log(x^y + y^x) >>> SR(Integer(0)).log() -Infinity >>> SR(-Integer(1)).log() I*pi >>> SR(Integer(1)).log() 0 >>> SR(Integer(1)/Integer(2)).log() log(1/2) >>> SR(RealNumber('0.5')).log() -0.693147180559945 >>> SR(RealNumber('0.5')).log().exp() 0.500000000000000 >>> math.log(RealNumber('0.5')) -0.6931471805599453 >>> plot(lambda x: SR(x).log(), RealNumber('0.1'),Integer(10)) # needs sage.plot Graphics object consisting of 1 graphics primitive
x, y = var('x, y') x.log() (x^y + y^x).log() SR(0).log() SR(-1).log() SR(1).log() SR(1/2).log() SR(0.5).log() SR(0.5).log().exp() math.log(0.5) plot(lambda x: SR(x).log(), 0.1,10) # needs sage.plot
To prevent automatic evaluation use the
hold
argument:sage: I.log() 1/2*I*pi sage: I.log(hold=True) log(I)
>>> from sage.all import * >>> I.log() 1/2*I*pi >>> I.log(hold=True) log(I)
I.log() I.log(hold=True)
To then evaluate again, we use
unhold()
:sage: a = I.log(hold=True); a.unhold() 1/2*I*pi
>>> from sage.all import * >>> a = I.log(hold=True); a.unhold() 1/2*I*pi
a = I.log(hold=True); a.unhold()
The
hold
parameter also works in functional notation:sage: log(-1, hold=True) log(-1) sage: log(-1) I*pi
>>> from sage.all import * >>> log(-Integer(1), hold=True) log(-1) >>> log(-Integer(1)) I*pi
log(-1, hold=True) log(-1)
- log_expand(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 simplifiedalgorithm
– (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()
andexpand_log()
are the sameEXAMPLES:
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)
(log(3/4*x^pi)).log_expand()
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)
(log(3/4*x^pi)).log_expand('all')
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)
(log(x^6)).log_expand('powers')
The expression
log((3*x)^6)
is not expanded withalgorithm='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)
(log((3*x)^6)).log_expand('powers')
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)
(log(3/4*x^pi)).log_expand() (log(3/4*x^pi)).log_expand('all') (log(3/4*x^pi)).log_expand()
AUTHORS:
Robert Marik (11-2009)
- log_gamma(hold=False)[source]¶
Return the log gamma function evaluated at
self
. This is the logarithm of gamma ofself
, where gamma is a complex function such that \(gamma(n)\) equals \(factorial(n-1)\).EXAMPLES:
sage: x = var('x') sage: x.log_gamma() log_gamma(x) sage: SR(2).log_gamma() 0 sage: SR(5).log_gamma() log(24) sage: a = SR(5).log_gamma(); a.n() 3.17805383034795 sage: SR(5-1).factorial().log() log(24) sage: from sage.misc.verbose import set_verbose sage: set_verbose(-1) sage: plot(lambda x: SR(x).log_gamma(), -7,8, plot_points=1000).show() # needs sage.plot sage: math.exp(0.5) 1.6487212707001282 sage: plot(lambda x: (SR(x).exp() - SR(-x).exp())/2 - SR(x).sinh(), -1, 1) # needs sage.plot Graphics object consisting of 1 graphics primitive
>>> from sage.all import * >>> x = var('x') >>> x.log_gamma() log_gamma(x) >>> SR(Integer(2)).log_gamma() 0 >>> SR(Integer(5)).log_gamma() log(24) >>> a = SR(Integer(5)).log_gamma(); a.n() 3.17805383034795 >>> SR(Integer(5)-Integer(1)).factorial().log() log(24) >>> from sage.misc.verbose import set_verbose >>> set_verbose(-Integer(1)) >>> plot(lambda x: SR(x).log_gamma(), -Integer(7),Integer(8), plot_points=Integer(1000)).show() # needs sage.plot >>> math.exp(RealNumber('0.5')) 1.6487212707001282 >>> plot(lambda x: (SR(x).exp() - SR(-x).exp())/Integer(2) - SR(x).sinh(), -Integer(1), Integer(1)) # needs sage.plot Graphics object consisting of 1 graphics primitive
x = var('x') x.log_gamma() SR(2).log_gamma() SR(5).log_gamma() a = SR(5).log_gamma(); a.n() SR(5-1).factorial().log() from sage.misc.verbose import set_verbose set_verbose(-1) plot(lambda x: SR(x).log_gamma(), -7,8, plot_points=1000).show() # needs sage.plot math.exp(0.5) plot(lambda x: (SR(x).exp() - SR(-x).exp())/2 - SR(x).sinh(), -1, 1) # needs sage.plot
To prevent automatic evaluation use the
hold
argument:sage: SR(5).log_gamma(hold=True) log_gamma(5)
>>> from sage.all import * >>> SR(Integer(5)).log_gamma(hold=True) log_gamma(5)
SR(5).log_gamma(hold=True)
To evaluate again, currently we must use numerical evaluation via
n()
:sage: a = SR(5).log_gamma(hold=True); a.n() 3.17805383034795
>>> from sage.all import * >>> a = SR(Integer(5)).log_gamma(hold=True); a.n() 3.17805383034795
a = SR(5).log_gamma(hold=True); a.n()
- log_simplify(algorithm=None)[source]¶
Simplify a (real) symbolic expression that contains logarithms.
The given expression is scanned recursively, transforming subexpressions of the form \(a \log(b) + c \log(d)\) into \(\log(b^{a} d^{c})\) before simplifying within the
log()
.The user can specify conditions that \(a\) and \(c\) must satisfy before this transformation will be performed using the optional parameter
algorithm
.Warning
This is only safe to call if every variable in the given expression is assumed to be real. The simplification it performs is in general not valid over the complex numbers. For example:
sage: x,y = SR.var('x,y') sage: f = log(x*y) - (log(x) + log(y)) sage: f(x=-1, y=i) -2*I*pi sage: f.simplify_log() 0
>>> from sage.all import * >>> x,y = SR.var('x,y') >>> f = log(x*y) - (log(x) + log(y)) >>> f(x=-Integer(1), y=i) -2*I*pi >>> f.simplify_log() 0
x,y = SR.var('x,y') f = log(x*y) - (log(x) + log(y)) f(x=-1, y=i) f.simplify_log()
INPUT:
self
– expression to be simplifiedalgorithm
– (default:None
) governs the condition on \(a\) and \(c\) which must be satisfied to contract expression \(a \log(b) + c \log(d)\). Values areNone
(use Maxima default, integers),'one'
(1 and -1),'ratios'
(rational numbers),'constants'
(constants),'all'
(all expressions).
ALGORITHM:
This uses the Maxima
logcontract()
command.ALIAS:
log_simplify()
andsimplify_log()
are the same.EXAMPLES:
sage: x,y,t = var('x y t')
>>> from sage.all import * >>> x,y,t = var('x y t')
x,y,t = var('x y t')
Only two first terms are contracted in the following example; the logarithm with coefficient \(\frac{1}{2}\) is not contracted:
sage: f = log(x)+2*log(y)+1/2*log(t) sage: f.simplify_log() log(x*y^2) + 1/2*log(t)
>>> from sage.all import * >>> f = log(x)+Integer(2)*log(y)+Integer(1)/Integer(2)*log(t) >>> f.simplify_log() log(x*y^2) + 1/2*log(t)
f = log(x)+2*log(y)+1/2*log(t) f.simplify_log()
To contract all terms in the previous example, we use the
'ratios'
algorithm
:sage: f.simplify_log(algorithm='ratios') log(sqrt(t)*x*y^2)
>>> from sage.all import * >>> f.simplify_log(algorithm='ratios') log(sqrt(t)*x*y^2)
f.simplify_log(algorithm='ratios')
To contract terms with no coefficient (more precisely, with coefficients \(1\) and \(-1\)), we use the
'one'
algorithm
:sage: f = log(x)+2*log(y)-log(t) sage: f.simplify_log('one') 2*log(y) + log(x/t)
>>> from sage.all import * >>> f = log(x)+Integer(2)*log(y)-log(t) >>> f.simplify_log('one') 2*log(y) + log(x/t)
f = log(x)+2*log(y)-log(t) f.simplify_log('one')
sage: f = log(x)+log(y)-1/3*log((x+1)) sage: f.simplify_log() log(x*y) - 1/3*log(x + 1) sage: f.simplify_log('ratios') log(x*y/(x + 1)^(1/3))
>>> from sage.all import * >>> f = log(x)+log(y)-Integer(1)/Integer(3)*log((x+Integer(1))) >>> f.simplify_log() log(x*y) - 1/3*log(x + 1) >>> f.simplify_log('ratios') log(x*y/(x + 1)^(1/3))
f = log(x)+log(y)-1/3*log((x+1)) f.simplify_log() f.simplify_log('ratios')
>>> from sage.all import * >>> f = log(x)+log(y)-Integer(1)/Integer(3)*log((x+Integer(1))) >>> f.simplify_log() log(x*y) - 1/3*log(x + 1) >>> f.simplify_log('ratios') log(x*y/(x + 1)^(1/3))
f = log(x)+log(y)-1/3*log((x+1)) f.simplify_log() f.simplify_log('ratios')
\(\pi\) is an irrational number; to contract logarithms in the following example we have to set
algorithm
to'constants'
or'all'
:sage: f = log(x)+log(y)-pi*log((x+1)) sage: f.simplify_log('constants') log(x*y/(x + 1)^pi)
>>> from sage.all import * >>> f = log(x)+log(y)-pi*log((x+Integer(1))) >>> f.simplify_log('constants') log(x*y/(x + 1)^pi)
f = log(x)+log(y)-pi*log((x+1)) f.simplify_log('constants')
x*log(9)
is contracted only ifalgorithm
is'all'
:sage: (x*log(9)).simplify_log() 2*x*log(3) sage: (x*log(9)).simplify_log('all') log(3^(2*x))
>>> from sage.all import * >>> (x*log(Integer(9))).simplify_log() 2*x*log(3) >>> (x*log(Integer(9))).simplify_log('all') log(3^(2*x))
(x*log(9)).simplify_log() (x*log(9)).simplify_log('all')
AUTHORS:
Robert Marik (11-2009)
- low_degree(s)[source]¶
Return the exponent of the lowest power of
s
inself
.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.low_degree(x) -1 sage: f.low_degree(y) -10 sage: f.low_degree(sin(x*y)) 0 sage: (x^3+y).low_degree(x) 0 sage: (x+x**2).low_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.low_degree(x) -1 >>> f.low_degree(y) -10 >>> f.low_degree(sin(x*y)) 0 >>> (x**Integer(3)+y).low_degree(x) 0 >>> (x+x**Integer(2)).low_degree(x) 1
var('x,y,a') f = 100 + a*x + x^3*sin(x*y) + x*y + x/y^10 + 2*sin(x*y)/x; f f.low_degree(x) f.low_degree(y) f.low_degree(sin(x*y)) (x^3+y).low_degree(x) (x+x**2).low_degree(x)
- match(pattern)[source]¶
Check if
self
matches the given pattern.INPUT:
pattern
– a symbolic expression, possibly containing wildcards to match for
OUTPUT:
None
if there is no match, or a dictionary mapping the wildcards to the matching values if a match was found. Note that the dictionary is empty if there were no wildcards in the given pattern.See also http://www.ginac.de/tutorial/Pattern-matching-and-advanced-substitutions.html
EXAMPLES:
sage: var('x,y,z,a,b,c,d,f,g') (x, y, z, a, b, c, d, f, g) sage: w0 = SR.wild(0); w1 = SR.wild(1); w2 = SR.wild(2) sage: ((x+y)^a).match((x+y)^a) # no wildcards, so empty dict {} sage: print(((x+y)^a).match((x+y)^b)) None sage: t = ((x+y)^a).match(w0^w1) sage: t[w0], t[w1] (x + y, a) sage: print(((x+y)^a).match(w0^w0)) None sage: ((x+y)^(x+y)).match(w0^w0) {$0: x + y} sage: t = ((a+b)*(a+c)).match((a+w0)*(a+w1)) sage: set([t[w0], t[w1]]) == set([b, c]) True sage: ((a+b)*(a+c)).match((w0+b)*(w0+c)) {$0: a} sage: t = ((a+b)*(a+c)).match((w0+w1)*(w0+w2)) sage: t[w0] a sage: set([t[w1], t[w2]]) == set([b, c]) True sage: t = ((a+b)*(a+c)).match((w0+w1)*(w1+w2)) sage: t[w1] a sage: set([t[w0], t[w2]]) == set([b, c]) True sage: t = (a*(x+y)+a*z+b).match(a*w0+w1) sage: s = set([t[w0], t[w1]]) sage: s == set([x+y, a*z+b]) or s == set([z, a*(x+y)+b]) True sage: print((a+b+c+d+f+g).match(c)) None sage: (a+b+c+d+f+g).has(c) True sage: (a+b+c+d+f+g).match(c+w0) {$0: a + b + d + f + g} sage: (a+b+c+d+f+g).match(c+g+w0) {$0: a + b + d + f} sage: (a+b).match(a+b+w0) # known bug {$0: 0} sage: print((a*b^2).match(a^w0*b^w1)) None sage: (a*b^2).match(a*b^w1) {$1: 2} sage: (x*x.arctan2(x^2)).match(w0*w0.arctan2(w0^2)) {$0: x}
>>> from sage.all import * >>> var('x,y,z,a,b,c,d,f,g') (x, y, z, a, b, c, d, f, g) >>> w0 = SR.wild(Integer(0)); w1 = SR.wild(Integer(1)); w2 = SR.wild(Integer(2)) >>> ((x+y)**a).match((x+y)**a) # no wildcards, so empty dict {} >>> print(((x+y)**a).match((x+y)**b)) None >>> t = ((x+y)**a).match(w0**w1) >>> t[w0], t[w1] (x + y, a) >>> print(((x+y)**a).match(w0**w0)) None >>> ((x+y)**(x+y)).match(w0**w0) {$0: x + y} >>> t = ((a+b)*(a+c)).match((a+w0)*(a+w1)) >>> set([t[w0], t[w1]]) == set([b, c]) True >>> ((a+b)*(a+c)).match((w0+b)*(w0+c)) {$0: a} >>> t = ((a+b)*(a+c)).match((w0+w1)*(w0+w2)) >>> t[w0] a >>> set([t[w1], t[w2]]) == set([b, c]) True >>> t = ((a+b)*(a+c)).match((w0+w1)*(w1+w2)) >>> t[w1] a >>> set([t[w0], t[w2]]) == set([b, c]) True >>> t = (a*(x+y)+a*z+b).match(a*w0+w1) >>> s = set([t[w0], t[w1]]) >>> s == set([x+y, a*z+b]) or s == set([z, a*(x+y)+b]) True >>> print((a+b+c+d+f+g).match(c)) None >>> (a+b+c+d+f+g).has(c) True >>> (a+b+c+d+f+g).match(c+w0) {$0: a + b + d + f + g} >>> (a+b+c+d+f+g).match(c+g+w0) {$0: a + b + d + f} >>> (a+b).match(a+b+w0) # known bug {$0: 0} >>> print((a*b**Integer(2)).match(a**w0*b**w1)) None >>> (a*b**Integer(2)).match(a*b**w1) {$1: 2} >>> (x*x.arctan2(x**Integer(2))).match(w0*w0.arctan2(w0**Integer(2))) {$0: x}
var('x,y,z,a,b,c,d,f,g') w0 = SR.wild(0); w1 = SR.wild(1); w2 = SR.wild(2) ((x+y)^a).match((x+y)^a) # no wildcards, so empty dict print(((x+y)^a).match((x+y)^b)) t = ((x+y)^a).match(w0^w1) t[w0], t[w1] print(((x+y)^a).match(w0^w0)) ((x+y)^(x+y)).match(w0^w0) t = ((a+b)*(a+c)).match((a+w0)*(a+w1)) set([t[w0], t[w1]]) == set([b, c]) ((a+b)*(a+c)).match((w0+b)*(w0+c)) t = ((a+b)*(a+c)).match((w0+w1)*(w0+w2)) t[w0] set([t[w1], t[w2]]) == set([b, c]) t = ((a+b)*(a+c)).match((w0+w1)*(w1+w2)) t[w1] set([t[w0], t[w2]]) == set([b, c]) t = (a*(x+y)+a*z+b).match(a*w0+w1) s = set([t[w0], t[w1]]) s == set([x+y, a*z+b]) or s == set([z, a*(x+y)+b]) print((a+b+c+d+f+g).match(c)) (a+b+c+d+f+g).has(c) (a+b+c+d+f+g).match(c+w0) (a+b+c+d+f+g).match(c+g+w0) (a+b).match(a+b+w0) # known bug print((a*b^2).match(a^w0*b^w1)) (a*b^2).match(a*b^w1) (x*x.arctan2(x^2)).match(w0*w0.arctan2(w0^2))
Beware that behind-the-scenes simplification can lead to surprising results in matching:
sage: print((x+x).match(w0+w1)) None sage: t = x+x; t 2*x sage: t.operator() <function mul_vararg ...>
>>> from sage.all import * >>> print((x+x).match(w0+w1)) None >>> t = x+x; t 2*x >>> t.operator() <function mul_vararg ...>
print((x+x).match(w0+w1)) t = x+x; t t.operator()
Since asking to match w0+w1 looks for an addition operator, there is no match.
- maxima_methods()[source]¶
Provide easy access to maxima methods, converting the result to a Sage expression automatically.
EXAMPLES:
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t log(sqrt(2) + 1) + log(sqrt(2) - 1) sage: res = t.maxima_methods().logcontract(); res log((sqrt(2) + 1)*(sqrt(2) - 1)) sage: type(res) <class 'sage.symbolic.expression.Expression'>
>>> from sage.all import * >>> t = log(sqrt(Integer(2)) - Integer(1)) + log(sqrt(Integer(2)) + Integer(1)); t log(sqrt(2) + 1) + log(sqrt(2) - 1) >>> res = t.maxima_methods().logcontract(); res log((sqrt(2) + 1)*(sqrt(2) - 1)) >>> type(res) <class 'sage.symbolic.expression.Expression'>
t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t res = t.maxima_methods().logcontract(); res type(res)
- minpoly(*args, **kwds)[source]¶
Return the minimal polynomial of this symbolic expression.
EXAMPLES:
sage: golden_ratio.minpoly() x^2 - x - 1
>>> from sage.all import * >>> golden_ratio.minpoly() x^2 - x - 1
golden_ratio.minpoly()
- mul(hold=False, *args)[source]¶
Return the product of the current expression and the given arguments.
To prevent automatic evaluation use the
hold
argument.EXAMPLES:
sage: x.mul(x) x^2 sage: x.mul(x, hold=True) x*x sage: x.mul(x, (2+x), hold=True) (x + 2)*x*x sage: x.mul(x, (2+x), x, hold=True) (x + 2)*x*x*x sage: x.mul(x, (2+x), x, 2*x, hold=True) (2*x)*(x + 2)*x*x*x
>>> from sage.all import * >>> x.mul(x) x^2 >>> x.mul(x, hold=True) x*x >>> x.mul(x, (Integer(2)+x), hold=True) (x + 2)*x*x >>> x.mul(x, (Integer(2)+x), x, hold=True) (x + 2)*x*x*x >>> x.mul(x, (Integer(2)+x), x, Integer(2)*x, hold=True) (2*x)*(x + 2)*x*x*x
x.mul(x) x.mul(x, hold=True) x.mul(x, (2+x), hold=True) x.mul(x, (2+x), x, hold=True) x.mul(x, (2+x), x, 2*x, hold=True)
To then evaluate again, we use
unhold()
:sage: a = x.mul(x, hold=True); a.unhold() x^2
>>> from sage.all import * >>> a = x.mul(x, hold=True); a.unhold() x^2
a = x.mul(x, hold=True); a.unhold()
- multiply_both_sides(x, checksign=None)[source]¶
Return a relation obtained by multiplying 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: var('x,y'); f = x + 3 < y - 2 (x, y) sage: f.multiply_both_sides(7) 7*x + 21 < 7*y - 14 sage: f.multiply_both_sides(-1/2) -1/2*x - 3/2 < -1/2*y + 1 sage: f*(-2/3) -2/3*x - 2 < -2/3*y + 4/3 sage: f*(-pi) -pi*(x + 3) < -pi*(y - 2)
>>> from sage.all import * >>> var('x,y'); f = x + Integer(3) < y - Integer(2) (x, y) >>> f.multiply_both_sides(Integer(7)) 7*x + 21 < 7*y - 14 >>> f.multiply_both_sides(-Integer(1)/Integer(2)) -1/2*x - 3/2 < -1/2*y + 1 >>> f*(-Integer(2)/Integer(3)) -2/3*x - 2 < -2/3*y + 4/3 >>> f*(-pi) -pi*(x + 3) < -pi*(y - 2)
var('x,y'); f = x + 3 < y - 2 f.multiply_both_sides(7) f.multiply_both_sides(-1/2) f*(-2/3) f*(-pi)
Since the direction of the inequality never changes when doing arithmetic with equations, you can multiply or divide the equation by a quantity with unknown sign:
sage: f*(1+I) (I + 1)*x + 3*I + 3 < (I + 1)*y - 2*I - 2 sage: f = sqrt(2) + x == y^3 sage: f.multiply_both_sides(I) I*x + I*sqrt(2) == I*y^3 sage: f.multiply_both_sides(-1) -x - sqrt(2) == -y^3
>>> from sage.all import * >>> f*(Integer(1)+I) (I + 1)*x + 3*I + 3 < (I + 1)*y - 2*I - 2 >>> f = sqrt(Integer(2)) + x == y**Integer(3) >>> f.multiply_both_sides(I) I*x + I*sqrt(2) == I*y^3 >>> f.multiply_both_sides(-Integer(1)) -x - sqrt(2) == -y^3
f*(1+I) f = sqrt(2) + x == y^3 f.multiply_both_sides(I) f.multiply_both_sides(-1)
Note that the direction of the following inequalities is not reversed:
sage: (x^3 + 1 > 2*sqrt(3)) * (-1) -x^3 - 1 > -2*sqrt(3) sage: (x^3 + 1 >= 2*sqrt(3)) * (-1) -x^3 - 1 >= -2*sqrt(3) sage: (x^3 + 1 <= 2*sqrt(3)) * (-1) -x^3 - 1 <= -2*sqrt(3)
>>> from sage.all import * >>> (x**Integer(3) + Integer(1) > Integer(2)*sqrt(Integer(3))) * (-Integer(1)) -x^3 - 1 > -2*sqrt(3) >>> (x**Integer(3) + Integer(1) >= Integer(2)*sqrt(Integer(3))) * (-Integer(1)) -x^3 - 1 >= -2*sqrt(3) >>> (x**Integer(3) + Integer(1) <= Integer(2)*sqrt(Integer(3))) * (-Integer(1)) -x^3 - 1 <= -2*sqrt(3)
(x^3 + 1 > 2*sqrt(3)) * (-1) (x^3 + 1 >= 2*sqrt(3)) * (-1) (x^3 + 1 <= 2*sqrt(3)) * (-1)
- negation()[source]¶
Return the negated version of
self
.This is the relation that is
False
iffself
isTrue
.EXAMPLES:
sage: (x < 5).negation() x >= 5 sage: (x == sin(3)).negation() x != sin(3) sage: (2*x >= sqrt(2)).negation() 2*x < sqrt(2)
>>> from sage.all import * >>> (x < Integer(5)).negation() x >= 5 >>> (x == sin(Integer(3))).negation() x != sin(3) >>> (Integer(2)*x >= sqrt(Integer(2))).negation() 2*x < sqrt(2)
(x < 5).negation() (x == sin(3)).negation() (2*x >= sqrt(2)).negation()
- nintegral(*args, **kwds)[source]¶
Compute the numerical integral of
self
.Please see
sage.calculus.calculus.nintegral
for more details.EXAMPLES:
sage: sin(x).nintegral(x,0,3) (1.989992496600..., 2.209335488557...e-14, 21, 0)
>>> from sage.all import * >>> sin(x).nintegral(x,Integer(0),Integer(3)) (1.989992496600..., 2.209335488557...e-14, 21, 0)
sin(x).nintegral(x,0,3)
- nintegrate(*args, **kwds)[source]¶
Compute the numerical integral of
self
.Please see
sage.calculus.calculus.nintegral
for more details.EXAMPLES:
sage: sin(x).nintegral(x,0,3) (1.989992496600..., 2.209335488557...e-14, 21, 0)
>>> from sage.all import * >>> sin(x).nintegral(x,Integer(0),Integer(3)) (1.989992496600..., 2.209335488557...e-14, 21, 0)
sin(x).nintegral(x,0,3)
- nops()[source]¶
Return the number of operands of this expression.
EXAMPLES:
sage: var('a,b,c,x,y') (a, b, c, x, y) sage: a.number_of_operands() 0 sage: (a^2 + b^2 + (x+y)^2).number_of_operands() 3 sage: (a^2).number_of_operands() 2 sage: (a*b^2*c).number_of_operands() 3
>>> from sage.all import * >>> var('a,b,c,x,y') (a, b, c, x, y) >>> a.number_of_operands() 0 >>> (a**Integer(2) + b**Integer(2) + (x+y)**Integer(2)).number_of_operands() 3 >>> (a**Integer(2)).number_of_operands() 2 >>> (a*b**Integer(2)*c).number_of_operands() 3
var('a,b,c,x,y') a.number_of_operands() (a^2 + b^2 + (x+y)^2).number_of_operands() (a^2).number_of_operands() (a*b^2*c).number_of_operands()
- norm()[source]¶
Return the complex norm of this symbolic expression, i.e., the expression times its complex conjugate. If \(c = a + bi\) is a complex number, then the norm of \(c\) is defined as the product of \(c\) and its complex conjugate
\[\text{norm}(c) = \text{norm}(a + bi) = c \cdot \overline{c} = a^2 + b^2.\]The norm of a complex number is different from its absolute value. The absolute value of a complex number is defined to be the square root of its norm. A typical use of the complex norm is in the integral domain \(\ZZ[i]\) of Gaussian integers, where the norm of each Gaussian integer \(c = a + bi\) is defined as its complex norm.
See also
EXAMPLES:
sage: a = 1 + 2*I sage: a.norm() 5 sage: a = sqrt(2) + 3^(1/3)*I; a sqrt(2) + I*3^(1/3) sage: a.norm() 3^(2/3) + 2 sage: CDF(a).norm() 4.080083823051... sage: CDF(a.norm()) 4.080083823051904
>>> from sage.all import * >>> a = Integer(1) + Integer(2)*I >>> a.norm() 5 >>> a = sqrt(Integer(2)) + Integer(3)**(Integer(1)/Integer(3))*I; a sqrt(2) + I*3^(1/3) >>> a.norm() 3^(2/3) + 2 >>> CDF(a).norm() 4.080083823051... >>> CDF(a.norm()) 4.080083823051904
a = 1 + 2*I a.norm() a = sqrt(2) + 3^(1/3)*I; a a.norm() CDF(a).norm() CDF(a.norm())
- normalize()[source]¶
Return this expression normalized as a fraction.
See also
numerator()
,denominator()
,numerator_denominator()
,combine()
EXAMPLES:
sage: var('x, y, a, b, c') (x, y, a, b, c) sage: g = x + y/(x + 2) sage: g.normalize() (x^2 + 2*x + y)/(x + 2) sage: f = x*(x-1)/(x^2 - 7) + y^2/(x^2-7) + 1/(x+1) + b/a + c/a sage: f.normalize() (a*x^3 + b*x^3 + c*x^3 + a*x*y^2 + a*x^2 + b*x^2 + c*x^2 + a*y^2 - a*x - 7*b*x - 7*c*x - 7*a - 7*b - 7*c)/((x^2 - 7)*a*(x + 1))
>>> from sage.all import * >>> var('x, y, a, b, c') (x, y, a, b, c) >>> g = x + y/(x + Integer(2)) >>> g.normalize() (x^2 + 2*x + y)/(x + 2) >>> 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.normalize() (a*x^3 + b*x^3 + c*x^3 + a*x*y^2 + a*x^2 + b*x^2 + c*x^2 + a*y^2 - a*x - 7*b*x - 7*c*x - 7*a - 7*b - 7*c)/((x^2 - 7)*a*(x + 1))
var('x, y, a, b, c') g = x + y/(x + 2) g.normalize() f = x*(x-1)/(x^2 - 7) + y^2/(x^2-7) + 1/(x+1) + b/a + c/a f.normalize()
ALGORITHM: Uses GiNaC.
- number_of_arguments()[source]¶
EXAMPLES:
sage: x,y = var('x,y') sage: f = x + y sage: f.number_of_arguments() 2 sage: g = f.function(x) sage: g.number_of_arguments() 1
>>> from sage.all import * >>> x,y = var('x,y') >>> f = x + y >>> f.number_of_arguments() 2 >>> g = f.function(x) >>> g.number_of_arguments() 1
x,y = var('x,y') f = x + y f.number_of_arguments() g = f.function(x) g.number_of_arguments()
sage: x,y,z = var('x,y,z') sage: (x+y).number_of_arguments() 2 sage: (x+1).number_of_arguments() 1 sage: (sin(x)+1).number_of_arguments() 1 sage: (sin(z)+x+y).number_of_arguments() 3 sage: (sin(x+y)).number_of_arguments() 2
>>> from sage.all import * >>> x,y,z = var('x,y,z') >>> (x+y).number_of_arguments() 2 >>> (x+Integer(1)).number_of_arguments() 1 >>> (sin(x)+Integer(1)).number_of_arguments() 1 >>> (sin(z)+x+y).number_of_arguments() 3 >>> (sin(x+y)).number_of_arguments() 2
x,y,z = var('x,y,z') (x+y).number_of_arguments() (x+1).number_of_arguments() (sin(x)+1).number_of_arguments() (sin(z)+x+y).number_of_arguments() (sin(x+y)).number_of_arguments()
>>> from sage.all import * >>> x,y,z = var('x,y,z') >>> (x+y).number_of_arguments() 2 >>> (x+Integer(1)).number_of_arguments() 1 >>> (sin(x)+Integer(1)).number_of_arguments() 1 >>> (sin(z)+x+y).number_of_arguments() 3 >>> (sin(x+y)).number_of_arguments() 2
x,y,z = var('x,y,z') (x+y).number_of_arguments() (x+1).number_of_arguments() (sin(x)+1).number_of_arguments() (sin(z)+x+y).number_of_arguments() (sin(x+y)).number_of_arguments()
- number_of_operands()[source]¶
Return the number of operands of this expression.
EXAMPLES:
sage: var('a,b,c,x,y') (a, b, c, x, y) sage: a.number_of_operands() 0 sage: (a^2 + b^2 + (x+y)^2).number_of_operands() 3 sage: (a^2).number_of_operands() 2 sage: (a*b^2*c).number_of_operands() 3
>>> from sage.all import * >>> var('a,b,c,x,y') (a, b, c, x, y) >>> a.number_of_operands() 0 >>> (a**Integer(2) + b**Integer(2) + (x+y)**Integer(2)).number_of_operands() 3 >>> (a**Integer(2)).number_of_operands() 2 >>> (a*b**Integer(2)*c).number_of_operands() 3
var('a,b,c,x,y') a.number_of_operands() (a^2 + b^2 + (x+y)^2).number_of_operands() (a^2).number_of_operands() (a*b^2*c).number_of_operands()
- numerator(normalize=True)[source]¶
Return the numerator of this symbolic expression.
INPUT:
normalize
– boolean (default:True
)
If
normalize
isTrue
, the expression is first normalized to have it as a fraction before getting the numerator.If
normalize
isFalse
, the expression is kept and if it is not a quotient, then this will return the expression itself.See also
normalize()
,denominator()
,numerator_denominator()
,combine()
EXAMPLES:
sage: a, x, y = var('a,x,y') sage: f = x*(x-a)/((x^2 - y)*(x-a)); f x/(x^2 - y) sage: f.numerator() x sage: f.denominator() x^2 - y sage: f.numerator(normalize=False) x sage: f.denominator(normalize=False) x^2 - y sage: y = var('y') sage: g = x + y/(x + 2); g x + y/(x + 2) sage: g.numerator() x^2 + 2*x + y sage: g.denominator() x + 2 sage: g.numerator(normalize=False) x + y/(x + 2) sage: g.denominator(normalize=False) 1
>>> from sage.all import * >>> a, x, y = var('a,x,y') >>> f = x*(x-a)/((x**Integer(2) - y)*(x-a)); f x/(x^2 - y) >>> f.numerator() x >>> f.denominator() x^2 - y >>> f.numerator(normalize=False) x >>> f.denominator(normalize=False) x^2 - y >>> y = var('y') >>> g = x + y/(x + Integer(2)); g x + y/(x + 2) >>> g.numerator() x^2 + 2*x + y >>> g.denominator() x + 2 >>> g.numerator(normalize=False) x + y/(x + 2) >>> g.denominator(normalize=False) 1
a, x, y = var('a,x,y') f = x*(x-a)/((x^2 - y)*(x-a)); f f.numerator() f.denominator() f.numerator(normalize=False) f.denominator(normalize=False) y = var('y') g = x + y/(x + 2); g g.numerator() g.denominator() g.numerator(normalize=False) g.denominator(normalize=False)
- numerator_denominator(normalize=True)[source]¶
Return the numerator and the denominator of this symbolic expression.
INPUT:
normalize
– boolean (default:True
)
If
normalize
isTrue
, the expression is first normalized to have it as a fraction before getting the numerator and denominator.If
normalize
isFalse
, the expression is kept and if it is not a quotient, then this will return the expression itself together with 1.See also
EXAMPLES:
sage: x, y, a = var("x y a") sage: ((x+y)^2/(x-y)^3*x^3).numerator_denominator() ((x + y)^2*x^3, (x - y)^3) sage: ((x+y)^2/(x-y)^3*x^3).numerator_denominator(False) ((x + y)^2*x^3, (x - y)^3) sage: g = x + y/(x + 2) sage: g.numerator_denominator() (x^2 + 2*x + y, x + 2) sage: g.numerator_denominator(normalize=False) (x + y/(x + 2), 1) sage: g = x^2*(x + 2) sage: g.numerator_denominator() ((x + 2)*x^2, 1) sage: g.numerator_denominator(normalize=False) ((x + 2)*x^2, 1)
>>> from sage.all import * >>> x, y, a = var("x y a") >>> ((x+y)**Integer(2)/(x-y)**Integer(3)*x**Integer(3)).numerator_denominator() ((x + y)^2*x^3, (x - y)^3) >>> ((x+y)**Integer(2)/(x-y)**Integer(3)*x**Integer(3)).numerator_denominator(False) ((x + y)^2*x^3, (x - y)^3) >>> g = x + y/(x + Integer(2)) >>> g.numerator_denominator() (x^2 + 2*x + y, x + 2) >>> g.numerator_denominator(normalize=False) (x + y/(x + 2), 1) >>> g = x**Integer(2)*(x + Integer(2)) >>> g.numerator_denominator() ((x + 2)*x^2, 1) >>> g.numerator_denominator(normalize=False) ((x + 2)*x^2, 1)
x, y, a = var("x y a") ((x+y)^2/(x-y)^3*x^3).numerator_denominator() ((x+y)^2/(x-y)^3*x^3).numerator_denominator(False) g = x + y/(x + 2) g.numerator_denominator() g.numerator_denominator(normalize=False) g = x^2*(x + 2) g.numerator_denominator() g.numerator_denominator(normalize=False)
- numerical_approx(prec=None, digits=None, algorithm=None)[source]¶
Return a numerical approximation of
self
withprec
bits (or decimaldigits
) of precision.No guarantee is made about the accuracy of the result.
INPUT:
prec
– precision in bitsdigits
– precision in decimal digits (only used ifprec
is not given)algorithm
– which algorithm to use to compute this approximation
If neither
prec
nordigits
is given, the default precision is 53 bits (roughly 16 digits).EXAMPLES:
sage: sin(x).subs(x=5).n() -0.958924274663138 sage: sin(x).subs(x=5).n(100) -0.95892427466313846889315440616 sage: sin(x).subs(x=5).n(digits=50) -0.95892427466313846889315440615599397335246154396460 sage: zeta(x).subs(x=2).numerical_approx(digits=50) 1.6449340668482264364724151666460251892189499012068 sage: cos(3).numerical_approx(200) -0.98999249660044545727157279473126130239367909661558832881409 sage: numerical_approx(cos(3),200) -0.98999249660044545727157279473126130239367909661558832881409 sage: numerical_approx(cos(3), digits=10) -0.9899924966 sage: (i + 1).numerical_approx(32) 1.00000000 + 1.00000000*I sage: (pi + e + sqrt(2)).numerical_approx(100) 7.2740880444219335226246195788
>>> from sage.all import * >>> sin(x).subs(x=Integer(5)).n() -0.958924274663138 >>> sin(x).subs(x=Integer(5)).n(Integer(100)) -0.95892427466313846889315440616 >>> sin(x).subs(x=Integer(5)).n(digits=Integer(50)) -0.95892427466313846889315440615599397335246154396460 >>> zeta(x).subs(x=Integer(2)).numerical_approx(digits=Integer(50)) 1.6449340668482264364724151666460251892189499012068 >>> cos(Integer(3)).numerical_approx(Integer(200)) -0.98999249660044545727157279473126130239367909661558832881409 >>> numerical_approx(cos(Integer(3)),Integer(200)) -0.98999249660044545727157279473126130239367909661558832881409 >>> numerical_approx(cos(Integer(3)), digits=Integer(10)) -0.9899924966 >>> (i + Integer(1)).numerical_approx(Integer(32)) 1.00000000 + 1.00000000*I >>> (pi + e + sqrt(Integer(2))).numerical_approx(Integer(100)) 7.2740880444219335226246195788
sin(x).subs(x=5).n() sin(x).subs(x=5).n(100) sin(x).subs(x=5).n(digits=50) zeta(x).subs(x=2).numerical_approx(digits=50) cos(3).numerical_approx(200) numerical_approx(cos(3),200) numerical_approx(cos(3), digits=10) (i + 1).numerical_approx(32) (pi + e + sqrt(2)).numerical_approx(100)
- op¶
Provide access to the operands of an expression through a property.
EXAMPLES:
sage: t = 1+x+x^2 sage: t.op Operands of x^2 + x + 1 sage: x.op Traceback (most recent call last): ... TypeError: expressions containing only a numeric coefficient, constant or symbol have no operands sage: t.op[0] x^2
>>> from sage.all import * >>> t = Integer(1)+x+x**Integer(2) >>> t.op Operands of x^2 + x + 1 >>> x.op Traceback (most recent call last): ... TypeError: expressions containing only a numeric coefficient, constant or symbol have no operands >>> t.op[Integer(0)] x^2
t = 1+x+x^2 t.op x.op t.op[0]
Indexing directly with
t[1]
causes problems with numpy types.sage: t[1] Traceback (most recent call last): … TypeError: ‘sage.symbolic.expression.Expression’ object …
- operands()[source]¶
Return a list containing the operands of this expression.
EXAMPLES:
sage: var('a,b,c,x,y') (a, b, c, x, y) sage: (a^2 + b^2 + (x+y)^2).operands() [a^2, b^2, (x + y)^2] sage: (a^2).operands() [a, 2] sage: (a*b^2*c).operands() [a, b^2, c]
>>> from sage.all import * >>> var('a,b,c,x,y') (a, b, c, x, y) >>> (a**Integer(2) + b**Integer(2) + (x+y)**Integer(2)).operands() [a^2, b^2, (x + y)^2] >>> (a**Integer(2)).operands() [a, 2] >>> (a*b**Integer(2)*c).operands() [a, b^2, c]
var('a,b,c,x,y') (a^2 + b^2 + (x+y)^2).operands() (a^2).operands() (a*b^2*c).operands()
- operator()[source]¶
Return the topmost operator in this expression.
EXAMPLES:
sage: x,y,z = var('x,y,z') sage: (x+y).operator() <function add_vararg ...> sage: (x^y).operator() <built-in function pow> sage: (x^y * z).operator() <function mul_vararg ...> sage: (x < y).operator() <built-in function lt> sage: abs(x).operator() abs sage: r = gamma(x).operator(); type(r) <class 'sage.functions.gamma.Function_gamma'> sage: psi = function('psi', nargs=1) sage: psi(x).operator() psi sage: r = psi(x).operator() sage: r == psi True sage: f = function('f', nargs=1, conjugate_func=lambda self, x: 2*x) sage: nf = f(x).operator() sage: nf(x).conjugate() 2*x sage: f = function('f') sage: a = f(x).diff(x); a diff(f(x), x) sage: a.operator() D[0](f)
>>> from sage.all import * >>> x,y,z = var('x,y,z') >>> (x+y).operator() <function add_vararg ...> >>> (x**y).operator() <built-in function pow> >>> (x**y * z).operator() <function mul_vararg ...> >>> (x < y).operator() <built-in function lt> >>> abs(x).operator() abs >>> r = gamma(x).operator(); type(r) <class 'sage.functions.gamma.Function_gamma'> >>> psi = function('psi', nargs=Integer(1)) >>> psi(x).operator() psi >>> r = psi(x).operator() >>> r == psi True >>> f = function('f', nargs=Integer(1), conjugate_func=lambda self, x: Integer(2)*x) >>> nf = f(x).operator() >>> nf(x).conjugate() 2*x >>> f = function('f') >>> a = f(x).diff(x); a diff(f(x), x) >>> a.operator() D[0](f)
x,y,z = var('x,y,z') (x+y).operator() (x^y).operator() (x^y * z).operator() (x < y).operator() abs(x).operator() r = gamma(x).operator(); type(r) psi = function('psi', nargs=1) psi(x).operator() r = psi(x).operator() r == psi f = function('f', nargs=1, conjugate_func=lambda self, x: 2*x) nf = f(x).operator() nf(x).conjugate() f = function('f') a = f(x).diff(x); a a.operator()
- partial_fraction(var=None)[source]¶
Return the partial fraction expansion of
self
with respect to the given variable.INPUT:
var
– variable name or string (default: first variable)
OUTPUT: a symbolic expression
See also
EXAMPLES:
sage: f = x^2/(x+1)^3 sage: f.partial_fraction() 1/(x + 1) - 2/(x + 1)^2 + 1/(x + 1)^3
>>> from sage.all import * >>> f = x**Integer(2)/(x+Integer(1))**Integer(3) >>> f.partial_fraction() 1/(x + 1) - 2/(x + 1)^2 + 1/(x + 1)^3
f = x^2/(x+1)^3 f.partial_fraction()
Notice that the first variable in the expression is used by default:
sage: y = var('y') sage: f = y^2/(y+1)^3 sage: f.partial_fraction() 1/(y + 1) - 2/(y + 1)^2 + 1/(y + 1)^3 sage: f = y^2/(y+1)^3 + x/(x-1)^3 sage: f.partial_fraction() y^2/(y^3 + 3*y^2 + 3*y + 1) + 1/(x - 1)^2 + 1/(x - 1)^3
>>> from sage.all import * >>> y = var('y') >>> f = y**Integer(2)/(y+Integer(1))**Integer(3) >>> f.partial_fraction() 1/(y + 1) - 2/(y + 1)^2 + 1/(y + 1)^3 >>> f = y**Integer(2)/(y+Integer(1))**Integer(3) + x/(x-Integer(1))**Integer(3) >>> f.partial_fraction() y^2/(y^3 + 3*y^2 + 3*y + 1) + 1/(x - 1)^2 + 1/(x - 1)^3
y = var('y') f = y^2/(y+1)^3 f.partial_fraction() f = y^2/(y+1)^3 + x/(x-1)^3 f.partial_fraction()
You can explicitly specify which variable is used:
sage: f.partial_fraction(y) x/(x^3 - 3*x^2 + 3*x - 1) + 1/(y + 1) - 2/(y + 1)^2 + 1/(y + 1)^3
>>> from sage.all import * >>> f.partial_fraction(y) x/(x^3 - 3*x^2 + 3*x - 1) + 1/(y + 1) - 2/(y + 1)^2 + 1/(y + 1)^3
f.partial_fraction(y)
- partial_fraction_decomposition(var=None)[source]¶
Return the partial fraction decomposition of
self
with respect to the given variable.INPUT:
var
– variable name or string (default: first variable)
OUTPUT: list of symbolic expressions
See also
EXAMPLES:
sage: f = x^2/(x+1)^3 sage: f.partial_fraction_decomposition() [1/(x + 1), -2/(x + 1)^2, (x + 1)^(-3)] sage: (4+f).partial_fraction_decomposition() [1/(x + 1), -2/(x + 1)^2, (x + 1)^(-3), 4]
>>> from sage.all import * >>> f = x**Integer(2)/(x+Integer(1))**Integer(3) >>> f.partial_fraction_decomposition() [1/(x + 1), -2/(x + 1)^2, (x + 1)^(-3)] >>> (Integer(4)+f).partial_fraction_decomposition() [1/(x + 1), -2/(x + 1)^2, (x + 1)^(-3), 4]
f = x^2/(x+1)^3 f.partial_fraction_decomposition() (4+f).partial_fraction_decomposition()
Notice that the first variable in the expression is used by default:
sage: y = var('y') sage: f = y^2/(y+1)^3 sage: f.partial_fraction_decomposition() [1/(y + 1), -2/(y + 1)^2, (y + 1)^(-3)] sage: f = y^2/(y+1)^3 + x/(x-1)^3 sage: f.partial_fraction_decomposition() [y^2/(y^3 + 3*y^2 + 3*y + 1), (x - 1)^(-2), (x - 1)^(-3)]
>>> from sage.all import * >>> y = var('y') >>> f = y**Integer(2)/(y+Integer(1))**Integer(3) >>> f.partial_fraction_decomposition() [1/(y + 1), -2/(y + 1)^2, (y + 1)^(-3)] >>> f = y**Integer(2)/(y+Integer(1))**Integer(3) + x/(x-Integer(1))**Integer(3) >>> f.partial_fraction_decomposition() [y^2/(y^3 + 3*y^2 + 3*y + 1), (x - 1)^(-2), (x - 1)^(-3)]
y = var('y') f = y^2/(y+1)^3 f.partial_fraction_decomposition() f = y^2/(y+1)^3 + x/(x-1)^3 f.partial_fraction_decomposition()
You can explicitly specify which variable is used:
sage: f.partial_fraction_decomposition(y) [1/(y + 1), -2/(y + 1)^2, (y + 1)^(-3), x/(x^3 - 3*x^2 + 3*x - 1)]
>>> from sage.all import * >>> f.partial_fraction_decomposition(y) [1/(y + 1), -2/(y + 1)^2, (y + 1)^(-3), x/(x^3 - 3*x^2 + 3*x - 1)]
f.partial_fraction_decomposition(y)
- plot(*args, **kwds)[source]¶
Plot a symbolic expression. All arguments are passed onto the standard
plot()
command.EXAMPLES:
This displays a straight line:
sage: sin(2).plot((x,0,3)) # needs sage.plot Graphics object consisting of 1 graphics primitive
>>> from sage.all import * >>> sin(Integer(2)).plot((x,Integer(0),Integer(3))) # needs sage.plot Graphics object consisting of 1 graphics primitive
sin(2).plot((x,0,3)) # needs sage.plot
This draws a red oscillatory curve:
sage: sin(x^2).plot((x,0,2*pi), rgbcolor=(1,0,0)) # needs sage.plot Graphics object consisting of 1 graphics primitive
>>> from sage.all import * >>> sin(x**Integer(2)).plot((x,Integer(0),Integer(2)*pi), rgbcolor=(Integer(1),Integer(0),Integer(0))) # needs sage.plot Graphics object consisting of 1 graphics primitive
sin(x^2).plot((x,0,2*pi), rgbcolor=(1,0,0)) # needs sage.plot
Another plot using the variable theta:
sage: var('theta') theta sage: (cos(theta) - erf(theta)).plot((theta,-2*pi,2*pi)) # needs sage.plot Graphics object consisting of 1 graphics primitive
>>> from sage.all import * >>> var('theta') theta >>> (cos(theta) - erf(theta)).plot((theta,-Integer(2)*pi,Integer(2)*pi)) # needs sage.plot Graphics object consisting of 1 graphics primitive
var('theta') (cos(theta) - erf(theta)).plot((theta,-2*pi,2*pi)) # needs sage.plot
A very thick green plot with a frame:
sage: sin(x).plot((x, -4*pi, 4*pi), # needs sage.plot ....: thickness=20, rgbcolor=(0,0.7,0)).show(frame=True)
>>> from sage.all import * >>> sin(x).plot((x, -Integer(4)*pi, Integer(4)*pi), # needs sage.plot ... thickness=Integer(20), rgbcolor=(Integer(0),RealNumber('0.7'),Integer(0))).show(frame=True)
sin(x).plot((x, -4*pi, 4*pi), # needs sage.plot thickness=20, rgbcolor=(0,0.7,0)).show(frame=True)
You can embed 2d plots in 3d space as follows:
sage: plot(sin(x^2), (x, -pi, pi), thickness=2).plot3d(z=1) # long time, needs sage.plot Graphics3d Object
>>> from sage.all import * >>> plot(sin(x**Integer(2)), (x, -pi, pi), thickness=Integer(2)).plot3d(z=Integer(1)) # long time, needs sage.plot Graphics3d Object
plot(sin(x^2), (x, -pi, pi), thickness=2).plot3d(z=1) # long time, needs sage.plot
A more complicated family:
sage: G = sum(plot(sin(n*x), (x, -2*pi, 2*pi)).plot3d(z=n) # needs sage.plot ....: for n in [0,0.1,..1]) sage: G.show(frame_aspect_ratio=[1,1,1/2]) # long time (5s on sage.math, 2012), needs sage.plot
>>> from sage.all import * >>> G = sum(plot(sin(n*x), (x, -Integer(2)*pi, Integer(2)*pi)).plot3d(z=n) # needs sage.plot ... for n in (ellipsis_range(Integer(0),RealNumber('0.1'),Ellipsis,Integer(1)))) >>> G.show(frame_aspect_ratio=[Integer(1),Integer(1),Integer(1)/Integer(2)]) # long time (5s on sage.math, 2012), needs sage.plot
G = sum(plot(sin(n*x), (x, -2*pi, 2*pi)).plot3d(z=n) # needs sage.plot for n in [0,0.1,..1]) G.show(frame_aspect_ratio=[1,1,1/2]) # long time (5s on sage.math, 2012), needs sage.plot
A plot involving the floor function:
sage: plot(1.0 - x * floor(1/x), (x,0.00001,1.0)) # needs sage.plot Graphics object consisting of 1 graphics primitive
>>> from sage.all import * >>> plot(RealNumber('1.0') - x * floor(Integer(1)/x), (x,RealNumber('0.00001'),RealNumber('1.0'))) # needs sage.plot Graphics object consisting of 1 graphics primitive
plot(1.0 - x * floor(1/x), (x,0.00001,1.0)) # needs sage.plot
Sage used to allow symbolic functions with “no arguments”; this no longer works:
sage: plot(2*sin, -4, 4) # needs sage.plot Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'Integer Ring' and '<class 'sage.functions.trig.Function_sin'>'
>>> from sage.all import * >>> plot(Integer(2)*sin, -Integer(4), Integer(4)) # needs sage.plot Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'Integer Ring' and '<class 'sage.functions.trig.Function_sin'>'
plot(2*sin, -4, 4) # needs sage.plot
You should evaluate the function first:
sage: plot(2*sin(x), -4, 4) # needs sage.plot Graphics object consisting of 1 graphics primitive
>>> from sage.all import * >>> plot(Integer(2)*sin(x), -Integer(4), Integer(4)) # needs sage.plot Graphics object consisting of 1 graphics primitive
plot(2*sin(x), -4, 4) # needs sage.plot
- poly(x=None)[source]¶
Express this symbolic expression as a polynomial in x. If this is not a polynomial in x, then some coefficients may be functions of x.
Warning
This is different from
polynomial()
which returns a Sage polynomial over a given base ring.EXAMPLES:
sage: var('a, x') (a, x) 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.poly(a) -2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1 sage: bool(p.poly(a) == (x-a*sqrt(2))^2 + x + 1) True sage: p.poly(x) 2*a^2 - (2*sqrt(2)*a - 1)*x + x^2 + 1
>>> from sage.all import * >>> var('a, x') (a, x) >>> 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.poly(a) -2*sqrt(2)*a*x + 2*a^2 + x^2 + x + 1 >>> bool(p.poly(a) == (x-a*sqrt(Integer(2)))**Integer(2) + x + Integer(1)) True >>> p.poly(x) 2*a^2 - (2*sqrt(2)*a - 1)*x + x^2 + 1
var('a, x') p = expand((x-a*sqrt(2))^2 + x + 1); p p.poly(a) bool(p.poly(a) == (x-a*sqrt(2))^2 + x + 1) p.poly(x)
- polynomial(base_ring=None, ring=None)[source]¶
Return this symbolic expression as an algebraic polynomial over the given base ring, if possible.
The point of this function is that it converts purely symbolic polynomials into optimised algebraic polynomials over a given base ring.
You can specify either the base ring (
base_ring
) you want the output polynomial to be over, or you can specify the full polynomial ring (ring
) you want the output polynomial to be an element of.INPUT:
base_ring
– (optional) the base ring for the polynomialring
– (optional) the parent for the polynomial
Warning
This is different from
poly()
which is used to rewriteself
as a polynomial in terms of one of the variables.EXAMPLES:
sage: f = x^2 -2/3*x + 1 sage: f.polynomial(QQ) x^2 - 2/3*x + 1 sage: f.polynomial(GF(19)) x^2 + 12*x + 1
>>> from sage.all import * >>> f = x**Integer(2) -Integer(2)/Integer(3)*x + Integer(1) >>> f.polynomial(QQ) x^2 - 2/3*x + 1 >>> f.polynomial(GF(Integer(19))) x^2 + 12*x + 1
f = x^2 -2/3*x + 1 f.polynomial(QQ) f.polynomial(GF(19))
Polynomials can be useful for getting the coefficients of an expression:
sage: g = 6*x^2 - 5 sage: g.coefficients() [[-5, 0], [6, 2]] sage: g.polynomial(QQ).list() [-5, 0, 6] sage: g.polynomial(QQ).monomial_coefficients() {0: -5, 2: 6}
>>> from sage.all import * >>> g = Integer(6)*x**Integer(2) - Integer(5) >>> g.coefficients() [[-5, 0], [6, 2]] >>> g.polynomial(QQ).list() [-5, 0, 6] >>> g.polynomial(QQ).monomial_coefficients() {0: -5, 2: 6}
g = 6*x^2 - 5 g.coefficients() g.polynomial(QQ).list() g.polynomial(QQ).monomial_coefficients()
sage: f = x^2*e + x + pi/e sage: f.polynomial(RDF) # abs tol 5e-16 2.718281828459045*x^2 + x + 1.1557273497909217 sage: g = f.polynomial(RR); g 2.71828182845905*x^2 + x + 1.15572734979092 sage: g.parent() Univariate Polynomial Ring in x over Real Field with 53 bits of precision sage: f.polynomial(RealField(100)) 2.7182818284590452353602874714*x^2 + x + 1.1557273497909217179100931833 sage: f.polynomial(CDF) # abs tol 5e-16 2.718281828459045*x^2 + x + 1.1557273497909217 sage: f.polynomial(CC) 2.71828182845905*x^2 + x + 1.15572734979092
>>> from sage.all import * >>> f = x**Integer(2)*e + x + pi/e >>> f.polynomial(RDF) # abs tol 5e-16 2.718281828459045*x^2 + x + 1.1557273497909217 >>> g = f.polynomial(RR); g 2.71828182845905*x^2 + x + 1.15572734979092 >>> g.parent() Univariate Polynomial Ring in x over Real Field with 53 bits of precision >>> f.polynomial(RealField(Integer(100))) 2.7182818284590452353602874714*x^2 + x + 1.1557273497909217179100931833 >>> f.polynomial(CDF) # abs tol 5e-16 2.718281828459045*x^2 + x + 1.1557273497909217 >>> f.polynomial(CC) 2.71828182845905*x^2 + x + 1.15572734979092
f = x^2*e + x + pi/e f.polynomial(RDF) # abs tol 5e-16 g = f.polynomial(RR); g g.parent() f.polynomial(RealField(100)) f.polynomial(CDF) # abs tol 5e-16 f.polynomial(CC)
>>> from sage.all import * >>> f = x**Integer(2)*e + x + pi/e >>> f.polynomial(RDF) # abs tol 5e-16 2.718281828459045*x^2 + x + 1.1557273497909217 >>> g = f.polynomial(RR); g 2.71828182845905*x^2 + x + 1.15572734979092 >>> g.parent() Univariate Polynomial Ring in x over Real Field with 53 bits of precision >>> f.polynomial(RealField(Integer(100))) 2.7182818284590452353602874714*x^2 + x + 1.1557273497909217179100931833 >>> f.polynomial(CDF) # abs tol 5e-16 2.718281828459045*x^2 + x + 1.1557273497909217 >>> f.polynomial(CC) 2.71828182845905*x^2 + x + 1.15572734979092
f = x^2*e + x + pi/e f.polynomial(RDF) # abs tol 5e-16 g = f.polynomial(RR); g g.parent() f.polynomial(RealField(100)) f.polynomial(CDF) # abs tol 5e-16 f.polynomial(CC)
We coerce a multivariate polynomial with complex symbolic coefficients:
sage: x, y, n = var('x, y, n') sage: f = pi^3*x - y^2*e - I; f pi^3*x - y^2*e - I sage: f.polynomial(CDF) # abs tol 1e-15 (-2.718281828459045)*y^2 + 31.006276680299816*x - 1.0*I sage: f.polynomial(CC) (-2.71828182845905)*y^2 + 31.0062766802998*x - 1.00000000000000*I sage: f.polynomial(ComplexField(70)) (-2.7182818284590452354)*y^2 + 31.006276680299820175*x - 1.0000000000000000000*I
>>> from sage.all import * >>> x, y, n = var('x, y, n') >>> f = pi**Integer(3)*x - y**Integer(2)*e - I; f pi^3*x - y^2*e - I >>> f.polynomial(CDF) # abs tol 1e-15 (-2.718281828459045)*y^2 + 31.006276680299816*x - 1.0*I >>> f.polynomial(CC) (-2.71828182845905)*y^2 + 31.0062766802998*x - 1.00000000000000*I >>> f.polynomial(ComplexField(Integer(70))) (-2.7182818284590452354)*y^2 + 31.006276680299820175*x - 1.0000000000000000000*I
x, y, n = var('x, y, n') f = pi^3*x - y^2*e - I; f f.polynomial(CDF) # abs tol 1e-15 f.polynomial(CC) f.polynomial(ComplexField(70))
Another polynomial:
sage: f = sum((e*I)^n*x^n for n in range(5)); f x^4*e^4 - I*x^3*e^3 - x^2*e^2 + I*x*e + 1 sage: f.polynomial(CDF) # abs tol 5e-16 54.598150033144236*x^4 - 20.085536923187668*I*x^3 - 7.38905609893065*x^2 + 2.718281828459045*I*x + 1.0 sage: f.polynomial(CC) 54.5981500331442*x^4 - 20.0855369231877*I*x^3 - 7.38905609893065*x^2 + 2.71828182845905*I*x + 1.00000000000000
>>> from sage.all import * >>> f = sum((e*I)**n*x**n for n in range(Integer(5))); f x^4*e^4 - I*x^3*e^3 - x^2*e^2 + I*x*e + 1 >>> f.polynomial(CDF) # abs tol 5e-16 54.598150033144236*x^4 - 20.085536923187668*I*x^3 - 7.38905609893065*x^2 + 2.718281828459045*I*x + 1.0 >>> f.polynomial(CC) 54.5981500331442*x^4 - 20.0855369231877*I*x^3 - 7.38905609893065*x^2 + 2.71828182845905*I*x + 1.00000000000000
f = sum((e*I)^n*x^n for n in range(5)); f f.polynomial(CDF) # abs tol 5e-16 f.polynomial(CC)
A multivariate polynomial over a finite field:
sage: f = (3*x^5 - 5*y^5)^7; f (3*x^5 - 5*y^5)^7 sage: g = f.polynomial(GF(7)); g 3*x^35 + 2*y^35 sage: parent(g) Multivariate Polynomial Ring in x, y over Finite Field of size 7
>>> from sage.all import * >>> f = (Integer(3)*x**Integer(5) - Integer(5)*y**Integer(5))**Integer(7); f (3*x^5 - 5*y^5)^7 >>> g = f.polynomial(GF(Integer(7))); g 3*x^35 + 2*y^35 >>> parent(g) Multivariate Polynomial Ring in x, y over Finite Field of size 7
f = (3*x^5 - 5*y^5)^7; f g = f.polynomial(GF(7)); g parent(g)
We check to make sure constants are converted appropriately:
sage: (pi*x).polynomial(SR) pi*x
>>> from sage.all import * >>> (pi*x).polynomial(SR) pi*x
(pi*x).polynomial(SR)
Using the
ring
parameter, you can also create polynomials rings over the symbolic ring where only certain variables are considered generators of the polynomial ring and the others are considered “constants”:sage: a, x, y = var('a,x,y') sage: f = a*x^10*y+3*x sage: B = f.polynomial(ring=SR['x,y']) sage: B.coefficients() [a, 3]
>>> from sage.all import * >>> a, x, y = var('a,x,y') >>> f = a*x**Integer(10)*y+Integer(3)*x >>> B = f.polynomial(ring=SR['x,y']) >>> B.coefficients() [a, 3]
a, x, y = var('a,x,y') f = a*x^10*y+3*x B = f.polynomial(ring=SR['x,y']) B.coefficients()
- power(exp, hold=False)[source]¶
Return the current expression to the power
exp
.To prevent automatic evaluation use the
hold
argument.EXAMPLES:
sage: (x^2).power(2) x^4 sage: (x^2).power(2, hold=True) (x^2)^2
>>> from sage.all import * >>> (x**Integer(2)).power(Integer(2)) x^4 >>> (x**Integer(2)).power(Integer(2), hold=True) (x^2)^2
(x^2).power(2) (x^2).power(2, hold=True)
To then evaluate again, we use
unhold()
:sage: a = (x^2).power(2, hold=True); a.unhold() x^4
>>> from sage.all import * >>> a = (x**Integer(2)).power(Integer(2), hold=True); a.unhold() x^4
a = (x^2).power(2, hold=True); a.unhold()
- power_series(base_ring)[source]¶
Return algebraic power series associated to this symbolic expression, which must be a polynomial in one variable, with coefficients coercible to the base ring.
The power series is truncated one more than the degree.
EXAMPLES:
sage: theta = var('theta') sage: f = theta^3 + (1/3)*theta - 17/3 sage: g = f.power_series(QQ); g -17/3 + 1/3*theta + theta^3 + O(theta^4) sage: g^3 -4913/27 + 289/9*theta - 17/9*theta^2 + 2602/27*theta^3 + O(theta^4) sage: g.parent() Power Series Ring in theta over Rational Field
>>> from sage.all import * >>> theta = var('theta') >>> f = theta**Integer(3) + (Integer(1)/Integer(3))*theta - Integer(17)/Integer(3) >>> g = f.power_series(QQ); g -17/3 + 1/3*theta + theta^3 + O(theta^4) >>> g**Integer(3) -4913/27 + 289/9*theta - 17/9*theta^2 + 2602/27*theta^3 + O(theta^4) >>> g.parent() Power Series Ring in theta over Rational Field
theta = var('theta') f = theta^3 + (1/3)*theta - 17/3 g = f.power_series(QQ); g g^3 g.parent()
- primitive_part(s)[source]¶
Return the primitive polynomial of this expression when considered as a polynomial in
s
.See also
unit()
,content()
, andunit_content_primitive()
.INPUT:
s
– a symbolic expression
OUTPUT:
The primitive polynomial as a symbolic expression. It is defined as the quotient by the
unit()
andcontent()
parts (with respect to the variables
).EXAMPLES:
sage: (2*x+4).primitive_part(x) x + 2 sage: (2*x+1).primitive_part(x) 2*x + 1 sage: (2*x+1/2).primitive_part(x) 4*x + 1 sage: var('y') y sage: (2*x + 4*sin(y)).primitive_part(sin(y)) x + 2*sin(y)
>>> from sage.all import * >>> (Integer(2)*x+Integer(4)).primitive_part(x) x + 2 >>> (Integer(2)*x+Integer(1)).primitive_part(x) 2*x + 1 >>> (Integer(2)*x+Integer(1)/Integer(2)).primitive_part(x) 4*x + 1 >>> var('y') y >>> (Integer(2)*x + Integer(4)*sin(y)).primitive_part(sin(y)) x + 2*sin(y)
(2*x+4).primitive_part(x) (2*x+1).primitive_part(x) (2*x+1/2).primitive_part(x) var('y') (2*x + 4*sin(y)).primitive_part(sin(y))
- prod(*args, **kwds)[source]¶
Return the symbolic product \(\prod_{v = a}^b\)
self
.This is the product respect to the variable \(v\) with endpoints \(a\) and \(b\).
INPUT:
expression
– a symbolic expressionv
– a variable or variable namea
– lower endpoint of the productb
– upper endpoint of the productalgorithm
– (default:'maxima'
) one of'maxima'
– use Maxima (the default)'giac'
– (optional) use Giac'sympy'
– use SymPy
hold
– boolean (default:False
); ifTrue
, don’t evaluate
- pyobject()[source]¶
Get the underlying Python object.
OUTPUT:
The Python object corresponding to this expression, assuming this expression is a single numerical value or an infinity representable in Python. Otherwise, a
TypeError
is raised.EXAMPLES:
sage: var('x') x sage: b = -17.3 sage: a = SR(b) sage: a.pyobject() -17.3000000000000 sage: a.pyobject() is b True
>>> from sage.all import * >>> var('x') x >>> b = -RealNumber('17.3') >>> a = SR(b) >>> a.pyobject() -17.3000000000000 >>> a.pyobject() is b True
var('x') b = -17.3 a = SR(b) a.pyobject() a.pyobject() is b
Integers and Rationals are converted internally though, so you won’t get back the same object:
sage: b = -17/3 sage: a = SR(b) sage: a.pyobject() -17/3 sage: a.pyobject() is b False
>>> from sage.all import * >>> b = -Integer(17)/Integer(3) >>> a = SR(b) >>> a.pyobject() -17/3 >>> a.pyobject() is b False
b = -17/3 a = SR(b) a.pyobject() a.pyobject() is b
- rational_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
x,y = var('x,y') a = (x-y)^5 a.expand() expand(a)
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
expand((x-1)^3/(y-1)) expand((x+sin((x+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)
f(x) = function('f')(x) fx = f(x*(x+1)); fx fx.expand()
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
a = (16*x-13)^2 == (3*x+5)^2/2 a.expand() a.expand('left') a.expand('right')
- rational_simplify(algorithm='full', map=False)[source]¶
Simplify rational expressions.
INPUT:
self
– symbolic expressionalgorithm
– (default:'full'
) string which switches the algorithm for simplifications. Possible values are'simple'
(simplify rational functions into quotient of two polynomials)'full'
(apply repeatedly, if necessary)'noexpand'
(convert to common denominator and add)
map
– boolean (default:False
); ifTrue
, the result is an expression whose leading operator is the same as that of the expressionself
but whose subparts are the results of applying simplification rules to the corresponding subparts of the expressions.
ALIAS:
rational_simplify()
andsimplify_rational()
are the sameDETAILS: We call Maxima functions ratsimp, fullratsimp and xthru. If each part of the expression has to be simplified separately, we use Maxima function map.
EXAMPLES:
sage: f = sin(x/(x^2 + x)) sage: f sin(x/(x^2 + x)) sage: f.simplify_rational() sin(1/(x + 1))
>>> from sage.all import * >>> f = sin(x/(x**Integer(2) + x)) >>> f sin(x/(x^2 + x)) >>> f.simplify_rational() sin(1/(x + 1))
f = sin(x/(x^2 + x)) f f.simplify_rational()
sage: f = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1)); f -((x + 1)*sqrt(x - 1) - (x - 1)^(3/2))/sqrt((x + 1)*(x - 1)) sage: f.simplify_rational() -2*sqrt(x - 1)/sqrt(x^2 - 1)
>>> from sage.all import * >>> f = ((x - Integer(1))**(Integer(3)/Integer(2)) - (x + Integer(1))*sqrt(x - Integer(1)))/sqrt((x - Integer(1))*(x + Integer(1))); f -((x + 1)*sqrt(x - 1) - (x - 1)^(3/2))/sqrt((x + 1)*(x - 1)) >>> f.simplify_rational() -2*sqrt(x - 1)/sqrt(x^2 - 1)
f = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1)); f f.simplify_rational()
>>> from sage.all import * >>> f = ((x - Integer(1))**(Integer(3)/Integer(2)) - (x + Integer(1))*sqrt(x - Integer(1)))/sqrt((x - Integer(1))*(x + Integer(1))); f -((x + 1)*sqrt(x - 1) - (x - 1)^(3/2))/sqrt((x + 1)*(x - 1)) >>> f.simplify_rational() -2*sqrt(x - 1)/sqrt(x^2 - 1)
f = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1)); f f.simplify_rational()
With
map=True
each term in a sum is simplified separately and thus the results are shorter for functions which are combination of rational and nonrational functions. In the following example, we use this option if we want not to combine logarithm and the rational function into one fraction:sage: f = (x^2-1)/(x+1)-ln(x)/(x+2) sage: f.simplify_rational() (x^2 + x - log(x) - 2)/(x + 2) sage: f.simplify_rational(map=True) x - log(x)/(x + 2) - 1
>>> from sage.all import * >>> f = (x**Integer(2)-Integer(1))/(x+Integer(1))-ln(x)/(x+Integer(2)) >>> f.simplify_rational() (x^2 + x - log(x) - 2)/(x + 2) >>> f.simplify_rational(map=True) x - log(x)/(x + 2) - 1
f = (x^2-1)/(x+1)-ln(x)/(x+2) f.simplify_rational() f.simplify_rational(map=True)
Here is an example from the Maxima documentation of where
algorithm='simple'
produces an (possibly useful) intermediate step:sage: y = var('y') sage: g = (x^(y/2) + 1)^2*(x^(y/2) - 1)^2/(x^y - 1) sage: g.simplify_rational(algorithm='simple') (x^(2*y) - 2*x^y + 1)/(x^y - 1) sage: g.simplify_rational() x^y - 1
>>> from sage.all import * >>> y = var('y') >>> g = (x**(y/Integer(2)) + Integer(1))**Integer(2)*(x**(y/Integer(2)) - Integer(1))**Integer(2)/(x**y - Integer(1)) >>> g.simplify_rational(algorithm='simple') (x^(2*y) - 2*x^y + 1)/(x^y - 1) >>> g.simplify_rational() x^y - 1
y = var('y') g = (x^(y/2) + 1)^2*(x^(y/2) - 1)^2/(x^y - 1) g.simplify_rational(algorithm='simple') g.simplify_rational()
With option
algorithm='noexpand'
we only convert to common denominators and add. No expansion of products is performed:sage: f = 1/(x+1)+x/(x+2)^2 sage: f.simplify_rational() (2*x^2 + 5*x + 4)/(x^3 + 5*x^2 + 8*x + 4) sage: f.simplify_rational(algorithm='noexpand') ((x + 2)^2 + (x + 1)*x)/((x + 2)^2*(x + 1))
>>> from sage.all import * >>> f = Integer(1)/(x+Integer(1))+x/(x+Integer(2))**Integer(2) >>> f.simplify_rational() (2*x^2 + 5*x + 4)/(x^3 + 5*x^2 + 8*x + 4) >>> f.simplify_rational(algorithm='noexpand') ((x + 2)^2 + (x + 1)*x)/((x + 2)^2*(x + 1))
f = 1/(x+1)+x/(x+2)^2 f.simplify_rational() f.simplify_rational(algorithm='noexpand')
- real(hold=False)[source]¶
Return the real part of this symbolic expression.
EXAMPLES:
sage: x = var('x') sage: x.real_part() real_part(x) sage: SR(2+3*I).real_part() 2 sage: SR(CDF(2,3)).real_part() 2.0 sage: SR(CC(2,3)).real_part() 2.00000000000000 sage: f = log(x) sage: f.real_part() log(abs(x))
>>> from sage.all import * >>> x = var('x') >>> x.real_part() real_part(x) >>> SR(Integer(2)+Integer(3)*I).real_part() 2 >>> SR(CDF(Integer(2),Integer(3))).real_part() 2.0 >>> SR(CC(Integer(2),Integer(3))).real_part() 2.00000000000000 >>> f = log(x) >>> f.real_part() log(abs(x))
x = var('x') x.real_part() SR(2+3*I).real_part() SR(CDF(2,3)).real_part() SR(CC(2,3)).real_part() f = log(x) f.real_part()
Using the
hold
parameter it is possible to prevent automatic evaluation:sage: SR(2).real_part() 2 sage: SR(2).real_part(hold=True) real_part(2)
>>> from sage.all import * >>> SR(Integer(2)).real_part() 2 >>> SR(Integer(2)).real_part(hold=True) real_part(2)
SR(2).real_part() SR(2).real_part(hold=True)
This also works using functional notation:
sage: real_part(I,hold=True) real_part(I) sage: real_part(I) 0
>>> from sage.all import * >>> real_part(I,hold=True) real_part(I) >>> real_part(I) 0
real_part(I,hold=True) real_part(I)
To then evaluate again, we use
unhold()
:sage: a = SR(2).real_part(hold=True); a.unhold() 2
>>> from sage.all import * >>> a = SR(Integer(2)).real_part(hold=True); a.unhold() 2
a = SR(2).real_part(hold=True); a.unhold()
- real_part(hold=False)[source]¶
Return the real part of this symbolic expression.
EXAMPLES:
sage: x = var('x') sage: x.real_part() real_part(x) sage: SR(2+3*I).real_part() 2 sage: SR(CDF(2,3)).real_part() 2.0 sage: SR(CC(2,3)).real_part() 2.00000000000000 sage: f = log(x) sage: f.real_part() log(abs(x))
>>> from sage.all import * >>> x = var('x') >>> x.real_part() real_part(x) >>> SR(Integer(2)+Integer(3)*I).real_part() 2 >>> SR(CDF(Integer(2),Integer(3))).real_part() 2.0 >>> SR(CC(Integer(2),Integer(3))).real_part() 2.00000000000000 >>> f = log(x) >>> f.real_part() log(abs(x))
x = var('x') x.real_part() SR(2+3*I).real_part() SR(CDF(2,3)).real_part() SR(CC(2,3)).real_part() f = log(x) f.real_part()
Using the
hold
parameter it is possible to prevent automatic evaluation:sage: SR(2).real_part() 2 sage: SR(2).real_part(hold=True) real_part(2)
>>> from sage.all import * >>> SR(Integer(2)).real_part() 2 >>> SR(Integer(2)).real_part(hold=True) real_part(2)
SR(2).real_part() SR(2).real_part(hold=True)
This also works using functional notation:
sage: real_part(I,hold=True) real_part(I) sage: real_part(I) 0
>>> from sage.all import * >>> real_part(I,hold=True) real_part(I) >>> real_part(I) 0
real_part(I,hold=True) real_part(I)
To then evaluate again, we use
unhold()
:sage: a = SR(2).real_part(hold=True); a.unhold() 2
>>> from sage.all import * >>> a = SR(Integer(2)).real_part(hold=True); a.unhold() 2
a = SR(2).real_part(hold=True); a.unhold()
- rectform()[source]¶
Convert this symbolic expression to rectangular form; that is, the form \(a + bi\) where \(a\) and \(b\) are real numbers and \(i\) is the imaginary unit.
Note
The name "rectangular" comes from the fact that, in the complex plane, \(a\) and \(bi\) are perpendicular.
INPUT:
self
– the expression to convert
OUTPUT:
A new expression, equivalent to the original, but expressed in the form \(a + bi\).
ALGORITHM:
We call Maxima’s
rectform()
and return the result unmodified.EXAMPLES:
The exponential form of \(\sin(x)\):
sage: f = (e^(I*x) - e^(-I*x)) / (2*I) sage: f.rectform() sin(x)
>>> from sage.all import * >>> f = (e**(I*x) - e**(-I*x)) / (Integer(2)*I) >>> f.rectform() sin(x)
f = (e^(I*x) - e^(-I*x)) / (2*I) f.rectform()
And \(\cos(x)\):
sage: f = (e^(I*x) + e^(-I*x)) / 2 sage: f.rectform() cos(x)
>>> from sage.all import * >>> f = (e**(I*x) + e**(-I*x)) / Integer(2) >>> f.rectform() cos(x)
f = (e^(I*x) + e^(-I*x)) / 2 f.rectform()
In some cases, this will simplify the given expression. For example, here, \(e^{ik\pi}\), \(\sin(k\pi)=0\) should cancel leaving only \(\cos(k\pi)\) which can then be simplified:
sage: k = var('k') sage: assume(k, 'integer') sage: f = e^(I*pi*k) sage: f.rectform() (-1)^k
>>> from sage.all import * >>> k = var('k') >>> assume(k, 'integer') >>> f = e**(I*pi*k) >>> f.rectform() (-1)^k
k = var('k') assume(k, 'integer') f = e^(I*pi*k) f.rectform()
However, in general, the resulting expression may be more complicated than the original:
sage: f = e^(I*x) sage: f.rectform() cos(x) + I*sin(x)
>>> from sage.all import * >>> f = e**(I*x) >>> f.rectform() cos(x) + I*sin(x)
f = e^(I*x) f.rectform()
- reduce_trig(var=None)[source]¶
Combine products and powers of trigonometric and hyperbolic sin’s and cos’s of x into those of multiples of x. It also tries to eliminate these functions when they occur in denominators.
INPUT:
self
– a symbolic expressionvar
– (default:None
) the variable which is used for these transformations. If not specified, all variables are used.
OUTPUT: a symbolic expression
EXAMPLES:
sage: y = var('y') sage: f = sin(x)*cos(x)^3+sin(y)^2 sage: f.reduce_trig() -1/2*cos(2*y) + 1/8*sin(4*x) + 1/4*sin(2*x) + 1/2
>>> from sage.all import * >>> y = var('y') >>> f = sin(x)*cos(x)**Integer(3)+sin(y)**Integer(2) >>> f.reduce_trig() -1/2*cos(2*y) + 1/8*sin(4*x) + 1/4*sin(2*x) + 1/2
y = var('y') f = sin(x)*cos(x)^3+sin(y)^2 f.reduce_trig()
To reduce only the expressions involving x we use optional parameter:
sage: f.reduce_trig(x) sin(y)^2 + 1/8*sin(4*x) + 1/4*sin(2*x)
>>> from sage.all import * >>> f.reduce_trig(x) sin(y)^2 + 1/8*sin(4*x) + 1/4*sin(2*x)
f.reduce_trig(x)
ALIAS:
trig_reduce()
andreduce_trig()
are the same
- residue(symbol)[source]¶
Calculate the residue of
self
with respect tosymbol
.INPUT:
symbol
– a symbolic variable or symbolic equality such asx == 5
. If an equality is given, the expansion is around the value on the right hand side of the equality, otherwise at0
.
OUTPUT: the residue of
self
Say,
symbol
isx == a
, then this function calculates the residue ofself
at \(x=a\), i.e., the coefficient of \(1/(x-a)\) of the series expansion ofself
around \(a\).EXAMPLES:
sage: (1/x).residue(x == 0) 1 sage: (1/x).residue(x == oo) -1 sage: (1/x^2).residue(x == 0) 0 sage: (1/sin(x)).residue(x == 0) 1 sage: var('q, n, z') (q, n, z) sage: (-z^(-n-1)/(1-z/q)^2).residue(z == q).simplify_full() (n + 1)/q^n sage: var('s') s sage: zeta(s).residue(s == 1) 1
>>> from sage.all import * >>> (Integer(1)/x).residue(x == Integer(0)) 1 >>> (Integer(1)/x).residue(x == oo) -1 >>> (Integer(1)/x**Integer(2)).residue(x == Integer(0)) 0 >>> (Integer(1)/sin(x)).residue(x == Integer(0)) 1 >>> var('q, n, z') (q, n, z) >>> (-z**(-n-Integer(1))/(Integer(1)-z/q)**Integer(2)).residue(z == q).simplify_full() (n + 1)/q^n >>> var('s') s >>> zeta(s).residue(s == Integer(1)) 1
(1/x).residue(x == 0) (1/x).residue(x == oo) (1/x^2).residue(x == 0) (1/sin(x)).residue(x == 0) var('q, n, z') (-z^(-n-1)/(1-z/q)^2).residue(z == q).simplify_full() var('s') zeta(s).residue(s == 1)
We can also compute the residue at more general places, given that the pole is recognized:
sage: k = var('k', domain='integer') sage: (gamma(1+x)/(1 - exp(-x))).residue(x==2*I*pi*k) gamma(2*I*pi*k + 1) sage: csc(x).residue(x==2*pi*k) 1
>>> from sage.all import * >>> k = var('k', domain='integer') >>> (gamma(Integer(1)+x)/(Integer(1) - exp(-x))).residue(x==Integer(2)*I*pi*k) gamma(2*I*pi*k + 1) >>> csc(x).residue(x==Integer(2)*pi*k) 1
k = var('k', domain='integer') (gamma(1+x)/(1 - exp(-x))).residue(x==2*I*pi*k) csc(x).residue(x==2*pi*k)
- resultant(other, var)[source]¶
Compute the resultant of this polynomial expression and the first argument with respect to the variable given as the second argument.
EXAMPLES:
sage: _ = var('a b n k u x y') sage: x.resultant(y, x) y sage: (x+y).resultant(x-y, x) -2*y sage: r = (x^4*y^2+x^2*y-y).resultant(x*y-y*a-x*b+a*b+u,x) sage: r.coefficient(a^4) b^4*y^2 - 4*b^3*y^3 + 6*b^2*y^4 - 4*b*y^5 + y^6 sage: x.resultant(sin(x), x) Traceback (most recent call last): ... RuntimeError: resultant(): arguments must be polynomials
>>> from sage.all import * >>> _ = var('a b n k u x y') >>> x.resultant(y, x) y >>> (x+y).resultant(x-y, x) -2*y >>> r = (x**Integer(4)*y**Integer(2)+x**Integer(2)*y-y).resultant(x*y-y*a-x*b+a*b+u,x) >>> r.coefficient(a**Integer(4)) b^4*y^2 - 4*b^3*y^3 + 6*b^2*y^4 - 4*b*y^5 + y^6 >>> x.resultant(sin(x), x) Traceback (most recent call last): ... RuntimeError: resultant(): arguments must be polynomials
_ = var('a b n k u x y') x.resultant(y, x) (x+y).resultant(x-y, x) r = (x^4*y^2+x^2*y-y).resultant(x*y-y*a-x*b+a*b+u,x) r.coefficient(a^4) x.resultant(sin(x), x)
- rhs()[source]¶
If
self
is a relational expression, return the right hand side of the relation. Otherwise, raise aValueError
.EXAMPLES:
sage: x = var('x') sage: eqn = (x-1)^2 <= x^2 - 2*x + 3 sage: eqn.right_hand_side() x^2 - 2*x + 3 sage: eqn.rhs() x^2 - 2*x + 3 sage: eqn.right() x^2 - 2*x + 3
>>> from sage.all import * >>> x = var('x') >>> eqn = (x-Integer(1))**Integer(2) <= x**Integer(2) - Integer(2)*x + Integer(3) >>> eqn.right_hand_side() x^2 - 2*x + 3 >>> eqn.rhs() x^2 - 2*x + 3 >>> eqn.right() x^2 - 2*x + 3
x = var('x') eqn = (x-1)^2 <= x^2 - 2*x + 3 eqn.right_hand_side() eqn.rhs() eqn.right()
- right()[source]¶
If
self
is a relational expression, return the right hand side of the relation. Otherwise, raise aValueError
.EXAMPLES:
sage: x = var('x') sage: eqn = (x-1)^2 <= x^2 - 2*x + 3 sage: eqn.right_hand_side() x^2 - 2*x + 3 sage: eqn.rhs() x^2 - 2*x + 3 sage: eqn.right() x^2 - 2*x + 3
>>> from sage.all import * >>> x = var('x') >>> eqn = (x-Integer(1))**Integer(2) <= x**Integer(2) - Integer(2)*x + Integer(3) >>> eqn.right_hand_side() x^2 - 2*x + 3 >>> eqn.rhs() x^2 - 2*x + 3 >>> eqn.right() x^2 - 2*x + 3
x = var('x') eqn = (x-1)^2 <= x^2 - 2*x + 3 eqn.right_hand_side() eqn.rhs() eqn.right()
- right_hand_side()[source]¶
If
self
is a relational expression, return the right hand side of the relation. Otherwise, raise aValueError
.EXAMPLES:
sage: x = var('x') sage: eqn = (x-1)^2 <= x^2 - 2*x + 3 sage: eqn.right_hand_side() x^2 - 2*x + 3 sage: eqn.rhs() x^2 - 2*x + 3 sage: eqn.right() x^2 - 2*x + 3
>>> from sage.all import * >>> x = var('x') >>> eqn = (x-Integer(1))**Integer(2) <= x**Integer(2) - Integer(2)*x + Integer(3) >>> eqn.right_hand_side() x^2 - 2*x + 3 >>> eqn.rhs() x^2 - 2*x + 3 >>> eqn.right() x^2 - 2*x + 3
x = var('x') eqn = (x-1)^2 <= x^2 - 2*x + 3 eqn.right_hand_side() eqn.rhs() eqn.right()
- roots(x=None, explicit_solutions=True, multiplicities=True, ring=None)[source]¶
Return roots of
self
that can be found exactly, possibly with multiplicities. Not all roots are guaranteed to be found.Warning
This is not a numerical solver - use
find_root()
to solve forself == 0
numerically on an interval.INPUT:
x
– variable to view the function in terms of (use default variable if not given)explicit_solutions
– boolean (default:True
); require that roots be explicit rather than implicitmultiplicities
– boolean (default:True
); whenTrue
, return multiplicitiesring
– a ring (default:None
); if notNone
, convertself
to a polynomial overring
and find roots overring
OUTPUT:
A list of pairs
(root, multiplicity)
or list of roots.If there are infinitely many roots, e.g., a function like \(\sin(x)\), only one is returned.
EXAMPLES:
sage: var('x, a') (x, a)
>>> from sage.all import * >>> var('x, a') (x, a)
var('x, a')
A simple example:
sage: ((x^2-1)^2).roots() [(-1, 2), (1, 2)] sage: ((x^2-1)^2).roots(multiplicities=False) [-1, 1]
>>> from sage.all import * >>> ((x**Integer(2)-Integer(1))**Integer(2)).roots() [(-1, 2), (1, 2)] >>> ((x**Integer(2)-Integer(1))**Integer(2)).roots(multiplicities=False) [-1, 1]
((x^2-1)^2).roots() ((x^2-1)^2).roots(multiplicities=False)
A complicated example:
sage: f = expand((x^2 - 1)^3*(x^2 + 1)*(x-a)); f -a*x^8 + x^9 + 2*a*x^6 - 2*x^7 - 2*a*x^2 + 2*x^3 + a - x
>>> from sage.all import * >>> f = expand((x**Integer(2) - Integer(1))**Integer(3)*(x**Integer(2) + Integer(1))*(x-a)); f -a*x^8 + x^9 + 2*a*x^6 - 2*x^7 - 2*a*x^2 + 2*x^3 + a - x
f = expand((x^2 - 1)^3*(x^2 + 1)*(x-a)); f
The default variable is \(a\), since it is the first in alphabetical order:
sage: f.roots() [(x, 1)]
>>> from sage.all import * >>> f.roots() [(x, 1)]
f.roots()
As a polynomial in \(a\), \(x\) is indeed a root:
sage: f.poly(a) x^9 - 2*x^7 + 2*x^3 - (x^8 - 2*x^6 + 2*x^2 - 1)*a - x sage: f(a=x) 0
>>> from sage.all import * >>> f.poly(a) x^9 - 2*x^7 + 2*x^3 - (x^8 - 2*x^6 + 2*x^2 - 1)*a - x >>> f(a=x) 0
f.poly(a) f(a=x)
The roots in terms of \(x\) are what we expect:
sage: f.roots(x) [(a, 1), (-I, 1), (I, 1), (1, 3), (-1, 3)]
>>> from sage.all import * >>> f.roots(x) [(a, 1), (-I, 1), (I, 1), (1, 3), (-1, 3)]
f.roots(x)
Only one root of \(\sin(x) = 0\) is given:
sage: f = sin(x) sage: f.roots(x) [(0, 1)]
>>> from sage.all import * >>> f = sin(x) >>> f.roots(x) [(0, 1)]
f = sin(x) f.roots(x)
Note
It is possible to solve a greater variety of equations using
solve()
and the keywordto_poly_solve
, but only at the price of possibly encountering approximate solutions. See documentation forsolve()
for more details.We derive the roots of a general quadratic polynomial:
sage: var('a,b,c,x') (a, b, c, x) sage: (a*x^2 + b*x + c).roots(x) [(-1/2*(b + sqrt(b^2 - 4*a*c))/a, 1), (-1/2*(b - sqrt(b^2 - 4*a*c))/a, 1)]
>>> from sage.all import * >>> var('a,b,c,x') (a, b, c, x) >>> (a*x**Integer(2) + b*x + c).roots(x) [(-1/2*(b + sqrt(b^2 - 4*a*c))/a, 1), (-1/2*(b - sqrt(b^2 - 4*a*c))/a, 1)]
var('a,b,c,x') (a*x^2 + b*x + c).roots(x)
By default, all the roots are required to be explicit rather than implicit. To get implicit roots, pass
explicit_solutions=False
to.roots()
sage: var('x') x sage: f = x^(1/9) + (2^(8/9) - 2^(1/9))*(x - 1) - x^(8/9) sage: f.roots() Traceback (most recent call last): ... RuntimeError: no explicit roots found sage: f.roots(explicit_solutions=False) [((2^(8/9) + x^(8/9) - 2^(1/9) - x^(1/9))/(2^(8/9) - 2^(1/9)), 1)]
>>> from sage.all import * >>> var('x') x >>> f = x**(Integer(1)/Integer(9)) + (Integer(2)**(Integer(8)/Integer(9)) - Integer(2)**(Integer(1)/Integer(9)))*(x - Integer(1)) - x**(Integer(8)/Integer(9)) >>> f.roots() Traceback (most recent call last): ... RuntimeError: no explicit roots found >>> f.roots(explicit_solutions=False) [((2^(8/9) + x^(8/9) - 2^(1/9) - x^(1/9))/(2^(8/9) - 2^(1/9)), 1)]
var('x') f = x^(1/9) + (2^(8/9) - 2^(1/9))*(x - 1) - x^(8/9) f.roots() f.roots(explicit_solutions=False)
Another example, but involving a degree 5 poly whose roots do not get computed explicitly:
sage: f = x^5 + x^3 + 17*x + 1 sage: f.roots() Traceback (most recent call last): ... RuntimeError: no explicit roots found sage: f.roots(explicit_solutions=False) [(x^5 + x^3 + 17*x + 1, 1)] sage: f.roots(explicit_solutions=False, multiplicities=False) [x^5 + x^3 + 17*x + 1]
>>> from sage.all import * >>> f = x**Integer(5) + x**Integer(3) + Integer(17)*x + Integer(1) >>> f.roots() Traceback (most recent call last): ... RuntimeError: no explicit roots found >>> f.roots(explicit_solutions=False) [(x^5 + x^3 + 17*x + 1, 1)] >>> f.roots(explicit_solutions=False, multiplicities=False) [x^5 + x^3 + 17*x + 1]
f = x^5 + x^3 + 17*x + 1 f.roots() f.roots(explicit_solutions=False) f.roots(explicit_solutions=False, multiplicities=False)
Now let us find some roots over different rings:
sage: f.roots(ring=CC) [(-0.0588115223184..., 1), (-1.331099917875... - 1.52241655183732*I, 1), (-1.331099917875... + 1.52241655183732*I, 1), (1.36050567903502 - 1.51880872209965*I, 1), (1.36050567903502 + 1.51880872209965*I, 1)] sage: (2.5*f).roots(ring=RR) [(-0.058811522318449..., 1)] sage: f.roots(ring=CC, multiplicities=False) [-0.05881152231844..., -1.331099917875... - 1.52241655183732*I, -1.331099917875... + 1.52241655183732*I, 1.36050567903502 - 1.51880872209965*I, 1.36050567903502 + 1.51880872209965*I] sage: f.roots(ring=QQ) [] sage: f.roots(ring=QQbar, multiplicities=False) [-0.05881152231844944?, -1.331099917875796? - 1.522416551837318?*I, -1.331099917875796? + 1.522416551837318?*I, 1.360505679035020? - 1.518808722099650?*I, 1.360505679035020? + 1.518808722099650?*I]
>>> from sage.all import * >>> f.roots(ring=CC) [(-0.0588115223184..., 1), (-1.331099917875... - 1.52241655183732*I, 1), (-1.331099917875... + 1.52241655183732*I, 1), (1.36050567903502 - 1.51880872209965*I, 1), (1.36050567903502 + 1.51880872209965*I, 1)] >>> (RealNumber('2.5')*f).roots(ring=RR) [(-0.058811522318449..., 1)] >>> f.roots(ring=CC, multiplicities=False) [-0.05881152231844..., -1.331099917875... - 1.52241655183732*I, -1.331099917875... + 1.52241655183732*I, 1.36050567903502 - 1.51880872209965*I, 1.36050567903502 + 1.51880872209965*I] >>> f.roots(ring=QQ) [] >>> f.roots(ring=QQbar, multiplicities=False) [-0.05881152231844944?, -1.331099917875796? - 1.522416551837318?*I, -1.331099917875796? + 1.522416551837318?*I, 1.360505679035020? - 1.518808722099650?*I, 1.360505679035020? + 1.518808722099650?*I]
f.roots(ring=CC) (2.5*f).roots(ring=RR) f.roots(ring=CC, multiplicities=False) f.roots(ring=QQ) f.roots(ring=QQbar, multiplicities=False)
Root finding over finite fields:
sage: f.roots(ring=GF(7^2, 'a')) # needs sage.rings.finite_rings [(3, 1), (4*a + 6, 2), (3*a + 3, 2)]
>>> from sage.all import * >>> f.roots(ring=GF(Integer(7)**Integer(2), 'a')) # needs sage.rings.finite_rings [(3, 1), (4*a + 6, 2), (3*a + 3, 2)]
f.roots(ring=GF(7^2, 'a')) # needs sage.rings.finite_rings
- round()[source]¶
Round this expression to the nearest integer.
EXAMPLES:
sage: u = sqrt(43203735824841025516773866131535024) sage: u.round() 207855083711803945 sage: t = sqrt(Integer('1'*1000)).round(); print(str(t)[-10:]) 3333333333 sage: (-sqrt(110)).round() -10 sage: (-sqrt(115)).round() -11 sage: (sqrt(-3)).round() Traceback (most recent call last): ... ValueError: could not convert sqrt(-3) to a real number
>>> from sage.all import * >>> u = sqrt(Integer(43203735824841025516773866131535024)) >>> u.round() 207855083711803945 >>> t = sqrt(Integer('1'*Integer(1000))).round(); print(str(t)[-Integer(10):]) 3333333333 >>> (-sqrt(Integer(110))).round() -10 >>> (-sqrt(Integer(115))).round() -11 >>> (sqrt(-Integer(3))).round() Traceback (most recent call last): ... ValueError: could not convert sqrt(-3) to a real number
u = sqrt(43203735824841025516773866131535024) u.round() t = sqrt(Integer('1'*1000)).round(); print(str(t)[-10:]) (-sqrt(110)).round() (-sqrt(115)).round() (sqrt(-3)).round()
- series(symbol, order=None)[source]¶
Return the power series expansion of
self
in terms of the given variable to the given order.INPUT:
symbol
– a symbolic variable or symbolic equality such asx == 5
; if an equality is given, the expansion is around the value on the right hand side of the equalityorder
– integer; if nothing given, it is set to the global default (20
), which can be changed usingset_series_precision()
OUTPUT: a power series
To truncate the power series and obtain a normal expression, use the
truncate()
command.EXAMPLES:
We expand a polynomial in \(x\) about 0, about \(1\), and also truncate it back to a polynomial:
sage: var('x,y') (x, y) sage: f = (x^3 - sin(y)*x^2 - 5*x + 3); f x^3 - x^2*sin(y) - 5*x + 3 sage: g = f.series(x, 4); g 3 + (-5)*x + (-sin(y))*x^2 + 1*x^3 + Order(x^4) sage: g.truncate() x^3 - x^2*sin(y) - 5*x + 3 sage: g = f.series(x==1, 4); g (-sin(y) - 1) + (-2*sin(y) - 2)*(x - 1) + (-sin(y) + 3)*(x - 1)^2 + 1*(x - 1)^3 + Order((x - 1)^4) sage: h = g.truncate(); h (x - 1)^3 - (x - 1)^2*(sin(y) - 3) - 2*(x - 1)*(sin(y) + 1) - sin(y) - 1 sage: h.expand() x^3 - x^2*sin(y) - 5*x + 3
>>> from sage.all import * >>> var('x,y') (x, y) >>> f = (x**Integer(3) - sin(y)*x**Integer(2) - Integer(5)*x + Integer(3)); f x^3 - x^2*sin(y) - 5*x + 3 >>> g = f.series(x, Integer(4)); g 3 + (-5)*x + (-sin(y))*x^2 + 1*x^3 + Order(x^4) >>> g.truncate() x^3 - x^2*sin(y) - 5*x + 3 >>> g = f.series(x==Integer(1), Integer(4)); g (-sin(y) - 1) + (-2*sin(y) - 2)*(x - 1) + (-sin(y) + 3)*(x - 1)^2 + 1*(x - 1)^3 + Order((x - 1)^4) >>> h = g.truncate(); h (x - 1)^3 - (x - 1)^2*(sin(y) - 3) - 2*(x - 1)*(sin(y) + 1) - sin(y) - 1 >>> h.expand() x^3 - x^2*sin(y) - 5*x + 3
var('x,y') f = (x^3 - sin(y)*x^2 - 5*x + 3); f g = f.series(x, 4); g g.truncate() g = f.series(x==1, 4); g h = g.truncate(); h h.expand()
We computer another series expansion of an analytic function:
sage: f = sin(x)/x^2 sage: f.series(x,7) 1*x^(-1) + (-1/6)*x + 1/120*x^3 + (-1/5040)*x^5 + Order(x^7) sage: f.series(x) 1*x^(-1) + (-1/6)*x + ... + Order(x^20) sage: f.series(x==1,3) (sin(1)) + (cos(1) - 2*sin(1))*(x - 1) + (-2*cos(1) + 5/2*sin(1))*(x - 1)^2 + Order((x - 1)^3) sage: f.series(x==1,3).truncate().expand() -2*x^2*cos(1) + 5/2*x^2*sin(1) + 5*x*cos(1) - 7*x*sin(1) - 3*cos(1) + 11/2*sin(1)
>>> from sage.all import * >>> f = sin(x)/x**Integer(2) >>> f.series(x,Integer(7)) 1*x^(-1) + (-1/6)*x + 1/120*x^3 + (-1/5040)*x^5 + Order(x^7) >>> f.series(x) 1*x^(-1) + (-1/6)*x + ... + Order(x^20) >>> f.series(x==Integer(1),Integer(3)) (sin(1)) + (cos(1) - 2*sin(1))*(x - 1) + (-2*cos(1) + 5/2*sin(1))*(x - 1)^2 + Order((x - 1)^3) >>> f.series(x==Integer(1),Integer(3)).truncate().expand() -2*x^2*cos(1) + 5/2*x^2*sin(1) + 5*x*cos(1) - 7*x*sin(1) - 3*cos(1) + 11/2*sin(1)
f = sin(x)/x^2 f.series(x,7) f.series(x) f.series(x==1,3) f.series(x==1,3).truncate().expand()
Expressions formed by combining series can be expanded by applying series again:
sage: (1/(1-x)).series(x, 3)+(1/(1+x)).series(x,3) (1 + 1*x + 1*x^2 + Order(x^3)) + (1 + (-1)*x + 1*x^2 + Order(x^3)) sage: _.series(x,3) 2 + 2*x^2 + Order(x^3) sage: (1/(1-x)).series(x, 3)*(1/(1+x)).series(x,3) (1 + 1*x + 1*x^2 + Order(x^3))*(1 + (-1)*x + 1*x^2 + Order(x^3)) sage: _.series(x,3) 1 + 1*x^2 + Order(x^3)
>>> from sage.all import * >>> (Integer(1)/(Integer(1)-x)).series(x, Integer(3))+(Integer(1)/(Integer(1)+x)).series(x,Integer(3)) (1 + 1*x + 1*x^2 + Order(x^3)) + (1 + (-1)*x + 1*x^2 + Order(x^3)) >>> _.series(x,Integer(3)) 2 + 2*x^2 + Order(x^3) >>> (Integer(1)/(Integer(1)-x)).series(x, Integer(3))*(Integer(1)/(Integer(1)+x)).series(x,Integer(3)) (1 + 1*x + 1*x^2 + Order(x^3))*(1 + (-1)*x + 1*x^2 + Order(x^3)) >>> _.series(x,Integer(3)) 1 + 1*x^2 + Order(x^3)
(1/(1-x)).series(x, 3)+(1/(1+x)).series(x,3) _.series(x,3) (1/(1-x)).series(x, 3)*(1/(1+x)).series(x,3) _.series(x,3)
Following the GiNaC tutorial, we use John Machin’s amazing formula \(\pi = 16 \tan^{-1}(1/5) - 4 \tan^{-1}(1/239)\) to compute digits of \(\pi\). We expand the arc tangent around 0 and insert the fractions 1/5 and 1/239.
sage: x = var('x') sage: f = atan(x).series(x, 10); f 1*x + (-1/3)*x^3 + 1/5*x^5 + (-1/7)*x^7 + 1/9*x^9 + Order(x^10) sage: float(16*f.subs(x==1/5) - 4*f.subs(x==1/239)) 3.1415926824043994
>>> from sage.all import * >>> x = var('x') >>> f = atan(x).series(x, Integer(10)); f 1*x + (-1/3)*x^3 + 1/5*x^5 + (-1/7)*x^7 + 1/9*x^9 + Order(x^10) >>> float(Integer(16)*f.subs(x==Integer(1)/Integer(5)) - Integer(4)*f.subs(x==Integer(1)/Integer(239))) 3.1415926824043994
x = var('x') f = atan(x).series(x, 10); f float(16*f.subs(x==1/5) - 4*f.subs(x==1/239))
- show()[source]¶
Pretty-print this symbolic expression.
This typesets it nicely and prints it immediately.
OUTPUT:
This method does not return anything. Like
print
, output is sent directly to the screen.Note that the output depends on the display preferences. For details, see
pretty_print()
.EXAMPLES:
sage: (x^2 + 1).show() x^2 + 1
>>> from sage.all import * >>> (x**Integer(2) + Integer(1)).show() x^2 + 1
(x^2 + 1).show()
EXAMPLES:
sage: %display ascii_art # not tested sage: (x^2 + 1).show() 2 x + 1
>>> from sage.all import * >>> %display ascii_art # not tested >>> (x**Integer(2) + Integer(1)).show() 2 x + 1
%display ascii_art # not tested (x^2 + 1).show()
- simplify(algorithm='maxima', **kwds)[source]¶
Return a simplified version of this symbolic expression.
INPUT:
algorithm
– one of :maxima
: (default) sends the expression tomaxima
and converts it back to Sagesympy
: converts the expression tosympy
, simplifies it (passing any optional keyword(s)), and converts the result to Sagegiac
: converts the expression togiac
, simplifies it, and converts the result to Sagefricas
: converts the expression tofricas
, simplifies it, and converts the result to Sage
See also
simplify_full()
,simplify_trig()
,simplify_rational()
,simplify_rectform()
simplify_factorial()
,simplify_log()
,simplify_real()
,simplify_hypergeometric()
,canonicalize_radical()
EXAMPLES:
sage: a = var('a'); f = x*sin(2)/(x^a); f x*sin(2)/x^a sage: f.simplify() x^(-a + 1)*sin(2)
>>> from sage.all import * >>> a = var('a'); f = x*sin(Integer(2))/(x**a); f x*sin(2)/x^a >>> f.simplify() x^(-a + 1)*sin(2)
a = var('a'); f = x*sin(2)/(x^a); f f.simplify()
Some simplifications are quite algorithm-specific:
sage: x, t = var("x, t") sage: ex = cos(t).exponentialize() sage: ex = ex.subs((sin(t).exponentialize()==x).solve(t)[0]) sage: ex 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) sage: ex.simplify() 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) sage: ex.simplify(algorithm='sympy') I*(x^2 + sqrt(x^2 - 1)*x - 1)/(x + sqrt(x^2 - 1)) sage: ex.simplify(algorithm='giac') # needs giac I*sqrt(x^2 - 1) sage: ex.simplify(algorithm='fricas') # optional - fricas (I*x^2 + I*sqrt(x^2 - 1)*x - I)/(x + sqrt(x^2 - 1))
>>> from sage.all import * >>> x, t = var("x, t") >>> ex = cos(t).exponentialize() >>> ex = ex.subs((sin(t).exponentialize()==x).solve(t)[Integer(0)]) >>> ex 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/2/(I*x + I*sqrt(x^2 - 1)) >>> ex.simplify() 1/2*I*x + 1/2*I*sqrt(x^2 - 1) + 1/(2*I*x + 2*I*sqrt(x^2 - 1)) >>> ex.simplify(algorithm='sympy') I*(x^2 + sqrt(x^2 - 1)*x - 1)/(x + sqrt(x^2 - 1)) >>> ex.simplify(algorithm='giac') # needs giac I*sqrt(x^2 - 1) >>> ex.simplify(algorithm='fricas') # optional - fricas (I*x^2 + I*sqrt(x^2 - 1)*x - I)/(x + sqrt(x^2 - 1))
x, t = var("x, t") ex = cos(t).exponentialize() ex = ex.subs((sin(t).exponentialize()==x).solve(t)[0]) ex ex.simplify() ex.simplify(algorithm='sympy') ex.simplify(algorithm='giac') # needs giac ex.simplify(algorithm='fricas') # optional - fricas
- simplify_factorial()[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
var('n,k') f = factorial(n+1)/factorial(n); f f.simplify_factorial()
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)
f = factorial(n)*(n+1); f simplify(f) f.simplify_factorial()
>>> 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)
f = factorial(n)*(n+1); f simplify(f) f.simplify_factorial()
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)
f = binomial(n, k)*factorial(k)*factorial(n-k); f f.simplify_factorial()
>>> 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)
f = binomial(n, k)*factorial(k)*factorial(n-k); f f.simplify_factorial()
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
f = factorial(x)/factorial(x-2)/2 + factorial(x+1)/factorial(x)/2; f g = f.simplify_factorial(); g g.simplify_rational()
- simplify_full()[source]¶
Apply
simplify_factorial()
,simplify_rectform()
,simplify_trig()
,simplify_rational()
, and thenexpand_sum()
toself
(in that order).ALIAS:
simplify_full
andfull_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
f = sin(x)^2 + cos(x)^2 f.simplify_full()
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))
f = sin(x/(x^2 + x)) f.simplify_full()
>>> from sage.all import * >>> f = sin(x/(x**Integer(2) + x)) >>> f.simplify_full() sin(1/(x + 1))
f = sin(x/(x^2 + x)) f.simplify_full()
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)
var('n,k') f = binomial(n,k)*factorial(k)*factorial(n-k) f.simplify_full()
>>> from sage.all import * >>> var('n,k') (n, k) >>> f = binomial(n,k)*factorial(k)*factorial(n-k) >>> f.simplify_full() factorial(n)
var('n,k') f = binomial(n,k)*factorial(k)*factorial(n-k) f.simplify_full()
- simplify_hypergeometric(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’shgfred
function, and'sage'
, which uses an algorithm implemented in the hypergeometric module
ALIAS:
hypergeometric_simplify()
andsimplify_hypergeometric()
are the sameEXAMPLES:
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
hypergeometric((5, 4), (4, 1, 2, 3), x).simplify_hypergeometric() (2*hypergeometric((), (), x)).simplify_hypergeometric() (nest(lambda y: hypergeometric([y], [1], x), 3, 1) # not tested, unstable .simplify_hypergeometric()) (nest(lambda y: hypergeometric([y], [1], x), 3, 1) # not tested, unstable .simplify_hypergeometric(algorithm='sage')) hypergeometric_M(1, 3, x).simplify_hypergeometric() (2 * hypergeometric_U(1, 3, x)).simplify_hypergeometric()
- simplify_log(algorithm=None)[source]¶
Simplify a (real) symbolic expression that contains logarithms.
The given expression is scanned recursively, transforming subexpressions of the form \(a \log(b) + c \log(d)\) into \(\log(b^{a} d^{c})\) before simplifying within the
log()
.The user can specify conditions that \(a\) and \(c\) must satisfy before this transformation will be performed using the optional parameter
algorithm
.Warning
This is only safe to call if every variable in the given expression is assumed to be real. The simplification it performs is in general not valid over the complex numbers. For example:
sage: x,y = SR.var('x,y') sage: f = log(x*y) - (log(x) + log(y)) sage: f(x=-1, y=i) -2*I*pi sage: f.simplify_log() 0
>>> from sage.all import * >>> x,y = SR.var('x,y') >>> f = log(x*y) - (log(x) + log(y)) >>> f(x=-Integer(1), y=i) -2*I*pi >>> f.simplify_log() 0
x,y = SR.var('x,y') f = log(x*y) - (log(x) + log(y)) f(x=-1, y=i) f.simplify_log()
INPUT:
self
– expression to be simplifiedalgorithm
– (default:None
) governs the condition on \(a\) and \(c\) which must be satisfied to contract expression \(a \log(b) + c \log(d)\). Values areNone
(use Maxima default, integers),'one'
(1 and -1),'ratios'
(rational numbers),'constants'
(constants),'all'
(all expressions).
ALGORITHM:
This uses the Maxima
logcontract()
command.ALIAS:
log_simplify()
andsimplify_log()
are the same.EXAMPLES:
sage: x,y,t = var('x y t')
>>> from sage.all import * >>> x,y,t = var('x y t')
x,y,t = var('x y t')
Only two first terms are contracted in the following example; the logarithm with coefficient \(\frac{1}{2}\) is not contracted:
sage: f = log(x)+2*log(y)+1/2*log(t) sage: f.simplify_log() log(x*y^2) + 1/2*log(t)
>>> from sage.all import * >>> f = log(x)+Integer(2)*log(y)+Integer(1)/Integer(2)*log(t) >>> f.simplify_log() log(x*y^2) + 1/2*log(t)
f = log(x)+2*log(y)+1/2*log(t) f.simplify_log()
To contract all terms in the previous example, we use the
'ratios'
algorithm
:sage: f.simplify_log(algorithm='ratios') log(sqrt(t)*x*y^2)
>>> from sage.all import * >>> f.simplify_log(algorithm='ratios') log(sqrt(t)*x*y^2)
f.simplify_log(algorithm='ratios')
To contract terms with no coefficient (more precisely, with coefficients \(1\) and \(-1\)), we use the
'one'
algorithm
:sage: f = log(x)+2*log(y)-log(t) sage: f.simplify_log('one') 2*log(y) + log(x/t)
>>> from sage.all import * >>> f = log(x)+Integer(2)*log(y)-log(t) >>> f.simplify_log('one') 2*log(y) + log(x/t)
f = log(x)+2*log(y)-log(t) f.simplify_log('one')
sage: f = log(x)+log(y)-1/3*log((x+1)) sage: f.simplify_log() log(x*y) - 1/3*log(x + 1) sage: f.simplify_log('ratios') log(x*y/(x + 1)^(1/3))
>>> from sage.all import * >>> f = log(x)+log(y)-Integer(1)/Integer(3)*log((x+Integer(1))) >>> f.simplify_log() log(x*y) - 1/3*log(x + 1) >>> f.simplify_log('ratios') log(x*y/(x + 1)^(1/3))
f = log(x)+log(y)-1/3*log((x+1)) f.simplify_log() f.simplify_log('ratios')
>>> from sage.all import * >>> f = log(x)+log(y)-Integer(1)/Integer(3)*log((x+Integer(1))) >>> f.simplify_log() log(x*y) - 1/3*log(x + 1) >>> f.simplify_log('ratios') log(x*y/(x + 1)^(1/3))
f = log(x)+log(y)-1/3*log((x+1)) f.simplify_log() f.simplify_log('ratios')
\(\pi\) is an irrational number; to contract logarithms in the following example we have to set
algorithm
to'constants'
or'all'
:sage: f = log(x)+log(y)-pi*log((x+1)) sage: f.simplify_log('constants') log(x*y/(x + 1)^pi)
>>> from sage.all import * >>> f = log(x)+log(y)-pi*log((x+Integer(1))) >>> f.simplify_log('constants') log(x*y/(x + 1)^pi)
f = log(x)+log(y)-pi*log((x+1)) f.simplify_log('constants')
x*log(9)
is contracted only ifalgorithm
is'all'
:sage: (x*log(9)).simplify_log() 2*x*log(3) sage: (x*log(9)).simplify_log('all') log(3^(2*x))
>>> from sage.all import * >>> (x*log(Integer(9))).simplify_log() 2*x*log(3) >>> (x*log(Integer(9))).simplify_log('all') log(3^(2*x))
(x*log(9)).simplify_log() (x*log(9)).simplify_log('all')
AUTHORS:
Robert Marik (11-2009)
- simplify_rational(algorithm='full', map=False)[source]¶
Simplify rational expressions.
INPUT:
self
– symbolic expressionalgorithm
– (default:'full'
) string which switches the algorithm for simplifications. Possible values are'simple'
(simplify rational functions into quotient of two polynomials)'full'
(apply repeatedly, if necessary)'noexpand'
(convert to common denominator and add)
map
– boolean (default:False
); ifTrue
, the result is an expression whose leading operator is the same as that of the expressionself
but whose subparts are the results of applying simplification rules to the corresponding subparts of the expressions.
ALIAS:
rational_simplify()
andsimplify_rational()
are the sameDETAILS: We call Maxima functions ratsimp, fullratsimp and xthru. If each part of the expression has to be simplified separately, we use Maxima function map.
EXAMPLES:
sage: f = sin(x/(x^2 + x)) sage: f sin(x/(x^2 + x)) sage: f.simplify_rational() sin(1/(x + 1))
>>> from sage.all import * >>> f = sin(x/(x**Integer(2) + x)) >>> f sin(x/(x^2 + x)) >>> f.simplify_rational() sin(1/(x + 1))
f = sin(x/(x^2 + x)) f f.simplify_rational()
sage: f = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1)); f -((x + 1)*sqrt(x - 1) - (x - 1)^(3/2))/sqrt((x + 1)*(x - 1)) sage: f.simplify_rational() -2*sqrt(x - 1)/sqrt(x^2 - 1)
>>> from sage.all import * >>> f = ((x - Integer(1))**(Integer(3)/Integer(2)) - (x + Integer(1))*sqrt(x - Integer(1)))/sqrt((x - Integer(1))*(x + Integer(1))); f -((x + 1)*sqrt(x - 1) - (x - 1)^(3/2))/sqrt((x + 1)*(x - 1)) >>> f.simplify_rational() -2*sqrt(x - 1)/sqrt(x^2 - 1)
f = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1)); f f.simplify_rational()
>>> from sage.all import * >>> f = ((x - Integer(1))**(Integer(3)/Integer(2)) - (x + Integer(1))*sqrt(x - Integer(1)))/sqrt((x - Integer(1))*(x + Integer(1))); f -((x + 1)*sqrt(x - 1) - (x - 1)^(3/2))/sqrt((x + 1)*(x - 1)) >>> f.simplify_rational() -2*sqrt(x - 1)/sqrt(x^2 - 1)
f = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1)); f f.simplify_rational()
With
map=True
each term in a sum is simplified separately and thus the results are shorter for functions which are combination of rational and nonrational functions. In the following example, we use this option if we want not to combine logarithm and the rational function into one fraction:sage: f = (x^2-1)/(x+1)-ln(x)/(x+2) sage: f.simplify_rational() (x^2 + x - log(x) - 2)/(x + 2) sage: f.simplify_rational(map=True) x - log(x)/(x + 2) - 1
>>> from sage.all import * >>> f = (x**Integer(2)-Integer(1))/(x+Integer(1))-ln(x)/(x+Integer(2)) >>> f.simplify_rational() (x^2 + x - log(x) - 2)/(x + 2) >>> f.simplify_rational(map=True) x - log(x)/(x + 2) - 1
f = (x^2-1)/(x+1)-ln(x)/(x+2) f.simplify_rational() f.simplify_rational(map=True)
Here is an example from the Maxima documentation of where
algorithm='simple'
produces an (possibly useful) intermediate step:sage: y = var('y') sage: g = (x^(y/2) + 1)^2*(x^(y/2) - 1)^2/(x^y - 1) sage: g.simplify_rational(algorithm='simple') (x^(2*y) - 2*x^y + 1)/(x^y - 1) sage: g.simplify_rational() x^y - 1
>>> from sage.all import * >>> y = var('y') >>> g = (x**(y/Integer(2)) + Integer(1))**Integer(2)*(x**(y/Integer(2)) - Integer(1))**Integer(2)/(x**y - Integer(1)) >>> g.simplify_rational(algorithm='simple') (x^(2*y) - 2*x^y + 1)/(x^y - 1) >>> g.simplify_rational() x^y - 1
y = var('y') g = (x^(y/2) + 1)^2*(x^(y/2) - 1)^2/(x^y - 1) g.simplify_rational(algorithm='simple') g.simplify_rational()
With option
algorithm='noexpand'
we only convert to common denominators and add. No expansion of products is performed:sage: f = 1/(x+1)+x/(x+2)^2 sage: f.simplify_rational() (2*x^2 + 5*x + 4)/(x^3 + 5*x^2 + 8*x + 4) sage: f.simplify_rational(algorithm='noexpand') ((x + 2)^2 + (x + 1)*x)/((x + 2)^2*(x + 1))
>>> from sage.all import * >>> f = Integer(1)/(x+Integer(1))+x/(x+Integer(2))**Integer(2) >>> f.simplify_rational() (2*x^2 + 5*x + 4)/(x^3 + 5*x^2 + 8*x + 4) >>> f.simplify_rational(algorithm='noexpand') ((x + 2)^2 + (x + 1)*x)/((x + 2)^2*(x + 1))
f = 1/(x+1)+x/(x+2)^2 f.simplify_rational() f.simplify_rational(algorithm='noexpand')
- simplify_real()[source]¶
Simplify the given expression over the real numbers. This allows the simplification of \(\sqrt{x^{2}}\) into \(\left|x\right|\) and the contraction of \(\log(x) + \log(y)\) into \(\log(xy)\).
INPUT:
self
– the expression to convert
OUTPUT:
A new expression, equivalent to the original one under the assumption that the variables involved are real.
EXAMPLES:
sage: f = sqrt(x^2) sage: f.simplify_real() abs(x)
>>> from sage.all import * >>> f = sqrt(x**Integer(2)) >>> f.simplify_real() abs(x)
f = sqrt(x^2) f.simplify_real()
sage: y = SR.var('y') sage: f = log(x) + 2*log(y) sage: f.simplify_real() log(x*y^2)
>>> from sage.all import * >>> y = SR.var('y') >>> f = log(x) + Integer(2)*log(y) >>> f.simplify_real() log(x*y^2)
y = SR.var('y') f = log(x) + 2*log(y) f.simplify_real()
>>> from sage.all import * >>> y = SR.var('y') >>> f = log(x) + Integer(2)*log(y) >>> f.simplify_real() log(x*y^2)
y = SR.var('y') f = log(x) + 2*log(y) f.simplify_real()
- simplify_rectform(complexity_measure='string_length')[source]¶
Attempt to simplify this expression by expressing it in the form \(a + bi\) where both \(a\) and \(b\) are real. This transformation is generally not a simplification, so we use the given
complexity_measure
to discard non-simplifications.INPUT:
self
– the expression to simplifycomplexity_measure
– (default:sage.symbolic.complexity_measures.string_length
) a function taking a symbolic expression as an argument and returning a measure of that expressions complexity. IfNone
is supplied, the simplification will be performed regardless of the result.
OUTPUT:
If the transformation produces a simpler expression (according to
complexity_measure
) then that simpler expression is returned. Otherwise, the original expression is returned.ALGORITHM:
We first call
rectform()
on the given expression. Then, the supplied complexity measure is used to determine whether or not the result is simpler than the original expression.EXAMPLES:
The exponential form of \(\tan(x)\):
sage: f = ( e^(I*x) - e^(-I*x) ) / ( I*e^(I*x) + I*e^(-I*x) ) sage: f.simplify_rectform() sin(x)/cos(x)
>>> from sage.all import * >>> f = ( e**(I*x) - e**(-I*x) ) / ( I*e**(I*x) + I*e**(-I*x) ) >>> f.simplify_rectform() sin(x)/cos(x)
f = ( e^(I*x) - e^(-I*x) ) / ( I*e^(I*x) + I*e^(-I*x) ) f.simplify_rectform()
This should not be expanded with Euler’s formula since the resulting expression is longer when considered as a string, and the default
complexity_measure
uses string length to determine which expression is simpler:sage: f = e^(I*x) sage: f.simplify_rectform() e^(I*x)
>>> from sage.all import * >>> f = e**(I*x) >>> f.simplify_rectform() e^(I*x)
f = e^(I*x) f.simplify_rectform()
However, if we pass
None
as our complexity measure, it is:sage: f = e^(I*x) sage: f.simplify_rectform(complexity_measure = None) cos(x) + I*sin(x)
>>> from sage.all import * >>> f = e**(I*x) >>> f.simplify_rectform(complexity_measure = None) cos(x) + I*sin(x)
f = e^(I*x) f.simplify_rectform(complexity_measure = None)
- simplify_trig(expand=True)[source]¶
Optionally expand and then employ identities such as \(\sin(x)^2 + \cos(x)^2 = 1\), \(\cosh(x)^2 - \sinh(x)^2 = 1\), \(\sin(x)\csc(x) = 1\), or \(\tanh(x)=\sinh(x)/\cosh(x)\) to simplify expressions containing tan, sec, etc., to sin, cos, sinh, cosh.
INPUT:
self
– symbolic expressionexpand
– boolean (default:True
); ifTrue
, expands trigonometric and hyperbolic functions of sums of angles and of multiple angles occurring inself
first. For best results,self
should be expanded. See alsoexpand_trig()
to get more controls on this expansion.
ALIAS:
trig_simplify()
andsimplify_trig()
are the sameEXAMPLES:
sage: f = sin(x)^2 + cos(x)^2; f cos(x)^2 + sin(x)^2 sage: f.simplify() cos(x)^2 + sin(x)^2 sage: f.simplify_trig() 1 sage: h = sin(x)*csc(x) sage: h.simplify_trig() 1 sage: k = tanh(x)*cosh(2*x) sage: k.simplify_trig() (2*sinh(x)^3 + sinh(x))/cosh(x)
>>> from sage.all import * >>> f = sin(x)**Integer(2) + cos(x)**Integer(2); f cos(x)^2 + sin(x)^2 >>> f.simplify() cos(x)^2 + sin(x)^2 >>> f.simplify_trig() 1 >>> h = sin(x)*csc(x) >>> h.simplify_trig() 1 >>> k = tanh(x)*cosh(Integer(2)*x) >>> k.simplify_trig() (2*sinh(x)^3 + sinh(x))/cosh(x)
f = sin(x)^2 + cos(x)^2; f f.simplify() f.simplify_trig() h = sin(x)*csc(x) h.simplify_trig() k = tanh(x)*cosh(2*x) k.simplify_trig()
In some cases we do not want to expand:
sage: f = tan(3*x) sage: f.simplify_trig() -(4*cos(x)^2 - 1)*sin(x)/(4*cos(x)*sin(x)^2 - cos(x)) sage: f.simplify_trig(False) sin(3*x)/cos(3*x)
>>> from sage.all import * >>> f = tan(Integer(3)*x) >>> f.simplify_trig() -(4*cos(x)^2 - 1)*sin(x)/(4*cos(x)*sin(x)^2 - cos(x)) >>> f.simplify_trig(False) sin(3*x)/cos(3*x)
f = tan(3*x) f.simplify_trig() f.simplify_trig(False)
- sin(hold=False)[source]¶
EXAMPLES:
sage: var('x, y') (x, y) sage: sin(x^2 + y^2) sin(x^2 + y^2) sage: sin(sage.symbolic.constants.pi) 0 sage: sin(SR(1)) sin(1) sage: sin(SR(RealField(150)(1))) 0.84147098480789650665250232163029899962256306
>>> from sage.all import * >>> var('x, y') (x, y) >>> sin(x**Integer(2) + y**Integer(2)) sin(x^2 + y^2) >>> sin(sage.symbolic.constants.pi) 0 >>> sin(SR(Integer(1))) sin(1) >>> sin(SR(RealField(Integer(150))(Integer(1)))) 0.84147098480789650665250232163029899962256306
var('x, y') sin(x^2 + y^2) sin(sage.symbolic.constants.pi) sin(SR(1)) sin(SR(RealField(150)(1)))
Using the
hold
parameter it is possible to prevent automatic evaluation:sage: SR(0).sin() 0 sage: SR(0).sin(hold=True) sin(0)
>>> from sage.all import * >>> SR(Integer(0)).sin() 0 >>> SR(Integer(0)).sin(hold=True) sin(0)
SR(0).sin() SR(0).sin(hold=True)
This also works using functional notation:
sage: sin(0,hold=True) sin(0) sage: sin(0) 0
>>> from sage.all import * >>> sin(Integer(0),hold=True) sin(0) >>> sin(Integer(0)) 0
sin(0,hold=True) sin(0)
To then evaluate again, we use
unhold()
:sage: a = SR(0).sin(hold=True); a.unhold() 0
>>> from sage.all import * >>> a = SR(Integer(0)).sin(hold=True); a.unhold() 0
a = SR(0).sin(hold=True); a.unhold()
- sinh(hold=False)[source]¶
Return sinh of
self
.We have \(\sinh(x) = (e^{x} - e^{-x})/2\).
EXAMPLES:
sage: x.sinh() sinh(x) sage: SR(1).sinh() sinh(1) sage: SR(0).sinh() 0 sage: SR(1.0).sinh() 1.17520119364380 sage: maxima('sinh(1.0)') 1.17520119364380... sinh(1.0000000000000000000000000) sage: SR(1).sinh().n(90) 1.1752011936438014568823819 sage: SR(RIF(1)).sinh() 1.175201193643802?
>>> from sage.all import * >>> x.sinh() sinh(x) >>> SR(Integer(1)).sinh() sinh(1) >>> SR(Integer(0)).sinh() 0 >>> SR(RealNumber('1.0')).sinh() 1.17520119364380 >>> maxima('sinh(1.0)') 1.17520119364380... sinh(1.0000000000000000000000000) >>> SR(Integer(1)).sinh().n(Integer(90)) 1.1752011936438014568823819 >>> SR(RIF(Integer(1))).sinh() 1.175201193643802?
x.sinh() SR(1).sinh() SR(0).sinh() SR(1.0).sinh() maxima('sinh(1.0)') SR(1).sinh().n(90) SR(RIF(1)).sinh()
To prevent automatic evaluation use the
hold
argument:sage: arccosh(x).sinh() sqrt(x + 1)*sqrt(x - 1) sage: arccosh(x).sinh(hold=True) sinh(arccosh(x))
>>> from sage.all import * >>> arccosh(x).sinh() sqrt(x + 1)*sqrt(x - 1) >>> arccosh(x).sinh(hold=True) sinh(arccosh(x))
arccosh(x).sinh() arccosh(x).sinh(hold=True)
This also works using functional notation:
sage: sinh(arccosh(x),hold=True) sinh(arccosh(x)) sage: sinh(arccosh(x)) sqrt(x + 1)*sqrt(x - 1)
>>> from sage.all import * >>> sinh(arccosh(x),hold=True) sinh(arccosh(x)) >>> sinh(arccosh(x)) sqrt(x + 1)*sqrt(x - 1)
sinh(arccosh(x),hold=True) sinh(arccosh(x))
To then evaluate again, we use
unhold()
:sage: a = arccosh(x).sinh(hold=True); a.simplify() sqrt(x + 1)*sqrt(x - 1)
>>> from sage.all import * >>> a = arccosh(x).sinh(hold=True); a.simplify() sqrt(x + 1)*sqrt(x - 1)
a = arccosh(x).sinh(hold=True); a.simplify()
- solve(x, multiplicities=False, solution_dict=False, explicit_solutions=False, to_poly_solve=False, algorithm=None, domain=None)[source]¶
Analytically solve the equation
self == 0
or a univariate inequality for the variable \(x\).Warning
This is not a numerical solver – use
find_root()
to solve forself == 0
numerically on an interval.INPUT:
x
– variable(s) to solve formultiplicities
– boolean (default:False
); ifTrue
, return corresponding multiplicities. This keyword is incompatible withto_poly_solve=True
and does not make any sense when solving an inequality.solution_dict
– boolean (default:False
); ifTrue
or nonzero, return a list of dictionaries containing solutions. Not used when solving an inequality.explicit_solutions
– boolean (default:False
); require that all roots be explicit rather than implicit. Not used when solving an inequality.to_poly_solve
– boolean (default:False
) or string; use Maxima’sto_poly_solver
package to search for more possible solutions, but possibly encounter approximate solutions. This keyword is incompatible withmultiplicities=True
and is not used when solving an inequality. Settingto_poly_solve
to'force'
omits Maxima’s solve command (useful when some solutions of trigonometric equations are lost).
EXAMPLES:
sage: z = var('z') sage: (z^5 - 1).solve(z) [z == 1/4*sqrt(5) + 1/4*I*sqrt(2*sqrt(5) + 10) - 1/4, z == -1/4*sqrt(5) + 1/4*I*sqrt(-2*sqrt(5) + 10) - 1/4, z == -1/4*sqrt(5) - 1/4*I*sqrt(-2*sqrt(5) + 10) - 1/4, z == 1/4*sqrt(5) - 1/4*I*sqrt(2*sqrt(5) + 10) - 1/4, z == 1] sage: solve((z^3-1)^3, z, multiplicities=True) ([z == 1/2*I*sqrt(3) - 1/2, z == -1/2*I*sqrt(3) - 1/2, z == 1], [3, 3, 3])
>>> from sage.all import * >>> z = var('z') >>> (z**Integer(5) - Integer(1)).solve(z) [z == 1/4*sqrt(5) + 1/4*I*sqrt(2*sqrt(5) + 10) - 1/4, z == -1/4*sqrt(5) + 1/4*I*sqrt(-2*sqrt(5) + 10) - 1/4, z == -1/4*sqrt(5) - 1/4*I*sqrt(-2*sqrt(5) + 10) - 1/4, z == 1/4*sqrt(5) - 1/4*I*sqrt(2*sqrt(5) + 10) - 1/4, z == 1] >>> solve((z**Integer(3)-Integer(1))**Integer(3), z, multiplicities=True) ([z == 1/2*I*sqrt(3) - 1/2, z == -1/2*I*sqrt(3) - 1/2, z == 1], [3, 3, 3])
z = var('z') (z^5 - 1).solve(z) solve((z^3-1)^3, z, multiplicities=True)
- solve_diophantine(x=None, solution_dict=False)[source]¶
Solve a polynomial equation in the integers (a so called Diophantine).
If the argument is just a polynomial expression, equate to zero. If
solution_dict=True
, return a list of dictionaries instead of a list of tuples.EXAMPLES:
sage: x,y = var('x,y') sage: solve_diophantine(3*x == 4) # needs sympy [] sage: solve_diophantine(x^2 - 9) # needs sympy [-3, 3] sage: sorted(solve_diophantine(x^2 + y^2 == 25)) # needs sympy [(-5, 0), (-4, -3), (-4, 3), (-3, -4), (-3, 4), (0, -5)...
>>> from sage.all import * >>> x,y = var('x,y') >>> solve_diophantine(Integer(3)*x == Integer(4)) # needs sympy [] >>> solve_diophantine(x**Integer(2) - Integer(9)) # needs sympy [-3, 3] >>> sorted(solve_diophantine(x**Integer(2) + y**Integer(2) == Integer(25))) # needs sympy [(-5, 0), (-4, -3), (-4, 3), (-3, -4), (-3, 4), (0, -5)...
x,y = var('x,y') solve_diophantine(3*x == 4) # needs sympy solve_diophantine(x^2 - 9) # needs sympy sorted(solve_diophantine(x^2 + y^2 == 25)) # needs sympy
The function is used when
solve()
is called with all variables assumed integer:sage: assume(x, 'integer') sage: assume(y, 'integer') sage: sorted(solve(x*y == 1, (x,y))) # needs sympy [(-1, -1), (1, 1)]
>>> from sage.all import * >>> assume(x, 'integer') >>> assume(y, 'integer') >>> sorted(solve(x*y == Integer(1), (x,y))) # needs sympy [(-1, -1), (1, 1)]
assume(x, 'integer') assume(y, 'integer') sorted(solve(x*y == 1, (x,y))) # needs sympy
You can also pick specific variables, and get the solution as a dictionary:
sage: # needs sympy sage: solve_diophantine(x*y == 10, x) [-10, -5, -2, -1, 1, 2, 5, 10] sage: sorted(solve_diophantine(x*y - y == 10, (x,y))) [(-9, -1), (-4, -2), (-1, -5), (0, -10), (2, 10), (3, 5), (6, 2), (11, 1)] sage: res = solve_diophantine(x*y - y == 10, solution_dict=True) sage: sol = [{y: -5, x: -1}, {y: -10, x: 0}, {y: -1, x: -9}, {y: -2, x: -4}, ....: {y: 10, x: 2}, {y: 1, x: 11}, {y: 2, x: 6}, {y: 5, x: 3}] sage: all(solution in res ....: for solution in sol) and bool(len(res) == len(sol)) True
>>> from sage.all import * >>> # needs sympy >>> solve_diophantine(x*y == Integer(10), x) [-10, -5, -2, -1, 1, 2, 5, 10] >>> sorted(solve_diophantine(x*y - y == Integer(10), (x,y))) [(-9, -1), (-4, -2), (-1, -5), (0, -10), (2, 10), (3, 5), (6, 2), (11, 1)] >>> res = solve_diophantine(x*y - y == Integer(10), solution_dict=True) >>> sol = [{y: -Integer(5), x: -Integer(1)}, {y: -Integer(10), x: Integer(0)}, {y: -Integer(1), x: -Integer(9)}, {y: -Integer(2), x: -Integer(4)}, ... {y: Integer(10), x: Integer(2)}, {y: Integer(1), x: Integer(11)}, {y: Integer(2), x: Integer(6)}, {y: Integer(5), x: Integer(3)}] >>> all(solution in res ... for solution in sol) and bool(len(res) == len(sol)) True
# needs sympy solve_diophantine(x*y == 10, x) sorted(solve_diophantine(x*y - y == 10, (x,y))) res = solve_diophantine(x*y - y == 10, solution_dict=True) sol = [{y: -5, x: -1}, {y: -10, x: 0}, {y: -1, x: -9}, {y: -2, x: -4}, {y: 10, x: 2}, {y: 1, x: 11}, {y: 2, x: 6}, {y: 5, x: 3}] all(solution in res for solution in sol) and bool(len(res) == len(sol))
If the solution is parametrized the parameter(s) are not defined, but you can substitute them with specific integer values:
sage: # needs sympy sage: x,y,z = var('x,y,z') sage: sol = solve_diophantine(x^2-y == 0); sol (t, t^2) sage: [(sol[0].subs(t=t),sol[1].subs(t=t)) for t in range(-3,4)] [(-3, 9), (-2, 4), (-1, 1), (0, 0), (1, 1), (2, 4), (3, 9)] sage: sol = solve_diophantine(x^2 + y^2 == z^2); sol (2*p*q, p^2 - q^2, p^2 + q^2) sage: [(sol[0].subs(p=p,q=q), sol[1].subs(p=p,q=q), sol[2].subs(p=p,q=q)) ....: for p in range(1,4) for q in range(1,4)] [(2, 0, 2), (4, -3, 5), (6, -8, 10), (4, 3, 5), (8, 0, 8), (12, -5, 13), (6, 8, 10), (12, 5, 13), (18, 0, 18)]
>>> from sage.all import * >>> # needs sympy >>> x,y,z = var('x,y,z') >>> sol = solve_diophantine(x**Integer(2)-y == Integer(0)); sol (t, t^2) >>> [(sol[Integer(0)].subs(t=t),sol[Integer(1)].subs(t=t)) for t in range(-Integer(3),Integer(4))] [(-3, 9), (-2, 4), (-1, 1), (0, 0), (1, 1), (2, 4), (3, 9)] >>> sol = solve_diophantine(x**Integer(2) + y**Integer(2) == z**Integer(2)); sol (2*p*q, p^2 - q^2, p^2 + q^2) >>> [(sol[Integer(0)].subs(p=p,q=q), sol[Integer(1)].subs(p=p,q=q), sol[Integer(2)].subs(p=p,q=q)) ... for p in range(Integer(1),Integer(4)) for q in range(Integer(1),Integer(4))] [(2, 0, 2), (4, -3, 5), (6, -8, 10), (4, 3, 5), (8, 0, 8), (12, -5, 13), (6, 8, 10), (12, 5, 13), (18, 0, 18)]
# needs sympy x,y,z = var('x,y,z') sol = solve_diophantine(x^2-y == 0); sol [(sol[0].subs(t=t),sol[1].subs(t=t)) for t in range(-3,4)] sol = solve_diophantine(x^2 + y^2 == z^2); sol [(sol[0].subs(p=p,q=q), sol[1].subs(p=p,q=q), sol[2].subs(p=p,q=q)) for p in range(1,4) for q in range(1,4)]
Solve Brahmagupta-Pell equations:
sage: sol = sorted(solve_diophantine(x^2 - 2*y^2 == 1), key=str); sol # needs sympy [(-sqrt(2)*(2*sqrt(2) + 3)^t + sqrt(2)*(-2*sqrt(2) + 3)^t - 3/2*(2*sqrt(2) + 3)^t - 3/2*(-2*sqrt(2) + 3)^t,... sage: [(sol[1][0].subs(t=t).simplify_full(), # needs sympy ....: sol[1][1].subs(t=t).simplify_full()) for t in range(-1,5)] [(1, 0), (3, -2), (17, -12), (99, -70), (577, -408), (3363, -2378)]
>>> from sage.all import * >>> sol = sorted(solve_diophantine(x**Integer(2) - Integer(2)*y**Integer(2) == Integer(1)), key=str); sol # needs sympy [(-sqrt(2)*(2*sqrt(2) + 3)^t + sqrt(2)*(-2*sqrt(2) + 3)^t - 3/2*(2*sqrt(2) + 3)^t - 3/2*(-2*sqrt(2) + 3)^t,... >>> [(sol[Integer(1)][Integer(0)].subs(t=t).simplify_full(), # needs sympy ... sol[Integer(1)][Integer(1)].subs(t=t).simplify_full()) for t in range(-Integer(1),Integer(5))] [(1, 0), (3, -2), (17, -12), (99, -70), (577, -408), (3363, -2378)]
sol = sorted(solve_diophantine(x^2 - 2*y^2 == 1), key=str); sol # needs sympy [(sol[1][0].subs(t=t).simplify_full(), # needs sympy sol[1][1].subs(t=t).simplify_full()) for t in range(-1,5)]
- sqrt(hold=False)[source]¶
Return the square root of this expression.
EXAMPLES:
sage: var('x, y') (x, y) sage: SR(2).sqrt() sqrt(2) sage: (x^2+y^2).sqrt() sqrt(x^2 + y^2) sage: (x^2).sqrt() sqrt(x^2)
>>> from sage.all import * >>> var('x, y') (x, y) >>> SR(Integer(2)).sqrt() sqrt(2) >>> (x**Integer(2)+y**Integer(2)).sqrt() sqrt(x^2 + y^2) >>> (x**Integer(2)).sqrt() sqrt(x^2)
var('x, y') SR(2).sqrt() (x^2+y^2).sqrt() (x^2).sqrt()
Immediate simplifications are applied:
sage: sqrt(x^2) sqrt(x^2) sage: x = SR.symbol('x', domain='real') sage: sqrt(x^2) abs(x) sage: forget() sage: assume(x<0) sage: sqrt(x^2) -x sage: sqrt(x^4) x^2 sage: forget() sage: x = SR.symbol('x', domain='real') sage: sqrt(x^4) x^2 sage: sqrt(sin(x)^2) abs(sin(x)) sage: sqrt((x+1)^2) abs(x + 1) sage: forget() sage: assume(x<0) sage: sqrt((x-1)^2) -x + 1 sage: forget()
>>> from sage.all import * >>> sqrt(x**Integer(2)) sqrt(x^2) >>> x = SR.symbol('x', domain='real') >>> sqrt(x**Integer(2)) abs(x) >>> forget() >>> assume(x<Integer(0)) >>> sqrt(x**Integer(2)) -x >>> sqrt(x**Integer(4)) x^2 >>> forget() >>> x = SR.symbol('x', domain='real') >>> sqrt(x**Integer(4)) x^2 >>> sqrt(sin(x)**Integer(2)) abs(sin(x)) >>> sqrt((x+Integer(1))**Integer(2)) abs(x + 1) >>> forget() >>> assume(x<Integer(0)) >>> sqrt((x-Integer(1))**Integer(2)) -x + 1 >>> forget()
sqrt(x^2) x = SR.symbol('x', domain='real') sqrt(x^2) forget() assume(x<0) sqrt(x^2) sqrt(x^4) forget() x = SR.symbol('x', domain='real') sqrt(x^4) sqrt(sin(x)^2) sqrt((x+1)^2) forget() assume(x<0) sqrt((x-1)^2) forget()
Using the
hold
parameter it is possible to prevent automatic evaluation:sage: SR(4).sqrt() 2 sage: SR(4).sqrt(hold=True) sqrt(4)
>>> from sage.all import * >>> SR(Integer(4)).sqrt() 2 >>> SR(Integer(4)).sqrt(hold=True) sqrt(4)
SR(4).sqrt() SR(4).sqrt(hold=True)
To then evaluate again, we use
unhold()
:sage: a = SR(4).sqrt(hold=True); a.unhold() 2
>>> from sage.all import * >>> a = SR(Integer(4)).sqrt(hold=True); a.unhold() 2
a = SR(4).sqrt(hold=True); a.unhold()
To use this parameter in functional notation, you must coerce to the symbolic ring:
sage: sqrt(SR(4),hold=True) sqrt(4) sage: sqrt(4,hold=True) Traceback (most recent call last): ... TypeError: ..._do_sqrt() got an unexpected keyword argument 'hold'
>>> from sage.all import * >>> sqrt(SR(Integer(4)),hold=True) sqrt(4) >>> sqrt(Integer(4),hold=True) Traceback (most recent call last): ... TypeError: ..._do_sqrt() got an unexpected keyword argument 'hold'
sqrt(SR(4),hold=True) sqrt(4,hold=True)
- step(hold=False)[source]¶
Return the value of the unit step function, which is 0 for negative x, 1 for 0, and 1 for positive x.
EXAMPLES:
sage: x = var('x') sage: SR(1.5).step() 1 sage: SR(0).step() 1 sage: SR(-1/2).step() 0 sage: SR(float(-1)).step() 0
>>> from sage.all import * >>> x = var('x') >>> SR(RealNumber('1.5')).step() 1 >>> SR(Integer(0)).step() 1 >>> SR(-Integer(1)/Integer(2)).step() 0 >>> SR(float(-Integer(1))).step() 0
x = var('x') SR(1.5).step() SR(0).step() SR(-1/2).step() SR(float(-1)).step()
Using the
hold
parameter it is possible to prevent automatic evaluation:sage: SR(2).step() 1 sage: SR(2).step(hold=True) unit_step(2)
>>> from sage.all import * >>> SR(Integer(2)).step() 1 >>> SR(Integer(2)).step(hold=True) unit_step(2)
SR(2).step() SR(2).step(hold=True)
- subs(*args, **kwds)[source]¶
Substitute the given subexpressions in this expression.
EXAMPLES:
sage: var('x,y,z,a,b,c,d,f,g') (x, y, z, a, b, c, d, f, g) sage: w0 = SR.wild(0); w1 = SR.wild(1) sage: t = a^2 + b^2 + (x+y)^3
>>> from sage.all import * >>> var('x,y,z,a,b,c,d,f,g') (x, y, z, a, b, c, d, f, g) >>> w0 = SR.wild(Integer(0)); w1 = SR.wild(Integer(1)) >>> t = a**Integer(2) + b**Integer(2) + (x+y)**Integer(3)
var('x,y,z,a,b,c,d,f,g') w0 = SR.wild(0); w1 = SR.wild(1) t = a^2 + b^2 + (x+y)^3
Substitute with keyword arguments (works only with symbols):
sage: t.subs(a=c) (x + y)^3 + b^2 + c^2 sage: t.subs(b=19, x=z) (y + z)^3 + a^2 + 361
>>> from sage.all import * >>> t.subs(a=c) (x + y)^3 + b^2 + c^2 >>> t.subs(b=Integer(19), x=z) (y + z)^3 + a^2 + 361
t.subs(a=c) t.subs(b=19, x=z)
Substitute with a dictionary argument:
sage: t.subs({a^2: c}) (x + y)^3 + b^2 + c sage: t.subs({w0^2: w0^3}) a^3 + b^3 + (x + y)^3
>>> from sage.all import * >>> t.subs({a**Integer(2): c}) (x + y)^3 + b^2 + c >>> t.subs({w0**Integer(2): w0**Integer(3)}) a^3 + b^3 + (x + y)^3
t.subs({a^2: c}) t.subs({w0^2: w0^3})
Substitute with one or more relational expressions:
sage: t.subs(w0^2 == w0^3) a^3 + b^3 + (x + y)^3 sage: t.subs(w0 == w0^2) a^8 + b^8 + (x^2 + y^2)^6 sage: t.subs(a == b, b == c) (x + y)^3 + b^2 + c^2
>>> from sage.all import * >>> t.subs(w0**Integer(2) == w0**Integer(3)) a^3 + b^3 + (x + y)^3 >>> t.subs(w0 == w0**Integer(2)) a^8 + b^8 + (x^2 + y^2)^6 >>> t.subs(a == b, b == c) (x + y)^3 + b^2 + c^2
t.subs(w0^2 == w0^3) t.subs(w0 == w0^2) t.subs(a == b, b == c)
Any number of arguments is accepted:
sage: t.subs(a=b, b=c) (x + y)^3 + b^2 + c^2 sage: t.subs({a:b}, b=c) (x + y)^3 + b^2 + c^2 sage: t.subs([x == 3, y == 2], a == 2, {b:3}) 138
>>> from sage.all import * >>> t.subs(a=b, b=c) (x + y)^3 + b^2 + c^2 >>> t.subs({a:b}, b=c) (x + y)^3 + b^2 + c^2 >>> t.subs([x == Integer(3), y == Integer(2)], a == Integer(2), {b:Integer(3)}) 138
t.subs(a=b, b=c) t.subs({a:b}, b=c) t.subs([x == 3, y == 2], a == 2, {b:3})
It can even accept lists of lists:
sage: eqn1 = (a*x + b*y == 0) sage: eqn2 = (1 + y == 0) sage: soln = solve([eqn1, eqn2], [x, y]) sage: soln [[x == b/a, y == -1]] sage: f = x + y sage: f.subs(soln) b/a - 1
>>> from sage.all import * >>> eqn1 = (a*x + b*y == Integer(0)) >>> eqn2 = (Integer(1) + y == Integer(0)) >>> soln = solve([eqn1, eqn2], [x, y]) >>> soln [[x == b/a, y == -1]] >>> f = x + y >>> f.subs(soln) b/a - 1
eqn1 = (a*x + b*y == 0) eqn2 = (1 + y == 0) soln = solve([eqn1, eqn2], [x, y]) soln f = x + y f.subs(soln)
Duplicate assignments will throw an error:
sage: t.subs({a:b}, a=c) Traceback (most recent call last): ... ValueError: duplicate substitution for a, got values b and c sage: t.subs([x == 1], a = 1, b = 2, x = 2) Traceback (most recent call last): ... ValueError: duplicate substitution for x, got values 1 and 2
>>> from sage.all import * >>> t.subs({a:b}, a=c) Traceback (most recent call last): ... ValueError: duplicate substitution for a, got values b and c >>> t.subs([x == Integer(1)], a = Integer(1), b = Integer(2), x = Integer(2)) Traceback (most recent call last): ... ValueError: duplicate substitution for x, got values 1 and 2
t.subs({a:b}, a=c) t.subs([x == 1], a = 1, b = 2, x = 2)
All substitutions are performed at the same time:
sage: t.subs({a:b, b:c}) (x + y)^3 + b^2 + c^2
>>> from sage.all import * >>> t.subs({a:b, b:c}) (x + y)^3 + b^2 + c^2
t.subs({a:b, b:c})
Substitutions are done term by term, in other words Sage is not able to identify partial sums in a substitution (see Issue #18396):
sage: f = x + x^2 + x^4 sage: f.subs(x = y) y^4 + y^2 + y sage: f.subs(x^2 == y) # one term is fine x^4 + x + y sage: f.subs(x + x^2 == y) # partial sum does not work x^4 + x^2 + x sage: f.subs(x + x^2 + x^4 == y) # whole sum is fine y
>>> from sage.all import * >>> f = x + x**Integer(2) + x**Integer(4) >>> f.subs(x = y) y^4 + y^2 + y >>> f.subs(x**Integer(2) == y) # one term is fine x^4 + x + y >>> f.subs(x + x**Integer(2) == y) # partial sum does not work x^4 + x^2 + x >>> f.subs(x + x**Integer(2) + x**Integer(4) == y) # whole sum is fine y
f = x + x^2 + x^4 f.subs(x = y) f.subs(x^2 == y) # one term is fine f.subs(x + x^2 == y) # partial sum does not work f.subs(x + x^2 + x^4 == y) # whole sum is fine
Note that it is the very same behavior as in Maxima:
sage: E = 'x^4 + x^2 + x' sage: subs = [('x','y'), ('x^2','y'), ('x^2+x','y'), ('x^4+x^2+x','y')] sage: cmd = '{}, {}={}' sage: for s1,s2 in subs: ....: maxima.eval(cmd.format(E, s1, s2)) 'y^4+y^2+y' 'y+x^4+x' 'x^4+x^2+x' 'y'
>>> from sage.all import * >>> E = 'x^4 + x^2 + x' >>> subs = [('x','y'), ('x^2','y'), ('x^2+x','y'), ('x^4+x^2+x','y')] >>> cmd = '{}, {}={}' >>> for s1,s2 in subs: ... maxima.eval(cmd.format(E, s1, s2)) 'y^4+y^2+y' 'y+x^4+x' 'x^4+x^2+x' 'y'
E = 'x^4 + x^2 + x' subs = [('x','y'), ('x^2','y'), ('x^2+x','y'), ('x^4+x^2+x','y')] cmd = '{}, {}={}' for s1,s2 in subs: maxima.eval(cmd.format(E, s1, s2))
Or as in Maple:
sage: cmd = 'subs({}={}, {})' # optional - maple sage: for s1,s2 in subs: # optional - maple ....: maple.eval(cmd.format(s1,s2, E)) 'y^4+y^2+y' 'x^4+x+y' 'x^4+x^2+x' 'y'
>>> from sage.all import * >>> cmd = 'subs({}={}, {})' # optional - maple >>> for s1,s2 in subs: # optional - maple ... maple.eval(cmd.format(s1,s2, E)) 'y^4+y^2+y' 'x^4+x+y' 'x^4+x^2+x' 'y'
cmd = 'subs({}={}, {})' # optional - maple for s1,s2 in subs: # optional - maple maple.eval(cmd.format(s1,s2, E))
But Mathematica does something different on the third example:
sage: cmd = '{} /. {} -> {}' # optional - mathematica sage: for s1,s2 in subs: # optional - mathematica ....: mathematica.eval(cmd.format(E,s1,s2)) 2 4 y + y + y 4 x + x + y 4 x + y y
>>> from sage.all import * >>> cmd = '{} /. {} -> {}' # optional - mathematica >>> for s1,s2 in subs: # optional - mathematica ... mathematica.eval(cmd.format(E,s1,s2)) 2 4 y + y + y 4 x + x + y 4 x + y y
cmd = '{} /. {} -> {}' # optional - mathematica for s1,s2 in subs: # optional - mathematica mathematica.eval(cmd.format(E,s1,s2))
The same, with formatting more suitable for cut and paste:
sage: for s1,s2 in subs: # optional - mathematica ....: mathematica(cmd.format(E,s1,s2)) y + y^2 + y^4 x + x^4 + y x^4 + y y
>>> from sage.all import * >>> for s1,s2 in subs: # optional - mathematica ... mathematica(cmd.format(E,s1,s2)) y + y^2 + y^4 x + x^4 + y x^4 + y y
for s1,s2 in subs: # optional - mathematica mathematica(cmd.format(E,s1,s2))
Warning
Unexpected results may occur if the left-hand side of some substitution is not just a single variable (or is a “wildcard” variable). For example, the result of
cos(cos(cos(x))).subs({cos(x) : x})
isx
, because the substitution is applied repeatedly. Such repeated substitutions (and pattern-matching code that may be somewhat unpredictable) are disabled only in the basic case where the left-hand side of every substitution is a variable. In particular, although the result of(x^2).subs({x : sqrt(x)})
isx
, the result of(x^2).subs({x : sqrt(x), y^2 : y})
issqrt(x)
, because repeated substitution is enabled by the presence of the expressiony^2
in the left-hand side of one of the substitutions, even though that particular substitution does not get applied.
- substitute_function(*args, **kwds)[source]¶
Substitute the given functions by their replacements in this expression.
EXAMPLES:
sage: x,y = var('x,y') sage: foo = function('foo'); bar = function('bar') sage: f = foo(x) + 1/foo(pi*y)
>>> from sage.all import * >>> x,y = var('x,y') >>> foo = function('foo'); bar = function('bar') >>> f = foo(x) + Integer(1)/foo(pi*y)
x,y = var('x,y') foo = function('foo'); bar = function('bar') f = foo(x) + 1/foo(pi*y)
Substitute with a dictionary:
sage: f.substitute_function({foo: bar}) 1/bar(pi*y) + bar(x) sage: f.substitute_function({foo(x): bar(x)}) 1/bar(pi*y) + bar(x)
>>> from sage.all import * >>> f.substitute_function({foo: bar}) 1/bar(pi*y) + bar(x) >>> f.substitute_function({foo(x): bar(x)}) 1/bar(pi*y) + bar(x)
f.substitute_function({foo: bar}) f.substitute_function({foo(x): bar(x)})
If the function expression to be substituted includes its arguments, the right hand side can be an arbitrary symbolic expression:
sage: f.substitute_function({foo(x): x^2}) x^2 + 1/(pi^2*y^2)
>>> from sage.all import * >>> f.substitute_function({foo(x): x**Integer(2)}) x^2 + 1/(pi^2*y^2)
f.substitute_function({foo(x): x^2})
Substitute with keyword arguments (works only if no function arguments are given):
sage: f.substitute_function(foo=bar) 1/bar(pi*y) + bar(x)
>>> from sage.all import * >>> f.substitute_function(foo=bar) 1/bar(pi*y) + bar(x)
f.substitute_function(foo=bar)
Substitute with a relational expression:
sage: f.substitute_function(foo(x)==bar(x)) 1/bar(pi*y) + bar(x) sage: f.substitute_function(foo(x)==bar(x+1)) 1/bar(pi*y + 1) + bar(x + 1)
>>> from sage.all import * >>> f.substitute_function(foo(x)==bar(x)) 1/bar(pi*y) + bar(x) >>> f.substitute_function(foo(x)==bar(x+Integer(1))) 1/bar(pi*y + 1) + bar(x + 1)
f.substitute_function(foo(x)==bar(x)) f.substitute_function(foo(x)==bar(x+1))
All substitutions are performed at the same time:
sage: g = foo(x) + 1/bar(pi*y) sage: g.substitute_function({foo: bar, bar: foo}) 1/foo(pi*y) + bar(x)
>>> from sage.all import * >>> g = foo(x) + Integer(1)/bar(pi*y) >>> g.substitute_function({foo: bar, bar: foo}) 1/foo(pi*y) + bar(x)
g = foo(x) + 1/bar(pi*y) g.substitute_function({foo: bar, bar: foo})
Any number of arguments is accepted:
sage: g.substitute_function({foo: bar}, bar(x) == x^2) 1/(pi^2*y^2) + bar(x)
>>> from sage.all import * >>> g.substitute_function({foo: bar}, bar(x) == x**Integer(2)) 1/(pi^2*y^2) + bar(x)
g.substitute_function({foo: bar}, bar(x) == x^2)
As well as lists of substitutions:
sage: g.substitute_function([foo(x) == 1, bar(x) == x]) 1/(pi*y) + 1
>>> from sage.all import * >>> g.substitute_function([foo(x) == Integer(1), bar(x) == x]) 1/(pi*y) + 1
g.substitute_function([foo(x) == 1, bar(x) == x])
Alternative syntax:
sage: g.substitute_function(foo, bar) 1/bar(pi*y) + bar(x)
>>> from sage.all import * >>> g.substitute_function(foo, bar) 1/bar(pi*y) + bar(x)
g.substitute_function(foo, bar)
Duplicate assignments will throw an error:
sage: g.substitute_function({foo:bar}, foo(x) == x^2) Traceback (most recent call last): ... ValueError: duplicate substitution for foo, got values bar and x |--> x^2 sage: g.substitute_function([foo(x) == x^2], foo = bar) Traceback (most recent call last): ... ValueError: duplicate substitution for foo, got values x |--> x^2 and bar
>>> from sage.all import * >>> g.substitute_function({foo:bar}, foo(x) == x**Integer(2)) Traceback (most recent call last): ... ValueError: duplicate substitution for foo, got values bar and x |--> x^2 >>> g.substitute_function([foo(x) == x**Integer(2)], foo = bar) Traceback (most recent call last): ... ValueError: duplicate substitution for foo, got values x |--> x^2 and bar
g.substitute_function({foo:bar}, foo(x) == x^2) g.substitute_function([foo(x) == x^2], foo = bar)
- substitution_delayed(pattern, replacement)[source]¶
Replace all occurrences of pattern by the result of replacement.
In contrast to
subs()
, the pattern may contains wildcards and the replacement can depend on the particular term matched by the pattern.INPUT:
pattern
– anExpression
, usually containing wildcardsreplacement
– a function; its argument is a dictionary mapping the wildcard occurring inpattern
to the actual values. If it returnsNone
, this occurrence ofpattern
is not replaced. Otherwise, it is replaced by the output ofreplacement
.
OUTPUT: an
Expression
EXAMPLES:
sage: var('x y') (x, y) sage: w0 = SR.wild(0) sage: sqrt(1 + 2*x + x^2).substitution_delayed( ....: sqrt(w0), lambda d: sqrt(factor(d[w0])) ....: ) sqrt((x + 1)^2) sage: def r(d): ....: if x not in d[w0].variables(): ....: return cos(d[w0]) sage: (sin(x^2 + x) + sin(y^2 + y)).substitution_delayed(sin(w0), r) cos(y^2 + y) + sin(x^2 + x)
>>> from sage.all import * >>> var('x y') (x, y) >>> w0 = SR.wild(Integer(0)) >>> sqrt(Integer(1) + Integer(2)*x + x**Integer(2)).substitution_delayed( ... sqrt(w0), lambda d: sqrt(factor(d[w0])) ... ) sqrt((x + 1)^2) >>> def r(d): ... if x not in d[w0].variables(): ... return cos(d[w0]) >>> (sin(x**Integer(2) + x) + sin(y**Integer(2) + y)).substitution_delayed(sin(w0), r) cos(y^2 + y) + sin(x^2 + x)
var('x y') w0 = SR.wild(0) sqrt(1 + 2*x + x^2).substitution_delayed( sqrt(w0), lambda d: sqrt(factor(d[w0])) ) def r(d): if x not in d[w0].variables(): return cos(d[w0]) (sin(x^2 + x) + sin(y^2 + y)).substitution_delayed(sin(w0), r)
See also
- subtract_from_both_sides(x)[source]¶
Return a relation obtained by subtracting
x
from both sides of this relation.EXAMPLES:
sage: eqn = x*sin(x)*sqrt(3) + sqrt(2) > cos(sin(x)) sage: eqn.subtract_from_both_sides(sqrt(2)) sqrt(3)*x*sin(x) > -sqrt(2) + cos(sin(x)) sage: eqn.subtract_from_both_sides(cos(sin(x))) sqrt(3)*x*sin(x) + sqrt(2) - cos(sin(x)) > 0
>>> from sage.all import * >>> eqn = x*sin(x)*sqrt(Integer(3)) + sqrt(Integer(2)) > cos(sin(x)) >>> eqn.subtract_from_both_sides(sqrt(Integer(2))) sqrt(3)*x*sin(x) > -sqrt(2) + cos(sin(x)) >>> eqn.subtract_from_both_sides(cos(sin(x))) sqrt(3)*x*sin(x) + sqrt(2) - cos(sin(x)) > 0
eqn = x*sin(x)*sqrt(3) + sqrt(2) > cos(sin(x)) eqn.subtract_from_both_sides(sqrt(2)) eqn.subtract_from_both_sides(cos(sin(x)))
- sum(*args, **kwds)[source]¶
Return the symbolic sum \(\sum_{v = a}^b\)
self
.with respect to the variable \(v\) with endpoints \(a\) and \(b\).
INPUT:
v
– a variable or variable namea
– lower endpoint of the sumb
– upper endpoint of the sumalgorithm
– (default:'maxima'
) one of'maxima'
– use Maxima (the default)'maple'
– (optional) use Maple'mathematica'
– (optional) use Mathematica'giac'
– (optional) use Giac'sympy'
– use SymPy
EXAMPLES:
sage: k, n = var('k,n') sage: k.sum(k, 1, n).factor() 1/2*(n + 1)*n
>>> from sage.all import * >>> k, n = var('k,n') >>> k.sum(k, Integer(1), n).factor() 1/2*(n + 1)*n
k, n = var('k,n') k.sum(k, 1, n).factor()
sage: (1/k^4).sum(k, 1, oo) 1/90*pi^4
>>> from sage.all import * >>> (Integer(1)/k**Integer(4)).sum(k, Integer(1), oo) 1/90*pi^4
(1/k^4).sum(k, 1, oo)
>>> from sage.all import * >>> (Integer(1)/k**Integer(4)).sum(k, Integer(1), oo) 1/90*pi^4
(1/k^4).sum(k, 1, oo)
sage: (1/k^5).sum(k, 1, oo) zeta(5)
>>> from sage.all import * >>> (Integer(1)/k**Integer(5)).sum(k, Integer(1), oo) zeta(5)
(1/k^5).sum(k, 1, oo)
>>> from sage.all import * >>> (Integer(1)/k**Integer(5)).sum(k, Integer(1), oo) zeta(5)
(1/k^5).sum(k, 1, oo)
A well known binomial identity:
sage: assume(n>=0) sage: binomial(n,k).sum(k, 0, n) 2^n
>>> from sage.all import * >>> assume(n>=Integer(0)) >>> binomial(n,k).sum(k, Integer(0), n) 2^n
assume(n>=0) binomial(n,k).sum(k, 0, n)
And some truncations thereof:
sage: binomial(n,k).sum(k,1,n) 2^n - 1 sage: binomial(n,k).sum(k,2,n) 2^n - n - 1 sage: binomial(n,k).sum(k,0,n-1) 2^n - 1 sage: binomial(n,k).sum(k,1,n-1) 2^n - 2
>>> from sage.all import * >>> binomial(n,k).sum(k,Integer(1),n) 2^n - 1 >>> binomial(n,k).sum(k,Integer(2),n) 2^n - n - 1 >>> binomial(n,k).sum(k,Integer(0),n-Integer(1)) 2^n - 1 >>> binomial(n,k).sum(k,Integer(1),n-Integer(1)) 2^n - 2
binomial(n,k).sum(k,1,n) binomial(n,k).sum(k,2,n) binomial(n,k).sum(k,0,n-1) binomial(n,k).sum(k,1,n-1)
The binomial theorem:
sage: x, y = var('x, y') sage: (binomial(n,k) * x^k * y^(n-k)).sum(k, 0, n) (x + y)^n
>>> from sage.all import * >>> x, y = var('x, y') >>> (binomial(n,k) * x**k * y**(n-k)).sum(k, Integer(0), n) (x + y)^n
x, y = var('x, y') (binomial(n,k) * x^k * y^(n-k)).sum(k, 0, n)
sage: (k * binomial(n, k)).sum(k, 1, n) 2^(n - 1)*n
>>> from sage.all import * >>> (k * binomial(n, k)).sum(k, Integer(1), n) 2^(n - 1)*n
(k * binomial(n, k)).sum(k, 1, n)
>>> from sage.all import * >>> (k * binomial(n, k)).sum(k, Integer(1), n) 2^(n - 1)*n
(k * binomial(n, k)).sum(k, 1, n)
sage: ((-1)^k*binomial(n,k)).sum(k, 0, n) 0
>>> from sage.all import * >>> ((-Integer(1))**k*binomial(n,k)).sum(k, Integer(0), n) 0
((-1)^k*binomial(n,k)).sum(k, 0, n)
>>> from sage.all import * >>> ((-Integer(1))**k*binomial(n,k)).sum(k, Integer(0), n) 0
((-1)^k*binomial(n,k)).sum(k, 0, n)
sage: (2^(-k)/(k*(k+1))).sum(k, 1, oo) -log(2) + 1
>>> from sage.all import * >>> (Integer(2)**(-k)/(k*(k+Integer(1)))).sum(k, Integer(1), oo) -log(2) + 1
(2^(-k)/(k*(k+1))).sum(k, 1, oo)
>>> from sage.all import * >>> (Integer(2)**(-k)/(k*(k+Integer(1)))).sum(k, Integer(1), oo) -log(2) + 1
(2^(-k)/(k*(k+1))).sum(k, 1, oo)
Summing a hypergeometric term:
sage: (binomial(n, k) * factorial(k) / factorial(n+1+k)).sum(k, 0, n) 1/2*sqrt(pi)/factorial(n + 1/2)
>>> from sage.all import * >>> (binomial(n, k) * factorial(k) / factorial(n+Integer(1)+k)).sum(k, Integer(0), n) 1/2*sqrt(pi)/factorial(n + 1/2)
(binomial(n, k) * factorial(k) / factorial(n+1+k)).sum(k, 0, n)
We check a well known identity:
sage: bool((k^3).sum(k, 1, n) == k.sum(k, 1, n)^2) True
>>> from sage.all import * >>> bool((k**Integer(3)).sum(k, Integer(1), n) == k.sum(k, Integer(1), n)**Integer(2)) True
bool((k^3).sum(k, 1, n) == k.sum(k, 1, n)^2)
A geometric sum:
sage: a, q = var('a, q') sage: (a*q^k).sum(k, 0, n) (a*q^(n + 1) - a)/(q - 1)
>>> from sage.all import * >>> a, q = var('a, q') >>> (a*q**k).sum(k, Integer(0), n) (a*q^(n + 1) - a)/(q - 1)
a, q = var('a, q') (a*q^k).sum(k, 0, n)
The geometric series:
sage: assume(abs(q) < 1) sage: (a*q^k).sum(k, 0, oo) -a/(q - 1)
>>> from sage.all import * >>> assume(abs(q) < Integer(1)) >>> (a*q**k).sum(k, Integer(0), oo) -a/(q - 1)
assume(abs(q) < 1) (a*q^k).sum(k, 0, oo)
A divergent geometric series. Do not forget to \(forget\) your assumptions:
sage: forget() sage: assume(q > 1) sage: (a*q^k).sum(k, 0, oo) Traceback (most recent call last): ... ValueError: Sum is divergent.
>>> from sage.all import * >>> forget() >>> assume(q > Integer(1)) >>> (a*q**k).sum(k, Integer(0), oo) Traceback (most recent call last): ... ValueError: Sum is divergent.
forget() assume(q > 1) (a*q^k).sum(k, 0, oo)
This summation only Mathematica can perform:
sage: (1/(1+k^2)).sum(k, -oo, oo, algorithm = 'mathematica') # optional - mathematica pi*coth(pi)
>>> from sage.all import * >>> (Integer(1)/(Integer(1)+k**Integer(2))).sum(k, -oo, oo, algorithm = 'mathematica') # optional - mathematica pi*coth(pi)
(1/(1+k^2)).sum(k, -oo, oo, algorithm = 'mathematica') # optional - mathematica
Use Giac to perform this summation:
sage: # needs giac sage: (sum(1/(1+k^2), k, -oo, oo, algorithm = 'giac')).factor() pi*(e^(2*pi) + 1)/((e^pi + 1)*(e^pi - 1))
>>> from sage.all import * >>> # needs giac >>> (sum(Integer(1)/(Integer(1)+k**Integer(2)), k, -oo, oo, algorithm = 'giac')).factor() pi*(e^(2*pi) + 1)/((e^pi + 1)*(e^pi - 1))
# needs giac (sum(1/(1+k^2), k, -oo, oo, algorithm = 'giac')).factor()
Use Maple as a backend for summation:
sage: (binomial(n,k)*x^k).sum(k, 0, n, algorithm = 'maple') # optional - maple (x + 1)^n
>>> from sage.all import * >>> (binomial(n,k)*x**k).sum(k, Integer(0), n, algorithm = 'maple') # optional - maple (x + 1)^n
(binomial(n,k)*x^k).sum(k, 0, n, algorithm = 'maple') # optional - maple
Note
Sage can currently only understand a subset of the output of Maxima, Maple and Mathematica, so even if the chosen backend can perform the summation the result might not be convertible into a usable Sage expression.
- tan(hold=False)[source]¶
EXAMPLES:
sage: var('x, y') (x, y) sage: tan(x^2 + y^2) tan(x^2 + y^2) sage: tan(sage.symbolic.constants.pi/2) Infinity sage: tan(SR(1)) tan(1) sage: tan(SR(RealField(150)(1))) 1.5574077246549022305069748074583601730872508
>>> from sage.all import * >>> var('x, y') (x, y) >>> tan(x**Integer(2) + y**Integer(2)) tan(x^2 + y^2) >>> tan(sage.symbolic.constants.pi/Integer(2)) Infinity >>> tan(SR(Integer(1))) tan(1) >>> tan(SR(RealField(Integer(150))(Integer(1)))) 1.5574077246549022305069748074583601730872508
var('x, y') tan(x^2 + y^2) tan(sage.symbolic.constants.pi/2) tan(SR(1)) tan(SR(RealField(150)(1)))
To prevent automatic evaluation use the
hold
argument:sage: (pi/12).tan() -sqrt(3) + 2 sage: (pi/12).tan(hold=True) tan(1/12*pi)
>>> from sage.all import * >>> (pi/Integer(12)).tan() -sqrt(3) + 2 >>> (pi/Integer(12)).tan(hold=True) tan(1/12*pi)
(pi/12).tan() (pi/12).tan(hold=True)
This also works using functional notation:
sage: tan(pi/12,hold=True) tan(1/12*pi) sage: tan(pi/12) -sqrt(3) + 2
>>> from sage.all import * >>> tan(pi/Integer(12),hold=True) tan(1/12*pi) >>> tan(pi/Integer(12)) -sqrt(3) + 2
tan(pi/12,hold=True) tan(pi/12)
To then evaluate again, we use
unhold()
:sage: a = (pi/12).tan(hold=True); a.unhold() -sqrt(3) + 2
>>> from sage.all import * >>> a = (pi/Integer(12)).tan(hold=True); a.unhold() -sqrt(3) + 2
a = (pi/12).tan(hold=True); a.unhold()
- tanh(hold=False)[source]¶
Return tanh of
self
.We have \(\tanh(x) = \sinh(x) / \cosh(x)\).
EXAMPLES:
sage: x.tanh() tanh(x) sage: SR(1).tanh() tanh(1) sage: SR(0).tanh() 0 sage: SR(1.0).tanh() 0.761594155955765 sage: maxima('tanh(1.0)') 0.7615941559557649 sage: plot(lambda x: SR(x).tanh(), -1, 1) # needs sage.plot Graphics object consisting of 1 graphics primitive
>>> from sage.all import * >>> x.tanh() tanh(x) >>> SR(Integer(1)).tanh() tanh(1) >>> SR(Integer(0)).tanh() 0 >>> SR(RealNumber('1.0')).tanh() 0.761594155955765 >>> maxima('tanh(1.0)') 0.7615941559557649 >>> plot(lambda x: SR(x).tanh(), -Integer(1), Integer(1)) # needs sage.plot Graphics object consisting of 1 graphics primitive
x.tanh() SR(1).tanh() SR(0).tanh() SR(1.0).tanh() maxima('tanh(1.0)') plot(lambda x: SR(x).tanh(), -1, 1) # needs sage.plot
To prevent automatic evaluation use the
hold
argument:sage: arcsinh(x).tanh() x/sqrt(x^2 + 1) sage: arcsinh(x).tanh(hold=True) tanh(arcsinh(x))
>>> from sage.all import * >>> arcsinh(x).tanh() x/sqrt(x^2 + 1) >>> arcsinh(x).tanh(hold=True) tanh(arcsinh(x))
arcsinh(x).tanh() arcsinh(x).tanh(hold=True)
This also works using functional notation:
sage: tanh(arcsinh(x), hold=True) tanh(arcsinh(x)) sage: tanh(arcsinh(x)) x/sqrt(x^2 + 1)
>>> from sage.all import * >>> tanh(arcsinh(x), hold=True) tanh(arcsinh(x)) >>> tanh(arcsinh(x)) x/sqrt(x^2 + 1)
tanh(arcsinh(x), hold=True) tanh(arcsinh(x))
To then evaluate again, we use
unhold()
:sage: a = arcsinh(x).tanh(hold=True); a.unhold() x/sqrt(x^2 + 1)
>>> from sage.all import * >>> a = arcsinh(x).tanh(hold=True); a.unhold() x/sqrt(x^2 + 1)
a = arcsinh(x).tanh(hold=True); a.unhold()
- taylor(*args)[source]¶
Expand this symbolic expression in a truncated Taylor or Laurent series in the variable \(v\) around the point \(a\), containing terms through \((x - a)^n\). Functions in more variables is also supported.
INPUT:
*args
– the following notation is supportedx
,a
,n
– variable, point, degree(x, a)
,(y, b)
,n
– variables with points, degree of polynomial
EXAMPLES:
sage: var('a, x, z') (a, x, z) sage: taylor(a*log(z), z, 2, 3) 1/24*a*(z - 2)^3 - 1/8*a*(z - 2)^2 + 1/2*a*(z - 2) + a*log(2)
>>> from sage.all import * >>> var('a, x, z') (a, x, z) >>> taylor(a*log(z), z, Integer(2), Integer(3)) 1/24*a*(z - 2)^3 - 1/8*a*(z - 2)^2 + 1/2*a*(z - 2) + a*log(2)
var('a, x, z') taylor(a*log(z), z, 2, 3)
sage: taylor(sqrt(sin(x) + a*x + 1), x, 0, 3) 1/48*(3*a^3 + 9*a^2 + 9*a - 1)*x^3 - 1/8*(a^2 + 2*a + 1)*x^2 + 1/2*(a + 1)*x + 1
>>> from sage.all import * >>> taylor(sqrt(sin(x) + a*x + Integer(1)), x, Integer(0), Integer(3)) 1/48*(3*a^3 + 9*a^2 + 9*a - 1)*x^3 - 1/8*(a^2 + 2*a + 1)*x^2 + 1/2*(a + 1)*x + 1
taylor(sqrt(sin(x) + a*x + 1), x, 0, 3)
>>> from sage.all import * >>> taylor(sqrt(sin(x) + a*x + Integer(1)), x, Integer(0), Integer(3)) 1/48*(3*a^3 + 9*a^2 + 9*a - 1)*x^3 - 1/8*(a^2 + 2*a + 1)*x^2 + 1/2*(a + 1)*x + 1
taylor(sqrt(sin(x) + a*x + 1), x, 0, 3)
sage: taylor(sqrt(x + 1), x, 0, 5) 7/256*x^5 - 5/128*x^4 + 1/16*x^3 - 1/8*x^2 + 1/2*x + 1
>>> from sage.all import * >>> taylor(sqrt(x + Integer(1)), x, Integer(0), Integer(5)) 7/256*x^5 - 5/128*x^4 + 1/16*x^3 - 1/8*x^2 + 1/2*x + 1
taylor(sqrt(x + 1), x, 0, 5)
>>> from sage.all import * >>> taylor(sqrt(x + Integer(1)), x, Integer(0), Integer(5)) 7/256*x^5 - 5/128*x^4 + 1/16*x^3 - 1/8*x^2 + 1/2*x + 1
taylor(sqrt(x + 1), x, 0, 5)
sage: taylor(1/log(x + 1), x, 0, 3) -19/720*x^3 + 1/24*x^2 - 1/12*x + 1/x + 1/2
>>> from sage.all import * >>> taylor(Integer(1)/log(x + Integer(1)), x, Integer(0), Integer(3)) -19/720*x^3 + 1/24*x^2 - 1/12*x + 1/x + 1/2
taylor(1/log(x + 1), x, 0, 3)
>>> from sage.all import * >>> taylor(Integer(1)/log(x + Integer(1)), x, Integer(0), Integer(3)) -19/720*x^3 + 1/24*x^2 - 1/12*x + 1/x + 1/2
taylor(1/log(x + 1), x, 0, 3)
sage: taylor(cos(x) - sec(x), x, 0, 5) -1/6*x^4 - x^2
>>> from sage.all import * >>> taylor(cos(x) - sec(x), x, Integer(0), Integer(5)) -1/6*x^4 - x^2
taylor(cos(x) - sec(x), x, 0, 5)
>>> from sage.all import * >>> taylor(cos(x) - sec(x), x, Integer(0), Integer(5)) -1/6*x^4 - x^2
taylor(cos(x) - sec(x), x, 0, 5)
sage: taylor((cos(x) - sec(x))^3, x, 0, 9) -1/2*x^8 - x^6
>>> from sage.all import * >>> taylor((cos(x) - sec(x))**Integer(3), x, Integer(0), Integer(9)) -1/2*x^8 - x^6
taylor((cos(x) - sec(x))^3, x, 0, 9)
>>> from sage.all import * >>> taylor((cos(x) - sec(x))**Integer(3), x, Integer(0), Integer(9)) -1/2*x^8 - x^6
taylor((cos(x) - sec(x))^3, x, 0, 9)
sage: taylor(1/(cos(x) - sec(x))^3, x, 0, 5) -15377/7983360*x^4 - 6767/604800*x^2 + 11/120/x^2 + 1/2/x^4 - 1/x^6 - 347/15120
>>> from sage.all import * >>> taylor(Integer(1)/(cos(x) - sec(x))**Integer(3), x, Integer(0), Integer(5)) -15377/7983360*x^4 - 6767/604800*x^2 + 11/120/x^2 + 1/2/x^4 - 1/x^6 - 347/15120
taylor(1/(cos(x) - sec(x))^3, x, 0, 5)
>>> from sage.all import * >>> taylor(Integer(1)/(cos(x) - sec(x))**Integer(3), x, Integer(0), Integer(5)) -15377/7983360*x^4 - 6767/604800*x^2 + 11/120/x^2 + 1/2/x^4 - 1/x^6 - 347/15120
taylor(1/(cos(x) - sec(x))^3, x, 0, 5)
- test_relation(ntests=20, domain=None, proof=True)[source]¶
Test this relation at several random values, attempting to find a contradiction. If this relation has no variables, it will also test this relation after casting into the domain.
Because the interval fields never return false positives, we can be assured that if
True
orFalse
is returned (and proof isFalse
) then the answer is correct.INPUT:
ntests
– (default: 20) the number of iterations to rundomain
– (optional) the domain from which to draw the random values defaults toCIF
for equality testing andRIF
for order testingproof
– (default:True
) ifFalse
and the domain is an interval field, regard overlapping (potentially equal) intervals as equal, and returnTrue
if all tests succeeded.
OUTPUT: boolean or
NotImplemented
, meaningTrue
– this relation holds in the domain and has no variablesFalse
– a contradiction was foundNotImplemented
– no contradiction found
EXAMPLES:
sage: (3 < pi).test_relation() True sage: (0 >= pi).test_relation() False sage: (exp(pi) - pi).n() 19.9990999791895 sage: (exp(pi) - pi == 20).test_relation() False sage: (sin(x)^2 + cos(x)^2 == 1).test_relation() NotImplemented sage: (sin(x)^2 + cos(x)^2 == 1).test_relation(proof=False) True sage: (x == 1).test_relation() False sage: var('x,y') (x, y) sage: (x < y).test_relation() False
>>> from sage.all import * >>> (Integer(3) < pi).test_relation() True >>> (Integer(0) >= pi).test_relation() False >>> (exp(pi) - pi).n() 19.9990999791895 >>> (exp(pi) - pi == Integer(20)).test_relation() False >>> (sin(x)**Integer(2) + cos(x)**Integer(2) == Integer(1)).test_relation() NotImplemented >>> (sin(x)**Integer(2) + cos(x)**Integer(2) == Integer(1)).test_relation(proof=False) True >>> (x == Integer(1)).test_relation() False >>> var('x,y') (x, y) >>> (x < y).test_relation() False
(3 < pi).test_relation() (0 >= pi).test_relation() (exp(pi) - pi).n() (exp(pi) - pi == 20).test_relation() (sin(x)^2 + cos(x)^2 == 1).test_relation() (sin(x)^2 + cos(x)^2 == 1).test_relation(proof=False) (x == 1).test_relation() var('x,y') (x < y).test_relation()
- to_gamma()[source]¶
Convert factorial, binomial, and Pochhammer symbol expressions to their gamma function equivalents.
EXAMPLES:
sage: m,n = var('m n', domain='integer') sage: factorial(n).to_gamma() gamma(n + 1) sage: binomial(m,n).to_gamma() gamma(m + 1)/(gamma(m - n + 1)*gamma(n + 1))
>>> from sage.all import * >>> m,n = var('m n', domain='integer') >>> factorial(n).to_gamma() gamma(n + 1) >>> binomial(m,n).to_gamma() gamma(m + 1)/(gamma(m - n + 1)*gamma(n + 1))
m,n = var('m n', domain='integer') factorial(n).to_gamma() binomial(m,n).to_gamma()
- trailing_coeff(s)[source]¶
Return the trailing coefficient of s in
self
, i.e., the coefficient of the smallest power of s inself
.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.trailing_coefficient(x) 2*sin(x*y) sage: f.trailing_coefficient(y) x sage: f.trailing_coefficient(sin(x*y)) a*x + x*y + x/y + 100
>>> 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.trailing_coefficient(x) 2*sin(x*y) >>> f.trailing_coefficient(y) x >>> f.trailing_coefficient(sin(x*y)) a*x + x*y + x/y + 100
var('x,y,a') f = 100 + a*x + x^3*sin(x*y) + x*y + x/y + 2*sin(x*y)/x; f f.trailing_coefficient(x) f.trailing_coefficient(y) f.trailing_coefficient(sin(x*y))
- trailing_coefficient(s)[source]¶
Return the trailing coefficient of s in
self
, i.e., the coefficient of the smallest power of s inself
.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.trailing_coefficient(x) 2*sin(x*y) sage: f.trailing_coefficient(y) x sage: f.trailing_coefficient(sin(x*y)) a*x + x*y + x/y + 100
>>> 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.trailing_coefficient(x) 2*sin(x*y) >>> f.trailing_coefficient(y) x >>> f.trailing_coefficient(sin(x*y)) a*x + x*y + x/y + 100
var('x,y,a') f = 100 + a*x + x^3*sin(x*y) + x*y + x/y + 2*sin(x*y)/x; f f.trailing_coefficient(x) f.trailing_coefficient(y) f.trailing_coefficient(sin(x*y))
- trig_expand(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 toTrue
.half_angles
– boolean (default:False
); ifTrue
, causes half-angles to be simplified awayplus
– boolean (default:True
); controls the sum rule. Expansion of sums (e.g. \(\sin(x + y)\)) will take place only ifplus
isTrue
.times
– boolean (default:True
); controls the product rule, expansion of products (e.g. \(\sin(2 x)\)) will take place only iftimes
isTrue
.
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)
sin(5*x).expand_trig() cos(2*x + var('y')).expand_trig()
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)
f = sin(sin(3*cos(2*x))*x) f.expand_trig() f.expand_trig(full=True) sin(2*x).expand_trig(times=False) sin(2*x).expand_trig(times=True) sin(2 + x).expand_trig(plus=False) sin(2 + x).expand_trig(plus=True) sin(x/2).expand_trig(half_angles=False) sin(x/2).expand_trig(half_angles=True)
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)
(x, k1, k2) = var('x, k1, k2') cos((k1-k2)*x).expand().expand_trig()
ALIAS:
trig_expand()
andexpand_trig()
are the same
- trig_reduce(var=None)[source]¶
Combine products and powers of trigonometric and hyperbolic sin’s and cos’s of x into those of multiples of x. It also tries to eliminate these functions when they occur in denominators.
INPUT:
self
– a symbolic expressionvar
– (default:None
) the variable which is used for these transformations. If not specified, all variables are used.
OUTPUT: a symbolic expression
EXAMPLES:
sage: y = var('y') sage: f = sin(x)*cos(x)^3+sin(y)^2 sage: f.reduce_trig() -1/2*cos(2*y) + 1/8*sin(4*x) + 1/4*sin(2*x) + 1/2
>>> from sage.all import * >>> y = var('y') >>> f = sin(x)*cos(x)**Integer(3)+sin(y)**Integer(2) >>> f.reduce_trig() -1/2*cos(2*y) + 1/8*sin(4*x) + 1/4*sin(2*x) + 1/2
y = var('y') f = sin(x)*cos(x)^3+sin(y)^2 f.reduce_trig()
To reduce only the expressions involving x we use optional parameter:
sage: f.reduce_trig(x) sin(y)^2 + 1/8*sin(4*x) + 1/4*sin(2*x)
>>> from sage.all import * >>> f.reduce_trig(x) sin(y)^2 + 1/8*sin(4*x) + 1/4*sin(2*x)
f.reduce_trig(x)
ALIAS:
trig_reduce()
andreduce_trig()
are the same
- trig_simplify(expand=True)[source]¶
Optionally expand and then employ identities such as \(\sin(x)^2 + \cos(x)^2 = 1\), \(\cosh(x)^2 - \sinh(x)^2 = 1\), \(\sin(x)\csc(x) = 1\), or \(\tanh(x)=\sinh(x)/\cosh(x)\) to simplify expressions containing tan, sec, etc., to sin, cos, sinh, cosh.
INPUT:
self
– symbolic expressionexpand
– boolean (default:True
); ifTrue
, expands trigonometric and hyperbolic functions of sums of angles and of multiple angles occurring inself
first. For best results,self
should be expanded. See alsoexpand_trig()
to get more controls on this expansion.
ALIAS:
trig_simplify()
andsimplify_trig()
are the sameEXAMPLES:
sage: f = sin(x)^2 + cos(x)^2; f cos(x)^2 + sin(x)^2 sage: f.simplify() cos(x)^2 + sin(x)^2 sage: f.simplify_trig() 1 sage: h = sin(x)*csc(x) sage: h.simplify_trig() 1 sage: k = tanh(x)*cosh(2*x) sage: k.simplify_trig() (2*sinh(x)^3 + sinh(x))/cosh(x)
>>> from sage.all import * >>> f = sin(x)**Integer(2) + cos(x)**Integer(2); f cos(x)^2 + sin(x)^2 >>> f.simplify() cos(x)^2 + sin(x)^2 >>> f.simplify_trig() 1 >>> h = sin(x)*csc(x) >>> h.simplify_trig() 1 >>> k = tanh(x)*cosh(Integer(2)*x) >>> k.simplify_trig() (2*sinh(x)^3 + sinh(x))/cosh(x)
f = sin(x)^2 + cos(x)^2; f f.simplify() f.simplify_trig() h = sin(x)*csc(x) h.simplify_trig() k = tanh(x)*cosh(2*x) k.simplify_trig()
In some cases we do not want to expand:
sage: f = tan(3*x) sage: f.simplify_trig() -(4*cos(x)^2 - 1)*sin(x)/(4*cos(x)*sin(x)^2 - cos(x)) sage: f.simplify_trig(False) sin(3*x)/cos(3*x)
>>> from sage.all import * >>> f = tan(Integer(3)*x) >>> f.simplify_trig() -(4*cos(x)^2 - 1)*sin(x)/(4*cos(x)*sin(x)^2 - cos(x)) >>> f.simplify_trig(False) sin(3*x)/cos(3*x)
f = tan(3*x) f.simplify_trig() f.simplify_trig(False)
- truncate()[source]¶
Given a power series or expression, return the corresponding expression without the big oh.
INPUT:
self
– a series as output by theseries()
command
OUTPUT: a symbolic expression
EXAMPLES:
sage: f = sin(x)/x^2 sage: f.truncate() sin(x)/x^2 sage: f.series(x,7) 1*x^(-1) + (-1/6)*x + 1/120*x^3 + (-1/5040)*x^5 + Order(x^7) sage: f.series(x,7).truncate() -1/5040*x^5 + 1/120*x^3 - 1/6*x + 1/x sage: f.series(x==1,3).truncate().expand() -2*x^2*cos(1) + 5/2*x^2*sin(1) + 5*x*cos(1) - 7*x*sin(1) - 3*cos(1) + 11/2*sin(1)
>>> from sage.all import * >>> f = sin(x)/x**Integer(2) >>> f.truncate() sin(x)/x^2 >>> f.series(x,Integer(7)) 1*x^(-1) + (-1/6)*x + 1/120*x^3 + (-1/5040)*x^5 + Order(x^7) >>> f.series(x,Integer(7)).truncate() -1/5040*x^5 + 1/120*x^3 - 1/6*x + 1/x >>> f.series(x==Integer(1),Integer(3)).truncate().expand() -2*x^2*cos(1) + 5/2*x^2*sin(1) + 5*x*cos(1) - 7*x*sin(1) - 3*cos(1) + 11/2*sin(1)
f = sin(x)/x^2 f.truncate() f.series(x,7) f.series(x,7).truncate() f.series(x==1,3).truncate().expand()
- unhold(exclude=None)[source]¶
Evaluates any held operations (with the
hold
keyword) in the expressionINPUT:
self
– an expression with held operationsexclude
– (default:None
) a list of operators to exclude from evaluation. Excluding arithmetic operators does not yet work (see Issue #10169).
OUTPUT:
A new expression with held operations, except those in
exclude
, evaluatedEXAMPLES:
sage: a = exp(I * pi, hold=True) sage: a e^(I*pi) sage: a.unhold() -1 sage: b = x.add(x, hold=True) sage: b x + x sage: b.unhold() 2*x sage: (a + b).unhold() 2*x - 1 sage: c = (x.mul(x, hold=True)).add(x.mul(x, hold=True), hold=True) sage: c x*x + x*x sage: c.unhold() 2*x^2 sage: sin(tan(0, hold=True), hold=True).unhold() 0 sage: sin(tan(0, hold=True), hold=True).unhold(exclude=[sin]) sin(0) sage: (e^sgn(0, hold=True)).unhold() 1 sage: (e^sgn(0, hold=True)).unhold(exclude=[exp]) e^0 sage: log(3).unhold() log(3)
>>> from sage.all import * >>> a = exp(I * pi, hold=True) >>> a e^(I*pi) >>> a.unhold() -1 >>> b = x.add(x, hold=True) >>> b x + x >>> b.unhold() 2*x >>> (a + b).unhold() 2*x - 1 >>> c = (x.mul(x, hold=True)).add(x.mul(x, hold=True), hold=True) >>> c x*x + x*x >>> c.unhold() 2*x^2 >>> sin(tan(Integer(0), hold=True), hold=True).unhold() 0 >>> sin(tan(Integer(0), hold=True), hold=True).unhold(exclude=[sin]) sin(0) >>> (e**sgn(Integer(0), hold=True)).unhold() 1 >>> (e**sgn(Integer(0), hold=True)).unhold(exclude=[exp]) e^0 >>> log(Integer(3)).unhold() log(3)
a = exp(I * pi, hold=True) a a.unhold() b = x.add(x, hold=True) b b.unhold() (a + b).unhold() c = (x.mul(x, hold=True)).add(x.mul(x, hold=True), hold=True) c c.unhold() sin(tan(0, hold=True), hold=True).unhold() sin(tan(0, hold=True), hold=True).unhold(exclude=[sin]) (e^sgn(0, hold=True)).unhold() (e^sgn(0, hold=True)).unhold(exclude=[exp]) log(3).unhold()
- unit(s)[source]¶
Return the unit of this expression when considered as a polynomial in
s
.See also
content()
,primitive_part()
, andunit_content_primitive()
.INPUT:
s
– a symbolic expression
OUTPUT:
The unit part of a polynomial as a symbolic expression. It is defined as the sign of the leading coefficient.
EXAMPLES:
sage: (2*x+4).unit(x) 1 sage: (-2*x+1).unit(x) -1 sage: (2*x+1/2).unit(x) 1 sage: var('y') y sage: (2*x - 4*sin(y)).unit(sin(y)) -1
>>> from sage.all import * >>> (Integer(2)*x+Integer(4)).unit(x) 1 >>> (-Integer(2)*x+Integer(1)).unit(x) -1 >>> (Integer(2)*x+Integer(1)/Integer(2)).unit(x) 1 >>> var('y') y >>> (Integer(2)*x - Integer(4)*sin(y)).unit(sin(y)) -1
(2*x+4).unit(x) (-2*x+1).unit(x) (2*x+1/2).unit(x) var('y') (2*x - 4*sin(y)).unit(sin(y))
- unit_content_primitive(s)[source]¶
Return the factorization into unit, content, and primitive part.
INPUT:
s
– a symbolic expression, usually a symbolic variable. The whole symbolic expressionself
will be considered as a univariate polynomial ins
.
OUTPUT:
A triple (unit, content, primitive polynomial)` containing the
unit
,content
, andprimitive polynomial
. Their product equalsself
.EXAMPLES:
sage: var('x,y') (x, y) sage: ex = 9*x^3*y+3*y sage: ex.unit_content_primitive(x) (1, 3*y, 3*x^3 + 1) sage: ex.unit_content_primitive(y) (1, 9*x^3 + 3, y)
>>> from sage.all import * >>> var('x,y') (x, y) >>> ex = Integer(9)*x**Integer(3)*y+Integer(3)*y >>> ex.unit_content_primitive(x) (1, 3*y, 3*x^3 + 1) >>> ex.unit_content_primitive(y) (1, 9*x^3 + 3, y)
var('x,y') ex = 9*x^3*y+3*y ex.unit_content_primitive(x) ex.unit_content_primitive(y)
- variables()[source]¶
Return sorted tuple of variables that occur in this expression.
EXAMPLES:
sage: (x,y,z) = var('x,y,z') sage: (x+y).variables() (x, y) sage: (2*x).variables() (x,) sage: (x^y).variables() (x, y) sage: sin(x+y^z).variables() (x, y, z)
>>> from sage.all import * >>> (x,y,z) = var('x,y,z') >>> (x+y).variables() (x, y) >>> (Integer(2)*x).variables() (x,) >>> (x**y).variables() (x, y) >>> sin(x+y**z).variables() (x, y, z)
(x,y,z) = var('x,y,z') (x+y).variables() (2*x).variables() (x^y).variables() sin(x+y^z).variables()
- zeta(hold=False)[source]¶
EXAMPLES:
sage: x, y = var('x, y') sage: (x/y).zeta() zeta(x/y) sage: SR(2).zeta() 1/6*pi^2 sage: SR(3).zeta() zeta(3) sage: SR(CDF(0,1)).zeta() # abs tol 1e-16 # needs sage.libs.pari 0.003300223685324103 - 0.4181554491413217*I sage: CDF(0,1).zeta() # abs tol 1e-16 # needs sage.libs.pari 0.003300223685324103 - 0.4181554491413217*I sage: plot(lambda x: SR(x).zeta(), -10,10).show(ymin=-3, ymax=3) # needs sage.plot
>>> from sage.all import * >>> x, y = var('x, y') >>> (x/y).zeta() zeta(x/y) >>> SR(Integer(2)).zeta() 1/6*pi^2 >>> SR(Integer(3)).zeta() zeta(3) >>> SR(CDF(Integer(0),Integer(1))).zeta() # abs tol 1e-16 # needs sage.libs.pari 0.003300223685324103 - 0.4181554491413217*I >>> CDF(Integer(0),Integer(1)).zeta() # abs tol 1e-16 # needs sage.libs.pari 0.003300223685324103 - 0.4181554491413217*I >>> plot(lambda x: SR(x).zeta(), -Integer(10),Integer(10)).show(ymin=-Integer(3), ymax=Integer(3)) # needs sage.plot
x, y = var('x, y') (x/y).zeta() SR(2).zeta() SR(3).zeta() SR(CDF(0,1)).zeta() # abs tol 1e-16 # needs sage.libs.pari CDF(0,1).zeta() # abs tol 1e-16 # needs sage.libs.pari plot(lambda x: SR(x).zeta(), -10,10).show(ymin=-3, ymax=3) # needs sage.plot
To prevent automatic evaluation use the
hold
argument:sage: SR(2).zeta(hold=True) zeta(2)
>>> from sage.all import * >>> SR(Integer(2)).zeta(hold=True) zeta(2)
SR(2).zeta(hold=True)
This also works using functional notation:
sage: zeta(2, hold=True) zeta(2) sage: zeta(2) 1/6*pi^2
>>> from sage.all import * >>> zeta(Integer(2), hold=True) zeta(2) >>> zeta(Integer(2)) 1/6*pi^2
zeta(2, hold=True) zeta(2)
To then evaluate again, we use
unhold()
:sage: a = SR(2).zeta(hold=True); a.unhold() 1/6*pi^2
>>> from sage.all import * >>> a = SR(Integer(2)).zeta(hold=True); a.unhold() 1/6*pi^2
a = SR(2).zeta(hold=True); a.unhold()
- class sage.symbolic.expression.ExpressionIterator¶
Bases:
object
- class sage.symbolic.expression.OperandsWrapper[source]¶
Bases:
SageObject
Operands wrapper for symbolic expressions.
EXAMPLES:
sage: x,y,z = var('x,y,z') sage: e = x + x*y + z^y + 3*y*z; e x*y + 3*y*z + x + z^y sage: e.op[1] 3*y*z sage: e.op[1,1] z sage: e.op[-1] z^y sage: e.op[1:] [3*y*z, x, z^y] sage: e.op[:2] [x*y, 3*y*z] sage: e.op[-2:] [x, z^y] sage: e.op[:-2] [x*y, 3*y*z] sage: e.op[-5] Traceback (most recent call last): ... IndexError: operand index out of range, got -5, expect between -4 and 3 sage: e.op[5] Traceback (most recent call last): ... IndexError: operand index out of range, got 5, expect between -4 and 3 sage: e.op[1,1,0] Traceback (most recent call last): ... TypeError: expressions containing only a numeric coefficient, constant or symbol have no operands sage: e.op[:1.5] Traceback (most recent call last): ... TypeError: slice indices must be integers or None or have an __index__ method sage: e.op[:2:1.5] Traceback (most recent call last): ... ValueError: step value must be an integer
>>> from sage.all import * >>> x,y,z = var('x,y,z') >>> e = x + x*y + z**y + Integer(3)*y*z; e x*y + 3*y*z + x + z^y >>> e.op[Integer(1)] 3*y*z >>> e.op[Integer(1),Integer(1)] z >>> e.op[-Integer(1)] z^y >>> e.op[Integer(1):] [3*y*z, x, z^y] >>> e.op[:Integer(2)] [x*y, 3*y*z] >>> e.op[-Integer(2):] [x, z^y] >>> e.op[:-Integer(2)] [x*y, 3*y*z] >>> e.op[-Integer(5)] Traceback (most recent call last): ... IndexError: operand index out of range, got -5, expect between -4 and 3 >>> e.op[Integer(5)] Traceback (most recent call last): ... IndexError: operand index out of range, got 5, expect between -4 and 3 >>> e.op[Integer(1),Integer(1),Integer(0)] Traceback (most recent call last): ... TypeError: expressions containing only a numeric coefficient, constant or symbol have no operands >>> e.op[:RealNumber('1.5')] Traceback (most recent call last): ... TypeError: slice indices must be integers or None or have an __index__ method >>> e.op[:Integer(2):RealNumber('1.5')] Traceback (most recent call last): ... ValueError: step value must be an integer
x,y,z = var('x,y,z') e = x + x*y + z^y + 3*y*z; e e.op[1] e.op[1,1] e.op[-1] e.op[1:] e.op[:2] e.op[-2:] e.op[:-2] e.op[-5] e.op[5] e.op[1,1,0] e.op[:1.5] e.op[:2:1.5]
- class sage.symbolic.expression.PynacConstant¶
Bases:
object
- expression()[source]¶
Return this constant as an Expression.
EXAMPLES:
sage: from sage.symbolic.expression import PynacConstant sage: f = PynacConstant('foo', 'foo', 'real') sage: f + 2 Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: '<class 'sage.symbolic.expression.PynacConstant'>' and 'Integer Ring' sage: foo = f.expression(); foo foo sage: foo + 2 foo + 2
>>> from sage.all import * >>> from sage.symbolic.expression import PynacConstant >>> f = PynacConstant('foo', 'foo', 'real') >>> f + Integer(2) Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: '<class 'sage.symbolic.expression.PynacConstant'>' and 'Integer Ring' >>> foo = f.expression(); foo foo >>> foo + Integer(2) foo + 2
from sage.symbolic.expression import PynacConstant f = PynacConstant('foo', 'foo', 'real') f + 2 foo = f.expression(); foo foo + 2
- name()[source]¶
Return the name of this constant.
EXAMPLES:
sage: from sage.symbolic.expression import PynacConstant sage: f = PynacConstant('foo', 'foo', 'real') sage: f.name() 'foo'
>>> from sage.all import * >>> from sage.symbolic.expression import PynacConstant >>> f = PynacConstant('foo', 'foo', 'real') >>> f.name() 'foo'
from sage.symbolic.expression import PynacConstant f = PynacConstant('foo', 'foo', 'real') f.name()
- serial()[source]¶
Return the underlying Pynac serial for this constant.
EXAMPLES:
sage: from sage.symbolic.expression import PynacConstant sage: f = PynacConstant('foo', 'foo', 'real') sage: f.serial() #random 15
>>> from sage.all import * >>> from sage.symbolic.expression import PynacConstant >>> f = PynacConstant('foo', 'foo', 'real') >>> f.serial() #random 15
from sage.symbolic.expression import PynacConstant f = PynacConstant('foo', 'foo', 'real') f.serial() #random
- class sage.symbolic.expression.SubstitutionMap[source]¶
Bases:
SageObject
- apply_to(expr, options)[source]¶
Apply the substitution to a symbolic expression.
EXAMPLES:
sage: from sage.symbolic.expression import make_map sage: subs = make_map({x:x+1}) sage: subs.apply_to(x^2, 0) (x + 1)^2
>>> from sage.all import * >>> from sage.symbolic.expression import make_map >>> subs = make_map({x:x+Integer(1)}) >>> subs.apply_to(x**Integer(2), Integer(0)) (x + 1)^2
from sage.symbolic.expression import make_map subs = make_map({x:x+1}) subs.apply_to(x^2, 0)
- class sage.symbolic.expression.SymbolicSeries[source]¶
Bases:
Expression
Trivial constructor.
EXAMPLES:
sage: loads(dumps((x+x^3).series(x,2))) 1*x + Order(x^2)
>>> from sage.all import * >>> loads(dumps((x+x**Integer(3)).series(x,Integer(2)))) 1*x + Order(x^2)
loads(dumps((x+x^3).series(x,2)))
- coefficients(x=None, sparse=True)[source]¶
Return the coefficients of this symbolic series as a list of pairs.
INPUT:
x
– (optional) variablesparse
– boolean (default:True
); ifFalse
return a list with as much entries as the order of the series
OUTPUT: depending on the value of
sparse
,A list of pairs
(expr, n)
, whereexpr
is a symbolic expression andn
is a power (sparse=True
, default)A list of expressions where the
n
-th element is the coefficient ofx^n
whenself
is seen as polynomial inx
(sparse=False
).
EXAMPLES:
sage: s = (1/(1-x)).series(x,6); s 1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6) sage: s.coefficients() [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]] sage: s.coefficients(x, sparse=False) [1, 1, 1, 1, 1, 1] sage: x,y = var("x,y") sage: s = (1/(1-y*x-x)).series(x,3); s 1 + (y + 1)*x + ((y + 1)^2)*x^2 + Order(x^3) sage: s.coefficients(x, sparse=False) [1, y + 1, (y + 1)^2]
>>> from sage.all import * >>> s = (Integer(1)/(Integer(1)-x)).series(x,Integer(6)); s 1 + 1*x + 1*x^2 + 1*x^3 + 1*x^4 + 1*x^5 + Order(x^6) >>> s.coefficients() [[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5]] >>> s.coefficients(x, sparse=False) [1, 1, 1, 1, 1, 1] >>> x,y = var("x,y") >>> s = (Integer(1)/(Integer(1)-y*x-x)).series(x,Integer(3)); s 1 + (y + 1)*x + ((y + 1)^2)*x^2 + Order(x^3) >>> s.coefficients(x, sparse=False) [1, y + 1, (y + 1)^2]
s = (1/(1-x)).series(x,6); s s.coefficients() s.coefficients(x, sparse=False) x,y = var("x,y") s = (1/(1-y*x-x)).series(x,3); s s.coefficients(x, sparse=False)
- default_variable()[source]¶
Return the expansion variable of this symbolic series.
EXAMPLES:
sage: s = (1/(1-x)).series(x,3); s 1 + 1*x + 1*x^2 + Order(x^3) sage: s.default_variable() x
>>> from sage.all import * >>> s = (Integer(1)/(Integer(1)-x)).series(x,Integer(3)); s 1 + 1*x + 1*x^2 + Order(x^3) >>> s.default_variable() x
s = (1/(1-x)).series(x,3); s s.default_variable()
- is_terminating_series()[source]¶
Return
True
if the series is without order term.A series is terminating if it can be represented exactly, without requiring an order term. You can explicitly request terminating series by setting the order to positive infinity.
OUTPUT: boolean;
True
if the series has no order termEXAMPLES:
sage: (x^5+x^2+1).series(x, +oo) 1 + 1*x^2 + 1*x^5 sage: (x^5+x^2+1).series(x,+oo).is_terminating_series() True sage: SR(5).is_terminating_series() False sage: exp(x).series(x,10).is_terminating_series() False
>>> from sage.all import * >>> (x**Integer(5)+x**Integer(2)+Integer(1)).series(x, +oo) 1 + 1*x^2 + 1*x^5 >>> (x**Integer(5)+x**Integer(2)+Integer(1)).series(x,+oo).is_terminating_series() True >>> SR(Integer(5)).is_terminating_series() False >>> exp(x).series(x,Integer(10)).is_terminating_series() False
(x^5+x^2+1).series(x, +oo) (x^5+x^2+1).series(x,+oo).is_terminating_series() SR(5).is_terminating_series() exp(x).series(x,10).is_terminating_series()
- power_series(base_ring)[source]¶
Return the algebraic power series associated to this symbolic series.
The coefficients must be coercible to the base ring.
EXAMPLES:
sage: ex = (gamma(1-x)).series(x,3); ex 1 + euler_gamma*x + (1/2*euler_gamma^2 + 1/12*pi^2)*x^2 + Order(x^3) sage: g = ex.power_series(SR); g 1 + euler_gamma*x + (1/2*euler_gamma^2 + 1/12*pi^2)*x^2 + O(x^3) sage: g.parent() Power Series Ring in x over Symbolic Ring
>>> from sage.all import * >>> ex = (gamma(Integer(1)-x)).series(x,Integer(3)); ex 1 + euler_gamma*x + (1/2*euler_gamma^2 + 1/12*pi^2)*x^2 + Order(x^3) >>> g = ex.power_series(SR); g 1 + euler_gamma*x + (1/2*euler_gamma^2 + 1/12*pi^2)*x^2 + O(x^3) >>> g.parent() Power Series Ring in x over Symbolic Ring
ex = (gamma(1-x)).series(x,3); ex g = ex.power_series(SR); g g.parent()
- truncate()[source]¶
Given a power series or expression, return the corresponding expression without the big oh.
OUTPUT: a symbolic expression
EXAMPLES:
sage: f = sin(x)/x^2 sage: f.truncate() sin(x)/x^2 sage: f.series(x,7) 1*x^(-1) + (-1/6)*x + 1/120*x^3 + (-1/5040)*x^5 + Order(x^7) sage: f.series(x,7).truncate() -1/5040*x^5 + 1/120*x^3 - 1/6*x + 1/x sage: f.series(x==1,3).truncate().expand() -2*x^2*cos(1) + 5/2*x^2*sin(1) + 5*x*cos(1) - 7*x*sin(1) - 3*cos(1) + 11/2*sin(1)
>>> from sage.all import * >>> f = sin(x)/x**Integer(2) >>> f.truncate() sin(x)/x^2 >>> f.series(x,Integer(7)) 1*x^(-1) + (-1/6)*x + 1/120*x^3 + (-1/5040)*x^5 + Order(x^7) >>> f.series(x,Integer(7)).truncate() -1/5040*x^5 + 1/120*x^3 - 1/6*x + 1/x >>> f.series(x==Integer(1),Integer(3)).truncate().expand() -2*x^2*cos(1) + 5/2*x^2*sin(1) + 5*x*cos(1) - 7*x*sin(1) - 3*cos(1) + 11/2*sin(1)
f = sin(x)/x^2 f.truncate() f.series(x,7) f.series(x,7).truncate() f.series(x==1,3).truncate().expand()
- sage.symbolic.expression.call_registered_function(serial, nargs, args, hold, allow_numeric_result, result_parent)[source]¶
Call a function registered with Pynac (GiNaC).
INPUT:
serial
– serial number of the functionnargs
– declared number of args (0 is variadic)args
– list of arguments to pass to the function; each must be anExpression
hold
– whether to leave the call unevaluatedallow_numeric_result
– ifTrue
, keep numeric results numeric; ifFalse
, make all results symbolic expressionsresult_parent
– an instance ofSymbolicRing
EXAMPLES:
sage: from sage.symbolic.expression import find_registered_function, call_registered_function sage: s_arctan = find_registered_function('arctan', 1) sage: call_registered_function(s_arctan, 1, [SR(1)], False, True, SR) 1/4*pi sage: call_registered_function(s_arctan, 1, [SR(1)], True, True, SR) arctan(1) sage: call_registered_function(s_arctan, 1, [SR(0)], False, True, SR) 0 sage: call_registered_function(s_arctan, 1, [SR(0)], False, True, SR).parent() Integer Ring sage: call_registered_function(s_arctan, 1, [SR(0)], False, False, SR).parent() Symbolic Ring
>>> from sage.all import * >>> from sage.symbolic.expression import find_registered_function, call_registered_function >>> s_arctan = find_registered_function('arctan', Integer(1)) >>> call_registered_function(s_arctan, Integer(1), [SR(Integer(1))], False, True, SR) 1/4*pi >>> call_registered_function(s_arctan, Integer(1), [SR(Integer(1))], True, True, SR) arctan(1) >>> call_registered_function(s_arctan, Integer(1), [SR(Integer(0))], False, True, SR) 0 >>> call_registered_function(s_arctan, Integer(1), [SR(Integer(0))], False, True, SR).parent() Integer Ring >>> call_registered_function(s_arctan, Integer(1), [SR(Integer(0))], False, False, SR).parent() Symbolic Ring
from sage.symbolic.expression import find_registered_function, call_registered_function s_arctan = find_registered_function('arctan', 1) call_registered_function(s_arctan, 1, [SR(1)], False, True, SR) call_registered_function(s_arctan, 1, [SR(1)], True, True, SR) call_registered_function(s_arctan, 1, [SR(0)], False, True, SR) call_registered_function(s_arctan, 1, [SR(0)], False, True, SR).parent() call_registered_function(s_arctan, 1, [SR(0)], False, False, SR).parent()
- sage.symbolic.expression.doublefactorial(n)[source]¶
The double factorial combinatorial function:
n!! == n * (n-2) * (n-4) * … * ({1|2}) with 0!! == (-1)!! == 1.
INPUT:
n
– integer>= 1
EXAMPLES:
sage: from sage.symbolic.expression import doublefactorial sage: doublefactorial(-1) 1 sage: doublefactorial(0) 1 sage: doublefactorial(1) 1 sage: doublefactorial(5) 15 sage: doublefactorial(20) 3715891200 sage: prod( [20,18,..,2] ) 3715891200
>>> from sage.all import * >>> from sage.symbolic.expression import doublefactorial >>> doublefactorial(-Integer(1)) 1 >>> doublefactorial(Integer(0)) 1 >>> doublefactorial(Integer(1)) 1 >>> doublefactorial(Integer(5)) 15 >>> doublefactorial(Integer(20)) 3715891200 >>> prod( (ellipsis_range(Integer(20),Integer(18),Ellipsis,Integer(2))) ) 3715891200
from sage.symbolic.expression import doublefactorial doublefactorial(-1) doublefactorial(0) doublefactorial(1) doublefactorial(5) doublefactorial(20) prod( [20,18,..,2] )
- sage.symbolic.expression.find_registered_function(name, nargs)[source]¶
Look up a function registered with Pynac (GiNaC).
Raise a
ValueError
if the function is not registered.OUTPUT: serial number of the function, for use in
call_registered_function()
EXAMPLES:
sage: from sage.symbolic.expression import find_registered_function sage: find_registered_function('arctan', 1) # random 19 sage: find_registered_function('archenemy', 1) Traceback (most recent call last): ... ValueError: cannot find GiNaC function with name archenemy and 1 arguments
>>> from sage.all import * >>> from sage.symbolic.expression import find_registered_function >>> find_registered_function('arctan', Integer(1)) # random 19 >>> find_registered_function('archenemy', Integer(1)) Traceback (most recent call last): ... ValueError: cannot find GiNaC function with name archenemy and 1 arguments
from sage.symbolic.expression import find_registered_function find_registered_function('arctan', 1) # random find_registered_function('archenemy', 1)
- sage.symbolic.expression.get_fn_serial()[source]¶
Return the overall size of the Pynac function registry which corresponds to the last serial value plus one.
EXAMPLES:
sage: from sage.symbolic.expression import get_fn_serial sage: from sage.symbolic.function import get_sfunction_from_serial sage: get_fn_serial() > 125 True sage: print(get_sfunction_from_serial(get_fn_serial())) None sage: get_sfunction_from_serial(get_fn_serial() - 1) is not None True
>>> from sage.all import * >>> from sage.symbolic.expression import get_fn_serial >>> from sage.symbolic.function import get_sfunction_from_serial >>> get_fn_serial() > Integer(125) True >>> print(get_sfunction_from_serial(get_fn_serial())) None >>> get_sfunction_from_serial(get_fn_serial() - Integer(1)) is not None True
from sage.symbolic.expression import get_fn_serial from sage.symbolic.function import get_sfunction_from_serial get_fn_serial() > 125 print(get_sfunction_from_serial(get_fn_serial())) get_sfunction_from_serial(get_fn_serial() - 1) is not None
- sage.symbolic.expression.get_ginac_serial()[source]¶
Number of C++ level functions defined by GiNaC. (Defined mainly for testing.)
EXAMPLES:
sage: sage.symbolic.expression.get_ginac_serial() >= 35 True
>>> from sage.all import * >>> sage.symbolic.expression.get_ginac_serial() >= Integer(35) True
sage.symbolic.expression.get_ginac_serial() >= 35
- sage.symbolic.expression.get_sfunction_from_hash(myhash)[source]¶
Return an already created
SymbolicFunction
given the hash.EXAMPLES:
sage: from sage.symbolic.expression import get_sfunction_from_hash sage: get_sfunction_from_hash(1) # random
>>> from sage.all import * >>> from sage.symbolic.expression import get_sfunction_from_hash >>> get_sfunction_from_hash(Integer(1)) # random
from sage.symbolic.expression import get_sfunction_from_hash get_sfunction_from_hash(1) # random
- sage.symbolic.expression.get_sfunction_from_serial(serial)[source]¶
Return an already created
SymbolicFunction
given the serial.These are stored in the dictionary
sfunction_serial_dict
.EXAMPLES:
sage: from sage.symbolic.function import get_sfunction_from_serial sage: get_sfunction_from_serial(65) #random f
>>> from sage.all import * >>> from sage.symbolic.function import get_sfunction_from_serial >>> get_sfunction_from_serial(Integer(65)) #random f
from sage.symbolic.function import get_sfunction_from_serial get_sfunction_from_serial(65) #random
- class sage.symbolic.expression.hold_class[source]¶
Bases:
object
Instances of this class can be used with Python \(with\).
EXAMPLES:
sage: with hold: ....: tan(1/12*pi) ....: tan(1/12*pi) sage: tan(1/12*pi) -sqrt(3) + 2 sage: with hold: ....: 2^5 ....: 32 sage: with hold: ....: SR(2)^5 ....: 2^5 sage: with hold: ....: t=tan(1/12*pi) ....: sage: t tan(1/12*pi) sage: t.unhold() -sqrt(3) + 2
>>> from sage.all import * >>> with hold: ... tan(Integer(1)/Integer(12)*pi) ....: tan(1/12*pi) >>> tan(Integer(1)/Integer(12)*pi) -sqrt(3) + 2 >>> with hold: ... Integer(2)**Integer(5) ....: 32 >>> with hold: ... SR(Integer(2))**Integer(5) ....: 2^5 >>> with hold: ... t=tan(Integer(1)/Integer(12)*pi) ....: >>> t tan(1/12*pi) >>> t.unhold() -sqrt(3) + 2
with hold: tan(1/12*pi) tan(1/12*pi) with hold: 2^5 with hold: SR(2)^5 with hold: t=tan(1/12*pi) t t.unhold()
- sage.symbolic.expression.init_function_table()[source]¶
Initialize the function pointer table in Pynac. This must be called before Pynac is used; otherwise, there will be segfaults.
- sage.symbolic.expression.init_pynac_I()[source]¶
Initialize the numeric
I
object in pynac. We use the generator ofQQ(i)
.EXAMPLES:
sage: from sage.symbolic.constants import I as symbolic_I sage: symbolic_I I sage: symbolic_I^2 -1
>>> from sage.all import * >>> from sage.symbolic.constants import I as symbolic_I >>> symbolic_I I >>> symbolic_I**Integer(2) -1
from sage.symbolic.constants import I as symbolic_I symbolic_I symbolic_I^2
Note that conversions to real fields will give
TypeError
:sage: float(symbolic_I) Traceback (most recent call last): ... TypeError: unable to simplify to float approximation sage: gp(symbolic_I) I sage: RR(symbolic_I) Traceback (most recent call last): ... TypeError: unable to convert '1.00000000000000*I' to a real number
>>> from sage.all import * >>> float(symbolic_I) Traceback (most recent call last): ... TypeError: unable to simplify to float approximation >>> gp(symbolic_I) I >>> RR(symbolic_I) Traceback (most recent call last): ... TypeError: unable to convert '1.00000000000000*I' to a real number
float(symbolic_I) gp(symbolic_I) RR(symbolic_I)
We can convert to complex fields:
sage: C = ComplexField(200); C Complex Field with 200 bits of precision sage: C(symbolic_I) 1.0000000000000000000000000000000000000000000000000000000000*I sage: symbolic_I._complex_mpfr_field_(ComplexField(53)) 1.00000000000000*I sage: symbolic_I._complex_double_(CDF) 1.0*I sage: CDF(symbolic_I) 1.0*I sage: z = symbolic_I + symbolic_I; z 2*I sage: C(z) 2.0000000000000000000000000000000000000000000000000000000000*I sage: 1e8*symbolic_I 1.00000000000000e8*I sage: complex(symbolic_I) 1j sage: QQbar(symbolic_I) I sage: abs(symbolic_I) 1 sage: symbolic_I.minpoly() x^2 + 1 sage: maxima(2*symbolic_I) 2*%i
>>> from sage.all import * >>> C = ComplexField(Integer(200)); C Complex Field with 200 bits of precision >>> C(symbolic_I) 1.0000000000000000000000000000000000000000000000000000000000*I >>> symbolic_I._complex_mpfr_field_(ComplexField(Integer(53))) 1.00000000000000*I >>> symbolic_I._complex_double_(CDF) 1.0*I >>> CDF(symbolic_I) 1.0*I >>> z = symbolic_I + symbolic_I; z 2*I >>> C(z) 2.0000000000000000000000000000000000000000000000000000000000*I >>> RealNumber('1e8')*symbolic_I 1.00000000000000e8*I >>> complex(symbolic_I) 1j >>> QQbar(symbolic_I) I >>> abs(symbolic_I) 1 >>> symbolic_I.minpoly() x^2 + 1 >>> maxima(Integer(2)*symbolic_I) 2*%i
C = ComplexField(200); C C(symbolic_I) symbolic_I._complex_mpfr_field_(ComplexField(53)) symbolic_I._complex_double_(CDF) CDF(symbolic_I) z = symbolic_I + symbolic_I; z C(z) 1e8*symbolic_I complex(symbolic_I) QQbar(symbolic_I) abs(symbolic_I) symbolic_I.minpoly() maxima(2*symbolic_I)
- sage.symbolic.expression.is_SymbolicEquation(x)[source]¶
Return
True
ifx
is a symbolic equation.This function is deprecated.
EXAMPLES:
The following two examples are symbolic equations:
sage: from sage.symbolic.expression import is_SymbolicEquation sage: is_SymbolicEquation(sin(x) == x) doctest:warning... DeprecationWarning: is_SymbolicEquation is deprecated; use 'isinstance(x, sage.structure.element.Expression) and x.is_relational()' instead See https://github.com/sagemath/sage/issues/35505 for details. True sage: is_SymbolicEquation(sin(x) < x) True sage: is_SymbolicEquation(x) False
>>> from sage.all import * >>> from sage.symbolic.expression import is_SymbolicEquation >>> is_SymbolicEquation(sin(x) == x) doctest:warning... DeprecationWarning: is_SymbolicEquation is deprecated; use 'isinstance(x, sage.structure.element.Expression) and x.is_relational()' instead See https://github.com/sagemath/sage/issues/35505 for details. True >>> is_SymbolicEquation(sin(x) < x) True >>> is_SymbolicEquation(x) False
from sage.symbolic.expression import is_SymbolicEquation is_SymbolicEquation(sin(x) == x) is_SymbolicEquation(sin(x) < x) is_SymbolicEquation(x)
This is not, since
2==3
evaluates to the booleanFalse
:sage: is_SymbolicEquation(2 == 3) False
>>> from sage.all import * >>> is_SymbolicEquation(Integer(2) == Integer(3)) False
is_SymbolicEquation(2 == 3)
However here since both 2 and 3 are coerced to be symbolic, we obtain a symbolic equation:
sage: is_SymbolicEquation(SR(2) == SR(3)) True
>>> from sage.all import * >>> is_SymbolicEquation(SR(Integer(2)) == SR(Integer(3))) True
is_SymbolicEquation(SR(2) == SR(3))
- sage.symbolic.expression.make_map(subs_dict)[source]¶
Construct a new substitution map.
OUTPUT: a new
SubstitutionMap
for doctestingEXAMPLES:
sage: from sage.symbolic.expression import make_map sage: make_map({x:x+1}) SubsMap
>>> from sage.all import * >>> from sage.symbolic.expression import make_map >>> make_map({x:x+Integer(1)}) SubsMap
from sage.symbolic.expression import make_map make_map({x:x+1})
- sage.symbolic.expression.math_sorted(expressions)[source]¶
Sort a list of symbolic numbers in the “Mathematics” order.
INPUT:
expressions
– list/tuple/iterable of symbolic expressions, or something that can be converted to one
OUTPUT:
The list sorted by ascending (real) value. If an entry does not define a real value (or plus/minus infinity), or if the comparison is not known, a
ValueError
is raised.EXAMPLES:
sage: from sage.symbolic.expression import math_sorted sage: math_sorted([SR(1), SR(e), SR(pi), sqrt(2)]) [1, sqrt(2), e, pi]
>>> from sage.all import * >>> from sage.symbolic.expression import math_sorted >>> math_sorted([SR(Integer(1)), SR(e), SR(pi), sqrt(Integer(2))]) [1, sqrt(2), e, pi]
from sage.symbolic.expression import math_sorted math_sorted([SR(1), SR(e), SR(pi), sqrt(2)])
- sage.symbolic.expression.mixed_order(lhs, rhs)[source]¶
Comparison in the mixed order
INPUT:
lhs
,rhs
– two symbolic expressions or something that can be converted to one
OUTPUT:
Either \(-1\), \(0\), or \(+1\) indicating the comparison. An exception is raised if the arguments cannot be converted into the symbolic ring.
EXAMPLES:
sage: from sage.symbolic.expression import mixed_order sage: mixed_order(1, oo) -1 sage: mixed_order(e, oo) -1 sage: mixed_order(pi, oo) -1 sage: mixed_order(1, sqrt(2)) -1 sage: mixed_order(x + x^2, x*(x+1)) -1
>>> from sage.all import * >>> from sage.symbolic.expression import mixed_order >>> mixed_order(Integer(1), oo) -1 >>> mixed_order(e, oo) -1 >>> mixed_order(pi, oo) -1 >>> mixed_order(Integer(1), sqrt(Integer(2))) -1 >>> mixed_order(x + x**Integer(2), x*(x+Integer(1))) -1
from sage.symbolic.expression import mixed_order mixed_order(1, oo) mixed_order(e, oo) mixed_order(pi, oo) mixed_order(1, sqrt(2)) mixed_order(x + x^2, x*(x+1))
Check that Issue #12967 is fixed:
sage: mixed_order(SR(oo), sqrt(2)) 1
>>> from sage.all import * >>> mixed_order(SR(oo), sqrt(Integer(2))) 1
mixed_order(SR(oo), sqrt(2))
Ensure that Issue #32185 is fixed:
sage: mixed_order(pi, 0) 1 sage: mixed_order(golden_ratio, 0) 1 sage: mixed_order(log2, 0) 1
>>> from sage.all import * >>> mixed_order(pi, Integer(0)) 1 >>> mixed_order(golden_ratio, Integer(0)) 1 >>> mixed_order(log2, Integer(0)) 1
mixed_order(pi, 0) mixed_order(golden_ratio, 0) mixed_order(log2, 0)
- sage.symbolic.expression.mixed_sorted(expressions)[source]¶
Sort a list of symbolic numbers in the “Mixed” order.
INPUT:
expressions
– list/tuple/iterable of symbolic expressions, or something that can be converted to one
OUTPUT:
In the list the numeric values are sorted by ascending (real) value, and the expressions with variables according to print order. If an entry does not define a real value (or plus/minus infinity), or if the comparison is not known, a
ValueError
is raised.EXAMPLES:
sage: from sage.symbolic.expression import mixed_sorted sage: mixed_sorted([SR(1), SR(e), SR(pi), sqrt(2), x, sqrt(x), sin(1/x)]) [1, sqrt(2), e, pi, sin(1/x), sqrt(x), x]
>>> from sage.all import * >>> from sage.symbolic.expression import mixed_sorted >>> mixed_sorted([SR(Integer(1)), SR(e), SR(pi), sqrt(Integer(2)), x, sqrt(x), sin(Integer(1)/x)]) [1, sqrt(2), e, pi, sin(1/x), sqrt(x), x]
from sage.symbolic.expression import mixed_sorted mixed_sorted([SR(1), SR(e), SR(pi), sqrt(2), x, sqrt(x), sin(1/x)])
- sage.symbolic.expression.new_Expression(parent, x)[source]¶
Convert
x
into the symbolic expression ringparent
.This is the element constructor.
EXAMPLES:
sage: a = SR(-3/4); a -3/4 sage: type(a) <class 'sage.symbolic.expression.Expression'> sage: a.parent() Symbolic Ring sage: K.<a> = QuadraticField(-3) # needs sage.rings.number_field sage: a + sin(x) # needs sage.rings.number_field I*sqrt(3) + sin(x) sage: x = var('x'); y0,y1 = PolynomialRing(ZZ,2,'y').gens() sage: x+y0/y1 x + y0/y1 sage: x.subs(x=y0/y1) y0/y1 sage: x + int(1) x + 1
>>> from sage.all import * >>> a = SR(-Integer(3)/Integer(4)); a -3/4 >>> type(a) <class 'sage.symbolic.expression.Expression'> >>> a.parent() Symbolic Ring >>> K = QuadraticField(-Integer(3), names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.number_field >>> a + sin(x) # needs sage.rings.number_field I*sqrt(3) + sin(x) >>> x = var('x'); y0,y1 = PolynomialRing(ZZ,Integer(2),'y').gens() >>> x+y0/y1 x + y0/y1 >>> x.subs(x=y0/y1) y0/y1 >>> x + int(Integer(1)) x + 1
a = SR(-3/4); a type(a) a.parent() K.<a> = QuadraticField(-3) # needs sage.rings.number_field a + sin(x) # needs sage.rings.number_field x = var('x'); y0,y1 = PolynomialRing(ZZ,2,'y').gens() x+y0/y1 x.subs(x=y0/y1) x + int(1)
- sage.symbolic.expression.new_Expression_from_pyobject(parent, x, force=True, recursive=True)[source]¶
Wrap the given Python object in a symbolic expression even if it cannot be coerced to the Symbolic Ring.
INPUT:
parent
– a symbolic ringx
– a Python objectforce
– boolean (default:True
); ifTrue
, the Python object is taken as is without attempting coercion or list traversalrecursive
– boolean (default:True
); disables recursive traversal of lists
EXAMPLES:
sage: t = SR._force_pyobject(QQ); t # indirect doctest Rational Field sage: type(t) <class 'sage.symbolic.expression.Expression'> sage: from sage.symbolic.expression import new_Expression_from_pyobject sage: t = new_Expression_from_pyobject(SR, 17); t 17 sage: type(t) <class 'sage.symbolic.expression.Expression'> sage: t2 = new_Expression_from_pyobject(SR, t, False); t2 17 sage: t2 is t True sage: tt = new_Expression_from_pyobject(SR, t, True); tt 17 sage: tt is t False
>>> from sage.all import * >>> t = SR._force_pyobject(QQ); t # indirect doctest Rational Field >>> type(t) <class 'sage.symbolic.expression.Expression'> >>> from sage.symbolic.expression import new_Expression_from_pyobject >>> t = new_Expression_from_pyobject(SR, Integer(17)); t 17 >>> type(t) <class 'sage.symbolic.expression.Expression'> >>> t2 = new_Expression_from_pyobject(SR, t, False); t2 17 >>> t2 is t True >>> tt = new_Expression_from_pyobject(SR, t, True); tt 17 >>> tt is t False
t = SR._force_pyobject(QQ); t # indirect doctest type(t) from sage.symbolic.expression import new_Expression_from_pyobject t = new_Expression_from_pyobject(SR, 17); t type(t) t2 = new_Expression_from_pyobject(SR, t, False); t2 t2 is t tt = new_Expression_from_pyobject(SR, t, True); tt tt is t
- sage.symbolic.expression.new_Expression_symbol(parent, name=None, latex_name=None, domain=None)[source]¶
Look up or create a symbol.
EXAMPLES:
sage: t0 = SR.symbol("t0") sage: t0.conjugate() conjugate(t0) sage: t1 = SR.symbol("t1", domain='real') sage: t1.conjugate() t1 sage: t0.abs() abs(t0) sage: t0_2 = SR.symbol("t0", domain='positive') sage: t0_2.abs() t0 sage: bool(t0_2 == t0) True sage: t0.conjugate() t0 sage: SR.symbol() # temporary variable symbol...
>>> from sage.all import * >>> t0 = SR.symbol("t0") >>> t0.conjugate() conjugate(t0) >>> t1 = SR.symbol("t1", domain='real') >>> t1.conjugate() t1 >>> t0.abs() abs(t0) >>> t0_2 = SR.symbol("t0", domain='positive') >>> t0_2.abs() t0 >>> bool(t0_2 == t0) True >>> t0.conjugate() t0 >>> SR.symbol() # temporary variable symbol...
t0 = SR.symbol("t0") t0.conjugate() t1 = SR.symbol("t1", domain='real') t1.conjugate() t0.abs() t0_2 = SR.symbol("t0", domain='positive') t0_2.abs() bool(t0_2 == t0) t0.conjugate() SR.symbol() # temporary variable
- sage.symbolic.expression.new_Expression_wild(parent, n=0)[source]¶
Return the n-th wild-card for pattern matching and substitution.
INPUT:
parent
– a symbolic ringn
– nonnegative integer
OUTPUT: n-th wildcard expression
EXAMPLES:
sage: x,y = var('x,y') sage: w0 = SR.wild(0); w1 = SR.wild(1) sage: pattern = sin(x)*w0*w1^2; pattern $1^2*$0*sin(x) sage: f = atan(sin(x)*3*x^2); f arctan(3*x^2*sin(x)) sage: f.has(pattern) True sage: f.subs(pattern == x^2) arctan(x^2)
>>> from sage.all import * >>> x,y = var('x,y') >>> w0 = SR.wild(Integer(0)); w1 = SR.wild(Integer(1)) >>> pattern = sin(x)*w0*w1**Integer(2); pattern $1^2*$0*sin(x) >>> f = atan(sin(x)*Integer(3)*x**Integer(2)); f arctan(3*x^2*sin(x)) >>> f.has(pattern) True >>> f.subs(pattern == x**Integer(2)) arctan(x^2)
x,y = var('x,y') w0 = SR.wild(0); w1 = SR.wild(1) pattern = sin(x)*w0*w1^2; pattern f = atan(sin(x)*3*x^2); f f.has(pattern) f.subs(pattern == x^2)
- sage.symbolic.expression.normalize_index_for_doctests(arg, nops)[source]¶
Wrapper function to test
normalize_index
.
- sage.symbolic.expression.paramset_from_Expression(e)[source]¶
EXAMPLES:
sage: from sage.symbolic.expression import paramset_from_Expression sage: f = function('f') sage: paramset_from_Expression(f(x).diff(x)) [0]
>>> from sage.all import * >>> from sage.symbolic.expression import paramset_from_Expression >>> f = function('f') >>> paramset_from_Expression(f(x).diff(x)) [0]
from sage.symbolic.expression import paramset_from_Expression f = function('f') paramset_from_Expression(f(x).diff(x))
- sage.symbolic.expression.print_order(lhs, rhs)[source]¶
Comparison in the print order
INPUT:
lhs
,rhs
– two symbolic expressions or something that can be converted to one
OUTPUT:
Either \(-1\), \(0\), or \(+1\) indicating the comparison. An exception is raised if the arguments cannot be converted into the symbolic ring.
EXAMPLES:
sage: from sage.symbolic.expression import print_order sage: print_order(1, oo) 1 sage: print_order(e, oo) -1 sage: print_order(pi, oo) 1 sage: print_order(1, sqrt(2)) 1
>>> from sage.all import * >>> from sage.symbolic.expression import print_order >>> print_order(Integer(1), oo) 1 >>> print_order(e, oo) -1 >>> print_order(pi, oo) 1 >>> print_order(Integer(1), sqrt(Integer(2))) 1
from sage.symbolic.expression import print_order print_order(1, oo) print_order(e, oo) print_order(pi, oo) print_order(1, sqrt(2))
Check that Issue #12967 is fixed:
sage: print_order(SR(oo), sqrt(2)) 1
>>> from sage.all import * >>> print_order(SR(oo), sqrt(Integer(2))) 1
print_order(SR(oo), sqrt(2))
- sage.symbolic.expression.print_sorted(expressions)[source]¶
Sort a list in print order.
INPUT:
expressions
– list/tuple/iterable of symbolic expressions, or something that can be converted to one
OUTPUT: the list sorted by
print_order()
EXAMPLES:
sage: from sage.symbolic.expression import print_sorted sage: print_sorted([SR(1), SR(e), SR(pi), sqrt(2)]) [e, sqrt(2), pi, 1]
>>> from sage.all import * >>> from sage.symbolic.expression import print_sorted >>> print_sorted([SR(Integer(1)), SR(e), SR(pi), sqrt(Integer(2))]) [e, sqrt(2), pi, 1]
from sage.symbolic.expression import print_sorted print_sorted([SR(1), SR(e), SR(pi), sqrt(2)])
- sage.symbolic.expression.py_denom_for_doctests(n)[source]¶
This function is used to test py_denom().
EXAMPLES:
sage: from sage.symbolic.expression import py_denom_for_doctests sage: py_denom_for_doctests(2/3) 3
>>> from sage.all import * >>> from sage.symbolic.expression import py_denom_for_doctests >>> py_denom_for_doctests(Integer(2)/Integer(3)) 3
from sage.symbolic.expression import py_denom_for_doctests py_denom_for_doctests(2/3)
- sage.symbolic.expression.py_eval_infinity_for_doctests()[source]¶
This function tests py_eval_infinity.
- sage.symbolic.expression.py_eval_neg_infinity_for_doctests()[source]¶
This function tests py_eval_neg_infinity.
- sage.symbolic.expression.py_eval_unsigned_infinity_for_doctests()[source]¶
This function tests py_eval_unsigned_infinity.
- sage.symbolic.expression.py_exp_for_doctests(x)[source]¶
This function tests py_exp.
EXAMPLES:
sage: from sage.symbolic.expression import py_exp_for_doctests sage: py_exp_for_doctests(CC(2)) 7.38905609893065
>>> from sage.all import * >>> from sage.symbolic.expression import py_exp_for_doctests >>> py_exp_for_doctests(CC(Integer(2))) 7.38905609893065
from sage.symbolic.expression import py_exp_for_doctests py_exp_for_doctests(CC(2))
- sage.symbolic.expression.py_factorial_py(x)[source]¶
This function is a python wrapper around py_factorial(). This wrapper is needed when we override the eval() method for GiNaC’s factorial function in sage.functions.other.Function_factorial.
- sage.symbolic.expression.py_float_for_doctests(n, kwds)[source]¶
This function is for testing py_float.
EXAMPLES:
sage: from sage.symbolic.expression import py_float_for_doctests sage: py_float_for_doctests(pi, {'parent':RealField(80)}) 3.1415926535897932384626 sage: py_float_for_doctests(I, {'parent':RealField(80)}) 1.0000000000000000000000*I sage: py_float_for_doctests(I, {'parent':float}) 1j sage: py_float_for_doctests(pi, {'parent':complex}) (3.141592653589793+0j)
>>> from sage.all import * >>> from sage.symbolic.expression import py_float_for_doctests >>> py_float_for_doctests(pi, {'parent':RealField(Integer(80))}) 3.1415926535897932384626 >>> py_float_for_doctests(I, {'parent':RealField(Integer(80))}) 1.0000000000000000000000*I >>> py_float_for_doctests(I, {'parent':float}) 1j >>> py_float_for_doctests(pi, {'parent':complex}) (3.141592653589793+0j)
from sage.symbolic.expression import py_float_for_doctests py_float_for_doctests(pi, {'parent':RealField(80)}) py_float_for_doctests(I, {'parent':RealField(80)}) py_float_for_doctests(I, {'parent':float}) py_float_for_doctests(pi, {'parent':complex})
- sage.symbolic.expression.py_is_cinteger_for_doctest(x)[source]¶
Return
True
if pynac should treat this object as an element of \(\ZZ(i)\).
- sage.symbolic.expression.py_is_crational_for_doctest(x)[source]¶
Return
True
if pynac should treat this object as an element of \(\QQ(i)\).
- sage.symbolic.expression.py_is_integer_for_doctests(x)[source]¶
Used internally for doctesting purposes.
- sage.symbolic.expression.py_latex_fderivative_for_doctests(id, params, args)[source]¶
Used internally for writing doctests for certain cdef’d functions.
EXAMPLES:
sage: from sage.symbolic.expression import py_latex_fderivative_for_doctests as py_latex_fderivative, get_ginac_serial, get_fn_serial sage: var('x,y,z') (x, y, z) sage: from sage.symbolic.function import get_sfunction_from_serial sage: foo = function('foo', nargs=2) sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z)) \mathrm{D}_{0, 1, 0, 1}\left({\rm foo}\right)\left(x, y^{z}\right)
>>> from sage.all import * >>> from sage.symbolic.expression import py_latex_fderivative_for_doctests as py_latex_fderivative, get_ginac_serial, get_fn_serial >>> var('x,y,z') (x, y, z) >>> from sage.symbolic.function import get_sfunction_from_serial >>> foo = function('foo', nargs=Integer(2)) >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_latex_fderivative(i, (Integer(0), Integer(1), Integer(0), Integer(1)), (x, y**z)) \mathrm{D}_{0, 1, 0, 1}\left({\rm foo}\right)\left(x, y^{z}\right)
from sage.symbolic.expression import py_latex_fderivative_for_doctests as py_latex_fderivative, get_ginac_serial, get_fn_serial var('x,y,z') from sage.symbolic.function import get_sfunction_from_serial foo = function('foo', nargs=2) for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
Test latex_name:
sage: foo = function('foo', nargs=2, latex_name=r'\mathrm{bar}') sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z)) \mathrm{D}_{0, 1, 0, 1}\left(\mathrm{bar}\right)\left(x, y^{z}\right)
>>> from sage.all import * >>> foo = function('foo', nargs=Integer(2), latex_name=r'\mathrm{bar}') >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_latex_fderivative(i, (Integer(0), Integer(1), Integer(0), Integer(1)), (x, y**z)) \mathrm{D}_{0, 1, 0, 1}\left(\mathrm{bar}\right)\left(x, y^{z}\right)
foo = function('foo', nargs=2, latex_name=r'\mathrm{bar}') for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
Test custom func:
sage: def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')' sage: foo = function('foo', nargs=2, print_latex_func=my_print) sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z)) \mathrm{D}_{0, 1, 0, 1}func_with_args(x, y^z)
>>> from sage.all import * >>> def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')' >>> foo = function('foo', nargs=Integer(2), print_latex_func=my_print) >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_latex_fderivative(i, (Integer(0), Integer(1), Integer(0), Integer(1)), (x, y**z)) \mathrm{D}_{0, 1, 0, 1}func_with_args(x, y^z)
def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')' foo = function('foo', nargs=2, print_latex_func=my_print) for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
- sage.symbolic.expression.py_latex_function_pystring(id, args, fname_paren=False)[source]¶
Return a string with the latex representation of the symbolic function specified by the given id applied to args.
See documentation of py_print_function_pystring for more information.
EXAMPLES:
sage: from sage.symbolic.expression import py_latex_function_pystring, get_ginac_serial, get_fn_serial sage: from sage.symbolic.function import get_sfunction_from_serial sage: var('x,y,z') (x, y, z) sage: foo = function('foo', nargs=2) sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_latex_function_pystring(i, (x,y^z)) '{\\rm foo}\\left(x, y^{z}\\right)' sage: py_latex_function_pystring(i, (x,y^z), True) '\\left({\\rm foo}\\right)\\left(x, y^{z}\\right)' sage: py_latex_function_pystring(i, (int(0),x)) '{\\rm foo}\\left(0, x\\right)'
>>> from sage.all import * >>> from sage.symbolic.expression import py_latex_function_pystring, get_ginac_serial, get_fn_serial >>> from sage.symbolic.function import get_sfunction_from_serial >>> var('x,y,z') (x, y, z) >>> foo = function('foo', nargs=Integer(2)) >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_latex_function_pystring(i, (x,y**z)) '{\\rm foo}\\left(x, y^{z}\\right)' >>> py_latex_function_pystring(i, (x,y**z), True) '\\left({\\rm foo}\\right)\\left(x, y^{z}\\right)' >>> py_latex_function_pystring(i, (int(Integer(0)),x)) '{\\rm foo}\\left(0, x\\right)'
from sage.symbolic.expression import py_latex_function_pystring, get_ginac_serial, get_fn_serial from sage.symbolic.function import get_sfunction_from_serial var('x,y,z') foo = function('foo', nargs=2) for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_latex_function_pystring(i, (x,y^z)) py_latex_function_pystring(i, (x,y^z), True) py_latex_function_pystring(i, (int(0),x))
Test latex_name:
sage: foo = function('foo', nargs=2, latex_name=r'\mathrm{bar}') sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_latex_function_pystring(i, (x,y^z)) '\\mathrm{bar}\\left(x, y^{z}\\right)'
>>> from sage.all import * >>> foo = function('foo', nargs=Integer(2), latex_name=r'\mathrm{bar}') >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_latex_function_pystring(i, (x,y**z)) '\\mathrm{bar}\\left(x, y^{z}\\right)'
foo = function('foo', nargs=2, latex_name=r'\mathrm{bar}') for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_latex_function_pystring(i, (x,y^z))
Test custom func:
sage: def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args)) sage: foo = function('foo', nargs=2, print_latex_func=my_print) sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_latex_function_pystring(i, (x,y^z)) 'my args are: x, y^z'
>>> from sage.all import * >>> def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args)) >>> foo = function('foo', nargs=Integer(2), print_latex_func=my_print) >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_latex_function_pystring(i, (x,y**z)) 'my args are: x, y^z'
def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args)) foo = function('foo', nargs=2, print_latex_func=my_print) for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_latex_function_pystring(i, (x,y^z))
- sage.symbolic.expression.py_latex_variable_for_doctests(x)[source]¶
Internal function used so we can doctest a certain cdef’d method.
EXAMPLES:
sage: sage.symbolic.expression.py_latex_variable_for_doctests('x') x sage: sage.symbolic.expression.py_latex_variable_for_doctests('sigma') \sigma
>>> from sage.all import * >>> sage.symbolic.expression.py_latex_variable_for_doctests('x') x >>> sage.symbolic.expression.py_latex_variable_for_doctests('sigma') \sigma
sage.symbolic.expression.py_latex_variable_for_doctests('x') sage.symbolic.expression.py_latex_variable_for_doctests('sigma')
- sage.symbolic.expression.py_lgamma_for_doctests(x)[source]¶
This function tests py_lgamma.
EXAMPLES:
sage: from sage.symbolic.expression import py_lgamma_for_doctests sage: py_lgamma_for_doctests(CC(I)) -0.650923199301856 - 1.87243664726243*I
>>> from sage.all import * >>> from sage.symbolic.expression import py_lgamma_for_doctests >>> py_lgamma_for_doctests(CC(I)) -0.650923199301856 - 1.87243664726243*I
from sage.symbolic.expression import py_lgamma_for_doctests py_lgamma_for_doctests(CC(I))
- sage.symbolic.expression.py_li2_for_doctests(x)[source]¶
This function is a python wrapper so py_psi2 can be tested. The real tests are in the docstring for py_psi2.
EXAMPLES:
sage: from sage.symbolic.expression import py_li2_for_doctests sage: py_li2_for_doctests(-1.1) -0.890838090262283
>>> from sage.all import * >>> from sage.symbolic.expression import py_li2_for_doctests >>> py_li2_for_doctests(-RealNumber('1.1')) -0.890838090262283
from sage.symbolic.expression import py_li2_for_doctests py_li2_for_doctests(-1.1)
- sage.symbolic.expression.py_li_for_doctests(x, n, parent)[source]¶
This function is a python wrapper so py_li can be tested. The real tests are in the docstring for py_li.
EXAMPLES:
sage: from sage.symbolic.expression import py_li_for_doctests sage: py_li_for_doctests(0,2,float) 0.000000000000000
>>> from sage.all import * >>> from sage.symbolic.expression import py_li_for_doctests >>> py_li_for_doctests(Integer(0),Integer(2),float) 0.000000000000000
from sage.symbolic.expression import py_li_for_doctests py_li_for_doctests(0,2,float)
- sage.symbolic.expression.py_log_for_doctests(x)[source]¶
This function tests py_log.
EXAMPLES:
sage: from sage.symbolic.expression import py_log_for_doctests sage: py_log_for_doctests(CC(e)) 1.00000000000000
>>> from sage.all import * >>> from sage.symbolic.expression import py_log_for_doctests >>> py_log_for_doctests(CC(e)) 1.00000000000000
from sage.symbolic.expression import py_log_for_doctests py_log_for_doctests(CC(e))
- sage.symbolic.expression.py_mod_for_doctests(x, n)[source]¶
This function is a python wrapper so py_mod can be tested. The real tests are in the docstring for py_mod.
EXAMPLES:
sage: from sage.symbolic.expression import py_mod_for_doctests sage: py_mod_for_doctests(5, 2) 1
>>> from sage.all import * >>> from sage.symbolic.expression import py_mod_for_doctests >>> py_mod_for_doctests(Integer(5), Integer(2)) 1
from sage.symbolic.expression import py_mod_for_doctests py_mod_for_doctests(5, 2)
- sage.symbolic.expression.py_numer_for_doctests(n)[source]¶
This function is used to test py_numer().
EXAMPLES:
sage: from sage.symbolic.expression import py_numer_for_doctests sage: py_numer_for_doctests(2/3) 2
>>> from sage.all import * >>> from sage.symbolic.expression import py_numer_for_doctests >>> py_numer_for_doctests(Integer(2)/Integer(3)) 2
from sage.symbolic.expression import py_numer_for_doctests py_numer_for_doctests(2/3)
- sage.symbolic.expression.py_print_fderivative_for_doctests(id, params, args)[source]¶
Used for testing a cdef’d function.
EXAMPLES:
sage: from sage.symbolic.expression import py_print_fderivative_for_doctests as py_print_fderivative, get_ginac_serial, get_fn_serial sage: var('x,y,z') (x, y, z) sage: from sage.symbolic.function import get_sfunction_from_serial sage: foo = function('foo', nargs=2) sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_print_fderivative(i, (0, 1, 0, 1), (x, y^z)) D[0, 1, 0, 1](foo)(x, y^z)
>>> from sage.all import * >>> from sage.symbolic.expression import py_print_fderivative_for_doctests as py_print_fderivative, get_ginac_serial, get_fn_serial >>> var('x,y,z') (x, y, z) >>> from sage.symbolic.function import get_sfunction_from_serial >>> foo = function('foo', nargs=Integer(2)) >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_print_fderivative(i, (Integer(0), Integer(1), Integer(0), Integer(1)), (x, y**z)) D[0, 1, 0, 1](foo)(x, y^z)
from sage.symbolic.expression import py_print_fderivative_for_doctests as py_print_fderivative, get_ginac_serial, get_fn_serial var('x,y,z') from sage.symbolic.function import get_sfunction_from_serial foo = function('foo', nargs=2) for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_print_fderivative(i, (0, 1, 0, 1), (x, y^z))
Test custom print function:
sage: def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')' sage: foo = function('foo', nargs=2, print_func=my_print) sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_print_fderivative(i, (0, 1, 0, 1), (x, y^z)) D[0, 1, 0, 1]func_with_args(x, y^z)
>>> from sage.all import * >>> def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')' >>> foo = function('foo', nargs=Integer(2), print_func=my_print) >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_print_fderivative(i, (Integer(0), Integer(1), Integer(0), Integer(1)), (x, y**z)) D[0, 1, 0, 1]func_with_args(x, y^z)
def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')' foo = function('foo', nargs=2, print_func=my_print) for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_print_fderivative(i, (0, 1, 0, 1), (x, y^z))
- sage.symbolic.expression.py_print_function_pystring(id, args, fname_paren=False)[source]¶
Return a string with the representation of the symbolic function specified by the given id applied to args.
INPUT:
id
– serial number of the corresponding symbolic functionparams
– set of parameter numbers with respect to which to take the derivativeargs
– arguments of the function
EXAMPLES:
sage: from sage.symbolic.expression import py_print_function_pystring, get_ginac_serial, get_fn_serial sage: from sage.symbolic.function import get_sfunction_from_serial sage: var('x,y,z') (x, y, z) sage: foo = function('foo', nargs=2) sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_print_function_pystring(i, (x,y)) 'foo(x, y)' sage: py_print_function_pystring(i, (x,y), True) '(foo)(x, y)' sage: def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args)) sage: foo = function('foo', nargs=2, print_func=my_print) sage: for i in range(get_ginac_serial(), get_fn_serial()): ....: if get_sfunction_from_serial(i) == foo: break sage: get_sfunction_from_serial(i) == foo True sage: py_print_function_pystring(i, (x,y)) 'my args are: x, y'
>>> from sage.all import * >>> from sage.symbolic.expression import py_print_function_pystring, get_ginac_serial, get_fn_serial >>> from sage.symbolic.function import get_sfunction_from_serial >>> var('x,y,z') (x, y, z) >>> foo = function('foo', nargs=Integer(2)) >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_print_function_pystring(i, (x,y)) 'foo(x, y)' >>> py_print_function_pystring(i, (x,y), True) '(foo)(x, y)' >>> def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args)) >>> foo = function('foo', nargs=Integer(2), print_func=my_print) >>> for i in range(get_ginac_serial(), get_fn_serial()): ... if get_sfunction_from_serial(i) == foo: break >>> get_sfunction_from_serial(i) == foo True >>> py_print_function_pystring(i, (x,y)) 'my args are: x, y'
from sage.symbolic.expression import py_print_function_pystring, get_ginac_serial, get_fn_serial from sage.symbolic.function import get_sfunction_from_serial var('x,y,z') foo = function('foo', nargs=2) for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_print_function_pystring(i, (x,y)) py_print_function_pystring(i, (x,y), True) def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args)) foo = function('foo', nargs=2, print_func=my_print) for i in range(get_ginac_serial(), get_fn_serial()): if get_sfunction_from_serial(i) == foo: break get_sfunction_from_serial(i) == foo py_print_function_pystring(i, (x,y))
- sage.symbolic.expression.py_psi2_for_doctests(n, x)[source]¶
This function is a python wrapper so py_psi2 can be tested. The real tests are in the docstring for py_psi2.
EXAMPLES:
sage: from sage.symbolic.expression import py_psi2_for_doctests sage: py_psi2_for_doctests(1, 2) 0.644934066848226
>>> from sage.all import * >>> from sage.symbolic.expression import py_psi2_for_doctests >>> py_psi2_for_doctests(Integer(1), Integer(2)) 0.644934066848226
from sage.symbolic.expression import py_psi2_for_doctests py_psi2_for_doctests(1, 2)
- sage.symbolic.expression.py_psi_for_doctests(x)[source]¶
This function is a python wrapper so py_psi can be tested. The real tests are in the docstring for py_psi.
EXAMPLES:
sage: from sage.symbolic.expression import py_psi_for_doctests sage: py_psi_for_doctests(2) 0.422784335098467
>>> from sage.all import * >>> from sage.symbolic.expression import py_psi_for_doctests >>> py_psi_for_doctests(Integer(2)) 0.422784335098467
from sage.symbolic.expression import py_psi_for_doctests py_psi_for_doctests(2)
- sage.symbolic.expression.py_stieltjes_for_doctests(x)[source]¶
This function is for testing py_stieltjes().
EXAMPLES:
sage: from sage.symbolic.expression import py_stieltjes_for_doctests sage: py_stieltjes_for_doctests(0.0) 0.577215664901533
>>> from sage.all import * >>> from sage.symbolic.expression import py_stieltjes_for_doctests >>> py_stieltjes_for_doctests(RealNumber('0.0')) 0.577215664901533
from sage.symbolic.expression import py_stieltjes_for_doctests py_stieltjes_for_doctests(0.0)
- sage.symbolic.expression.py_tgamma_for_doctests(x)[source]¶
This function is for testing py_tgamma().
- sage.symbolic.expression.py_zeta_for_doctests(x)[source]¶
This function is for testing py_zeta().
EXAMPLES:
sage: from sage.symbolic.expression import py_zeta_for_doctests sage: py_zeta_for_doctests(CC.0) 0.00330022368532410 - 0.418155449141322*I
>>> from sage.all import * >>> from sage.symbolic.expression import py_zeta_for_doctests >>> py_zeta_for_doctests(CC.gen(0)) 0.00330022368532410 - 0.418155449141322*I
from sage.symbolic.expression import py_zeta_for_doctests py_zeta_for_doctests(CC.0)
- sage.symbolic.expression.register_or_update_function(self, name, latex_name, nargs, evalf_params_first, update)[source]¶
Register the function
self
with Pynac (GiNaC).OUTPUT: serial number of the function, for use in
call_registered_function()
EXAMPLES:
sage: from sage.symbolic.function import BuiltinFunction sage: class Archosaurian(BuiltinFunction): ....: def __init__(self): ....: BuiltinFunction.__init__(self, 'archsaur', nargs=1) ....: def _eval_(self, x): ....: return x * exp(x) sage: archsaur = Archosaurian() # indirect doctest sage: archsaur(2) 2*e^2
>>> from sage.all import * >>> from sage.symbolic.function import BuiltinFunction >>> class Archosaurian(BuiltinFunction): ... def __init__(self): ... BuiltinFunction.__init__(self, 'archsaur', nargs=Integer(1)) ... def _eval_(self, x): ... return x * exp(x) >>> archsaur = Archosaurian() # indirect doctest >>> archsaur(Integer(2)) 2*e^2
from sage.symbolic.function import BuiltinFunction class Archosaurian(BuiltinFunction): def __init__(self): BuiltinFunction.__init__(self, 'archsaur', nargs=1) def _eval_(self, x): return x * exp(x) archsaur = Archosaurian() # indirect doctest archsaur(2)
- sage.symbolic.expression.solve_diophantine(f, *args, **kwds)[source]¶
Solve a Diophantine equation.
The argument, if not given as symbolic equation, is set equal to zero. It can be given in any form that can be converted to symbolic. Please see
Expression.solve_diophantine()
for a detailed synopsis.EXAMPLES:
sage: R.<a,b> = PolynomialRing(ZZ); R Multivariate Polynomial Ring in a, b over Integer Ring sage: solve_diophantine(a^2 - 3*b^2 + 1) [] sage: sorted(solve_diophantine(a^2 - 3*b^2 + 2), key=str) [(-1/2*sqrt(3)*(sqrt(3) + 2)^t + 1/2*sqrt(3)*(-sqrt(3) + 2)^t - 1/2*(sqrt(3) + 2)^t - 1/2*(-sqrt(3) + 2)^t, -1/6*sqrt(3)*(sqrt(3) + 2)^t + 1/6*sqrt(3)*(-sqrt(3) + 2)^t - 1/2*(sqrt(3) + 2)^t - 1/2*(-sqrt(3) + 2)^t), (1/2*sqrt(3)*(sqrt(3) + 2)^t - 1/2*sqrt(3)*(-sqrt(3) + 2)^t + 1/2*(sqrt(3) + 2)^t + 1/2*(-sqrt(3) + 2)^t, 1/6*sqrt(3)*(sqrt(3) + 2)^t - 1/6*sqrt(3)*(-sqrt(3) + 2)^t + 1/2*(sqrt(3) + 2)^t + 1/2*(-sqrt(3) + 2)^t)]
>>> from sage.all import * >>> R = PolynomialRing(ZZ, names=('a', 'b',)); (a, b,) = R._first_ngens(2); R Multivariate Polynomial Ring in a, b over Integer Ring >>> solve_diophantine(a**Integer(2) - Integer(3)*b**Integer(2) + Integer(1)) [] >>> sorted(solve_diophantine(a**Integer(2) - Integer(3)*b**Integer(2) + Integer(2)), key=str) [(-1/2*sqrt(3)*(sqrt(3) + 2)^t + 1/2*sqrt(3)*(-sqrt(3) + 2)^t - 1/2*(sqrt(3) + 2)^t - 1/2*(-sqrt(3) + 2)^t, -1/6*sqrt(3)*(sqrt(3) + 2)^t + 1/6*sqrt(3)*(-sqrt(3) + 2)^t - 1/2*(sqrt(3) + 2)^t - 1/2*(-sqrt(3) + 2)^t), (1/2*sqrt(3)*(sqrt(3) + 2)^t - 1/2*sqrt(3)*(-sqrt(3) + 2)^t + 1/2*(sqrt(3) + 2)^t + 1/2*(-sqrt(3) + 2)^t, 1/6*sqrt(3)*(sqrt(3) + 2)^t - 1/6*sqrt(3)*(-sqrt(3) + 2)^t + 1/2*(sqrt(3) + 2)^t + 1/2*(-sqrt(3) + 2)^t)]
R.<a,b> = PolynomialRing(ZZ); R solve_diophantine(a^2 - 3*b^2 + 1) sorted(solve_diophantine(a^2 - 3*b^2 + 2), key=str)
- sage.symbolic.expression.test_binomial(n, k)[source]¶
The Binomial coefficients. It computes the binomial coefficients. For integer n and k and positive n this is the number of ways of choosing k objects from n distinct objects. If n is negative, the formula binomial(n,k) == (-1)^k*binomial(k-n-1,k) is used to compute the result.
INPUT:
n
,k
– integers, withk >= 0
OUTPUT: integer
EXAMPLES:
sage: import sage.symbolic.expression sage: sage.symbolic.expression.test_binomial(5,2) 10 sage: sage.symbolic.expression.test_binomial(-5,3) -35 sage: -sage.symbolic.expression.test_binomial(3-(-5)-1, 3) -35
>>> from sage.all import * >>> import sage.symbolic.expression >>> sage.symbolic.expression.test_binomial(Integer(5),Integer(2)) 10 >>> sage.symbolic.expression.test_binomial(-Integer(5),Integer(3)) -35 >>> -sage.symbolic.expression.test_binomial(Integer(3)-(-Integer(5))-Integer(1), Integer(3)) -35
import sage.symbolic.expression sage.symbolic.expression.test_binomial(5,2) sage.symbolic.expression.test_binomial(-5,3) -sage.symbolic.expression.test_binomial(3-(-5)-1, 3)
- sage.symbolic.expression.tolerant_is_symbol(a)[source]¶
Utility function to test if something is a symbol.
Returns False for arguments that do not have an is_symbol attribute. Returns the result of calling the is_symbol method otherwise.
EXAMPLES:
sage: from sage.symbolic.expression import tolerant_is_symbol sage: tolerant_is_symbol(var("x")) True sage: tolerant_is_symbol(None) False sage: None.is_symbol() Traceback (most recent call last): ... AttributeError: 'NoneType' object has no attribute 'is_symbol'...
>>> from sage.all import * >>> from sage.symbolic.expression import tolerant_is_symbol >>> tolerant_is_symbol(var("x")) True >>> tolerant_is_symbol(None) False >>> None.is_symbol() Traceback (most recent call last): ... AttributeError: 'NoneType' object has no attribute 'is_symbol'...
from sage.symbolic.expression import tolerant_is_symbol tolerant_is_symbol(var("x")) tolerant_is_symbol(None) None.is_symbol()
- sage.symbolic.expression.unpack_operands(ex)[source]¶
EXAMPLES:
sage: from sage.symbolic.expression import unpack_operands sage: t = SR._force_pyobject((1, 2, x, x+1, x+2)) sage: unpack_operands(t) (1, 2, x, x + 1, x + 2) sage: type(unpack_operands(t)) <... 'tuple'> sage: list(map(type, unpack_operands(t))) [<class 'sage.rings.integer.Integer'>, <class 'sage.rings.integer.Integer'>, <class 'sage.symbolic.expression.Expression'>, <class 'sage.symbolic.expression.Expression'>, <class 'sage.symbolic.expression.Expression'>] sage: u = SR._force_pyobject((t, x^2)) sage: unpack_operands(u) ((1, 2, x, x + 1, x + 2), x^2) sage: type(unpack_operands(u)[0]) <... 'tuple'>
>>> from sage.all import * >>> from sage.symbolic.expression import unpack_operands >>> t = SR._force_pyobject((Integer(1), Integer(2), x, x+Integer(1), x+Integer(2))) >>> unpack_operands(t) (1, 2, x, x + 1, x + 2) >>> type(unpack_operands(t)) <... 'tuple'> >>> list(map(type, unpack_operands(t))) [<class 'sage.rings.integer.Integer'>, <class 'sage.rings.integer.Integer'>, <class 'sage.symbolic.expression.Expression'>, <class 'sage.symbolic.expression.Expression'>, <class 'sage.symbolic.expression.Expression'>] >>> u = SR._force_pyobject((t, x**Integer(2))) >>> unpack_operands(u) ((1, 2, x, x + 1, x + 2), x^2) >>> type(unpack_operands(u)[Integer(0)]) <... 'tuple'>
from sage.symbolic.expression import unpack_operands t = SR._force_pyobject((1, 2, x, x+1, x+2)) unpack_operands(t) type(unpack_operands(t)) list(map(type, unpack_operands(t))) u = SR._force_pyobject((t, x^2)) unpack_operands(u) type(unpack_operands(u)[0])