Rcpp

2013-12-09 25 views
12

diğer paketinden C işlevini kullanarak çok boyutlu birleştirme gerçekleştirmek için C++ işlevinde bir C yordamı çağırmak çalışıyorum.Rcpp

ben yeniden oluşturmaya çalışıyorum temel Ar örneği sadece this recipe from the gallery aşağıdaki Rcpp bu R işlevi diyebiliriz ama ileri geri c/c geçiş bazı performans cezası olacağını

library(cubature) 
integrand <- function(x) sin(x) 
adaptIntegrate(integrand, 0, pi) 

olduğunu ++ R'ye C++'dan direkt olarak C fonksiyonu çağırmak daha mantıklı görünüyor.

adapt_integrate rutin C ı ancak, C++ onu aramak için anlamıyorum

// R_RegisterCCallable("cubature", "adapt_integrate", (DL_FUNC) adapt_integrate); 

ile cubature ihraç edilmektedir. İşte bu benim topal girişimi,

Bu, derlenemiyor; Açıkçası çok aptalca bir şey yapıyorum ve R_GetCCallable çıktısını Rcpp::Function'a dönüştürmek için bazı önemli adımları atıyorum (veya doğrudan arayın?). İşlev işaretçileriyle ilgili birçok ilgili yazı okudum, ancak harici bir C işlevi kullanarak bir örnek görmedim.

cevap

6

Maalesef cubatureinst/include başlıkların birlikte gelmez, bu yüzden onlardan ödünç ve kodunuzda böyle bir şey yapmak zorunda:

typedef void (*integrand) (unsigned ndim, const double *x, void *, 
      unsigned fdim, double *fval); 

int adapt_integrate(
    unsigned fdim, integrand f, void *fdata, 
    unsigned dim, const double *xmin, const double *xmax, 
    unsigned maxEval, double reqAbsError, double reqRelError, 
    double *val, double *err) 
{ 
    typedef int (*Fun)(unsigned,integrand,void*,unsigned, 
     const double*,const double*, unsigned, double, double, double*, double*) ; 
    Fun fun = (Fun) R_GetCCallable("cubature", "adapt_integrate") ;   
    return fun(fdim,f,fdata,dim,xmin,xmax,maxEval,reqAbsError, reqRelError,val,err); 
} 

O sürdürücü ile negociate için iyi bir fikir olabilir cubature, inst/include numaralı belgede beyanları gönderir, böylece yalnızca LinkingTo'u kullanmanız gerekir.

+0

Bu eksik parçaları birleştirdiğiniz için çok teşekkürler. Problemi yeniden gözden geçirmem gerekecek, çünkü ne yazık ki, 'adap_integrate' göründüğümden armadillo'nun veri yapılarını kullanarak tanımladığım bir integrali kolayca kabul etmeyecek. Tamlık için, minimal bir kullanım örneği ekleyebilir misiniz? – baptiste

+0

Size ne verir, "cubature" in kayıtlı olduğu işlev işaretçisine erişimdir. O zaman C fonksiyonunda ne yapman gerektiğini bilmiyorum ... –

+0

, [kullanım örneği dikkate alındığında] (http://ab-initio.mit.edu/wiki/index.php/Cubature# Örnek) İleride bir sorun görüyorum: 'adap_integrate_v'' * fdata' gibi nesnelere imleçler bekler, integral '' fval' gibi imleçler bekler; arma :: colvec nesnesi. İkisi arasında köprü kurabileceğimi sanmıyorum. R-level arayüzüne bağlı kalmak ya da kendi 2D quadrature'ımı C++ 'da uygulamak zorunda kalabilirim. – baptiste

2

Bu soruyu daha önce görmedik ve @Romain buna hitap ediyor gibi görünüyor.

Tüm taraflar birlikte çalışırken bunun nasıl yapılacağına dair bir çalışma örneği, tamlık açısından xts ve RcppXts paketleri tarafından sağlanır. xts, biz bunu (kaynak) (yaklaşık on fonksiyonlar için) inst/include/xtsAPI.h dosyası:

SEXP attribute_hidden xtsLag(SEXP x, SEXP k, SEXP pad) {  
    static SEXP(*fun)(SEXP,SEXP,SEXP) = NULL;   
    if (fun == NULL)         
     fun = (SEXP(*)(SEXP,SEXP,SEXP)) R_GetCCallable("xts","lagXts"); 
    return fun(x, k, pad);        
} 

R_registerRoutines ve R_RegisterCCallable olağan iş ile birlikte.

RcppXts bu oldukça iyi çalışıyor

function("xtsLag", 
     &xtsLag,  
     List::create(Named("x"), Named("k"), Named("pad")), 
     "Extract the coredata from xts object"); 

olarak (bir Rcpp Modülünde) alınır. Birisi bana xts tarafını daha sıkı bir şekilde yazmam için beni azarladı (if NULL sahte).

+0

İşaretçiler için teşekkürler, maalesef bu iki parça kod arasındaki uygun yapıştırıcının çalışmasının beni daha yavaş R uygulamasıyla hesaplamaları yapmaktan çok daha fazla zaman ve ıstırap çekeceği bir durum söz konusudur. Aksi halde eski bir sürümü kullanan R paketinden ziyade orijinal küp koduna doğrudan bağlantıyı düşünürdüm. – baptiste

0

Bu soru şimdi üç yaşında ama RcppNumerical kütüphanesi kullanılabilir olduğunu şimdi Rcpp ile çok boyutlu entegrasyon daha kolay olabileceğini işaret etmek istiyorum: https://github.com/yixuan/RcppNumerical

integraller hesaplamak için rutinleri Thomas Hahn Küba dayanmaktadır paketi ve ayrıca CRAN'daki R2Cuba kütüphanesinde mevcuttur, bu yüzden Küba'dan adaptIntegrate() fonksiyonu üzerinden Küba rutinlerini kabul edebiliyorsanız, bu paket ilgi çekebilir.

+0

İşaretçi için teşekkürler. Bununla birlikte, soru bir yorum olarak kalması en iyisidir, çünkü soru özellikle entegrasyon hakkında değildi, aksine başka bir paketten bir C işlevine erişme hakkındaydı. Yine de bağlantıyı takdir ediyorum, kendi kopyasını kullanarak bitirdim, ama bu çok değerli bir alternatife benziyor (özellikle eğer Eigen kullanıyorsa, ama Armadillo'ya alışkınım). Kübrenin bir avantajı, vektör değerli integrallerle başa çıkabilme yeteneğidir. – baptiste

İlgili konular