Reduce One or a System of Inequalities for a Single Variable Algebraically#

Use SymPy to reduce one or a system of inequalities for a single variable algebraically. For example, reducing x^2 < \pi, x > 0 yields 0 < x <
\sqrt{\pi}.

Note

SymPy can currently reduce for only one symbol (variable) in an inequality.

SymPy can reduce a system containing more than one symbol, if there is only one symbol per inequality.

Alternatives to Consider#

  • To reduce for more than one symbol in an inequality, try SciPy’s linprog()

  • To reduce Boolean expressions, use as_set

Examples#

Reducing a System of Inequalities for a Single Variable Algebraically#

reduce_inequalities() accepts a list or tuple of inequalities to be reduced as a system:

>>> from sympy import symbols, reduce_inequalities, pi
>>> x = symbols('x')
>>> reduce_inequalities([x >= 0, x**2 <= pi], x)
(0 <= x) & (x <= sqrt(pi))

Note

While solve() currently accomplishes the same thing (by calling reduce_inequalities() internally), that functionality may be deprecated or removed from solve(). We thus recommend using reduce_inequalities().

reduce_inequalities() is the top-level inequality-reducing function which will internally call any other lower-level inequality-reducing functions as needed.

Reducing One Inequality for a Single Variable Algebraically#

If you have only one inequality, you can optionally exclude the list construct and simply pass reduce_inequalities() the inequality as an expression:

>>> from sympy import symbols, reduce_inequalities, pi
>>> x = symbols('x')
>>> reduce_inequalities(x**2 <= pi, x)
(x <= sqrt(pi)) & (-sqrt(pi) <= x)

Guidance#

Include the Variable to Be Reduced for in the Function Call#

We recommend you include the variable to be reduced for as the second argument for reduce_inequalities() to ensure that it reduces for the desired variable.

Reduce a System of Inequalities Algebraically#

You can create your inequalities, then reduce the system as a list:

>>> from sympy import symbols, reduce_inequalities, pi
>>> x = symbols('x')
>>> reduce_inequalities([3*x >= 1, x**2 <= pi], x)
(1/3 <= x) & (x <= sqrt(pi))

Use the Result#

A common way to use the result is to extract the bounds for the symbol (variable). For example, for a solution of 0 < x < \sqrt{\pi}, you might want to extract 0 and \sqrt{\pi}.

Extract a List of Decomposed Relations#

You can decompose a set of relations which is joined by ^ (Or) or & (And) into individual relations using relational atoms. Using canonical will put order each relation so the symbol is on the left, so you can take the right-hand side rhs to extract the constants:

>>> from sympy import symbols, reduce_inequalities, pi
>>> from sympy.core.relational import Relational
>>> x = symbols('x')
>>> eq = reduce_inequalities([3*x >= 1, x**2 <= pi], x); eq
(1/3 <= x) & (x <= sqrt(pi))
>>> relations = [(i.lhs, i.rel_op, i.rhs) for i in [i.canonical for i in eq.atoms(Relational)]]
>>> relations_sorted = sorted(relations, key=lambda x: float(x[2])) # Sorting relations just to ensure consistent list order for docstring testing
>>> relations_sorted
[(x, '>=', 1/3), (x, '<=', sqrt(pi))]

Extract a Tuple of Relations#

The args (arguments) of reduced relations are the individual relations, so you can extract the constants from the left- or right-hand side of the args:

>>> from sympy import symbols, reduce_inequalities, pi
>>> x = symbols('x')
>>> eq = reduce_inequalities([3*x >= 1, x**2 <= pi], x); eq
(1/3 <= x) & (x <= sqrt(pi))
>>> eq.args
(1/3 <= x, x <= sqrt(pi))
>>> constants = []
>>> for arg in eq.args:
...     if arg.lhs == x:
...         constants.append(arg.rhs)
...     else:
...         constants.append(arg.lhs)
>>> constants
[1/3, sqrt(pi)]

Limitations of Inequality Reduction Using SymPy#

SymPy Can Reduce for Only One Symbol of Interest Per Inequality#

SymPy can currently reduce for only one symbol (variable) of interest in a given inequality.

>>> from sympy import reduce_inequalities, symbols
>>> x, y = symbols("x y")
>>> reduce_inequalities([x + y > 1, y > 0], [x, y])
Traceback (most recent call last):
...
NotImplementedError: inequality has more than one symbol of interest.

You can use SciPy’s linprog() to reduce this system of inequalities.

SymPy can reduce for more than one symbol in a system, if there is only one symbol of interest per inequality. For example, the following system of inequalities has two variables, x and y. SymPy can reduce for x, and gives the constraints on y.

>>> from sympy import reduce_inequalities, symbols
>>> x, y = symbols("x y")
>>> reduce_inequalities([x + y > 1, y > 0], x)
(0 < y) & (y < oo) & (x > 1 - y)

(oo is Infinity.)

If each inequality contains only one symbol to be reduced for, SymPy can reduce the set of inequalities for multiple symbols:

>>> from sympy import reduce_inequalities, symbols
>>> x, y = symbols("x y")
>>> x_y_reduced = reduce_inequalities([x > 1, y > 0], [x, y]); x_y_reduced
(0 < y) & (1 < x) & (x < oo) & (y < oo)

Note that this provides no mathematical insight beyond reducing the inequalities separately:

>>> from sympy import And
>>> x_reduced = reduce_inequalities(x > 1, x); x_reduced
(1 < x) & (x < oo)
>>> y_reduced = reduce_inequalities(y > 0, y); y_reduced
(0 < y) & (y < oo)
>>> And(x_reduced, y_reduced) == x_y_reduced
True

so the benefit of solving such inequalities as a set maybe only convenience.

Limitations on Types of Inequalities That SymPy Can Solve#

reduce_inequalities() can solve a system of inequalities involving a power of the symbol to be reduced for, or involving another symbol, but not both:

>>> from sympy import reduce_inequalities
>>> from sympy.abc import x, y
>>> reduce_inequalities([x ** 2 < 4, x > 0], x)
(0 < x) & (x < 2)
>>> reduce_inequalities([x < y, x > 0], x)
(0 < x) & (x < oo) & (x < y)
>>> reduce_inequalities([x ** 2 - y < 4, x > 0], x)
Traceback (most recent call last):
...
NotImplementedError: The inequality, -_y + x**2 - 4 < 0, cannot be solved using
solve_univariate_inequality.

Not All Results Are Returned for Periodic Functions#

The results returned for trigonometric inequalities are restricted in its periodic interval. reduce_inequalities() tries to return just enough solutions so that all (infinitely many) solutions can generated from the returned solutions by adding integer multiples of the periodicity() of the equation, here 2\pi.

>>> from sympy import reduce_inequalities, cos
>>> from sympy.abc import x, y
>>> from sympy.calculus.util import periodicity
>>> reduce_inequalities([2*cos(x) < 1, x > 0], x)
(0 < x) & (x < oo) & (pi/3 < x) & (x < 5*pi/3)
>>> periodicity(2*cos(x), x)
2*pi

Not All Systems of Inequalities Can Be Reduced#

Systems of Inequalities Which Cannot Be Satisfied#

If the system of inequalities has incompatible conditions, for example x < 0 and x > \pi, SymPy will return False:

>>> from sympy import symbols, reduce_inequalities, pi
>>> x = symbols('x')
>>> reduce_inequalities([x < 0, x > pi], x)
False

Systems of Inequalities That Cannot Be Reduced Analytically#

SymPy may reflect that your system of inequalities has no solutions that can be expressed algebraically (symbolically) by returning an error such as NotImplementedError:

>>> from sympy import symbols, reduce_inequalities, cos
>>> x = symbols('x')
>>> reduce_inequalities([cos(x) - x > 0, x > 0], x)
Traceback (most recent call last):
...
NotImplementedError: The inequality, -x + cos(x) > 0, cannot be solved using solve_univariate_inequality.

so you may have to reduce your inequalities numerically instead using SciPy’s linprog().

Inequalities Which Can Be Reduced Analytically, and SymPy Cannot Reduce#

Refer to Limitations of Inequality Reduction Using SymPy above.

Report a Bug#

If you find a bug with diophantine(), please post the problem on the SymPy mailing list. Until the issue is resolved, you can use a different method listed in Alternatives to Consider.