2012-03-21 55 views
2

我正在嘗試使用pnorm和qnorm之類的函數,用Rcpp編寫一段C++代碼。我可以使用https://stackoverflow.com/a/9738848/567015中解釋的這些矢量的Rcpp糖版本,但我不需要在矢量上做這個,而只需要雙倍。從Rmath.h中使用pnorm與Rcpp

如果我理解正確,我可以使用Rf_前綴從Rmath.h中獲取標量版本。然而,Rf_pnorm不起作用:

library("inline") 
Src <- ' 
double y = as<double>(x); 
double res = Rf_pnorm(y,0.0,1.0); 
return wrap(res) ; 
' 

fx <- cxxfunction(signature(x = "numeric") ,Src, plugin = "Rcpp") 

fx(1) 

給出的錯誤:

file10c81a585dee.cpp: In function 'SEXPREC* file10c81a585dee(SEXP)': 
file10c81a585dee.cpp:32:32: error: 'Rf_pnorm' was not declared in this scope 

我有些google搜索和反覆試驗是Rf_pnorm5的工作,但需要下尾額外的參數和日誌規模後發現:

Src <- ' 
double y = as<double>(x); 
double res = Rf_pnorm5(y,0.0,1.0,1,0); 
return wrap(res) ; 
' 

fx <- cxxfunction(signature(x = "numeric") ,Src, plugin = "Rcpp") 

fx(1) 
## [1] 0.8413447 

好,但我不明白爲什麼這個工程,但Rf_pnorm沒有。我寧願使用Rf_pnorm,因爲我認爲這可以更容易地爲不同的發行版找到正確的代碼。

回答

3

這裏是RCPP糖變體,它是更自然RCPP:

R> library(inline) 
R> 
R> Src <- ' 
+ NumericVector y = NumericVector(x); 
+ NumericVector res = pnorm(y,0.0,1.0); 
+ return res; 
+ ' 
R> 
R> fx <- cxxfunction(signature(x = "numeric") , body=Src, plugin = "Rcpp") 
R> 
R> fx(seq(0.8, 1.2, by=0.1)) 
[1] 0.788145 0.815940 0.841345 0.864334 0.884930 
R>  
R> fx(1.0)  ## can also call with scalar args 
[1] 0.841345 
R>  

在我們的頭更仔細地觀察,我們取消定義pnorm等人從Rmath.h爲了定義(矢量化)的變種你來自Rcpp糖。

編輯於2012年11月14日:隨着RCPP 0.10.0今天發佈,你可以調用做簽名R::pnorm(double, double, double, int, int)如果你想用書面反對Rmath.h C風格的代碼。 Rcpp糖仍然給你矢量化的版本。

+0

謝謝。我認爲使用Rcpp Sugar版本確實是最簡單的。用'pnorm(NumericVector(1,y),0.0,1.0)[0]'發現了一個解決方法,它似乎工作正常。 – 2012-03-21 14:26:05

+0

你不應該需要這個。我發佈的'fx()'函數也可以用標量調用 - 請記住,所有R對象都是向量,有時長度爲1。 – 2012-03-21 14:44:01