![](/img/trans.png)
[英]Rcpp: how to combine the R function and Rcpp function together to make a package
[英]how to add function in R package into rcpp code
我正在編寫rcpp代碼,並且想在“ invgamma”包中使用函數dinvgamma(rinvgamma)。 以下是我的所有代碼。 我嘗試將包“ invgamma”放入環境中,然后將其內部的函數稱為Rcpp :: Function。
#include <Rcpp.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <R_ext/Utils.h>
using namespace Rcpp;
// [[Rcpp::export]]
RcppExport SEXP updatesigama2_mu(SEXP sigma2_mu,
SEXP mu,
SEXP u0,
SEXP v0,
SEXP K,
SEXP SS,
SEXP acc,
SEXP sigma2_mu_list)
{
BEGIN_RCPP
Rcpp::Environment invgamma("package:invgamma");
Rcpp::Function dinvgamma = invgamma["dinvgamma"];
Rcpp::Function rinvgamma = invgamma["rinvgamma"];
double xacc = Rcpp::as<double>(acc);
Rcpp::NumericVector xsigma2_mu_list(sigma2_mu_list);
Rcpp::NumericVector xmu(mu);//vector mu
double xsigma2_mu = Rcpp::as<double>(sigma2_mu);
int xK = Rcpp::as<int>(K);
int xSS = Rcpp::as<int>(SS);// time for irrecation
double xu0 = Rcpp::as<double>(u0);
double xv0 = Rcpp::as<double>(v0);
Rcpp::RNGScope scope;
int c = 0; int d = 0;
c = xu0 + 0.5*xK + 1;
d = xv0 + 0.5*sum(xmu);
for (int ss = 0; ss<xSS; ss++){//iteration
Rcpp::NumericVector tmp = rinvgamma(1,0,1);//proposal distribution Normal(0,10)
Rcpp::NumericVector u = Rcpp::runif(1);
Rcpp::NumericVector a = dinvgamma(tmp[0], c, pow(d,-1),d, false ) * dinvgamma(xsigma2_mu,1,0,1,false)/
(dinvgamma(xsigma2_mu,c,pow(d,-1),d,false)*dinvgamma(tmp[0],1,0,1,false))
xsigma2_mu_list[1] = tmp[0];
xsigma2_mu_list[2] = a[0];
if ( u[0] <= a[0] ){
xsigma2_mu = tmp[0];
xacc += 1;
}
}
return Rcpp::List::create(Rcpp::Named("sigma2_mu") = xsigma2_mu,
Rcpp::Named("acc") = xacc,
Rcpp::Named("sigma2_mu_list") = xsigma2_mu_list);
END_RCPP
}
我將其用作以下形式,但不起作用。 它會錯過某些東西嗎?
Rcpp::NumericVector a = dinvgamma(tmp[0], c, pow(d,-1),d, false ) * dinvgamma(xsigma2_mu,1,0,1,false)/
(dinvgamma(xsigma2_mu,c,pow(d,-1),d,false)*dinvgamma(tmp[0],1,0,1,false))
加載某些程序包中定義的R函數沒有原則性問題。 但是,必須附加該程序包才能使用它的環境。 請參見示例中的函數rfunc()
。 對於逆Gamma,更容易根據Gamma函數定義自己的函數。 請參見示例中的函數sugar()
。
例:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List rfunc() {
Rcpp::Environment invgamma("package:invgamma");
Rcpp::Function dinvgamma = invgamma["dinvgamma"];
Rcpp::Function rinvgamma = invgamma["rinvgamma"];
Rcpp::NumericVector tmp = rinvgamma(5, 1);
Rcpp::NumericVector a = dinvgamma(tmp, 1);
return Rcpp::List::create(Rcpp::Named("tmp") = tmp,
Rcpp::Named("a") = a);
}
Rcpp::NumericVector rinvgamma(R_xlen_t n,
double shape,
double rate = 1.0) {
return 1.0/Rcpp::rgamma(n, shape, rate);
}
Rcpp::NumericVector dinvgamma(Rcpp::NumericVector x,
double shape,
double rate = 1.0,
bool log = false) {
Rcpp::NumericVector log_f = Rcpp::dgamma(1.0/x, shape, rate, true) - 2 * Rcpp::log(x);
if (log)
return log_f;
return Rcpp::exp(log_f);
}
// [[Rcpp::export]]
Rcpp::List sugar() {
Rcpp::NumericVector tmp = rinvgamma(5, 1);
Rcpp::NumericVector a = dinvgamma(tmp, 1);
return Rcpp::List::create(Rcpp::Named("tmp") = tmp,
Rcpp::Named("a") = a);
}
/*** R
library(invgamma)
set.seed(42)
rfunc()
set.seed(42)
sugar()
microbenchmark::microbenchmark(rfunc(), sugar())
*/
輸出:
> library(invgamma)
> set.seed(42)
> rfunc()
$tmp
[1] 0.5156511 5.5426504 1.8711424 41.7271256 2.3376817
$a
[1] 0.5408323347 0.0271775313 0.1673728698 0.0005607317 0.1193024224
> set.seed(42)
> sugar()
$tmp
[1] 0.5156511 5.5426504 1.8711424 41.7271256 2.3376817
$a
[1] 0.5408323347 0.0271775313 0.1673728698 0.0005607317 0.1193024224
> microbenchmark::microbenchmark(rfunc(), sugar())
Unit: microseconds
expr min lq mean median uq max neval
rfunc() 115.098 117.1595 130.80325 117.9270 119.429 1342.420 100
sugar() 7.333 8.3810 26.03649 9.2195 10.023 1657.404 100
使用Rcpp糖的性能提升非常可觀!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.