Hello Rcpp

This past weekend I discovered the wonders of c++ thanks to this datacamp course. Although c++ syntax is different, knowing Fortran made this much easier.

Filling a matrix with c++

The following code creates a function that can be called from R to fill a matrix. Something that is different than in Fortran is that to make loops more efficient you have to do right (j) to left (i) instead of left to right. The other big difference, c++ starts counting at 0 instead of 1! This one got me more than once…

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericMatrix my_matrix(int I, int J) {
NumericMatrix A(I,J);
int iter = 0;
for(int j = 0; j < J; j++) {
for(int i = 0; i < I; i++){
iter++;
A(i,j) = iter ;
}
}
return A;
}


my_matrix(6,5)

##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    7   13   19   25
## [2,]    2    8   14   20   26
## [3,]    3    9   15   21   27
## [4,]    4   10   16   22   28
## [5,]    5   11   17   23   29
## [6,]    6   12   18   24   30


Similarly to Fortran, you can use OpenMP do speed things up very easily:

#include <Rcpp.h>
// [[Rcpp::plugins(openmp)]]
#include <omp.h>

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

using namespace Rcpp;

// [[Rcpp::export]]
NumericMatrix my_matrix(int I, int J, int nthreads) {
NumericMatrix A(I,J);
// create a thread safe accessor for A
RcppParallel::RMatrix<double> a(A);
int tid;
#pragma omp parallel for private(tid)
for(int j = 0; j < J; j++) {
for(int i = 0; i < I; i++) {
a(i, j) = tid ;
}
}

return A;
}


my_matrix(6,5,4)

##      [,1] [,2] [,3] [,4] [,5]
## [1,]    0    0    1    2    3
## [2,]    0    0    1    2    3
## [3,]    0    0    1    2    3
## [4,]    0    0    1    2    3
## [5,]    0    0    1    2    3
## [6,]    0    0    1    2    3


In this case a is a safe accessor for A. For more details check RcppParallel.

My conclusion: although Fortran is faster than c++, writing c++ code using Rcpp is way easier than writing Fortran code, and my time is way more valuable than the small difference that I may gain by using Fortran.