ウェブサイトの例をなぞってみる

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector callFunctionInt2Vector(int x, Function f) {
    NumericVector res = f(x);
    return res;
}
> sourceCpp("callFunctionInt2Vector.cpp")
> callFunctionInt2Vector(10,rnorm)
 [1] -0.9999129  1.2634527  1.3301896  0.4461846 -0.9047776  1.2276814  0.4284985
 [8] -3.3401143 -0.1681339  0.3275609
> set.seed(42)
> callFunctionInt2Vector(10,rnorm)
 [1]  1.37095845 -0.56469817  0.36312841  0.63286260  0.40426832 -0.10612452  1.51152200
 [8] -0.09465904  2.01842371 -0.06271410
> set.seed(42)
> rnorm(10)
 [1]  1.37095845 -0.56469817  0.36312841  0.63286260  0.40426832 -0.10612452  1.51152200
 [8] -0.09465904  2.01842371 -0.06271410
  • パーミュテーションテストっぽいもの(RでできることをC++内から呼び出しているだけだからなんていうこともないけれど)
#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector permutationTestRY(NumericVector x, NumericVector y, int nperm,Function f1, Function f2) {
	int xn = x.size();
    NumericVector tmpx(xn);
    NumericVector res(nperm);
	for(int i=0;i<nperm;++i){
		NumericVector tmpx = f1(x);
		NumericVector tmpcor = f2(tmpx,y);
		res[i] = tmpcor[0];
	}
    return res;
}
> sourceCpp("permutationTestRY.cpp")
> permutationTestRY(x,y,100,sample,cor)
  • rbenchmark()で比較
library(rbenchmark)

permutationTestRYR <- function(x,y,n){
	ret <- rep(0,n)
	for(i in 1:n){
		tmp <- sample(x)
		ret[i] <- cor(tmp,y)
	}
	ret
}
x <- runif(1000)
y <- rnorm(1000)

benchmark(
permutationTestRY(x,y,1000,sample,cor),
permutationTestRYR(x,y,1000),
columns=c("test", "replications","elapsed", "relative"),
replications=100,
order="relative")
  • 面倒をしている分cppの方が遅いが。
                                        test replications elapsed relative
2             permutationTestRYR(x, y, 1000)          100   28.74     1.00
1 permutationTestRY(x, y, 1000, sample, cor)          100   38.22     1.33

一括してsourceCpp() たくさんcppファイルを作ったら

  • 練習でたくさんのcppファイルを作ると、sourceCpp("hoge.cpp")が面倒くさくなる
  • ので、ディレクトリの中のcppファイルのリストを作って、一括して処理
library(Rcpp)
library(RcppArmadillo)
sourceCpp.list <- function(files,silent=TRUE){
	for(i in 1:length(files)){
		if(!silent){
			print(files[i])
		}
		sourceCpp(files[i])
	}
}
cpp.files <- list.files(pattern=".cpp$")
sourceCpp.list(cpp.files)