簡體   English   中英

在R中創建一個新的概率分布(依賴於之前的r.v.)

[英]Create a new probability distribution (relying on the previous r.v.) in R

我想寫這個 pdf 並使用它生成隨機數。

假設 X 是一個僅取 0 或 1 值的隨機變量,則 pdf 如下:

P(X_t) = a^[(1-X_(t-1))*X_t] * (1-a)^[(1-X_(t-1))*(1-X_t)] * b^[X_(t-1)*(1-X_t)] * (1-b)^[X_(t-1)*X_t]

X_t : 當前的 r.v., X_(t-1) : 之前的 r.v.,其中 t=1,2,...,T 並給出 t=0 的初始值。 最后,a 和 b 是兩個已知概率。

不確定我是否完全理解,但您可以執行以下操作。

如果我們說 'y' 是先前的實現,而 'x' 是當前的實現,那么我們有:

P(x=0|y=0) = 1-a
P(x=1|y=0) = a
P(x=0|y=1) = b
P(x=1|y=1) = 1-b

因此,我們可以在 [0,1] 中生成統一變量 U,如果 y = 0 則設置 x = 0 如果 U <= 1-a,否則 x = 1; 如果 y = 1,則設置 x = 0 如果 U <= b,否則設置 x = 1

以下 function 可以解決問題,其中 x0 是 x 的初始值:

rhany <- function(n, a, b, x0 = 0) {
    sim <- c(x0, runif(n-1))
    for (i in 2:n){
        sim[i] = (sim[i-1] == 0) * ((sim[i] <= 1-a) * 0 + (sim[i] > a) * 1) + 
                 (sim[i-1] == 1) * ((sim[i] <= b) * 0 + (sim[i] > 1-b) * 1)
    }
    sim
}

那么如果你運行 function:

rhany(10, 0.1, 0.7)
[1] 0 1 0 1 1 1 0 1 1 0

誠然,for循環減慢了function; 在我的機器上生成 1e7 變量大約需要 9 秒。 您可以使用 Rcpp package 重新實現:

library(Rcpp)

cppFunction('NumericVector rhanya(double a, double b, NumericVector zs) {
    int n = zs.size();
    NumericVector sim = zs;
    for (int i = 1; i < n; i++) {
        sim[i] = (sim[i-1] == 0) * ((sim[i] <= 1-a) * 0 + (sim[i] > a) * 1) + (sim[i-1] == 1) * ((sim[i] <= b) * 0 + (sim[i] > 1-b) * 1);
    }
    return(sim);
}')

rhany1 <- function(n, a, b, x0 = 0) {
    sim <- c(x0, runif(n-1))
    rhanya(a, b, sim)
}

這個 function rhany1 需要不到 0.5 秒的時間來生成 1e7 個變量。

您可以測試兩個函數 rhany 和 rhany1 在設置相同種子時是否給出相同的結果:

set.seed(123); bc <- rhany(1e7, 0.1, 0.7)
set.seed(123); ac <- rhany1(1e7, 0.1, 0.7)
all.equal(ac, bc)
[1] TRUE

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM