Question

I understand that this has been solved in C/C++, but I am not comfortable enough with those languages to be able to convert it to python. I am trying to create this in python. The closest I was able to come was this:

#This is meant to work for functions of the form x^a + b = 0

def secant(base, exp=2, it=20):
    def f(x):
        return x**exp - base
    x1 = base / float(exp**2)
    xnm1 = x1 - 5
    xnm2 = x1 + 5
    xn = 0
    for n in range(it):
        q = (xnm1-xnm2)/float(f(xnm1)-f(xnm2))
        xn = xnm1 - (f(xnm1)*q)
        xnm1, xnm2 = xn, xnm1
    return xn

print secant(2, 2)

This returns the error:

Traceback (most recent call last):
  File "/Users/Joe/Desktop/secant.py", line 16, in <module>
    print secant(2, 2)
  File "/Users/Joe/Desktop/secant.py", line 11, in secant
    q = (xnm1-xnm2)/float(f(xnm1)-f(xnm2))
ZeroDivisionError: float division by zero

I was able, however, to program the Newton method, which I based this code off of. If it helps, here it is:

def newton(base, exp=2, it=20):
    def f(x):
        return x**exp - base
    def df(x):
        return exp*(x**(exp-1))
    x1 = base / float(exp**2)
    xnp = x1
    xn = 0
    for n in range(it):
        xn = xnp - ((f(xnp)/df(xnp)))
        xnp = xn
    return xn

The following method gives an answer with 12 digits of accuracy after 20 iterations. Any help would be appreciated.

Was it helpful?

Solution

You are getting a division by zero error because the algorithm converged to the answer within the precision of Python floats. In addition to iterating a maximum number of times (to avoid an infinite loop), you should also check if the last two guesses are "close enough".

OTHER TIPS

It is the round of float number that matters. In the former case, after some iterations, the difference between f(xnm1) and f(xnm2) are so small that the float will fail to represent it, so it will be rounded to zero, then the error is thrown.

In the latter one, we calculate the slope at that point directly by using derivative, though which is small, it is non-zero(yet it will almost remains a same value in the next iterations), so it will not throw an error.

Here's an example, and IEEE floating point.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top