Whats going on with this code that finds roots?

时间:2016-07-11 20:00:44

标签: python

Lines Im having trouble with are:

  1. while not withinEpsilon(ans**pwr, val, epsilon): is it, while withinEpsilon is false, continue executing?

  2. Why do I need a negative absolute value and why is it between max val and 1?

    low = -abs(val)    
    high = max(abs(val), 1.0)
    
  3. if isEven(pwr) and val < 0: Why would it matter if the power was even?

Here is the full code:

def isEven(i):
    '''assumes i is a positive int
       returns true if i is even, otherwise False'''
    return i%2 == 0

def findRoot(pwr, val, epsilon):
    '''assumes pwr an int; val, epsilon floats > 0'''
    assert type(pwr) == int
    assert type(val) == float
    assert type(epsilon) == float
    assert pwr > 0 and epsilon > 0
    if isEven(pwr) and val < 0:
        return None
    low = -abs(val)
    high = max(abs(val), 1.0)
    ans = (high + low)/2.0
    while not withinEpsilon(ans**pwr, val, epsilon):
        #print 'ans =', ans, 'low =', low, 'high =', high
        if ans**pwr < val:
           low = ans
        else:
           high = ans
        ans = (high + low)/2.0
    return ans

def testFindRoot():
    """x float, epsilon float, pwr positive int"""
    for x in (-1.0, 1.0, 3456.0):
        for pwr in (1, 2, 3):
            ans = findRoot(pwr, x, 0.001)
            if ans == None:
                print 'The answer is imaginary'
            else:
                print ans, 'to the power', pwr,\
                'is close to', x 

testFindRoot()

1 个答案:

答案 0 :(得分:1)

  1. Yes, the code specifies to continue looping while withinEpsilon is False.
  2. The code is using dichotomy to find "ans" such that "0 < |val - ans**n| < epsilon".

    "low" must be smaller than the root, and "high" must be bigger : that's why low = -|val|

    You can check that for any value u, (-u)**n < u (except when u is negative and exponent is even)

    high = max(|val|, 1) because if |val| > 1, |val| ** n > |val| >= val and if |val| < 1, the root is necessarily smaller than 1

  3. If the power is even and the value is negative, your root cannot be Real (because x**2n cannot be negative for any x in R)