首页 > 解决方案 > Rcpp:数值积分错误。没有匹配的初始化构造函数

问题描述

我在 R 中有这个函数,我试图复制到 Rcpp 中,但它给了我一些问题。尝试使用 RcppNumerical 集成函数时出现错误。当我尝试将函数导入 R: 时,它给了我以下错误代码 No matching constructor for initialization of 'BetaFunc'

我有点不确定如何在 Rcpp 中使用类 public Func 来使用 RcppNumerical 集成函数。

这是我遇到问题的 Rcpp 函数:

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
#include <RcppArmadillo.h>
#include <RcppNumerical.h>
#include <RcppEigen.h>
#include <RcppArmadilloExtensions/sample.h>

using namespace Numer;
using namespace arma;
using namespace Rcpp;

typedef Eigen::Map<Eigen::MatrixXd> MapMat;
typedef Eigen::Map<Eigen::VectorXd> MapVec;

// Define the function to integrate over
class BetaFunc: public Func {

private:
  const double alpha;
  const double beta;
  const NumericVector vX;
  const int i;
  const NumericVector n;
  const NumericVector indx;

public:
  BetaFunc(const double alpha_, const double beta_, int i_,
           const NumericVector vX_,
           const NumericVector n_,
           const NumericVector indx_) : alpha(alpha_), beta(beta_), i(i_), vX(vX_), n(n_), indx(indx_) {}

  double operator()(const double& dZ) const {

    double Vr = Rf_dbeta(dZ, vX[i] + alpha, n[i] - vX[i] + beta, 0);
    int int_size = indx.length();

    for (int j = 0; j < int_size; j++) {

      int di = indx[j];

      Vr *= Rf_pbeta(dZ, vX[di] + alpha, n[di] - vX[di] + beta, 1, 0);

    }
    return Vr;
  }  
};

// [[Rcpp::export]]
// Estimate the Bayesian posterior probability of each alternative
// being the best binomial bandit
NumericVector best_binomial_bandit(NumericVector vX, NumericVector n, double alpha = 1,
                                   double beta = 1) {
  int iK = vX.size();

  NumericVector vAns(iK);

  IntegerVector vSeq = seq(0, iK-1);

  for (int i = 0; i < iK; i++) {

    // Vector of zeros
    LogicalVector vLogi(iK);

    vLogi[i] = 1;
    // Create integervector with all values except value i
    IntegerVector indx = vSeq[vLogi < 1];
    const double lower = 0, upper = 1;
    BetaFunc f(alpha, beta, i, vX, n, indx);
    double err_est;
    int err_code;

    vAns[i] = integrate(f, lower, upper, err_est, err_code);

  }

 return vAns;

}

这是正常工作的 R 函数:

bbb <-
  function(x, n, alpha=1, beta=1) {
    k <- length(x)
    ans <- numeric(k)
    for (i in (1:k)) {
      indx <- (1:k)[-i]
      f <- function(z) {
        r <- dbeta(z, x[i] + alpha, n[i] - x[i] + beta)
        for (j in indx) {
          r <- r * pbeta(z, x[j] + alpha, n[j] - x[j] + beta)
        }
        return(r)
      }
      ans[i] = integrate(f, 0, 1)$value
    }
    return(ans)
}

这只是我用来测试功能的一个最小示例:

library(Rcpp)
sourceCpp("./best_binomial_bandit.cpp")

set.seed(1)
x <- c(0.1, 0.2, 0.3, 0.4, 0.5)
n <- c(1, 2, 3, 4, 5)

bb_res <- bbb(x, n, 1, 1)

bb_cpp_res <- best_binomial_bandit(x, n, 0.2, 0.4)

library(microbenchmark)
microbenchmark(bbb(x, n, 1, 1),
               best_binomial_bandit(x, n, 1, 1))

非常感谢您的帮助。

标签: rrcpp

解决方案


正如评论中提到的@coatless,函数签名已关闭。准确地说,构造函数 for 的最后一个参数BetaFunc被定义为 aNumericalVector但被调用为 a IntegerVector。在我看来,后者更合适。更改 to 的最后一个参数BetaFunc()会使IntegerVector示例编译。但是,它实际上比您的 R 代码慢。结果也不一样。


推荐阅读