Rcpp:数值积分错误。没有匹配的初始化构造函数
Rcpp: Error with numerical integration. No matching constructor for initialization
我在 R 中有这个函数,我正试图将其复制到 Rcpp 中,但它给我带来了一些问题。尝试使用 RcppNumerical 集成函数时出现错误。当我尝试将函数源代码导入 R 时,它给了我以下错误代码:
No matching constructor for initialization of 'BetaFunc'
.
我有点不确定如何在 Rcpp 中使用 class 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))
非常感谢您的帮助。
正如@coatless 在评论中提到的,函数签名已关闭。准确地说,BetaFunc
的构造函数的最后一个参数定义为 NumericalVector
,但使用 IntegerVector
调用。在我看来,后者更合适。将 BetaFunc()
的最后一个参数更改为 IntegerVector
使示例可以编译。但是,它实际上比您的 R 代码慢。而且结果也不一样。
我在 R 中有这个函数,我正试图将其复制到 Rcpp 中,但它给我带来了一些问题。尝试使用 RcppNumerical 集成函数时出现错误。当我尝试将函数源代码导入 R 时,它给了我以下错误代码:
No matching constructor for initialization of 'BetaFunc'
.
我有点不确定如何在 Rcpp 中使用 class 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))
非常感谢您的帮助。
正如@coatless 在评论中提到的,函数签名已关闭。准确地说,BetaFunc
的构造函数的最后一个参数定义为 NumericalVector
,但使用 IntegerVector
调用。在我看来,后者更合适。将 BetaFunc()
的最后一个参数更改为 IntegerVector
使示例可以编译。但是,它实际上比您的 R 代码慢。而且结果也不一样。