我已经搜索了一个小时来进行数值积分的方法。我是Rcpp
的新手,现在重写我的旧程序。我在R做过的是:
x=smpl.x(n,theta.true)
joint=function(theta){# the joint dist for
#all random variable
d=c()
for(i in 1:n){
d[i]=den(x[i],theta)
}
return(prod(d)*dbeta(theta,a,b)) }
joint.vec=Vectorize(joint)##vectorize the function, as required when
##using integrate()
margin=integrate(joint.vec,0,1)$value # the
##normalizeing constant at the donominator
area=integrate(joint.vec,0,theta.true)$value # the values at the
## numeritor
integrate()
函数速度很慢,而且由于我正在对大小为n的样本的后验分布进行积分,因此积分的值会很大而且误差很大。 Rcpp
的帮助下重写我的代码,但我不知道如何处理集成。我应该加c++ h file
吗?还是有什么建议吗?答案 0 :(得分:0)
您可以在C
中对自己的功能进行编码,然后通过sourceCpp
功能调用它,然后在integrate
中调用R
。或者,您可以使用R
的{{1}}宏在C
代码中调用Function
的集成功能。有关如何从Rcpp
调用R
函数的示例,请参见第56页的Dirk的书(无缝R和C ++与Rcpp的集成)。另一种替代方案(我认为对大多数情况来说是最好的)是使用C
包将C
中编写的函数直接集成到C
中。
关于巨大的归一化常数,有时最好在积分之前在模式下缩放函数(您可以找到具有RcppGSL
,nlminb
等模式的模式。然后,集成重新调整的函数并恢复原始的nroming常量,将得到的归一化常数乘以重新缩放因子。希望这可能有所帮助!
答案 1 :(得分:0)
// [[Rcpp::export]]
double den_cpp (double x, double theta){
return(2*x/theta*(x<=theta)+2*(1-x)/(1-theta)*(theta<x));
}
// [[Rcpp::export]]
double joint_cpp ( double theta,int n,NumericVector x, double a, double b){
double val = 1.0;
NumericVector d(n);
for (int i = 0; i < n; i++){
double tmp = den_cpp(x[i],theta);
val = val*tmp;
}
val=val*R::dbeta(theta,a,b,0);
return(val);
}
// [[Rcpp::export]]
List Cov_rate_raw ( double theta_true, int n, double a, double b,NumericVector x){
//This function is used to test, not used in the fanal one
int steps = 1000;
double s = 0;
double start = 1.0e-4;
std::cout<<start<<" ";
double end = 1-start;
std::cout<<end<<" ";
double h = (end-start)/steps;
std::cout<<"1st h ="<<h<<" ";
double area = 0;
double margin = 0;
for (int i = 0; i < steps ; i++){
double at_x = start+h*i;
double f_val = (joint_cpp(at_x,n,x,a,b)+4*joint_cpp(at_x+h/2,n,x,a,b)+joint_cpp(at_x+h,n,x,a,b))/6;
s = s + f_val;
}
margin = h*s;
s=0;
h=(theta_true-start)/steps;
std::cout<<"2nd h ="<<h<<" ";
for (int i = 0; i < steps ; i++){
double at_x = start+h*i;
double f_val = (joint_cpp(at_x,n,x,a,b)+4*joint_cpp(at_x+h/2,n,x,a,b)+joint_cpp(at_x+h,n,x,a,b))/6;
s = s + f_val;
}
area = h * s;
double r = area/margin;
int cover = (r>=0.025)&&(r<=0.975);
List ret;
ret["s"] = s;
ret["margin"] = margin;
ret["area"] = area;
ret["ratio"] = r;
ret["if_cover"] = cover;
return(ret);
}
我对c ++并不擅长,所以两个 for 循环就像傻了。
它通常有效,但仍有几个潜在的问题: