4.2 Symbolic Equations and Inequalities

Module: sage.calculus.equations

Symbolic Equations and Inequalities.

Sage can solve symbolic equations and express inequalities. For example, we derive the quadratic formula as follows:

sage: a,b,c = var('a,b,c')
sage: qe = (a*x^2 + b*x + c == 0)
sage: print qe
                                 2
                              a x  + b x + c == 0
sage: print solve(qe, x)
[
                                      2
                              - sqrt(b  - 4 a c) - b
                          x == ----------------------
                                       2 a,
                                     2
                               sqrt(b  - 4 a c) - b
                           x == --------------------
                                       2 a
]

Author Log:

sage: x,y,a = var('x,y,a')
sage: f = x^2 + y^2 == 1
sage: f.solve(x)
[x == -sqrt(1 - y^2), x == sqrt(1 - y^2)]

sage: f = x^5 + a
sage: solve(f==0,x)
[x == e^(2*I*pi/5)*(-a)^(1/5), x == e^(4*I*pi/5)*(-a)^(1/5), x ==
e^(-(4*I*pi/5))*(-a)^(1/5), x == e^(-(2*I*pi/5))*(-a)^(1/5), x ==
(-a)^(1/5)]

You can also do arithmetic with inequalities, as illustrated below:

sage: var('x y')
(x, y)
sage: f = x + 3 == y - 2
sage: f
x + 3 == y - 2
sage: g = f - 3; g
x == y - 5
sage: h =  x^3 + sqrt(2) == x*y*sin(x)
sage: h
x^3 + sqrt(2) == x*sin(x)*y
sage: h - sqrt(2)
x^3 == x*sin(x)*y - sqrt(2)
sage: h + f
x^3 + x + sqrt(2) + 3 == x*sin(x)*y + y - 2
sage: f = x + 3 < y - 2
sage: g = 2 < x+10
sage: f - g
x + 1 < y - x - 12
sage: f + g
x + 5 < y + x + 8
sage: f*(-1)
-x - 3 > 2 - y

TESTS: We test serializing symbolic equations:

sage: eqn = x^3 + 2/3 >= x
sage: loads(dumps(eqn))
x^3 + 2/3 >= x
sage: loads(dumps(eqn)) == eqn 
True

Module-level Functions

assume( )

Make the given assumptions.

Input:

*args
- assumptions

sage: assume(x > 0)
sage: bool(sqrt(x^2) == x)
True
sage: forget()
sage: bool(sqrt(x^2) == x)
False

An integer constraint:

sage: var('n, P, r, r2')
(n, P, r, r2)
sage: assume(n, 'integer')
sage: c = P*e^(r*n)
sage: d = P*(1+r2)^n
sage: solve(c==d,r2)
[r2 == e^r - 1]

sage: sin(n*pi)
0
sage: forget()
sage: sin(n*pi)
sin(pi*n)

assumptions( )

List all current symbolic assumptions.

sage: var('x,y,z, w')
(x, y, z, w)
sage: forget()
sage: assume(x^2+y^2 > 0)
sage: assumptions()
[y^2 + x^2 > 0]
sage: forget(x^2+y^2 > 0)
sage: assumptions()
[]
sage: assume(x > y)
sage: assume(z > w)
sage: assumptions()
[x > y, z > w]
sage: forget()
sage: assumptions()
[]

forget( )

Forget the given assumption, or call with no arguments to forget all assumptions.

Here an assumption is some sort of symbolic constraint.

Input:

*args
- assumptions (default: forget all assumptions)

We define and forget multiple assumptions:

sage: var('x,y,z')
(x, y, z)
sage: assume(x>0, y>0, z == 1, y>0)
sage: assumptions()
[x > 0, y > 0, z == 1]
sage: forget(x>0, z==1)
sage: assumptions()
[y > 0]
sage: assume(y, 'even')
sage: assumptions()
[y > 0, y is even]
sage: cos(y*pi)
1
sage: forget()
sage: cos(y*pi)
cos(pi*y)
sage: assumptions()
[]

is_SymbolicEquation( x)

Return True if x is a symbolic equation.

The following two examples are symbolic equations:

sage: is_SymbolicEquation(sin(x) == x)
True
sage: is_SymbolicEquation(sin(x) < x)
True

This is not, since 2==3 evaluates to the boolean False:

sage: is_SymbolicEquation(2 == 3)
False

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

preprocess_assumptions( args)

Turns a list of the form (var1, var2, ..., 'property') into a sequence of declarations (var1 is property), (var2 is property), ...

sage: from sage.calculus.equations import preprocess_assumptions
sage: preprocess_assumptions([x, 'integer', x > 4])
[x is integer, x > 4]
sage: var('x,y')
(x, y)
sage: preprocess_assumptions([x, y, 'integer', x > 4, y, 'even'])
[x is integer, y is integer, x > 4, y is even]

solve( f)

Algebraically solve an equation of system of equations for given variables.

Input:

f
- equation or system of equations (given by a list or tuple)
*args
- variables to solve for.
solution_dict = True
- return a list of dictionaries containing the solutions.

sage: x, y = var('x, y')
sage: solve([x+y==6, x-y==4], x, y)
[[x == 5, y == 1]]
sage: solve([x^2+y^2 == 1, y^2 == x^3 + x + 1], x, y)
[[x == (-sqrt(3)*I - 1)/2, y == -sqrt(3 - sqrt(3)*I)/sqrt(2)],
 [x == (-sqrt(3)*I - 1)/2, y == sqrt(3 - sqrt(3)*I)/sqrt(2)],
 [x == (sqrt(3)*I - 1)/2, y == -sqrt(sqrt(3)*I + 3)/sqrt(2)],
 [x == (sqrt(3)*I - 1)/2, y == sqrt(sqrt(3)*I + 3)/sqrt(2)],
 [x == 0, y == -1],
 [x == 0, y == 1]]
sage: solutions=solve([x^2+y^2 == 1, y^2 == x^3 + x + 1], x, y, solution_dict=True); solutions
[{y: -sqrt(3 - sqrt(3)*I)/sqrt(2), x: (-sqrt(3)*I - 1)/2},
 {y: sqrt(3 - sqrt(3)*I)/sqrt(2), x: (-sqrt(3)*I - 1)/2},
 {y: -sqrt(sqrt(3)*I + 3)/sqrt(2), x: (sqrt(3)*I - 1)/2},
 {y: sqrt(sqrt(3)*I + 3)/sqrt(2), x: (sqrt(3)*I - 1)/2},
 {y: -1, x: 0},
 {y: 1, x: 0}]
sage: for solution in solutions: print solution[x].n(digits=3), ",", solution[y].n(digits=3)
-0.500 - 0.866*I , -1.27 + 0.341*I
-0.500 - 0.866*I , 1.27 - 0.341*I
-0.500 + 0.866*I , -1.27 - 0.341*I
-0.500 + 0.866*I , 1.27 + 0.341*I
0.000 , -1.00
0.000 , 1.00

If True appears in the list of equations it is ignored, and if False appears in the list then no solutions are returned. E.g., note that the first 3==3 evaluates to True, not to a symbolic equation.

sage: solve([3==3, 1.00000000000000*x^3 == 0], x)
[x == 0]
sage: solve([1.00000000000000*x^3 == 0], x)
[x == 0]

Here, the first equation evaluates to False, so there are no solutions:

sage: solve([1==3, 1.00000000000000*x^3 == 0], x)
[]

sage: var('s,i,b,m,g')
(s, i, b, m, g)
sage: sys = [ m*(1-s) - b*s*i, b*s*i-g*i ];
sage: solve(sys,s,i);
[[s == 1, i == 0], [s == g/b, i == (b - g)*m/(b*g)]]
sage: solve(sys,[s,i]);
[[s == 1, i == 0], [s == g/b, i == (b - g)*m/(b*g)]]

solve_mod( eqns, modulus)

Return all solutions to an equation or list of equations modulo the given integer modulus. Each equation must involve only polynomials in 1 or many variables.

The solutions are returned as $ n$ -tuples, where $ n$ is the number of variables appearing anywhere in the given equations. The variables are in alphabetical order.

Input:

eqns
- equation or list of equations
modulus
- an integer

sage: var('x,y')
(x, y)
sage: solve_mod([x^2 + 2 == x, x^2 + y == y^2], 14)
[(2, 4), (6, 4), (9, 4), (13, 4)]
sage: solve_mod([x^2 == 1, 4*x  == 11], 15)
[(14,)]

Fermat's equation modulo 3 with exponent 5:

sage: var('x,y,z')
(x, y, z)
sage: solve_mod([x^5 + y^5 == z^5], 3)
[(0, 0, 0), (0, 1, 1), (0, 2, 2), (1, 0, 1), (1, 1, 2), (1, 2, 0), (2, 0,
2), (2, 1, 0), (2, 2, 1)]

WARNING: Currently this naively enumerates all possible solutions. The interface is good, but the algorithm is horrible if the modulus is at all large! Sage does have the ability to do something much faster in certain cases at least by using the Chinese Remainder Theorem, Gröbner basis, linear algebra techniques, etc. But for a lot of toy problems this function as is might be useful. At least it establishes an interface.

string_to_list_of_solutions( s)

Used internally by the symbolic solve command to convert the output of Maxima's solve command to a list of solutions in Sage's symbolic package.

We derive the (monic) quadratic formula:

sage: var('x,a,b')
(x, a, b)
sage: solve(x^2 + a*x + b == 0, x)
[x == (-sqrt(a^2 - 4*b) - a)/2, x == (sqrt(a^2 - 4*b) - a)/2]

Behind the scenes when the above is evaluated the function string_to_list_of_solutions is called with input the string $ s$ below:

sage: s = '[x=-(sqrt(a^2-4*b)+a)/2,x=(sqrt(a^2-4*b)-a)/2]'
sage: sage.calculus.equations.string_to_list_of_solutions(s)
[x == (-sqrt(a^2 - 4*b) - a)/2, x == (sqrt(a^2 - 4*b) - a)/2]

var_cmp( x, y)

Return comparison of the two variables x and y, which is just the comparison of the underlying string representations of the variables. This is used internally by the Calculus package.

Input:

x, y
- symbolic variables

Output: Python integer; either -1, 0, or 1.

sage: sage.calculus.equations.var_cmp(x,x)
0
sage: sage.calculus.equations.var_cmp(x,var('z'))
-1
sage: sage.calculus.equations.var_cmp(x,var('a'))
1

Class: GenericDeclaration

class GenericDeclaration
GenericDeclaration( self, var, assumption)

This class represents generic assumptions, such as a variable being an integer or a function being increasing. It passes such information to maxima's declare (wrapped in a context so it is able to forget).

Input:

var
- the variable about which assumptions are being made
assumption
- a maxima feature, either user defined or in the list given by maxima('features')

sage: from sage.calculus.equations import GenericDeclaration
sage: decl = GenericDeclaration(x, 'integer')
sage: decl.assume()
sage: sin(x*pi)
0
sage: decl.forget()
sage: sin(x*pi)
sin(pi*x)

Here is the list of acceptable features:

sage: maxima('features')
[integer,noninteger,even,odd,rational,irrational,real,imaginary,complex,ana
lytic,increasing,decreasing,oddfun,evenfun,posfun,commutative,lassociative,
rassociative,symmetric,antisymmetric,integervalued]

Functions: assume,$ \,$ forget

assume( self)

TEST:

sage: from sage.calculus.equations import GenericDeclaration
sage: decl = GenericDeclaration(x, 'even')
sage: decl.assume()
sage: cos(x*pi)
1
sage: decl.forget()

forget( self)

TEST:

sage: from sage.calculus.equations import GenericDeclaration
sage: decl = GenericDeclaration(x, 'odd')
sage: decl.assume()
sage: cos(x*pi)
-1
sage: decl.forget()
sage: cos(x*pi)
cos(pi*x)

Special Functions: __cmp__,$ \,$ __init__,$ \,$ __repr__

__cmp__( self, other)

TESTS:

sage: from sage.calculus.equations import GenericDeclaration as GDecl
sage: var('y')
y
sage: GDecl(x, 'integer') == GDecl(x, 'integer')
True
sage: GDecl(x, 'integer') == GDecl(x, 'rational')
False
sage: GDecl(x, 'integer') == GDecl(y, 'integer')
False

__repr__( self)

sage: from sage.calculus.equations import GenericDeclaration
sage: GenericDeclaration(x, 'foo')
x is foo

Class: SymbolicEquation

class SymbolicEquation
A symbolic equation, which consists of a left hand side, an operator and a right hand side.

SymbolicEquation( self, left, right, op)

Create a symbolic expression.

Internally a symbolic expression is simply a left side (self._left), operator (self._op), and a right hand side (self._right), where the left and right hand sides are symbolic expressions and the operator is a Python equation or inequality operator, e.g., operator.le.

One should not call the SymbolicEquation constructor directly, since it does no type checking. However, we illustrate how to do so below.

Bad illustrative usage:

sage: eqn = sage.calculus.equations.SymbolicEquation(-x, x^2 + 1, operator.gt); eqn
-x > x^2 + 1

Really bad usage!

sage: eqn.__init__(x, 2*x+pi, operator.lt)
sage: eqn                 # cripes!
x < 2*x + pi

Functions: add_to_both_sides,$ \,$ assume,$ \,$ divide_both_sides,$ \,$ expand,$ \,$ find_root,$ \,$ forget,$ \,$ left,$ \,$ left_hand_side,$ \,$ lhs,$ \,$ multiply_both_sides,$ \,$ operator,$ \,$ rhs,$ \,$ right,$ \,$ right_hand_side,$ \,$ solve,$ \,$ subs,$ \,$ substitute,$ \,$ subtract_from_both_sides,$ \,$ variables

add_to_both_sides( self, x)

Add $ x$ to both sides of this symbolic equation.

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)
y^2 + x^2 <= 1 - z^2
sage: eqn.add_to_both_sides(I)
z^2 + y^2 + x^2 + I <= I + 1

assume( self)

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

We call the assume method to assume that $ x>2$ :

sage: (x > 2).assume()

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

sage: bool(x > 0)
True
sage: bool(x < 0)
False

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

sage: bool(x > 3)
False

TESTS:

sage: v,c = var('v,c')
sage: assume(c != 0)
sage: integral((1+v^2/c^2)^3/(1-v^2/c^2)^(3/2),v)
-75*sqrt(c^2)*arcsin(sqrt(c^2)*v/c^2)/8 - v^5/(4*c^4*sqrt(1 - v^2/c^2)) -
17*v^3/(8*c^2*sqrt(1 - v^2/c^2)) + 83*v/(8*sqrt(1 - v^2/c^2))

divide_both_sides( self, x, [checksign=True])

Divide both sides of the inequality by $ x$ .

Input:

x
- number
checksign
- (default: True) boolean; if True, switch direction of inequality of x is negative; otherwise direction will not switch.

sage: var('theta')
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: assume(theta > 0)
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
sage: forget(theta > 0)
sage: eqn.divide_both_sides(theta)
Traceback (most recent call last):
...
ValueError: unable to multiply or divide both sides of an inequality by a
number whose sign can't be determined.

As a shorthand you can just use the divides notation:

sage: (x^3 + 1 > x^2 - 1) / (-1)
-x^3 - 1 < 1 - x^2

The quantity $ x^2 - 1$ could be either negative or positive depending on $ x$ , so dividing by it is not defined.

sage: (x^3 + 1 > x^2 - 1) / (x^2 - 1)
Traceback (most recent call last):
...
ValueError: unable to multiply or divide both sides of an inequality by a
number whose sign can't be determined.

If we specify that $ x^2 - 1> 0$ , then dividing is defined.

sage: assume(x^2 - 1 > 0)
sage: (x^3 + 1 > x^2 - 1) / (x^2 - 1)
(x^3 + 1)/(x^2 - 1) > 1
sage: forget()

We can also specify that $ x^2 - 1 < 0$ . Note that now the inequality direction changes.

sage: assume(x^2 - 1 < 0)
sage: (x^3 + 1 > x^2 - 1) / (x^2 - 1)
(x^3 + 1)/(x^2 - 1) < 1
sage: forget()

expand( self, [side=None])

Expands one or both sides of the equation.

If side is not specified, then both sides of the equation are expanded by calling expand() on the corresponding SymbolicExpression.

If side is `left' (or `right'), then only the left (or right) side of the equation is expanded.

sage: a = (16*x-13)/6 == (3*x+5)/2 - (4-x)/3
sage: a.expand()
8*x/3 - 13/6 == 11*x/6 + 7/6
sage: a.expand('left')
8*x/3 - 13/6 == (3*x + 5)/2 - (4 - x)/3
sage: a.expand('right')
(16*x - 13)/6 == 11*x/6 + 7/6

find_root( self)

If this is a symbolic equality with an equals sign == find numerically a single root of this equation in a given interval. Otherwise raise a ValueError. See the documentation for the global find_root method for more about the options to this function.

Note that this symbolic expression must involve at most one variable.

sage: (x == sin(x)).find_root(-2,2)
0.0
sage: (x^5 + 3*x + 2 == 0).find_root(-2,2)
-0.63283452024215225
sage: (cos(x) == sin(x)).find_root(10,20)
19.634954084936208

We illustrate some valid error conditions:

sage: (cos(x) != sin(x)).find_root(10,20)
Traceback (most recent call last):
...
ValueError: Symbolic equation must be an equality.
sage: (SR(3)==SR(2)).find_root(-1,1)
Traceback (most recent call last):
...
RuntimeError: no zero in the interval, since constant expression is not 0.

There must be at most one variable:

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.

forget( self)

Forget the given constraint.

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]

left( self)

Return the left hand side of this equation.

sage: eqn = x^3 + 2/3 >= x - pi
sage: eqn.lhs()
x^3 + 2/3
sage: eqn.left()
x^3 + 2/3
sage: eqn.left_hand_side()
x^3 + 2/3

SYNONYMS: lhs, left_hand_side

left_hand_side( self)

Return the left hand side of this equation.

sage: eqn = x^3 + 2/3 >= x - pi
sage: eqn.lhs()
x^3 + 2/3
sage: eqn.left()
x^3 + 2/3
sage: eqn.left_hand_side()
x^3 + 2/3

SYNONYMS: lhs, left_hand_side

lhs( self)

Return the left hand side of this equation.

sage: eqn = x^3 + 2/3 >= x - pi
sage: eqn.lhs()
x^3 + 2/3
sage: eqn.left()
x^3 + 2/3
sage: eqn.left_hand_side()
x^3 + 2/3

SYNONYMS: lhs, left_hand_side

multiply_both_sides( self, x)

Multiply both sides of this inequality by $ x$ .

sage: var('x,y'); f = x + 3 < y - 2
(x, y)
sage: f.multiply_both_sides(7)
7*(x + 3) < 7*(y - 2)
sage: f.multiply_both_sides(-1/2)
(-x - 3)/2 > (2 - y)/2        
sage: f*(-2/3)
-2*(x + 3)/3 > -2*(y - 2)/3
sage: f*(-pi)
-1*pi*(x + 3) > -1*pi*(y - 2)
sage: f*(1+I)
Traceback (most recent call last):
...
ValueError: unable to multiply or divide both sides of an inequality by a
number whose sign can't be determined.

Multiplying by complex numbers works only if it's an equality:

sage: f = sqrt(2) + x == y^3
sage: f.multiply_both_sides(I)
I*(x + sqrt(2)) == I*y^3
sage: f.multiply_both_sides(-1)
-x - sqrt(2) == -y^3

Some further examples:

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)

operator( self)

Return the operator in this equation.

sage: eqn = x^3 + 2/3 >= x - pi
sage: eqn.operator()
<built-in function ge>
sage: (x^3 + 2/3 < x - pi).operator()
<built-in function lt>
sage: (x^3 + 2/3 == x - pi).operator()
<built-in function eq>

rhs( self)

Return the right hand side of this equation.

sage: (x + sqrt(2) >= sqrt(3) + 5/2).right()
sqrt(3) + 5/2
sage: (x + sqrt(2) >= sqrt(3) + 5/2).rhs()
sqrt(3) + 5/2
sage: (x + sqrt(2) >= sqrt(3) + 5/2).right_hand_side()
sqrt(3) + 5/2

SYNONYMS: rhs, right_hand_side

right( self)

Return the right hand side of this equation.

sage: (x + sqrt(2) >= sqrt(3) + 5/2).right()
sqrt(3) + 5/2
sage: (x + sqrt(2) >= sqrt(3) + 5/2).rhs()
sqrt(3) + 5/2
sage: (x + sqrt(2) >= sqrt(3) + 5/2).right_hand_side()
sqrt(3) + 5/2

SYNONYMS: rhs, right_hand_side

right_hand_side( self)

Return the right hand side of this equation.

sage: (x + sqrt(2) >= sqrt(3) + 5/2).right()
sqrt(3) + 5/2
sage: (x + sqrt(2) >= sqrt(3) + 5/2).rhs()
sqrt(3) + 5/2
sage: (x + sqrt(2) >= sqrt(3) + 5/2).right_hand_side()
sqrt(3) + 5/2

SYNONYMS: rhs, right_hand_side

solve( self, [x=None], [multiplicities=False], [solution_dict=False], [explicit_solutions=False])

Symbolically solve for the given variable.

WARNING: In many cases, only one solution is computed.

Input:

x
- a SymbolicVariable object (if not given, the first in the expression is used)

multiplicities
- (default: False) if True, also returns the multiplicities of each solution, in order.

solution_dict
- (default: False) if True, return the solution as a dictionary rather than an equation.

explicit_solution
- (default: False); if True, require that all solutions returned be explicit (rather than
Implicit) output: a list of symbolicequations with the variable to solve for on the left hand side.

sage: S = solve(x^3 - 1 == 0, x)
sage: S
[x == (sqrt(3)*I - 1)/2, x == (-sqrt(3)*I - 1)/2, x == 1]
sage: S[0]
x == (sqrt(3)*I - 1)/2
sage: S[0].right()
(sqrt(3)*I - 1)/2
sage: S = solve(x^3 - 1 == 0, x, solution_dict=True)
sage: S
[{x: (sqrt(3)*I - 1)/2}, {x: (-sqrt(3)*I - 1)/2}, {x: 1}]

We illustrate finding multiplicities of solutions:

sage: f = (x-1)^5*(x^2+1)
sage: solve(f == 0, x)
[x == -1*I, x == I, x == 1]
sage: solve(f == 0, x, multiplicities=True)
([x == -1*I, x == I, x == 1], [1, 1, 5])

subs( self)

Do the given symbolic substitution to both sides of the equation. The notation is the same for substitute on a symbolic expression.

sage: var('a')
a
sage: e = (x^3 + a == sin(x/a)); e
x^3 + a == sin(x/a)
sage: e.substitute(x=5*x)
125*x^3 + a == sin(5*x/a)
sage: e.substitute(a=1)
x^3 + 1 == sin(x)
sage: e.substitute(a=x)
x^3 + x == sin(1)
sage: e.substitute(a=x, x=1)
x + 1 == sin(1/x)
sage: e.substitute({a:x, x:1})
x + 1 == sin(1/x)

substitute( self)

Do the given symbolic substitution to both sides of the equation. The notation is the same for substitute on a symbolic expression.

sage: var('a')
a
sage: e = (x^3 + a == sin(x/a)); e
x^3 + a == sin(x/a)
sage: e.substitute(x=5*x)
125*x^3 + a == sin(5*x/a)
sage: e.substitute(a=1)
x^3 + 1 == sin(x)
sage: e.substitute(a=x)
x^3 + x == sin(1)
sage: e.substitute(a=x, x=1)
x + 1 == sin(1/x)
sage: e.substitute({a:x, x:1})
x + 1 == sin(1/x)

subtract_from_both_sides( self, x)

Subtract $ x$ from both sides of this symbolic equation.

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) > cos(sin(x)) - sqrt(2)
sage: eqn.subtract_from_both_sides(cos(sin(x)))
-cos(sin(x)) + sqrt(3)*x*sin(x) + sqrt(2) > 0

variables( self)

Return the variables appearing in this symbolic equation.

Output:

tuple
- tuple of the variables in this equation (the result of calling this is cached).

sage: var('x,y,z,w')
(x, y, z, w)
sage: f =  (x+y+w) == (x^2 - y^2 - z^3);   f
y + x + w == -z^3 - y^2 + x^2
sage: f.variables()
(w, x, y, z)

Special Functions: __add__,$ \,$ __call__,$ \,$ __cmp__,$ \,$ __div__,$ \,$ __getitem__,$ \,$ __init__,$ \,$ __mul__,$ \,$ __radd__,$ \,$ __rmul__,$ \,$ __rsub__,$ \,$ __str__,$ \,$ __sub__,$ \,$ _arith,$ \,$ _latex_,$ \,$ _maxima_,$ \,$ _maxima_init_,$ \,$ _repr_,$ \,$ _scalar

__add__( self, right)

Add two symbolic equations.

sage: var('a,b')
(a, b)
sage: m = 144 == -10 * a + b
sage: n = 136 == 10 * a + b
sage: m + n
280 == 2*b

__call__( self)

Substitute both sides of this equation

This is very slow currently since we piggy-back off of the symbolic matrix functionality.

sage: var('theta')
theta
sage: eqn =   (x^3 + theta < sin(x*theta))
sage: eqn(x = 5)
theta + 125 < sin(5*theta)
sage: eqn(theta=x, x=0)
x < 0
sage: var('y')
y
sage: eqn = x^3 < sin(y)
sage: eqn(2)
8 < sin(y)
sage: eqn(2,3)
8 < sin(3)
sage: eqn = x^3 < 2
sage: eqn(2)
8 < 2

__cmp__( self, right)

sage: (x>0) == (x>0)
True
sage: (x>0) == (x>1)
False
sage: (x>0) != (x>1)
True

__div__( self, right)

Divide two symbolic equations.

sage: m = x == 5*x + 1
sage: n = sin(x) == sin(x+2*pi)
sage: m / n
x/sin(x) == (5*x + 1)/sin(x)
sage: m = x != 5*x + 1
sage: n = sin(x) != sin(x+2*pi)
sage: m / n
x/sin(x) != (5*x + 1)/sin(x)

__getitem__( self, i)

Return the ith part of this equation:

Output:

self[0]
- left hand side
self[1]
- operator
self[2]
- right hand side

sage: eqn = x^2 + sin(x) < cos(x^2)
sage: eqn[0]
sin(x) + x^2
sage: eqn[1]
<built-in function lt>
sage: eqn[2]
cos(x^2)
sage: eqn[-1]
cos(x^2)

__mul__( self, right)

Multiply two symbolic equations.

sage: m = x == 5*x + 1
sage: n = sin(x) == sin(x+2*pi)
sage: m * n
x*sin(x) == (5*x + 1)*sin(x)

__radd__( self, left)

Add two symbolic equations.

sage: var('a,b')
(a, b)            
sage: m = 144 == -10 * a + b
sage: n = 136 == 10 * a + b
sage: int(-144) + m
0 == b - 10*a - 144

__rmul__( self, left)

Multiply two symbolic equations.

sage: m = 2*x == 3*x^2 - 5
sage: int(-1) * m
-2*x == 5 - 3*x^2

__rsub__( self, left)

Subtract two symbolic equations.

sage: var('a,b')
(a, b)
sage: m = 144 == -10 * a + b
sage: n = 136 == 10 * a + b
sage: int(144) - m
0 == b - 10*a - 144

__str__( self)

Return the string representation of this equation, in 2-d ASCII art.

Output: string

sage: f =  (x^2 - x == 0)
sage: f
x^2 - x == 0
sage: print f
                                   2
                                  x  - x == 0

Here we call __str__ explicitly:

sage: (x > 2/3).__str__()
'                                         2\r\n                            
x > -\r\n                                         3'

__sub__( self, right)

Subtract two symbolic equations.

sage: var('a,b')
(a, b)            
sage: m = 144 == 20 * a + b
sage: n = 136 == 10 * a + b
sage: m - n
8 == 10*a

_arith( self, right, op)

This function is called internally to implement arithmetic operations on symbolic expressions.

Input:

self
- a symbolic equation
right
- a symbolic equation
op
- an operation, e.g., operator.add

We create two symbolic equations and add them:

sage: e1 = x^3 + x < sin(2*x)
sage: e2 = x^2 - x < cos(x)
sage: e1._arith(e2, operator.add)
x^3 + x^2 < sin(2*x) + cos(x)

We try to multiply them, which doesn't really make sense:

sage: e1._arith(e2, operator.mul)
Traceback (most recent call last):
...
ValueError: cannot multiply or divide inequalities.

We can multiply equalities though:

sage: e1 = x^3 + x == sin(2*x)
sage: e2 = x^2 - x == cos(x)
sage: f = e1._arith(e2, operator.mul); f
(x^2 - x)*(x^3 + x) == cos(x)*sin(2*x)

By the way, we can expand the above product by calling the expand method:

sage: f.expand()
x^5 - x^4 + x^3 - x^2 == cos(x)*sin(2*x)

_latex_( self)

Return latex representation of this symbolic equation.

This is obtained by calling the _latex_ method on both the left and right hand sides, and typesetting the operator symbol correctly.

Output:

string
- a string

The output is a strig with backslashes, so prints funny:

sage: (x^(3/5) >= pi)._latex_()
'{x}^{\\frac{3}{5}}   \\geq  \\pi'

Call the latex method to get an object that prints more nicely:

sage: latex(x^(3/5) >= pi)
{x}^{\frac{3}{5}}   \geq  \pi

_maxima_( self, [session=None])

Return version of this symbolic expression but in the given Maxima session.

sage: e1 = x^3 + x == sin(2*x)
sage: z = e1._maxima_()
sage: z.parent() is sage.calculus.calculus.maxima
True
sage: z = e1._maxima_(maxima)
sage: z.parent() is maxima
True
sage: z = maxima(e1)
sage: z.parent() is maxima
True

_maxima_init_( self, [maxima=Maxima], [assume=False])

Return string representation for this symbolic equation in a form suitable for evaluation in Maxima.

sage: (x^(3/5) >= pi^2 + e^i)._maxima_init_()
'((x) ^ (3/5)) >= (((%pi) ^ (2)) + ((%e) ^ (%i)))'
sage: (x == 0)._maxima_init_(assume=True)
'equal(x, 0)'
sage: (x != 0)._maxima_init_(assume=True)
'notequal(x, 0)'

_repr_( self)

Return non-ASCII art string representation of this symbolic equation. This is called implicitly when displaying an equation (without using print).

We create an inequality $ f$ and called the _repr_ method on it, and note that this produces the same string as just displaying $ f$ :

sage: f = x^3 + 1/3*x - sqrt(2) <= sin(x)
sage: f._repr_()
'x^3 + x/3 - sqrt(2) <= sin(x)'
sage: f
x^3 + x/3 - sqrt(2) <= sin(x)

When using print the __str__ method is called instead, which results in ASCII art:

sage: print f
                   3   x
                  x  + - - sqrt(2) <= sin(x)
                       3

_scalar( self, scalar, op, [checksign=True])

Input:

scalar
- number
op
- operation to perform
checksign
- (default: True) boolean; if True and op is multiply or divides, switch direction of inequality of x is negative; otherwise direction will not switch.

sage: var('x y')
(x, y)
sage: f = x + 3 < y - 2
sage: f*-1
-x - 3 > 2 - y
sage: f._scalar(-1, operator.mul, checksign=True)
-x - 3 > 2 - y
sage: f._scalar(-1, operator.mul, checksign=False)
-x - 3 < 2 - y
sage: f * 5
5*(x + 3) < 5*(y - 2)
sage: f - 3
x < y - 5
sage: f + 2
x + 5 < y

See About this document... for information on suggesting changes.