Search code examples
pythonfunctioncall

Can't figure out what to do for "call function until otherwise"


I'm taking an university course on python, I'm stuck on an assignment question that asks for the following:

Write a function iterate with the following arguments:

f: a function
start: a numeric starting value
tol: a numerical tolerance (default value 1e-6)
itmax: a maximum number of iterations (default value 1000)

Starting from the initial value, your function should keep repeating calls to the function (e.g. y=f(y)) until the absolute value of f(y)-y is less than tol or the number of iterations is equal to itmax.

To check if my code is correct, the following should be True

print(approx_equal(iterate(math.sqrt,1.01,tol=1e-4),[6, 1.0000777399813863]))
print(approx_equal(iterate(math.cos,0),[34, 0.7390855263619245]))
print(approx_equal(iterate(math.cos,0,tol=1e-8),[46, 0.7390851366465718]))
print(approx_equal(iterate(math.cos,0,itmax=5),[5, 0.7013687736227565]))

This is what I have so far:

def approx_equal(f,start,tol,itmax):
    y=start
    tol=1e-6
    itmax=1000
        for i in range(itmax):
                y=f(y)
        while abs(f(y)-y) < tol or i==itmax:
                break

I'm not sure how to do the "repeat calls to the function until the absolute value of f(y)-y is less than tol or the number of iterations is equal to itmax.


Solution

  • Your function is pretty close, but you have a couple of issues. To pass a default value for a parameter, you need to do it in the first line of the definition statement. The way you have it currently written, tol will always be 1e-6 and itmax will always be 1000.

    Also, you should add a check against the tolerance using if. You can use either break or return if the difference is less than the tolerance. break will break the for loop, but return will exit the function and give a value.

    def approx_equal(f, start, tol=1e-6 ,itmax=1000):
        y = start
        for i in range(itmax):
            y_new = f(y)
            if abs(y_new-y) < tol:
                return y  # return the value when the next iteration is not needed
            else:
                y = y_new