|
## ============================================================================= |
|
## Simple Examples: Pure R vs C++ Speed Comparison |
|
## ============================================================================= |
|
|
|
rm(list=ls()) |
|
setwd("/media/SUPPORT/Repo/sandbox/cpp") |
|
library(Rcpp) |
|
library(microbenchmark) |
|
set.seed(1234) |
|
|
|
## ============================================================================= |
|
## Parameters |
|
## ============================================================================= |
|
|
|
n_fib <- 15 |
|
n_times <- 500 |
|
|
|
|
|
## ============================================================================= |
|
## Fibonacci recursive |
|
## ============================================================================= |
|
|
|
## Pure R ---------------------- |
|
fibR <- function(n) { |
|
if (n == 0) return(0) |
|
if (n == 1) return(1) |
|
return (fibR(n - 1) + fibR(n - 2)) |
|
} |
|
|
|
## CPP -------------------------- |
|
cppFunction(' |
|
int fibC(const int x) { |
|
if (x == 0) return (0); |
|
if (x == 1) return (1); |
|
return fibC(x - 1) + fibC(x - 2); |
|
}') |
|
|
|
## Benchmark ------------------------ |
|
res <- summary(microbenchmark(fibR(n_fib), fibC(n_fib), times = n_times)) |
|
cat("\nExample: Fibonacci Recursive\n") |
|
print(res) |
|
cat("Speed Up = ", res[1,]$median / res[2,]$median, "x\n", sep = "") |
|
|
|
|
|
## ============================================================================= |
|
## Fibonacci for loop |
|
## ============================================================================= |
|
|
|
## linear / iterative solution --------------- |
|
fibRiter <- function(n) { |
|
first <- 0 |
|
second <- 1 |
|
third <- 0 |
|
for (i in seq_len(n)) { |
|
third <- first + second |
|
first <- second |
|
second <- third |
|
} |
|
return(first) |
|
} |
|
|
|
## CPP ----------------- |
|
cppFunction(' |
|
int fibCiter(const int n) { |
|
double first = 0; |
|
double second = 1; |
|
double third = 0; |
|
for (int i = 0; i < n; i++) { |
|
third = first + second; |
|
first = second; |
|
second = first; |
|
} |
|
return(first); |
|
}') |
|
|
|
## Benchmark --------------------- |
|
res <- summary(microbenchmark(fibRiter(n_fib), fibCiter(n_fib), times = n_times)) |
|
cat("\nExample: Fibonacci For Loop\n") |
|
print(res) |
|
cat("Speed Up = ", res[1,]$median / res[2,]$median, "x\n", sep = "") |
|
|
|
|
|
## ============================================================================= |
|
## VAR Simulation |
|
## ============================================================================= |
|
|
|
## parameter and error terms used throughout --------------------------- |
|
a <- matrix(c(0.5,0.1,0.1,0.5),nrow=2) |
|
u <- matrix(rnorm(10000),ncol=2) |
|
|
|
## Let’s start with the R version ------------------- |
|
rSim <- function(coeff, errors) { |
|
simdata <- matrix(0, nrow(errors), ncol(errors)) |
|
for (row in 2:nrow(errors)) { |
|
simdata[row,] = coeff %*% simdata[(row-1),] + errors[row,] |
|
} |
|
return(simdata) |
|
} |
|
rData <- rSim(a, u) # generated by R |
|
|
|
## Cpp ------------------------------------------------------------- |
|
## Now load ’inline’ to compile C++ code on the fly |
|
suppressMessages(require(inline)) |
|
code <- ' |
|
arma::mat coeff = Rcpp::as<arma::mat>(a); |
|
arma::mat errors = Rcpp::as<arma::mat>(u); |
|
int m = errors.n_rows; |
|
int n = errors.n_cols; |
|
arma::mat simdata(m,n); |
|
simdata.row(0) = arma::zeros<arma::mat>(1,n); |
|
for (int row=1; row<m; row++) { |
|
simdata.row(row) = simdata.row(row-1) * trans(coeff) + errors.row(row); |
|
} |
|
return Rcpp::wrap(simdata);' |
|
|
|
## create the compiled function |
|
rcppSim <- cxxfunction(signature(a = "numeric", u = "numeric"), |
|
code, plugin="RcppArmadillo") |
|
rcppData <- rcppSim(a,u) # generated by C++ code |
|
stopifnot(all.equal(rData, rcppData)) # checking results |
|
|
|
## Compare ------------------------------ |
|
res <- summary(microbenchmark(rSim(a,u), rcppSim(a,u), times = n_times)) |
|
cat("\nExample: VAR Simulation\n") |
|
print(res) |
|
cat("Speed Up = ", res[1,]$median / res[2,]$median, "x\n", sep = "") |