#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. Я понял, что этот цикл был перегружен, и предложил это решение в моем длинном тексте. Наверное, я надеялся найти решение с использованием рекурсии. Может быть, я слишком увлекаюсь.