【问题标题】:Use pnorm from Rmath.h with Rcpp将 Rmath.h 中的 pnorm 与 Rcpp 一起使用
【发布时间】:2012-03-21 12:56:59
【问题描述】:

我正在尝试使用 pnorm 和 qnorm 等函数使用 Rcpp 编写一段 C++ 代码。我可以按照https://stackoverflow.com/a/9738848/567015 中的说明将这些的 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

经过一些谷歌搜索和反复试验,我发现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,因为我认为这样可以更轻松地为不同的发行版找到正确的代码。

【问题讨论】:

    标签: r rcpp


    【解决方案1】:

    这里是 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> 
    

    更仔细地查看我们的标题,我们从 Rmath.h 取消定义 pnorm 等,以便定义您从 Rcpp 糖获得的(矢量化)变体。

    于 2012-11-14 编辑:今天发布的 Rcpp 0.10.0,如果你想使用 C 风格,你可以调用签名 R::pnorm(double, double, double, int, int)针对Rmath.h 编写的代码。 Rcpp 糖仍然为您提供矢量化版本。

    【讨论】:

    • 谢谢。我认为确实使用 Rcpp 糖版是最简单的。找到了pnorm(NumericVector(1,y),0.0,1.0)[0] 的解决方法,似乎工作正常。
    • 你不应该需要那个。我发布的fx() 函数也可以用标量调用——请记住,所有 R 对象都是向量,有时长度为 1。
    猜你喜欢
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    相关资源
    最近更新 更多