Ваша главная проблема в вашей рутине x_next
.У вас есть 1
, где должно быть x_n
.Таким образом, процедура должна быть
def x_next(f, x_n):
return x_n - (f(x_n) / derivative(f, x_n))
Ваша производная программа также плохая.Если вам нужно приблизить производную, Ньютон-Рафсон не лучший метод для использования.Ваш метод аппроксимации, который вы используете, также не годится в численном отношении, хотя он следует определению производной.Если вы должны использовать приближение, используйте
def derivative(f, x):
dx = 1E-8
return (f(x + dx) - f(x - dx)) / (2.0 * dx)
Но в этом случае производную очень легко вычислить напрямую.Так что лучше использовать
def derivative(f, x):
return -2 * 1.5 * np.cos(x) / 2.7
. Вы также не печатаете свое окончательное приближение для корня и его значения функции - вы вычисляете его и возвращаете, не печатая.Поэтому поместите свой оператор print
, прежде чем проверять его на возвращение.
С этими изменениями (плюс комментирование импорта matplotlib
, который вы никогда не используете), ваш код теперь
#import matplotlib.pyplot as plt
import numpy as np
def f(theta):
return 1 - (((2 * 1.5) * np.sin(theta))/ 2.7)
def derivative(f, x):
return -2 * 1.5 * np.cos(x) / 2.7
def x_next(f, x_n):
return x_n - (f(x_n) / derivative(f, x_n))
def newtons_method(f, x_n = 1, i = 0, max_iter = 100):
i = i + 1
if (i == max_iter):
return None
x_n = x_next(f, x_n)
print("i:",i,"x_n:",x_n,"f(x_n)",f(x_n))
if (abs(f(x_n)) < 1E-4):
return x_n
newtons_method(f, x_n, i, max_iter)
print(newtons_method(f))
и результат - только две строки
i: 1 x_n: 1.1083264212579311 f(x_n) 0.005607493777795347
i: 2 x_n: 1.1196379358595814 f(x_n) 6.373534192993802e-05
, что вы и хотите.Если вы настаиваете на использовании числового приближения для производной, используйте версию, которую я дал выше, и результат немного отличается:
i: 1 x_n: 1.10832642185337 f(x_n) 0.005607493482616466
i: 2 x_n: 1.1196379360265405 f(x_n) 6.373526104597182e-05