sympy / sympy

A computer algebra system written in pure Python

Home Page:https://sympy.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Real-Root Isolation

anirjoshi opened this issue · comments

Is it possible to use SymPy library to get intervals (with rational endpoints) such that there is exactly one root in the interval? I would like to use an implementation of RRI algorithm for my purpose.

I believe the intervals function function does this. But it seems that this does not work for reals, and works only for integer roots? For example the following program gives an error:

from sympy import Poly
from sympy.abc import x
from sympy import div, ZZ, QQ, RR
Poly(x**2 - 3, x,domain='R').intervals()

The error is as follows:

Traceback (most recent call last):
File "", line 1, in
File "/some_path/sympy/polys/polytools.py", line 3423, in intervals
result = f.rep.intervals(
File "/some_path/sympy/polys/polyclasses.py", line 836, in intervals
return dup_isolate_real_roots(f.rep, f.dom, eps=eps, inf=inf, sup=sup, fast=fast)
File "/some_path/sympy/polys/rootisolation.py", line 610, in dup_isolate_real_roots
raise DomainError("isolation of real roots not supported over %s" % K)
sympy.polys.polyerrors.DomainError: isolation of real roots not supported over RR

On the other hand the following program works:

from sympy import Poly
from sympy.abc import x
from sympy import div, ZZ, QQ, RR
Poly(x**2 - 3, x,domain='Z').intervals(eps=1e-10)

And it prints [((-262087/151316, -191861/110771), 1), ((191861/110771, 262087/151316), 1)] a valid interval in rationals.

I would like to isolate real roots into rational intervals. It would be great if this is possible using SymPy.

see related issue #19164

In [2]: Poly(x**2 - 3).intervals()
Out[2]: [((-2, -1), 1), ((1, 2), 1)]

Using domain='R' doesn't make any sense. The coefficients need to be rational numbers. The roots do not need to be rational. Real roots are bounded by default. Use all=True to bound non-real roots as well:

In [5]: Poly(x**2 + 1).intervals(all=True)
Out[5]: ([], [((-2⋅ⅈ, 2), 1), ((0, 2 + 2⋅ⅈ), 1)])

@smichr @oscarbenjamin thank you for the pointer, that issue seems to talk more about the way of solving equation than finding intervals in which a root exists. My concern is the following:
Given a univariate polynomial with rational coefficients, is there any function (such as intervals()) that returns intervals (with both endpoints rational) in which exactly one real-root exists? For example consider the polynomial:
Poly(x**2 - 3, x,domain='Z').intervals(eps=1e-10), it is assumed to be on integers right? because of domain='Z'. I would like the polynomial with rational coefficients to be considered over real numbers. That is, inputs and outputs of the polynomials are reals. Then, is there any function that returns all intervals with rational endpoints [eg. (a/b,c/d)] such that there is exactly one real root in the interval?

You already have the function that does what you are asking for:

In [13]: intervals(x**2 - 3)
Out[13]: [((-2, -1), 1), ((1, 2), 1)]

Great! Thank you for the quick response!

Hi @oscarbenjamin is it guaranteed that two intervals would not have any intersection point?

GitHub issues are not for getting help with using SymPy. I am going to close this. Use a different forum (e.g. the mailing list) to ask questions.

Thank you for pointing to the correct forum.