# Find all roots of an equation

Hello,

I have tried the following: used solve() by itself and with "to_solve_poly=True", imported simpy, tried find_root, and tried eq.roots(). find_root() gave me one root when there are several between 0,11.

How can I solve for all the roots in a range. Here is my final code.

var('PI')

PI = 2*asin(1.0)
eq = exp(-x)-sin(0.5*PI*x)==0
show(plot(exp(-x)-sin(0.5*PI*x), x, xmin = -10, xmax = 10, ymin =-10, ymax=10))
eq.find_root(0, 11)
edit retag close merge delete

Sort by » oldest newest most voted

First, note that you can use the symbolic pi directly:

sage: eq = exp(-x)-sin(pi*x/2)==0

Then the find_root method only gives you one root that belongs to the interval. If you want all the roots, you have to localize:

sage: eq.find_root(0,1)
0.4435735341042928
sage: eq.find_root(0,2)
1.9048930509820137
sage: eq.find_root(2,5)
4.011527092383197
sage: eq.find_root(5,7)
5.998419479660961
sage: eq.find_root(7,9)
8.000213516551632
sage: eq.find_root(9,11)
9.999971096671594

Or, more compactly:

sage: endpoints = [0,1,2,5,7,9,11]
sage: [eq.find_root(i,j) for (i,j) in zip(endpoints,endpoints[1:])]
[0.4435735341042928,
1.9048930509820123,
4.011527092383197,
5.998419479660961,
8.000213516551632,
9.999971096671594]
more

To complete tmonteil's answer : you can show that for x>5, say, $e^{-x}$ is negligible compared to $\sin(x)$, with a small upper bound $b$. Given that the slope of $\sin(x)$ is also bounded by -1 and 1 and continuity pf those functions, you can deduce (Rolle's theorem and corollaries) a "research box" around the (known) roots of $\sin{x}$ guaranteeing you that $e^{-x}\sin{\frac{\pi x}{2}}$ has exactly one root in this box, numerically found by bfind_root with arbitrary precision. Thius obtraining an arnitrarily precise solution.

You can also show that your function has no negative roots, and finally establish, by similar arguments the existence of three roots between 0 and 5.

( 2020-09-18 17:39:48 -0500 )edit

Although for other functions, if there is no root in an interval, you get a RuntimeError that has to be accounted for. So, a bit more obtuse example:

var('k x')
eq = x^3-5*x^2+15==0
ranges = [[k,k+1] for k in [-10..10]]

for width in ranges:
try:
root = eq.find_root(width[0],width[1])
print(f"Root between {width[0]} and {width[1]} is {root}")
except RuntimeError:
print(f"No root between {width[0]} and {width[1]}")
more