Search code examples
pythonnumerical-methodsnewtons-method

newton method using python


p= lambda x: 3 * x**3 - 5.03 * x**2 - 1.95 * x + 0.02

dp = lambda x: 9 * x**2 - 10.06 * x - 1.95
x0 = -1
tol = 10**-4
max_iter = 100

def newton_method(f, df, x0, tol, max_iter=100):
    for i in range(max_iter):
        fx = f(x0)
        dfx = df(x0)
        if df==0 and dfx!=0 :
            raise Exception('division by 0')
        
        elif fx==0:
            return i, x0
        
        x = x0 - fx/dfx
        
        if abs(x-x0) <=tol:
              return i, x0
        x0 = x
    raise ValueError("The newton method doesn't converge after {} iterations".format(max_iter))

c,r = newton_method(p, dp , x0, tol, max_iter)
print("Approssimazione:", r,c)

the function looks like that works well if i put a starting point of -1 or 0, but if i put a value near 5 ( another zero is circa 5.3) the function "converges" to 2 that is far from being a a solution.

it is even odder if i put x_0=2 because the function does 0 iterations and regards 2 as a solution no matter which tolerance i put, it is like the function shuts when it checks if the absolute value is lesser or equal than the tolerance, but if i try to compute the x term at i=0 the result isn't lesser or equal than any tolerance, could someone help me to understand what's wrong with the algorithm?


Solution

  • The graph for the function 𝑓(𝑥)=3𝑥³−5.03𝑥²−1.95𝑥+0.02 looks like this (produced by Wolfram):

    enter image description here

    The roots are at:

    • 𝑥 = −1/3
    • 𝑥 = 1/100
    • 𝑥 = 2

    The results you get from running your function are as expected.

    Notably, when you start with 5, it is expected that the process converges to 2, which is a solution. On the other hand 5.3 is not a zero-point of this function.