Рекурсивно используя выход в качестве входа для функции
Редактировать: это постоянная проблема с перебалансированным портфелем.
Кто-нибудь знает, какую функцию использовать для рекурсивного вызова?
let s = сток;
пусть с = наличные деньги;
пусть X_0 = начальное богатство;
пусть r = случайный вектор выглядит так (1,-0,5,-0,5,1, -. 5,1,1,1-0,5,...) # вероятность получения 1 или 0,5 составляет 50%.
X_0 = s + c
X_1 = 1/2 * x_0 * (1 + r) + 1/2 * x_0
X_2 = 1/2 * x_1 * (1 + r) + 1/2 * x_1 # в этом уравнении x_0 заменено на x_1, вот и все
X_3 = 1/2 * x_2 * (1 + r) + 1/2 * x_2
.... и так далее,
Есть ли в R функция, которая принимает входные данные с последнего шага в качестве входных данных для этого шага?
do.call? lapply? отзыв? Я не мог понять это!
Заранее спасибо!
2 ответа
Его работа сделана специально для функции высшего порядка Reduce
, Вот код
calc_wealth <- function(x, r){
return(0.5*x*(1 + r) + 0.5*x)
}
x0 <- 10
set.seed(1234)
r <- sample(c(-0.5, 1), size = 5, replace = TRUE, prob = c(0.5, 0.5))
wealth <- Reduce('calc_wealth', r, init = x0, accumulate = TRUE)
> r
[1] 1.0 -0.5 -0.5 -0.5 -0.5
> wealth
[1] 10.000000 15.000000 11.250000 8.437500 6.328125 4.746094
Вот соответствующая документация для Reduce
извлечено из файла справки.
Reduce(f, x, init, right = FALSE, accumulate = FALSE)
Reduce использует двоичную функцию для последовательного объединения элементов данного вектора и, возможно, заданного начального значения. Если задано значение init, Reduce логически добавляет его в начало (при переходе слева направо) или конец x соответственно. Если этот возможно расширенный вектор v имеет n > 1 элементов, Reduce последовательно применяет f к элементам v слева направо или справа налево соответственно. Т.е. уменьшение влево вычисляет l_1 = f(v_1, v_2), l_2 = f(l_1, v_3) и т. Д. И возвращает l_{n-1} = f(l_{n-2}, v_n),
[EDIT:] ОП пояснил, что r
изменяет каждый цикл, и они хотят избежать использования for
петля.
В этом случае вы можете попробовать что-то вроде:
# generate vector of .5s and 1s with 50% probability of each.
# length N.
rs <- ifelse(runif(N)<.5,.5,1)
x0 <- ... # set x0
x <- x0
# loop over rs, evaluation a new x each time. Note the '<<-'
vapply( rs, function(r) x <<- 1/2*x*(1+r)+1/2*x, -1 )
x # contains final value after N iterations.
Помните vapply
требует третьего аргумента, дающего тип возвращаемого значения функции, и это немного ускоряет его sapply
и т. д. ?vapply
).
Значение <<-
это изменить x
в глобальной среде, а не в рамках функции в vapply
,
Применяются обычные предостережения для возни в других областях (т.е. будьте осторожны, вы не изменяете x
в какой-то среде ты не хотел).
Вы могли бы достичь этого с for
цикл:
N = number of times to iterate the loop
x_0 <- s+c
x <- x_0
for ( i in 1:N ) {
# [calculate r here]
# calculate x
x <- 1/2*x*(1+r) + 1/2*x
}
Однако ваше уравнение выглядит так, что его можно упростить, чтобы избежать всего этого:
x_{i+1} = 1/2 * x_i * (1+r) + 1/2 * x_i
= 1/2 * x_i * (1+r +1)
= 1/2 * x_i * (2+r)
В этом случае можно увидеть, что:
x_n = [1/2 * (2+r) ]^n * x_0
Когда вы говорите, что r
является "не постоянным", вы имеете в виду, что он меняется каждый раз, когда вы рассчитываете x_i
? Как в r
в уравнении для x_1
это не то же самое, что r
в уравнении для x_2
? В этом случае вы должны использовать цикл for и упрощенное уравнение для x_n
не действителен