Is My Python Bisection Method Code Correct?

Join the discussion
Registration is free. Ask a follow-up in this thread, or start your own.
1 reply · 2K views
ver_mathstats
Messages
258
Reaction score
21
Python:
import math

def poly(x):
    return (x**4 + 2*x**3 - 7*x**2 - 8*x + 12)

def bisect(f,a,b,tol=1e-6):
    while (b-a)>tol:
        m=(a+b)/2
        if (f(a)>=0>=f(m)) or (f(a)<=0<=f(m)):
            b=m
        else:
            a=m
    return (f(a),a)

print(bisect(poly,-4,-2.5))

Here is the code I have using a guide by my teacher. I put a test value at the end just to see if there was an error when I ran it which there was not. Could this please be checked over as I am unsure if I did this right? Thank you.
 
Physics news on Phys.org
ver_mathstats said:
Could this please be checked over as I am unsure if I did this right? Thank you.
Does it come up with the right answer?

There are are couple of things that I notice:
Python:
if (f(a) >= 0 >= f(m)) or (f(a) <= 0 <= f(m)):
This uses an unusual feature of Python called conditional expression chaining which in many other languages will throw an error but in some others will appear to work but give the wrong answer. It is also completely unnecessary here and
Python:
if ((f(a) >= 0 and 0 >= f(m)) or (f(a) <= 0 and 0 <= f(m)):
will compile to exactly the same code. In this situation there are two schools of thought:
  • You should use all the features of a language that are available if they improve understanding for people that know the language well;
  • You should avoid 'quirks' of any particular language if they may be misunderstood by people that may not know the language as well as you do.
This also applies to human language of course, and the general rule is that you should adapt your language to the audience. If was writing to a lawyer I might have said "this dilemma applies mutatis mutandis in human language" (well I wouldn't of course, but I couldn't think of a better example). So as this is (I assume) a general introduction to programming course, I would avoid conditional expression chaining.

But more importantly,
Python:
from numpy import sign
...
if (sign(f(a)) == sign(f(m)):
    a = m
else
    b = m
Has the same result, is easier to read and more efficient because f(a) and f(m) are only evaluated once.

I would also think again about
Python:
    return (f(a),a)
  • - is a always the best approximation you have calculated at this point?
  • - it is possible that a or b is by chance an exact (within machine epsilon) root, what does your code do then?