某ドキュメントのほぼまんまなんだけど,Rcppでコードを生成する場合,大まかに四つの方法に分けられるかと
ソースに書いてコンパイルし,Rでロードする
C/C++のまんまの関数コードだけのファイル
fibonacci00.cpp
int fibonacci(const int x){
if(x==0)return(0);
if(x==1)return(1);
return fibonacci(x-1)+fibonacci(x-2);
}
これをRcpp/Rで利用するためラッパー関数コードだけのファイル
fibonacci0.cpp
#include <Rcpp.h>
extern int fibonacci(const int x);
extern "C" SEXP fibWrapper ( SEXP xs ) {
int x = Rcpp::as<int>(xs);
int fib = fibonacci (x);
return Rcpp::wrap(fib);
}
んでもって二つをR CMD でコンパイル
$ R CMD SHLIB fibonacci0.cpp fibonacci00.cpp
g++ -shared -L/usr/local/lib -o fibonacci0.so fibonacci0.o fibonacci00.o -L/R/libs/Rcpp/lib -lRcpp -Wl,-rpath,/R/libs/Rcpp/lib -L/usr/local/lib/R/lib -lR
Rでロードして利用
> dyn.load ("fibonacci0.so")
> .Call ("fibWrapper", 10)
[1] 55
> dyn.unload ("fibonacci0.so")
inlineパッケージを使ってコードもRのスクリプトに書き込む
R.R
> library (inline)
> library (Rcpp)
> incltxt <- '
+ int fibonacci(const int x){
+ if(x==0)return(0);
+ if(x==1)return(1);
+ return fibonacci(x-1)+fibonacci(x-2);
+ }'
> fibRcpp <- cxxfunction(signature(xs = 'int'),
+ plugin = 'Rcpp',
+ incl = incltxt,
+ body = '
+ int x = Rcpp::as<int>(xs);
+ return Rcpp::wrap(fibonacci(x));
+ ')
> fibRcpp(10)
[1] 55
attriburesを使う.ラッパーを定義する必要なし
fibonacci.cpp
#include<Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
int fibonacci(const int x){
if(x < 2)
return x;
else
return(fibonacci(x - 1))+fibonacci(x-2);
}
sourceCpp()でコンパイルする.ラッパーを定義する必要なし
> sourceCpp ("fibonacci.cpp")
> fibonacci(10)
[1] 55
まだある
cppFuncitonを使う.これまたRのスクリプトにコードを書く
> txt <- '
+ int fibonacci (const int x) {
+ if ( x < 2) return ( x ) ;
+ return ( fibonacci ( x - 1) ) + fibonacci ( x - 2) ;
+ }'
> fib <- cppFunction(txt)
> fib (10)
[1] 55
Rcppは進化が激しいので,追って整理するのが大変...