我必须计算函数的双积分:
> DIntegral <- function(x,y){res <- pnorm(x,1,0.1) * dexp(y-2,1.2)
return(res)
}
x和y的上限分别为:10
和Infinity
。
x和y的下限分别是:1
和2
。
如何在RcppNumerical
中进行这种双重集成?
对于一维集成,我的C ++文件如下所示:
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
#include <RcppNumerical.h>
using namespace Numer;
class PDF: public Func
{
private:
double beta;
double M0;
public:
PDF( double beta_, double M0_): beta(beta_), M0(M0_) {};
double operator()(const double& x) const
{
return R::dexp(x-M0,beta,0);
}
};
// [[Rcpp::export]]
double integrate_test2( double beta, double M0, double upper, double lower)
{
PDF f( beta, M0);
double err_est;
int err_code;
double res = integrate ( f, lower, upper,err_est,err_code);
return(res);
}
具有有限限制的二维积分代码
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
#include <RcppNumerical.h>
using namespace Numer;
class PDF: public MFunc
{
private:
double mu;
double sigma;
double beta;
double M0;
public:
PDF( double mu_, double sigma_, double beta_, double M0_): mu(mu_), sigma(sigma_), beta(beta_), M0(M0_) {};
double operator()(Constvec& x)
{
return R::pnorm(x[0],mu,sigma,1,0) * R::dexp(x[1]-M0,beta,0);
}
};
// [[Rcpp::export]]
double integrate_test2( double mu, double sigma, double beta, double M0)
{
Eigen::VectorXd lower(2);
lower << 1, 2;
Eigen::VectorXd upper(2);
upper << 10, 50;
PDF f( mu, sigma, beta, M0);
double err_est;
int err_code;
double err_est2;
int err_code2;
double res = integrate ( f, lower, upper,err_est,err_code);
return(res);
}
答案 0 :(得分:0)
我已经更新了您的代码,以将积分限制作为参数并返回错误代码并进行估算:
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
#include <RcppNumerical.h>
using namespace Numer;
class PDF: public MFunc
{
private:
double mu;
double sigma;
double beta;
double M0;
public:
PDF( double mu_, double sigma_, double beta_, double M0_): mu(mu_), sigma(sigma_), beta(beta_), M0(M0_) {};
double operator()(Constvec& x)
{
return R::pnorm(x[0],mu,sigma,1,0) * R::dexp(x[1]-M0,beta,0);
}
};
// [[Rcpp::export]]
Rcpp::List integrate_test2( double mu, double sigma, double beta, double M0, Eigen::VectorXd lower, Eigen::VectorXd upper)
{
PDF f( mu, sigma, beta, M0);
double err_est;
int err_code;
double res = integrate ( f, lower, upper,err_est,err_code);
return Rcpp::List::create(
Rcpp::Named("result") = res,
Rcpp::Named("error_estimate") = err_est,
Rcpp::Named("error_code") = err_code
);
}
/*** R
integrate_test2(1, 0.1, 1.2, 2, c(1, 2), c(10, 50))
integrate_test2(1, 0.1, 1.2, 2, c(1, 2), c(10, 1e4))
integrate_test2(1, 0.1, 1.2, 2, c(1, 2), c(10, 1e6))
integrate_test2(1, 0.1, 1.2, 2, c(1, 2), c(10, 1e8))
*/
结果:
> Rcpp::sourceCpp('2d_int.cpp')
> integrate_test2(1, 0.1, 1.2, 2, c(1, 2), c(10, 50))
$result
[1] 8.950068
$error_estimate
[1] 0.3570577
$error_code
[1] 1
> integrate_test2(1, 0.1, 1.2, 2, c(1, 2), c(10, 1e4))
$result
[1] 4.787999
$error_estimate
[1] 16.12484
$error_code
[1] 1
> integrate_test2(1, 0.1, 1.2, 2, c(1, 2), c(10, 1e6))
$result
[1] 1.605216e-314
$error_estimate
[1] 4.320299e-313
$error_code
[1] 0
> integrate_test2(1, 0.1, 1.2, 2, c(1, 2), c(10, 1e8))
$result
[1] 0
$error_estimate
[1] 0
$error_code
[1] 0
因此对于较小的y上限,积分不会收敛。并且当它收敛时,结果(几乎)为零。当人们将上限提高到大约1e307
,即几乎.Machine$double.xmax
时,这种情况不会改变。之后,我得到NaN
。
但是,如果我使用cubature
包,结果将大不相同:
library(cubature)
DIntegral <- function(x){
res <- pnorm(x[1],1,0.1) * dexp(x[2]-2,1.2)
return(res)
}
cubintegrate(f = DIntegral, lower = c(1, 2), upper = c(10, 50), method = "hcubature")
#> $integral
#> [1] 8.961023
#>
#> $error
#> [1] 4.888071e-05
#>
#> $neval
#> [1] 983
#>
#> $returnCode
#> [1] 0
cubintegrate(f = DIntegral, lower = c(1, 2), upper = c(10, 1000), method = "hcubature")
#> $integral
#> [1] 8.960415
#>
#> $error
#> [1] 7.145898e-05
#>
#> $neval
#> [1] 1701611595
#>
#> $returnCode
#> [1] 0
cubintegrate(f = DIntegral, lower = c(1, 2), upper = c(10, Inf), method = "hcubature")
#> $integral
#> [1] 8.960105
#>
#> $error
#> [1] 8.515124e-05
#>
#> $neval
#> [1] 1706522167
#>
#> $returnCode
#> [1] 0
我不确定这是怎么回事。