R 上的简单高斯过程模拟
Simple Gaussian Process Simulation on R
如何使用均值函数 m(t) = 0
和模拟高斯过程 X(t), t = 1, . . . , 200
协方差函数 r(h) = Cov(t, t + h) = exp(-|h|)
。我知道这个过程有时被称为
Ornstein-Uhlenbeck 过程,但如何绘制模拟过程。
感谢期待
使用此处的函数:https://quant.stackexchange.com/questions/1260/r-code-for-ornstein-uhlenbeck-process
ornstein_uhlenbeck <- function(T,n,nu,lambda,sigma,x0){
dw <- rnorm(n, 0, sqrt(T/n))
dt <- T/n
x <- c(x0)
for (i in 2:(n+1)) {
x[i] <- x[i-1] + lambda*(nu-x[i-1])*dt + sigma*dw[i-1]
}
return(x);
}
test <- ornstein_uhlenbeck(200, 200, 0, 0.8, 1, 0)
plot(x = seq_along(test), y = test, type = 'l')
(请注意,它只为您提供一个近似分布,如 link 中问题的答案之一所述。)
我假设 T = 200,n = 200,nu = 0(如您所述),均值回归参数为 0.8,sigma 为 1,过程从 0 开始。
根据 Wikipedia 定义,Ornstein–Uhlenbeck 过程由以下随机微分方程定义:
其中 是一个维纳过程,它的一个特性是它具有高斯增量,即
上述方程可以按以下方式离散化:
其中
由于维纳过程的高斯增量 属性,我们得到 。这意味着可以使用 sqrt(dt)*rnorm(1)
生成增量值
我在 R 中编写了以下函数,它采用时间向量、过程的平均值、标准差和 theta 的值。
simulate <- function(t, mean=0, std=1, x0=mean, theta=1, number.of.points=length(t)){
# calculate time differences
dt <- diff(t)
X <- vector("numeric", length=number.of.points)
X[1] <- x0
for(i in 1:(number.of.points-1)){
X[i+1] <- X[i] + theta * (mean-X[i])*dt[i] + std * sqrt(dt[i])* rnorm(1)
}
data.frame(x=t, y=X)
}
simulate(t=1:200) %>% ggplot(aes(x,y)) + geom_line()
另一个实现使用purrr
simulate <- function(t, mean=0, sd=1, theta=1, number.of.points=length(t)){
stopifnot(!missing(t) | !missing(number.of.points))
if(missing(t)){
t <- 1:number.of.points
}
unlist(purrr::accumulate2(vector("numeric", length=number.of.points-1), diff(t), function(x, o, y) {
x + theta*(mean - x)* y + sqrt(y)*rnorm(1)
}, .init=x0), use.names=F) -> X
data.frame(x=t, y=X)
}
simulate(number.of.points=200) %>% ggplot(aes(x,y)) + geom_line()
如何使用均值函数 m(t) = 0
和模拟高斯过程 X(t), t = 1, . . . , 200
协方差函数 r(h) = Cov(t, t + h) = exp(-|h|)
。我知道这个过程有时被称为
Ornstein-Uhlenbeck 过程,但如何绘制模拟过程。
感谢期待
使用此处的函数:https://quant.stackexchange.com/questions/1260/r-code-for-ornstein-uhlenbeck-process
ornstein_uhlenbeck <- function(T,n,nu,lambda,sigma,x0){
dw <- rnorm(n, 0, sqrt(T/n))
dt <- T/n
x <- c(x0)
for (i in 2:(n+1)) {
x[i] <- x[i-1] + lambda*(nu-x[i-1])*dt + sigma*dw[i-1]
}
return(x);
}
test <- ornstein_uhlenbeck(200, 200, 0, 0.8, 1, 0)
plot(x = seq_along(test), y = test, type = 'l')
(请注意,它只为您提供一个近似分布,如 link 中问题的答案之一所述。)
我假设 T = 200,n = 200,nu = 0(如您所述),均值回归参数为 0.8,sigma 为 1,过程从 0 开始。
根据 Wikipedia 定义,Ornstein–Uhlenbeck 过程由以下随机微分方程定义:
上述方程可以按以下方式离散化:
sqrt(dt)*rnorm(1)
我在 R 中编写了以下函数,它采用时间向量、过程的平均值、标准差和 theta 的值。
simulate <- function(t, mean=0, std=1, x0=mean, theta=1, number.of.points=length(t)){
# calculate time differences
dt <- diff(t)
X <- vector("numeric", length=number.of.points)
X[1] <- x0
for(i in 1:(number.of.points-1)){
X[i+1] <- X[i] + theta * (mean-X[i])*dt[i] + std * sqrt(dt[i])* rnorm(1)
}
data.frame(x=t, y=X)
}
simulate(t=1:200) %>% ggplot(aes(x,y)) + geom_line()
purrr
simulate <- function(t, mean=0, sd=1, theta=1, number.of.points=length(t)){
stopifnot(!missing(t) | !missing(number.of.points))
if(missing(t)){
t <- 1:number.of.points
}
unlist(purrr::accumulate2(vector("numeric", length=number.of.points-1), diff(t), function(x, o, y) {
x + theta*(mean - x)* y + sqrt(y)*rnorm(1)
}, .init=x0), use.names=F) -> X
data.frame(x=t, y=X)
}
simulate(number.of.points=200) %>% ggplot(aes(x,y)) + geom_line()