MIT 6.00 Метод Ньютона в Python 3

Это часть второй задачи, поставленной для MIT OCW 6.00 Intro to Computing and Programming using Python. Сначала я создал функцию, которая оценивает многочлен для заданного значения x. Затем функция, которая вычисляет производную для данного многочлена. Используя их, я создал функцию, которая оценивает первую производную для данного многочлена и значения x.

Затем я попытался создать функцию для оценки корня любого заданного многочлена в пределах допуска (эпсилон).

Тестовый пример внизу с ожидаемым результатом.

Я новичок в программировании и новичок в Python, поэтому я включил в код несколько комментариев, чтобы объяснить, что, по моему мнению, код должен делать.

def evaluate_poly(poly, x):
""" Computes the polynomial function for a given value x. Returns that value."""
answer = poly[0]
for i in range (1, len(poly)):
    answer = answer + poly[i] * x**i
return answer


def compute_deriv(poly):
"""
#Computes and returns the derivative of a polynomial function. If the
#derivative is 0, returns (0.0,)."""
dpoly = ()
for i in range(1,len(poly)):
    dpoly = dpoly + (poly[i]*i,)

return dpoly

def df(poly, x):
"""Computes and returns the solution as a float to the derivative of a polynomial function
"""
dx = evaluate_poly(compute_deriv(poly), x)
#dpoly = compute_deriv(poly)
#dx = evaluate_poly(dpoly, x)
return dx




def compute_root(poly, x_0, epsilon):
"""
Uses Newton's method to find and return a root of a polynomial function.
Returns a float containing the root"""
iteration = 0
fguess = evaluate_poly(poly, x_0) #evaluates poly for first guess
print(fguess)
x_guess = x_0 #initialize x_guess
if fguess > 0 and fguess < epsilon: #if solution for first guess is close enough to root return first guess
    return x_guess
else: 
    while fguess > 0 and fguess > epsilon:
        iteration+=1
        x_guess = x_0 - (evaluate_poly(poly,x_0)/df(poly, x_0))
        fguess = evaluate_poly(poly, x_guess)
        if fguess > 0 and fguess < epsilon:
            break #fguess where guess is close enough to root, breaks while loop, skips else, return x_guess
        else:
            x_0 = x_guess #guess again with most recent guess as x_0 next time through while loop
print(iteration)
return x_guess




#Example:
poly = (-13.39, 0.0, 17.5, 3.0, 1.0)    #x^4 + 3x^3 + 17.5x^2 - 13.39
x_0 = 0.1
epsilon = .0001
print (compute_root(poly, x_0, epsilon))
#answer should be 0.80679075379635201

Первые 3 функции возвращают правильные ответы, но compute_root (метод Ньютона), похоже, не входит в цикл while, потому что, когда я запускаю ячейку print(iteration), выдает 0. Я бы подумал, что, поскольку if fguess > 0 and fguess < epsilon: должен возвращать false для тестового примера (оператор print(fguess) печатает -13.2119 ), интерпретатор перейдет к else и войдет в цикл while, пока не найдет решение, которое находится в пределах эпсилона 0.

Я попытался устранить первые if else условия, чтобы у меня был только один оператор return, и у меня возникла та же проблема.

Что могло быть причиной того, что функция вообще пропустила цикл else case / while? Я в тупике!

Спасибо, что искали и / или помогали!


person Durf    schedule 17.09.2016    source источник
comment
Небольшое, но важное наблюдение: у вас нет доступа к 1-му (элементу с индексом 0) любого массива. Это должно быть for i in range (len(poly)):, а не for i in range (1, len(poly)):. Измените код в методах вычисления полиномов и производных, чтобы отразить это.   -  person EvilTak    schedule 17.09.2016
comment
Вы должны сами решать наборы задач.   -  person Padraic Cunningham    schedule 17.09.2016
comment
Это должно быть abs(fguess) < epsilon как условие для корня. На данный момент вы исключаете -epsilon < fguess < 0 как приблизительные решения.   -  person Lutz Lehmann    schedule 17.09.2016
comment
@EvilTak: Нет, эти циклы верны для полиномиальной оценки, соответственно. построение производных коэффициентов.   -  person Lutz Lehmann    schedule 17.09.2016
comment
Падраич, я ценю вашу приверженность академической честности, но, учитывая ограниченные ресурсы, я решил следовать политике: Из Руководства по сотрудничеству EdX: Это нормально, если кто-то покажет вам несколько шагов решения, в котором вы на какое-то время застряли, при условии конечно, вы пытались решить это самостоятельно, но безуспешно. Из Политики сотрудничества на ocw.mit.edu: Наша политика проста: если иное не указано в самом задании, не стесняйтесь сотрудничать друг с другом по всем отдельным группам задач, но отметьте, с кем вы сотрудничали. Спасибо!   -  person Durf    schedule 18.09.2016


Ответы (1)


Вроде бы небольшая оплошность. Обратите внимание, как fguess печатается со значением -13,2119. В вашем while условии (в else из compute_root) вам требуется fguess > 0 and fguess < epsilon, который не выполняется, поэтому дальше ничего не делается, и вы выходите без итераций.

Вместо:

while fguess < 0 or fguess > epsilon:

Дам вам то, что вам нужно:

-13.2119
7
0.806790753796352
person ptev    schedule 17.09.2016