help me here, estimating the root of the equation. Here is a code:
def binary_search(f,domain, MAX = 1000):
start, end = domain
if start >= end:
raise ValueError("Domain is empty")
mid = (start end) / 2
fmid = f(mid)
step = 0
while abs(fmid) > 0.0001 and step < MAX:
if fmid < 0:
start = mid
else:
end = mid
mid = (start end) / 2
fmid = f(mid)
step = 1
return round(mid, 2)
Here are inputs:
import numpy as np
f = lambda x:(np.sin(x)**2)*(x**2)-2
domain = (0,2)
x=binary_search(f,domain)
x
The problem with this code is not consistent. When the domain is (0, 2) it gives the expected answer, which is 1.43. However, in the domain (2, 3) and (-2, -1) it gives wrong answers which are 2.0 and -2.0 respectively. But I noticed that when I change the if statement under ‘while loop’ from "f mid < 0” to “fmid > 0”, the domains (2, 3) and (-2, -1) give correct answers, which are 2,56 and -1,43 respectively. But now, the domain (0, 2) gives the wrong answer. How can I fix this?
CodePudding user response:
The problem lies in the fact that your code assumes whether the function is increasing or decreasing. And the logic you are refering to just changes this assumption. However your function is increasing in some intervals and decreasing in the others.
if fmid < 0:
start = mid
else:
end = mid
should be (using import numpy as np
)
if np.sign(fmid) == np.sign(f(start)):
start = mid
else:
end = mid
or without numpy
if fmid * f(start) >= 0:
start = mid
else:
end = mid
In other words we move the left limit iff the signs between mid and left match. Alternatively you could just run your function twice with arguments shuffled and get the smaller absolute value.