-1

I'm new to python and i'm having a hard time trying to find the root of a polynomial via using the bisection method. So far I have 2 methods. One for evaluating the polynomial at value x

 def eval(x, poly):
 """
Evaluate the polynomial at the value x.
poly is a list of coefficients from lowest to highest.

:param x:     Argument at which to evaluate
:param poly:  The polynomial coefficients, lowest order to highest
:return:      The result of evaluating the polynomial at x
"""

result = poly[0]
for i in range(1, len(poly)):
  result = result + poly[i] * x**i

return result

The next method is supposed to use bisection to find the root of the polynomials given

def bisection(a, b, poly, tolerance):
poly(a) <= 0
poly(b) >= 0

try:
    if









"""
Assume that poly(a) <= 0 and poly(b) >= 0.

:param a: poly(a) <= 0  Raises an exception if not true
:param b: poly(b) >= 0  Raises an exception if not true
:param poly: polynomial coefficients, low order first
:param tolerance: greater than 0
:return:  a value between a and b that is within tolerance of a root of the polynomial
"""

How would I find the root using bisection? I have been provided a test script to test these out.

EDIT: I followed the pseudocode and ended up with this:

def bisection(a, b, poly, tolerance):
#poly(a) <= 0
#poly(b) >= 0
difference = abs(a-b)
xmid = (a-b)/2
n = 1
nmax = 60




while n <= nmax:
 mid = (a-b) / 2
 if poly(mid) == 0 or (b - a)/2 < tolerance:
       print(mid)

 n = n + 1
 if sign(poly(mid)) == sign(poly(a)):
     a = mid
 else:
     b = mid


return xmid

is this correct? I havent been able to test it because of indentation errors with the return xmid statement.

Asen Christov
  • 848
  • 6
  • 21
dabrams493
  • 61
  • 6
  • Just follow the pseudo-code here : https://en.wikipedia.org/wiki/Bisection_method ? – a_pradhan Aug 31 '15 at 07:55
  • Why do you want to reinvent the wheel ? http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.optimize.bisect.html – Moritz Aug 31 '15 at 09:01

1 Answers1

0

Your code seems fine, besides the mess with xmid and mid. mid = (a + b) / 2 instead of mid = (a - b) / 2 and you don't need the difference variable.

Cleaned it up a bit:

def sign(x):
  return -1 if x < 0 else (1 if x > 0 else 0)

def bisection(a, b, poly, tolerance):
  mid = a # will be overwritten
  for i in range(60):
    mid = (a+b) / 2
    if poly(mid) == 0 or (b - a)/2 < tolerance:
      return mid
    if sign(poly(mid)) == sign(poly(a)):
      a = mid
    else:
      b = mid
  return mid

print(bisection(-10**10, 10**10, lambda x: x**5 - x**4 - x**3 - x**2 - x + 9271, 0.00001))
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97