2015-11-06 237 views
1

我想使用函數vdRngGaussian正常(平均值,sigma2)中繪製n個隨機變量。 一種方式做,這是命令使用vdRngGaussian提出正態隨機變量

vdRngGaussian(VSL_RNG_METHOD_GAUSSIAN_ICDF, stream, n, x, mean, sqrt(sigma2)) 

取而代之的是我想用一個for循環。該MEX-代碼我寫的是

#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <mkl.h> 
#include "mkl_vml.h" 
#include "mex.h" 
#include "matrix.h" 
#include "mkl_vsl.h" 
#include <time.h> 
#define SEED time(NULL) 

double normal(double mean, double sigma2, VSLStreamStatePtr stream); 

/* main fucntion */ 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{ 
    double *x, mean, sigma2; 

    VSLStreamStatePtr stream; 
    vslNewStream(&stream, VSL_BRNG_MT19937, SEED); 

    /* make pointers to input data */ 
    mean = (double)mxGetScalar(prhs[0]); 
    sigma2= (double)mxGetScalar(prhs[1]); 

    /* make pointers to output data */ 
    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 
    x = mxGetPr(plhs[0]); 


    x[0] = normal(mean, sigma2, stream); 


    /* Deleting the stream */ 
    vslDeleteStream(&stream); 

    return; 
} 

double normal(double mean, double sigma2, VSLStreamStatePtr stream) 
{ 
    double x[1]; 

    vdRngGaussian(VSL_RNG_METHOD_GAUSSIAN_ICDF, stream, 1, x, mean, sqrt(sigma2)); 

    return(x[0]); 
} 

當我用命令運行代碼

for i=1:5 
out(i) = normalc(0.0, 1.0); 
end 

我得到如下結果:

-1.1739 -1.1739 -1.1739 -1.1739 -1.1739 

如果我把我的函數5次無一個for循環我得到這些結果

-0.2720, 2.1457, -1.2397, 0.7501, 0.1490 

你能幫我嗎。 非常感謝。

回答

1

要創建與vslNewStream小溪種子(隨機數發生器的初始狀態)作爲參數,而你就time function from the C time librarythe output基礎此。問題是它返回。這個分辨率太粗糙了,當你在for循環中調用它時,最終會得到相同的種子。 (假設for循環執行得很快,並且你很幸運有開始時間。)

也許使用不同的種子,如high_resolution_clock from the C++11 <chrono> header。你可能仍然得到了劃時代的時間,但在不同的單位:

using namespace std::chrono; 
system_clock::time_point now = high_resolution_clock::now(); 
system_clock::duration epoch = now.time_since_epoch(); 

long long ns = duration_cast<nanoseconds>(epoch).count(); 
long long mic = duration_cast<microseconds>(epoch).count(); 
long long ms = duration_cast<milliseconds>(epoch).count(); 

Demo (cpp.sh)

或者,您可以使用從MKL's mkl_get_cpu_clocks function過去的CPU時鐘,但是當您關閉機器時,這會回到零。 或只是time in seconds as a double with MKL's dsecnd

+0

感謝您的幫助。我試圖按照你的建議使用「high_resolution_clock」,但是當我運行代碼時,我得到這個消息:「error:identifier」使用「未定義的名稱空間標準;」。我試圖添加庫來修復它,但我沒有運氣。我讀了函數「dscend」,並且它返回兩次函數調用之間的時間(如果我理解正確的話)。你能否告訴我更多的細節如何使用它來定義一個新的種子?我很抱歉,也許這個問題很愚蠢,但我對C是新手。非常感謝。 –

+0

@ F.F。這意味着你不能編譯爲C++,或者你的編譯器不支持C++ 11,或者你沒有啓用C++ 11支持。你能給編譯器詳細信息嗎?您沒有將問題標記爲任何語言。對於'dsecnd',它通常用於計時,但它返回一個絕對時間,可能會被使用(乘以1e7左右,並舍入到要求的整數類型中)。 – chappjc

+0

你好@chappjc。我遇到了一些意想不到的問題,而且我以前也看不到yor的消息。我用擴展名.cpp保存了我的代碼,它工作正常。非常感謝你。 –