inspired by http://bicycle1885.hatenablog.com/entry/2015/01/04/175916
速度がどうというより、愚直なループをみたらRcppをさくっと適用できるようになりたい。
見本(Julia)はこちら。
circle_in = 0.0
for i in 1:100000000
l = (rand()^2 + rand()^2) ^ 0.5
if l <= 1
circle_in = circle_in + 1
end
end
println(4 * circle_in / 100000000)
Rで愚直に書くとこんな感じ。
calcPiR <- function(){
circle_in = 0
for (i in 1:100000000){
l = sqrt(runif(1)^2 + (runif(1))^2)
if (l <= 1){
circle_in = circle_in + 1
}
}
4 * circle_in / 100000000
}
しかしこれだといつまで経っても終わらないので少しはましなコードにしてそちらを実験に使う。
ましなコードはこちらからもってきた。
http://gallery.rcpp.org/articles/simulating-pi/
ということでRと愚直なC++のループとRのコードっぽいC++で比較した。
library(Rcpp)
library(microbenchmark)
calcPiR2 <- function() {
x <- runif(100000000)
y <- runif(100000000)
d <- sqrt(x^2 + y^2)
return(4 * sum(d < 1.0) / 100000000)
}
cppFunction('double calcPiCpp() {
double circle_in = 0.0;
for (int i = 0; i < 100000000; i++) {
double l = sqrt(pow(rand()/2147483648., 2)+pow(rand()/2147483648.,2));
if (l <= 1){
circle_in = circle_in + 1.0;
}
}
return 4*circle_in/100000000;
}')
cppFunction('double calcPiCpp2() {
NumericVector x = runif(100000000);
NumericVector y = runif(100000000);
NumericVector d = sqrt(x*x + y*y);
return 4.0 * sum(d < 1.0) / 100000000;
}')
# @kos59125より
calc_pi <- function(n, k) {
stopifnot(n %% k == 0)
r <- n %/% k
s <- 0
loop <- 0L
while (loop < r) {
x <- runif(k)
y <- runif(k)
s <- s + sum(x * x + y * y <= 1)
loop <- loop + 1L
}
4 * s / n
}
microbenchmark(calcPiR2(), calcPiCpp(), calcPiCpp2(), calc_pi(100000000L, 10000L), times=3L)
## Unit: seconds
## expr min lq mean median
## calcPiR2() 10.709923 10.710115 11.513909 10.710307
## calcPiCpp() 2.355628 2.358802 2.374402 2.361975
## calcPiCpp2() 5.680846 5.695607 5.791551 5.710368
## calc_pi(100000000L, 10000L) 9.068039 9.424003 9.547543 9.779967
## uq max neval
## 11.915902 13.121498 3
## 2.383789 2.405603 3
## 5.846904 5.983440 3
## 9.787296 9.794624 3
環境はこちら。
sessionInfo()
## R version 3.1.1 (2014-07-10)
## Platform: x86_64-apple-darwin13.1.0 (64-bit)
##
## locale:
## [1] ja_JP.UTF-8/ja_JP.UTF-8/ja_JP.UTF-8/C/ja_JP.UTF-8/ja_JP.UTF-8
##
## attached base packages:
## [1] stats grDevices datasets graphics utils methods base
##
## other attached packages:
## [1] microbenchmark_1.4-2 Rcpp_0.11.3
##
## loaded via a namespace (and not attached):
## [1] audio_0.1-5 beepr_1.1 colorspace_1.2-4 digest_0.6.4
## [5] evaluate_0.5.5 formatR_1.0 ggplot2_1.0.0 grid_3.1.1
## [9] gtable_0.1.2 htmltools_0.2.6 knitr_1.7 MASS_7.3-33
## [13] munsell_0.4.2 plyr_1.8.1 proto_0.3-10 reshape2_1.4
## [17] rmarkdown_0.3.10 scales_0.2.4 stringr_0.6.2 tools_3.1.1
## [21] yeah_0.3.3