網頁

2018年12月17日 星期一

openMP平行化random number以及常態分佈




1. openMP平行化random number
#pragma omp parallel
{
    #pragma omp for 
    for (int i = 0; i < H; ++i) 
        for (int j = 0; j < W; ++j) 
            m[i][j] = rand()%15; 
}

如果每個thread都執行and()%15,那麼每個thread都會產生相同的random number list。
為了讓每個thread有不同的random number,利用 srand() 函數改變一開始的亂數值( srand() 函數也是定義在 stdlib.h), srand() 需要一個參數做為種子,以產生一個新的亂數數列,而這個參數我們通常以目前的時間傳入,也就是使用 time() 函數,而 time() 是定義在 time.h 中,整個程式如下:

#pragma omp parallel
    srand(int(time(NULL)) ^ omp_get_thread_num());
    #pragma omp for 
    for (int i = 0; i < H; ++i) 
        for (int j = 0; j < W; ++j) 
            m[i][j] = rand()%15; 
}

參考

2. 常態分佈
先產生U,V兩組隨機變數,他們必須是位於(0,1] (0<U,V<=1)區間,且必須是uniformly distributed,接著套入公式

Z = sqrt( -2 ln(U) ) * cos(2 * PI * V) (cos也可以用sin)

Z所產生出來的值就會是標準常態分佈的~Gaussian(0,1),區間是在(-6,6),接著把他延伸到任何樣子的常態分佈,根據標準常態分佈轉換的定理,
如果Z是標準常態分佈~Gaussian(0, 1),而X是~Gaussian(mean, std^2),
則X轉換為Z的公式為

Z = (X - mean) / std,因此要將Z擴展到所有情況只要做

X = Z * std + mean

參考

沒有留言:

張貼留言