Home > other >  How to Make Python Print something at nth Iteration within a For Loop?
How to Make Python Print something at nth Iteration within a For Loop?

Time:02-11

I want to preface my question by saying that I am very new to Python and have only started using it for a specific class in grad school.

I have written a script to find the root of a function using iterative methods such as the Fixed-point, Bisection, and Newton-Raphson methods. The python code for my algorithms are as follows:

Fixed-Point Method:

def fixedpoint(func, g_func,x0,tol, MAXIT):
    
    def g(x):
        return eval(g_func)
    
    print(f"Seeking root of {func}.")
    print("FIXED POINT ITERATION:")
    iterated_x = g(x0)
    for i in range(0, MAXIT):
        iterated_x = g(iterated_x)
        print("Iteration", i   1, iterated_x)
        condition = abs(g(iterated_x) - (iterated_x)) 
        if condition < tol:
            print(f"The root converges to {iterated_x} after {i 1} iterations.")
            break
        if i == MAXIT and condition >= tol:
            print("ERROR: The root did not converge after maximum iterations.")

fixedpoint('x**2 - 4*x   2', '(x**2 2)/4', 0.75, 10**(-4), 100)
fixedpoint('math.exp(-x)   x - 7 ', '7 - math.exp(-x)', 0.75, 10**(-4), 100)

Bisection Method:

def bisection(func,a, b, tol, MAXIT):
    
    def f(x):
        return eval(func)
    
    print(f"Seeking root of {func}")
    print("BISECTION METHOD:")
    if f(a)*f(b) <0:
        for i in range(0, MAXIT):
            c = (a b)/2
            if f(a)*f(c) < 0:
                a = a
                b = c
                print(f"Iteration", i   1, f(c))
            elif f(b)*f(c) < 0:
                b = b
                a = c
                print(f"Iteration", i   1, f(c))
            if f(c) == 0 or abs(f(c)) < tol:
                print ("Exact Solution Found")
                print(f"Iteration", i   1, c)
                print("The root converges to", c, "after", i   1, "iterations.")
                break
            elif i == MAXIT and abs(f(c)) > tol:
                print("Bisection method fails.")
                
    return None

bisection('x**2 - 4*x   2',0.5, 1, 10**(-4), 100)
bisection('math.exp(-x)   x - 7',6, 8, 10**(-4), 100)

Newton-Raphson Method:

def newtonraphson(func, deriv, x0, tol, MAXIT):
    
    def f(x):
        return eval(func)

    def ddx(x):
        return eval(deriv)
        
    
    print(f"Seeking root of {func}.")
    print("NEWTON-RAPHSON METHOD:")
    
    for i in range(1, MAXIT):
        iterated_x = x0 - (f(x0)/ddx(x0))
        x0 = iterated_x
        print(f"Iteration", i, x0)

        if f(x0) < tol:
            print(f"The root converges to {x0} after {i} iterations.")
            break
        elif i==MAXIT and f(x0) > tol:
            print("After maximum iterations, root was not found.")

newtonraphson('x**2-4*x 2', '2*x-4', 0.75,10**(-4), 100)
newtonraphson('math.exp(-x)   x - 7', '-(math.exp(-x))   1', 0.75,10**(-4), 100)

While my script is successfully able to find the roots for the equations I am interested in, I am stuck with a simpler problem. Basically, I want to tell my program that if after maximum iterations, my tolerance condition is not fulfilled, print "Method Failed".

However, my code does not print the statement I want it to when I experiment with functions that don't coverage when maximum iterations is set at 100 and tolerance is set to 0.0001.

Is my syntax right for the fail print statement?

Do conditions like "if i==MAXIT and f(x0) > tol" make sense in the context of the function I have written?

I would appreciate any and all advice for this issue as I am trying hard to improve at Python.

Thank you.

CodePudding user response:

The problem you are facing is that range in python only function from the start index to one before the end index. That is, range(0,3) goes over the numbers (0,1,2). What is happening in your code is that you simply fail to activate the fail condition because the index never actually reaches that value. However, the fix is easy. In your functions where you say:

for i in range(1,MAXIT):
    if f(x0) < tol:
        print(f"The root converges to {x0} after {i} iterations.")
        break
    elif i==MAXIT and f(x0) > tol:
        print("After maximum iterations, root was not found.")

simply replace it with

for i in range(1,MAXIT):
    if f(x0) < tol:
        print(f"The root converges to {x0} after {i} iterations.")
        return

print("After maximum iterations, root was not found.")

instead. What this will do is stop the function if it finds the solution, and give you your error message if you manage to get through the entire loop without finding the answer.

  • Related