此R脚本生成时间序列集合。该系列来自函数f(t)= alpha * f(t-0)+ epsilon,其中epsilon是来自正态分布的随机数。
最终结果是从不同的alpha值生成的合奏列表。
如何进行矢量化?使用基本功能会很棒,但也欢迎需要额外软件包的解决方案。
steps <- 1000 # number of times each "pseudo random walk" is iterated
N <- 5 # number of walks in each ensemble
mu <- 0 # normal distribution mean
mysd <- 1 # normal distribution standard deviation
alphas <- c(0, 0.5, 0.7, 1, 1.5, 2) # set of different alphas to generate ensembles with
# Pseudo random walk generator
generate.rw <- function(steps, alpha, my, mysd) {
epsilons <- rnorm(n = steps, mean = mu, sd = mysd)
rw <- vector(,steps)
rw[1] <- epsilons[1]
for (i in 2:steps) rw[i] <- alpha * rw[i-1] + epsilons[i]
return(rw)
}
# Ensemble generator
ensemble <- function(N, steps, alpha, mu, mysd) {
result <- matrix(,N,steps)
for (i in 1:N) result[i,] <- generate.rw(steps, alpha, my, mysd)
return(result)
}
# Get a list of ensembles with different values of alpha
ensembles <- lapply(alphas, ensemble, steps = steps, N = N, mu = mu, mysd = mysd)
答案 0 :(得分:2)
您可以从使用
开始filter(rnorm(steps, mu, mysd), alpha, "recursive")
代表generate.rw
和
replicate(generate.rw(steps, alpha, mu, mysd), n = N)
代表ensemble
。顺便说一句,如果alpha与1不同,那么它实际上不是随机游走;检查订单1(简称AR(1))和?arima.sim
(替代filter
)的自回归流程。
答案 1 :(得分:0)
你可能想(重新)看看Wold定理。这个想法是,如果你递归地解决你的AR(1),它将很容易矢量化。严格来说,当系列不遵循随机趋势(即alpha小于1)时,Wold定理仅适用/有意义,但稍后会更多。
这是模型的递归解决方案Yt = alpha Yt-1 + epsilon_t:
Yt = Sum alpha ^ i * epsilon_t-i。
现在,矢量化解决方案显而易见。
res = rep(list(NA),length(alpha))
for (i in 1:length(alpha)){
epsilon = rnorm(n = steps, mu, mysd)
alpha_power = alpha[i]^seq(0,(steps-1))
res[[i]] = alpha_power%*%epsilon
#or if you want to save each Yt, alpha_power*epsilon
}
上面的代码确实循环了alphas。有一些方法可以避免这种循环,但是,考虑到alpha的数量相对较少,我觉得没有必要。最重要的是我将代码中最昂贵的部分(即需要多次迭代的部分)矢量化了。
这种方法比朱利叶斯更快。我认为,因为它确实是矢量化的。我相信replicate
是apply
家庭的一部分,但我可能错了。
最后,当alpha&gt; 1,你的模型没有任何意义。当α<1时如图1所示,正如你在上面的等式中可以看到的那样,冲击消失了,最接近的冲击被赋予最大的重量,例如, .5 ^ 100 * .5基本上为零。当alpha> 1,震动的重量随时间增加,例如2 ^ 100 * .5真的很大。换句话说,你的模型基本上没有预测能力,因为你的系列在未来几步之后几乎可以在任何地方使用。
最后一件事,正如朱利叶斯建议的那样,你应该改变问题的标题。当且仅当alpha = 1时,AR(1)遵循随机游走。