Используйте pnorm из Rmath.h с Rcpp - PullRequest
2 голосов
/ 21 марта 2012

Я пытаюсь написать кусок кода C ++ с помощью Rcpp, используя такие функции, как pnorm и qnorm. Я могу использовать версии Rcpp Sugar для этих векторов, как описано в https://stackoverflow.com/a/9738848/567015,, но мне не нужно делать это на векторе, а только на двойном.

Если я правильно понимаю, я могу использовать префикс 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, потому что я думаю, что это облегчает поиск правильных кодов для разных дистрибутивов.

1 Ответ

3 голосов
/ 21 марта 2012

Вот вариант сахара 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 sugar.

Изменить на 2012-11-14: С Rcpp 0.10.0, выпущенным сегодня, вы можете позвонить сделать подпись R::pnorm(double, double, double, int, int), если вы хотите использовать написанный код в стиле C против Rmath.h. Rcpp сахар все еще дает вам векторизованные версии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...