Переназначить функцию и избежать рекурсивного определения в Julia

#recursion #julia

#рекурсия #julia

Вопрос:

Мне нужно работать с последовательностью функций

h_k(x) = (I f_k( ) )^k g(x)

для каждого k = 1, …, N.

Базовый пример (N = 2, f_k =f) выглядит следующим образом:

 f(x) = x^2
g(x) = x
h1(x) = g(x)   f(g(x))
h2(x) = g(x)   f(g(x))   f(g(x)   f(g(x)))
println(h1(1)) # returns 2
println(h2(1)) # returns 6
  

Мне нужно записать это в цикле, и было бы лучше переопределять g(x) на каждой итерации. К сожалению, я не знаю, как это сделать в Julia, не вступая в противоречие с синтаксисом рекурсивного определения g(x) . Действительно,

 f(x) = x^2
g(x) = x
for i=1:2
    global g(x) = g(x)   f(g(x))
    println(g(1))
end
  

приводит к ошибке StackOverflowError.

Как правильно переопределить g(x) в Julia, используя его предыдущее определение?

PS Для тех, кто предположил бы, что эту проблему можно решить с помощью рекурсии: я хочу использовать цикл for из-за того, как функции f_k(x) (в приведенном выше, каждая f_k = f) вычисляются в реальной задаче, из которой это вытекает.

Ответ №1:

Я не уверен, что это лучше, но естественным подходом является использование анонимных функций вот так:

 let
    f(x) = x^2
    g = x -> x
    for i=1:2
        l = g
        g = x -> l(x)   f(l(x))
        println(g(1))
    end
end
  

или вот так

 f(x) = x^2
g = x -> x
for i=1:4
    l = g
    global g = x -> l(x)   f(l(x))
    println(g(1))
end
  

(Я предпочитаю использовать первый вариант let , поскольку он позволяет избежать использования глобальных переменных)

Проблема в том, что l это локальная переменная цикла, которая получает новую привязку на каждой итерации, в то время g как является внешней по отношению к циклу.

Вы также можете ознакомиться с этим разделом руководства Julia.