我正在尝试使用像pnorm和qnorm这样的函数用Rcpp编写一段C ++代码。我可以使用这些向量的Rcpp糖版本,如https://stackoverflow.com/a/9738848/567015中所述,但我不需要在向量上执行此操作,只需要在double上执行此操作。
如果我理解正确,我可以使用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
我在谷歌搜索和试错后发现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
因为我认为这样可以更容易地为不同的发行版找到正确的代码。
答案 0 :(得分: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
et al,以便定义从Rcpp sugar获得的(矢量化)变体。
编辑于2012-11-14: 今天发布了Rcpp 0.10.0,如果您想使用C,可以调用签名R::pnorm(double, double, double, int, int)
针对Rmath.h
编写的代码。 Rcpp糖仍然为您提供矢量化版本。