#julia #numerical-methods
#джулия #численные методы
Вопрос:
Я пытаюсь реализовать метод дефляции для нахождения нескольких корней многочлена на Julia. В методе дефляции новые функции генерируются из фактической функции, разделенной на x - x_roots[i]
, и корень новой сгенерированной функции должен быть найден. Но g(x) = g(x) / (x - x_root)
выдает мне ошибку переполнения стека, поскольку, вероятно, она сгенерировала бесконечное рекурсивное отношение. Как я могу генерировать новую функцию на каждом шаге?
function deflation(f::Function, order)
roots=[]
n=1
g(x)=f(x)
x_root=Muller_method(f,-5,0,5,1e-5,50)
while n<=order
x_root=Muller_method(a,-5,0,5,1e-5,50)
g(x)=g(x)/(x-x_root)
append!(roots,x_root)
n=n 1
end
return (roots)
Комментарии:
1. Вы должны попробовать опубликовать минимальные (не) рабочие примеры, которые мы можем воспроизвести в наших собственных системах. Например, ваш код (в его нынешнем виде) содержит несколько ошибок, которые совершенно не связаны с вашим вопросом:
g
никогда не вызывается,a
иMuller_method
не определены, вdeflation
определении функции отсутствуетend
ключевое слово… Наличие воспроизводимого примера помогло бы нам помочь вам!2. Кстати, инициализировать нетипизированные массивы с помощью
[]
часто не очень хорошая идея. Если вы знаете, чтоroots
будет содержать только числа с плавающей запятой, было бы намного лучше инициализировать его следующим образом, например:roots = Float64[]
.3. Я не поделился этой частью, потому что думал, что это не так. Прошу прощения за то, что это был мой первый пост. Большое вам спасибо.
Ответ №1:
Что-то подобное вызывает бесконечную рекурсию:
julia> g(x) = x
g (generic function with 1 method)
julia> g(1)
1
julia> g(x) = g(x) / 2
g (generic function with 1 method)
julia> g(1)
ERROR: StackOverflowError:
Stacktrace:
[1] g(::Int64) at ./REPL[3]:1 (repeats 79984 times)
Это связано с тем, что определения функции (или метода) не работают как присвоение переменной: каждое повторное определение g(x)
перезаписывает предыдущее (обратите внимание, что g
выше всегда используется только один метод). Когда определение метода ссылается на самого себя, это рекурсия, то есть оно ссылается на свою собственную версию в момент вызова функции.
Что касается вашего метода дефляции, возможно, вы могли бы определить новую функцию, которая закрывает вектор найденных в данный момент корней. Рассмотрим следующий пример, чтобы увидеть, как все будет работать:
julia> f(x) = (x-1) * (x-2)
f (generic function with 1 method)
julia> roots = Float64[]
Float64[]
# g is defined once, and accounts for all currently found roots
julia> g(x) = f(x) / reduce(*, x-root for root in roots; init=one(x))
g (generic function with 1 method)
# No roots are identified at the beginning
julia> g(1 eps())
-2.2204460492503126e-16
julia> g(2 eps())
0.0
# But the results produced by g update as roots are identified
julia> push!(roots, 1.)
1-element Array{Float64,1}:
1.0
julia> g(1 eps())
-0.9999999999999998
julia> g(2 eps())
0.0
Комментарии:
1. Большое вам спасибо. Я не знал метода уменьшения. Это мне очень помогло, еще раз спасибо.