Способ выхода из внутренней части цикла в общем случае - оператор break
;return
выполняет ту же цель, потому что он просто выходит из всей функции.
Для сравнения вы можете использовать Base.isapprox(x, y; atol=atol, rtol=rtol)
. Документация начинается с:
Неточное сравнение на равенство: true
, если norm(x-y) <= max(atol, rtol*max(norm(x), norm(y)))
.
norm
возвращается к abs
для чисел. И я думаю, что вы могли бы иметь ошибку в обоих сравнениях, всегда сравнивая значение в x0
с самим собой.
Что касается разрыва по нулевым производным, я думаю, здесь @assert
уместно: есливы получаете нулевую производную, вы не останавливаете итерацию и не возвращаете результат, но вы выдаваете ошибку, чтобы обозначить недопустимое условие. Таким образом, я бы написал вашу функцию следующим образом:
function newton_root_finding(f, ∂f, x0, rtol=1e-8, atol=1e-8)
x_old = x0
y_old = f(x0)
while true
df_old = ∂f(x_old)
@assert !isapprox(df_old, 0, rtol=rtol, atol=atol) "Zero derivative. No solution found."
x_new = x_old - y_old / df_old
y_new = f(x_new)
isapprox(y_old, y_new, rtol=rtol, atol=atol) && return x_new
x_old, y_old = x_new, y_new
end
end
Это возвращает 3.357392012620626e-26 + 1.4142135623730951im
в вашем тестовом примере, приблизительно sqrt(2)im
.