Я пытаюсь решить это упражнение для колледжа.Я уже представил код ниже.Однако я не совсем доволен этим.
Задача состоит в том, чтобы построить реализацию метода Ньютона для решения следующей нелинейной системы уравнений:
В порядкеЧтобы изучить метод Ньютона, помимо занятий, я посмотрел это видео на YouTube: https://www.youtube.com/watch?v=zPDp_ewoyhM
Парень на видео объяснил математический процесс, лежащий в основе метода Ньютона, и вручную сделал две итерации.
Я сделал реализацию Python для этого, и код отлично подошел для примера на видео.Тем не менее, пример на видео имеет дело с 2 переменными, а моя домашняя работа - с 3 переменными.Следовательно, я адаптировал его.
Это код:
import numpy as np
#### example from youtube https://www.youtube.com/watch?v=zPDp_ewoyhM
def jacobian_example(x,y):
return [[1,2],[2*x,8*y]]
def function_example(x,y):
return [(-1)*(x+(2*y)-2),(-1)*((x**2)+(4*(y**2))-4)]
####################################################################
### agora com os dados do exercício
def jacobian_exercise(x,y,z):
return [[1,1,1],[2*x,2*y,2*z],[np.exp(x),x,-x]]
#print (jacobian_exercise(1,2,3))
jotinha = (jacobian_exercise(1,2,3))
def function_exercise(x,y,z):
return [x+y+z-3, (x**2)+(y**2)+(z**2)-5,(np.exp(x))+(x*y)-(x*z)-1]
#print (function_exercise(1,2,3))
bezao = (function_exercise(1,2,3))
def x_delta_by_gauss(J,b):
return np.linalg.solve(J,b)
print (x_delta_by_gauss(jotinha, bezao))
x_delta_test = x_delta_by_gauss(jotinha,bezao)
def x_plus_1(x_delta,x_previous):
x_next = x_previous + x_delta
return x_next
print (x_plus_1(x_delta_test,[1,2,3]))
def newton_method(x_init):
first = x_init[0]
second = x_init[1]
third = x_init[2]
jacobian = jacobian_exercise(first, second, third)
vector_b_f_output = function_exercise(first, second, third)
x_delta = x_delta_by_gauss(jacobian, vector_b_f_output)
x_plus_1 = x_delta + x_init
return x_plus_1
def iterative_newton(x_init):
counter = 0
x_old = x_init
print ("x_old", x_old)
x_new = newton_method(x_old)
print ("x_new", x_new)
diff = np.linalg.norm(x_old-x_new)
print (diff)
while diff>0.000000000000000000000000000000000001:
counter += 1
print ("x_old", x_old)
x_new = newton_method(x_old)
print ("x_new", x_new)
diff = np.linalg.norm(x_old-x_new)
print (diff)
x_old = x_new
convergent_val = x_new
print (counter)
return convergent_val
#print (iterative_newton([1,2]))
print (iterative_newton([0,1,2]))
Я почти уверен, что этот код определенно не совсем неправильный. Если я введу начальные значения каквектор [0,1,2], мой код возвращает в качестве выхода [0,1,2].Это правильный ответ, он решает три уравнения, приведенные выше.
Более того, если вход [0,2,1], немного другой вход, код также работает, и ответ, который он возвращает, также является правильнымone.
Однако, если я изменю свое начальное значение на что-то вроде [1,2,3], я получу странный результат: 527.7482, -1.63 и 2.14.
Этот результат не даетлюбое чувство.Посмотрите на первое уравнение, если вы введете эти значения, вы можете легко увидеть, что (527) + (- 1.63) + (2.14) не равно 3. Это неверно.
Если я изменю входзначение, близкое к правильному решению, например [0.1,1.1,2.1], также приводит к сбою.
ОК, метод Ньютона не гарантирует правильную сходимость. Я знаю.Помимо прочего, это зависит от начального значения.
Является ли моя реализация неверной в любом случае?Или вектор [1,2,3] является просто «плохим» начальным значением?
Спасибо.