2016-12-29 76 views
0

我正在寫一個大都市,黑斯廷斯算法爲N(0,1)分佈利用分佈函數:RCPP - 如何在C++代碼

#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
NumericVector metropolis(int R, double b, double x0){ 
    NumericVector y(R); 
    y(1) = x0; 
    for(int i=1; i<R; ++i){ 
     y(i) = y(i-1); 
     double xs = y(i)+runif(1, -b,b)[0]; 
     double a = dnorm(xs, 0, 1)[0]/dnorm(y(i), 0, 1)[0]; 
     NumericVector A(2); 
     A(0) = 1; 
     A(1) = a; 
     double random = runif(1)[0]; 
     if(random <= min(A)){ 
      y[i] = xs; 
     } 
    } 
    return y; 
} 

但每次我試圖編譯功能,出現此錯誤:12

行:調用 'dnorm4' 不匹配函數

我試着寫使用dnorm一個微不足道的功能,如

NumericVector den(NumericVector y, double a, double b){ 
    NumericVector x = dnorm(y,a,b); 
    return x; 
} 

它的工作原理。有人知道我爲什麼在Metropolis代碼中出現這種類型的錯誤嗎? 有沒有其他的方式來使用像R中的C++代碼中的密度函數?

+2

在SO和其他地方的Rcpp圖庫上有_dozens_適合的例子。 –

回答

3

在Rcpp中,有兩套採樣器 - 標量和矢量 - 按命名空間R::Rcpp::分開。他們是這樣劃分是:

  • 標返回一個值(如doubleint
  • 矢量返回多個值(例如NumericVectorIntegerVector

在這種情況下,你想成爲使用標量採樣空間和而不是的矢量採樣空間。

這是顯而易見的,因爲:

double a = dnorm(xs, 0, 1)[0]/dnorm(y(i), 0, 1)[0]; 

調用所述子集操作者[0]以獲得向量的唯一元件。


這個問題的第二部分是第四個參數的缺失部分由

線12暗示:呼叫爲「dnorm4」

如果沒有匹配的功能看看dnorm函數的R定義,你會看到:

dnorm(x, mean = 0, sd = 1, log = FALSE) 

在這種情況下,您只提供了第四個參數。


其結果是,你可能會想以下幾點:

// [[Rcpp::export]] 
NumericVector metropolis(int R, double b, double x0){ 
    NumericVector y(R); 
    y(1) = x0; // C++ indices start at 0, you should change this! 
    for(int i=1; i<R; ++i){ // C++ indices start at 0!!! 
     y(i) = y(i-1); 
     double xs = y(i) + R::runif(-b, b); 
     double a = R::dnorm(xs, 0.0, 1.0, false)/R::dnorm(y(i), 0.0, 1.0, false); 
     NumericVector A(2); 
     A(0) = 1; 
     A(1) = a; 
     double random = R::runif(0.0, 1.0); 
     if(random <= min(A)){ 
      y[i] = xs; 
     } 
    } 
    return y; 
} 

旁註:

C++指標在0 1結果開始,上面的向量稍微有點問題,因爲通過填充y向量y(1)而不是y(0)。儘管如此,我仍將此作爲練習,以供您糾正。

+0

對於R的'Rf_ *'函數,我還有一個不變的界面來計數三個。所有這些在這裏和其他地方都有詳細的討論。真的不需要一個新的問題,而是一個很好的答案。謝謝,@coatless。 –