在Rcpp函数周围构建包装器时出错

时间:2016-07-29 21:57:09

标签: r rcpp

我在Rcpp声明了以下函数:

#include <Rcpp.h>
// [[Rcpp::depends(RcppArmadillo)]]
#include <Rmath.h>

using namespace Rcpp;

// [[Rcpp::export]]
double loglikZeta(double zold, double zstar, NumericVector y, int K, double p){
NumericVector num = Rcpp::dbinom(y,K,p*zstar);
NumericVector den = Rcpp::dbinom(y,K,p*zold);
return (num[0]/den[0]);
}

// [[Rcpp::export]]
double singleZetaSampler(NumericVector z, NumericVector y,
                     double p, int K, int i, double zstar){

return loglikZeta(z[i-1],zstar,y[i-1],K,p);
} 

现在声明(在加载包和文件之后):

z <- y <- c(rep(1,20),rep(0,20))
n <- length(y)
K <- 3
p <- 0.5
i <- 30
zstar <- 1

意外的行为是,如果我试着打电话,我每次都有不同的结果(函数中没有任何随机的):

singleZetaSampler(z,y,p,K,i,zstar)
[1] 1.000051
singleZetaSampler(z,y,p,K,i,zstar)
[1] 0.1887447
singleZetaSampler(z,y,p,K,i,zstar)
[1] 0.9999998

我在这里做的是否有任何重大错误,或者这些结果实际上是意外的?

编辑:

很抱歉,如果功能没有意义,请按原样使用。这是原来的功能:

// [[Rcpp::export]]
NumericVector zetaSampler(int n, NumericVector z, NumericVector y,
                      double p, int K){
NumericVector xx(n);
for(int i = 0; i < n; i++){
    xx(i) = loglikZeta(z[i],1,y[i],K,p);

}

return xx;
}

并致电:

zetaSampler(length(z),z,y,p,K)
和以前一样,每次给出不同的结果。

1 个答案:

答案 0 :(得分:2)

两件事。一个实际错误,一种风格。

风格问题是你包括Rmath.h并且当你不应该依赖于RcppArmadillo。真正的错误是你抽样20次,然后设置i=30并访问第30个元素。所以你得到随机输入。

这就是我刚刚运行的内容,它得到了相同结果的三倍。

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
double loglikZeta(double zold, double zstar, NumericVector y, int K, double p){
  NumericVector num = Rcpp::dbinom(y,K,p*zstar);
  NumericVector den = Rcpp::dbinom(y,K,p*zold);
  return (num[0]/den[0]);
}

// [[Rcpp::export]]
double singleZetaSampler(NumericVector z, NumericVector y,
                         double p, int K, int i, double zstar){

  return loglikZeta(z[i-1],zstar,y[i-1],K,p);
} 

/*** R
z <- y <- c(rep(1,20),rep(0,20))
n <- length(y)
K <- 3
p <- 0.5
i <- 20  # not 30
zstar <- 1
singleZetaSampler(z,y,p,K,i,zstar)
singleZetaSampler(z,y,p,K,i,zstar)
singleZetaSampler(z,y,p,K,i,zstar)
*/

输出:

R> sourceCpp("/tmp/foo.cpp")

R> z <- y <- c(rep(1,20),rep(0,20))

R> n <- length(y)

R> K <- 3

R> p <- 0.5

R> i <- 20  # not 30

R> zstar <- 1

R> singleZetaSampler(z,y,p,K,i,zstar)
[1] 1

R> singleZetaSampler(z,y,p,K,i,zstar)
[1] 1

R> singleZetaSampler(z,y,p,K,i,zstar)
[1] 1
R>

编辑:似乎在修复版本中更好地工作,强制标量参数loglikZeta()

// [[Rcpp::export]]
double loglikZeta(double zold, double zstar, double y, int K, double p){
  double num = R::dbinom(y, K, p*zstar, false);
  double den = R::dbinom(y, K, p*zold, false);
  return (num/den);
}

请注意,Rcpp::dbinom()的签名为Rcpp::dbinom(Rcpp::NumericVector, int, double, bool=false)