Вложение рекурсивной функции в другую

#r #recursion

#r #рекурсия

Вопрос:

Я мало занимался рекурсивными функциями, но успешно закодировал f() , который выполняет задачу вывода вектора (в данном случае N = 3) вероятностей.

 # Data
ps <- structure(c(0.68, 0.255, 0, 0.17, 0.595, 0, 0.15, 0.15, 1), .Dim = c(3L, 3L))
po <- structure(c(0.7, 0, 0, 0.3, 1, 1), .Dim = 3:2)
pp <- c(1,0,0)
y <- c(1,1,2,1,2,2,1,2)
 
 # Recursive function
f <- function(o,pp,q = 1,si = 1:(nrow(ps)){
  if(q == length(si)) return(0)
  else{
    return(ps[q,si]*po[si,o]*pp[q]   f(o = o,pp = pp,q 1,si = si))
  }
}

> f(y[2],pp)
[1] 0.476 0.000 0.000
> f(y[3],pp)
[1] 0.204 0.170 0.150
 

Теперь мне нужен вывод f(o = y[2],pp = pp) в качестве аргумента для pp in f(o = y[3],pp = .) . И так далее, и так далее, пока o не будет исчерпан. Интуитивно кажется, что рекурсия снова является ответом, но я не могу найти решение.

Я могу прийти к правильному ответу несколькими способами. Ниже for приведен цикл. Этот ответ кажется расточительным, поскольку я бы инициализировал матрицу каждый раз, когда вызываю функцию, а также сохранял ненужные значения. Я полагаю, что другим решением было бы продолжать перезаписывать pp в цикле. Другим способом было бы вложить или соединить их вместе, но это кажется избыточным и не очень гибким. f() Есть ли более элегантное решение?

Желаемый результат:

 g <- function(pp,obs){
  b <- matrix(0,3,8)
  b[,1] <- pp
  for(i in 2:8){
    b[,i] <- f(o = obs[i],pp = b[,i-1])
  }
  log(sum(b[,8]))
}

> g(pp = pp,obs = y)
[1] -6.439479
 

PS Я понимаю, что есть доступные пакеты, которые будут делать то, что я пытаюсь сделать (скрытый алгоритм пересылки модели Маркова). Я просто пытаюсь понять, что происходит под капотом, и лучше разобраться в рекурсивном программировании. Я ценю любую помощь от сообщества. Спасибо!!

Ответ №1:

Вам не нужна матрица, вы можете просто продолжать заменять pp значения

 g <- function(pp, obs) {
  for ( i in 2:8) {
    pp <- f(obs[i], pp)
  }
  log(sum(pp))
}
g(pp, y)
# [1] -6.439479
 

Комментарии:

1. Я понял, что этот цикл был перегружен, и предложил это решение в моем длинном тексте. Наверное, я надеялся найти решение с использованием рекурсии. Может быть, я слишком увлекаюсь.