我可以使用 RcppNumerical 在重复的一维积分中躲避 'abstract class'
Can I dodge 'abstract class' in repeated 1-D integration using RcppNumerical
我正在寻找用于二维数值积分的确定性线程安全 Rcpp 算法。 RcppNumerical 为 Cuba 提供了一个用于多维集成的部分接口,但从我的试验来看,在 RcppParallel 中似乎不是线程安全的,它可能使用了 Monte Carlo 方法。这让我回到了重复的一维积分。我已经成功地将它与(非线程安全的)R 函数 Rdqags 一起使用,但是我的(可能是幼稚的)RcppNumerical 编码无法编译,因为嵌套的 class 是抽象的。可能是由于 operator() 虚函数。
任何人都可以在 RcppNumerical 或其他替代方案中提出解决此问题的方法吗?
下面是我模拟 https://github.com/yixuan/RcppNumerical 中的二维示例的测试代码。它会给出类似
的错误
cannot declare variable 'f2' to be of abstract type 'Normal2'
cannot declare variable 'f1' to be of abstract type 'Normal1'
默里
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
#include <RcppNumerical.h>
using namespace Numer;
// P(a1 < X1 < b1, a2 < X2 < b2), (X1, X2) ~ N([0], [1 rho])
// ([0], [rho 1])
class Normal2: public Func
{
private:
const double rho;
const double x;
double const1; // 2 * (1 - rho^2)
double const2; // 1 / (2 * PI) / sqrt(1 - rho^2)
public:
Normal2(const double& rho_, const double& x_) : rho(rho_), x(x_)
{
const1 = 2.0 * (1.0 - rho * rho);
const2 = 1.0 / (2 * M_PI) / std::sqrt(1.0 - rho * rho);
}
// PDF of bivariate normal
double operator()(const double& y)
{
double z = x * x - 2 * rho * x * y + y * y;
return const2 * std::exp(-z / const1);
}
};
class Normal1: public Func
{
private:
const double rho;
double a2, b2;
public:
Normal1(const double& rho_, const double& a2_, const double& b2_) : rho(rho_), a2(a2_), b2(b2_) {}
// integral in y dimension for given x
double operator()(const double& x)
{
Normal2 f2(rho, x);
double err_est;
int err_code;
const double res = integrate(f2, a2, b2, err_est, err_code);
return res;
}
};
// [[Rcpp::export]]
Rcpp::List integrate_test3()
{
double a1 = -1.0;
double b1 = 1.0;
double a2 = -1.0;
double b2 = 1.0;
Normal1 f1(0.5, a2, b2); // rho = 0.5
double err_est;
int err_code;
const double res = integrate(f1, a1, b1, err_est, err_code);
return Rcpp::List::create(
Rcpp::Named("approximate") = res,
Rcpp::Named("error_estimate") = err_est,
Rcpp::Named("error_code") = err_code
);
}
Numer::Func
class 是一个抽象 class 因为一个未定义的方法:
virtual double operator()(const double& x) const = 0;
现在您正在为
提供实施
double operator()(const double& x)
这使得上述方法未定义,因此 class 抽象。您应该将其更改为
double operator()(const double& x) const
Normal1
和 Normal2
都可以编译您的代码。
顺便说一句,我的编译器 (gcc 9.2) 对这个问题甚至很明确:
59094915.cpp: In member function ‘double Normal1::operator()(const double&)’:
59094915.cpp:43:17: error: cannot declare variable ‘f2’ to be of abstract type ‘Normal2’
43 | Normal2 f2(rho, x);
| ^~
59094915.cpp:9:7: note: because the following virtual functions are pure within ‘Normal2’:
9 | class Normal2: public Func
| ^~~~~~~
In file included from /usr/local/lib/R/site-library/RcppNumerical/include/integration/wrapper.h:13,
from /usr/local/lib/R/site-library/RcppNumerical/include/RcppNumerical.h:16,
from 59094915.cpp:3:
/usr/local/lib/R/site-library/RcppNumerical/include/integration/../Func.h:26:20: note: ‘virtual double Numer::Func::operator()(const double&) const’
26 | virtual double operator()(const double& x) const = 0;
| ^~~~~~~~
59094915.cpp: In function ‘Rcpp::List integrate_test3()’:
59094915.cpp:58:13: error: cannot declare variable ‘f1’ to be of abstract type ‘Normal1’
58 | Normal1 f1(0.5, a2, b2); // rho = 0.5
| ^~
59094915.cpp:32:7: note: because the following virtual functions are pure within ‘Normal1’:
32 | class Normal1: public Func
| ^~~~~~~
In file included from /usr/local/lib/R/site-library/RcppNumerical/include/integration/wrapper.h:13,
from /usr/local/lib/R/site-library/RcppNumerical/include/RcppNumerical.h:16,
from 59094915.cpp:3:
/usr/local/lib/R/site-library/RcppNumerical/include/integration/../Func.h:26:20: note: ‘virtual double Numer::Func::operator()(const double&) const’
26 | virtual double operator()(const double& x) const = 0;
| ^~~~~~~~
我正在寻找用于二维数值积分的确定性线程安全 Rcpp 算法。 RcppNumerical 为 Cuba 提供了一个用于多维集成的部分接口,但从我的试验来看,在 RcppParallel 中似乎不是线程安全的,它可能使用了 Monte Carlo 方法。这让我回到了重复的一维积分。我已经成功地将它与(非线程安全的)R 函数 Rdqags 一起使用,但是我的(可能是幼稚的)RcppNumerical 编码无法编译,因为嵌套的 class 是抽象的。可能是由于 operator() 虚函数。
任何人都可以在 RcppNumerical 或其他替代方案中提出解决此问题的方法吗?
下面是我模拟 https://github.com/yixuan/RcppNumerical 中的二维示例的测试代码。它会给出类似
的错误cannot declare variable 'f2' to be of abstract type 'Normal2'
cannot declare variable 'f1' to be of abstract type 'Normal1'
默里
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
#include <RcppNumerical.h>
using namespace Numer;
// P(a1 < X1 < b1, a2 < X2 < b2), (X1, X2) ~ N([0], [1 rho])
// ([0], [rho 1])
class Normal2: public Func
{
private:
const double rho;
const double x;
double const1; // 2 * (1 - rho^2)
double const2; // 1 / (2 * PI) / sqrt(1 - rho^2)
public:
Normal2(const double& rho_, const double& x_) : rho(rho_), x(x_)
{
const1 = 2.0 * (1.0 - rho * rho);
const2 = 1.0 / (2 * M_PI) / std::sqrt(1.0 - rho * rho);
}
// PDF of bivariate normal
double operator()(const double& y)
{
double z = x * x - 2 * rho * x * y + y * y;
return const2 * std::exp(-z / const1);
}
};
class Normal1: public Func
{
private:
const double rho;
double a2, b2;
public:
Normal1(const double& rho_, const double& a2_, const double& b2_) : rho(rho_), a2(a2_), b2(b2_) {}
// integral in y dimension for given x
double operator()(const double& x)
{
Normal2 f2(rho, x);
double err_est;
int err_code;
const double res = integrate(f2, a2, b2, err_est, err_code);
return res;
}
};
// [[Rcpp::export]]
Rcpp::List integrate_test3()
{
double a1 = -1.0;
double b1 = 1.0;
double a2 = -1.0;
double b2 = 1.0;
Normal1 f1(0.5, a2, b2); // rho = 0.5
double err_est;
int err_code;
const double res = integrate(f1, a1, b1, err_est, err_code);
return Rcpp::List::create(
Rcpp::Named("approximate") = res,
Rcpp::Named("error_estimate") = err_est,
Rcpp::Named("error_code") = err_code
);
}
Numer::Func
class 是一个抽象 class 因为一个未定义的方法:
virtual double operator()(const double& x) const = 0;
现在您正在为
提供实施 double operator()(const double& x)
这使得上述方法未定义,因此 class 抽象。您应该将其更改为
double operator()(const double& x) const
Normal1
和 Normal2
都可以编译您的代码。
顺便说一句,我的编译器 (gcc 9.2) 对这个问题甚至很明确:
59094915.cpp: In member function ‘double Normal1::operator()(const double&)’:
59094915.cpp:43:17: error: cannot declare variable ‘f2’ to be of abstract type ‘Normal2’
43 | Normal2 f2(rho, x);
| ^~
59094915.cpp:9:7: note: because the following virtual functions are pure within ‘Normal2’:
9 | class Normal2: public Func
| ^~~~~~~
In file included from /usr/local/lib/R/site-library/RcppNumerical/include/integration/wrapper.h:13,
from /usr/local/lib/R/site-library/RcppNumerical/include/RcppNumerical.h:16,
from 59094915.cpp:3:
/usr/local/lib/R/site-library/RcppNumerical/include/integration/../Func.h:26:20: note: ‘virtual double Numer::Func::operator()(const double&) const’
26 | virtual double operator()(const double& x) const = 0;
| ^~~~~~~~
59094915.cpp: In function ‘Rcpp::List integrate_test3()’:
59094915.cpp:58:13: error: cannot declare variable ‘f1’ to be of abstract type ‘Normal1’
58 | Normal1 f1(0.5, a2, b2); // rho = 0.5
| ^~
59094915.cpp:32:7: note: because the following virtual functions are pure within ‘Normal1’:
32 | class Normal1: public Func
| ^~~~~~~
In file included from /usr/local/lib/R/site-library/RcppNumerical/include/integration/wrapper.h:13,
from /usr/local/lib/R/site-library/RcppNumerical/include/RcppNumerical.h:16,
from 59094915.cpp:3:
/usr/local/lib/R/site-library/RcppNumerical/include/integration/../Func.h:26:20: note: ‘virtual double Numer::Func::operator()(const double&) const’
26 | virtual double operator()(const double& x) const = 0;
| ^~~~~~~~