2017-05-19 3 views
1

Ich übersetze meinen R-Code mit einigen vorbereiteten Funktionen zu RcppArmadillo. Ich möchte einige dieser Funktionen direkt in meinem Rcpp-Code verwenden, anstatt zu übersetzen. Zum Beispiel möchte ich die sigma2 Funktion aufzurufen:Call R Funktionen in RcppArmadillo mit Gürteltier Datentyp

sigma2<- function(xi.vec,w.vec,log10lambda,n,q){ 
    lambda <- 10^log10lambda 
    (1/(n-q))*sum((lambda*xi.vec*(w.vec^2))/(lambda*xi.vec+1)) 
} 

Ein typischer RCPP Code ist wie folgt:

#include <RcppArmadillo.h> 
// [[Rcpp::depends(RcppArmadillo)]] 


// [[Rcpp::export]] 
SEXP myS(){ 

    Rcpp::Environment myEnv = Rcpp::Environment::global_env(); 
    Rcpp::Function myS = myEnv["sigma2"]; 
    arma::vec xvec = myEnv["xi.vec"]; 
    arma::vec wvec = myEnv["w.vec"]; 
    double l = myEnv["log10lambda"]; 
    int n = myEnv["n"]; 
    int q = myEnv["q"]; 

    return myS(Rcpp::Named("xi.vec",xvec), 
      Rcpp::Named("w.vec",wvec), 
      Rcpp::Named("l",l), 
      Rcpp::Named("n",n), 
      Rcpp::Named("q",q)); 
} 

Natürlich funktioniert es. Aber mein Problem ist, dass in meinem Fall die Parameter der sigma2 Funktion vorher als Ausgabe einer anderen Funktion (zB func1) in RcppArmadillo definiert werden sollten und sie Armadillo-Datentyp haben. Zum Beispiel haben xi.vec und w.vecvec Typ. Jetzt möchte ich wissen, wie kann ich diesen Code ändern, um sigma2 anrufen? Muss ich meine Umgebung ändern?

Antwort

2

Zuerst sagen Sie einfach nein zu R-Funktionen und Umgebungen in C++ - Routinen einbetten. Es gibt keine Beschleunigung in diesem Fall; nur eine beträchtliche Verlangsamung. Darüber hinaus gibt es ein größeres Potenzial für Dinge, Cockeye zu gehen, wenn die Variablen nicht im Bereich global.env abgerufen werden können.


In Ihrem Fall, Sie scheinen myS() aus myS() ohne Abbruchbedingung zu rufen. Somit wird Ihre Funktion niemals enden.

z.B.

SEXP myS(){ 

Rcpp::Function myS = myEnv["sigma2"]; 

return myS(Rcpp::Named("xi.vec",xvec), 
      Rcpp::Named("w.vec",wvec), 
      Rcpp::Named("l",l), 
      Rcpp::Named("n",n), 
      Rcpp::Named("q",q)); 
} 

Schalter ein myS_R und myS_cpp sein.


In Bezug auf Umgebung Hijacking müssten Sie die Werte nach C++ übergeben. Sie können nicht auf eine R-Funktion zugreifen, um Werte zu erhalten, die vor dem Aufruf übergeben wurden.

z.B.

SEXP myS_cpp(arma::vec xvec, arma::vec wvec, double l, int n, int q){ 
    // code here 
} 
+0

Danke für die Antwort. Genau das habe ich gesucht. – Ham82

+0

Keine "erhebliche" Verlangsamung; es fügt eine Ebene hinzu, so dass es messbar ist, aber Sie machen es zu dramatisch. –