# Digest of Seamless R and C++ Integration with Rcpp (待修改)

Yao Yao on June 6, 2015

Rcpp 初体验。请结合 Rcpp Hierarchy 做进一步的理解。本文待修改。

## Chapter 1. A Gentle Introduction to Rcpp

### 1.1 inline 写法

#### inline 原理之一：C++ function wrapper

int fibonacci(const int x) {
if (x == 0) return(0);
if (x == 1) return(1);
return (fibonacci(x - 1)) + fibonacci(x - 2);
}


R 的底层是 C，我们要把这个 C++ function 给 R 调用的话，需要写一个 wrapper。具体的原理这里不展示，你只要知道要有这个 wrapper 就好了：

// SEXP means "pointer to S expression"

extern "C" SEXP fibWrapper(SEXP xs) {
int x = Rcpp::as<int>(xs);
int fib = fibonacci(x);
return (Rcpp::wrap(fib));
}

• Rcpp::as<int>(xs) converts the incoming argument xs from SEXP to integer.
• Rcpp::wrap(fib) converts the integer result fib to the SEXP type.

#### inline 实例

With inline package providing a complete wrapper around the compilation, linking, and loading steps, the programmer can concentrate on the actual code (in either one of the supported languages C, C++, or Fortran) and forget about the operating-system specific details of compilation, linking, and loading. A single entry point, the function cxxfunction() can be used to turn code supplied as a text variable into an executable function.

• 类似地还有一个 cfunction() 接口
library(inline)

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));
'
)


### 1.2 Rcpp Attributes 写法

/***** 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);
}


R 调用起来也很方便：

library(Rcpp)

sourceCpp("fibonacci.cpp")
fibonacci(20)
[1] 6765


## Chapter 2. Tools and Setup

### Only gcc compilers are supported on Windows platform

As Rcpp is of course a C++ application, this last restriction applies and we need to stick with the compilers used to build R on the different platforms. 而 R 的 windows 版本是用 gcc 编译器编译的，所以我们自己写的 C++ 文件也要配套使用 gcc 编译器。

### inline 原理之二：.Call() 接口

dyn.load("fibonacci.so")
.Call("fibWrapper", 10)
[1] 55

• dyn.load() loads the shared library. It uses the full filename, including
• the explicit platform-dependent extension which is .so on Unix,
• .dll onWindows,
• and .dylib on OS X

### Plugins of inline

We have seen the use of the options plugin="Rcpp" in the previous examples. Plugins provide a general mechanism for packages using Rcpp to supply additional information which may be needed to compile and link the particular package. 这里说的 additional information，may include additional header files and directories, as well as additional library names to link against as well as their locations.

### cppFunction() and evalCpp()

Rcpp 除了 sourceCpp() 外，还有

• cppFunction(): creates a function from a argument of text.
• 步骤包括：
1. It creates a temporary file.
2. It creates a wrapper.
3. It returns an R function which calls the wrapper.
• 注意 cxxfunction()inline 包的。
• evalCpp(): evaluates a C++ expression directly
cpptxt <- '
int fibonacci(const int x) {
if (x < 2) return(x);
return (fibonacci(x - 1)) + fibonacci(x - 2);
}
'



code <- 'C++ code goes here'

gslVolumes <- cppFunction(code, depends="RcppGSL")


## Chapter 3. Data Structures: Part One

### 3.1 The RObject Class

In Rcpp class hierarchy, although RObject is not directly user-facing, it provides the foundation upon which many important and frequently-used classes are built. 感觉就像 java 的 Object class。

• An instance of the RObject class encapsulates an R object.
• Every R object itself is internally represented by a SEXP.
• SEXP is a pointer to SEXPREC.
• SEXPREC is S expression object.
• One key aspect is that S expression objects are union types.
• In fact, the SEXP is indeed the only data member of an RObject.
• 另外还有一种类型 VECSXP is a vector of SEXP.
• The RObject effectively treats its underlying SEXP as a resource.
• The constructor of the RObject class takes the necessary measures to guarantee that the underlying SEXP is protected from the R garbage collector,
• and the destructor assumes the responsibility to withdraw that protection.

### 3.2 Rcpp::IntegerVector

Rcpp::IntegerVector 可以理解为 vector<int>，我们可以把 c(1,2,3) 或者 1:10 传给它，或者 return 一个 IntegerVector 回来给 R 用。

### 3.3 Rcpp::NumericVector

#### shallow copy 和 deep copy 的问题

src <- '
Rcpp::NumericVector invec(vx);
Rcpp::NumericVector outvec(vx);
for (int i=0; i<invec.size(); i++) {
outvec[i] = log(invec[i]);
}
return outvec;
'

fun <- cxxfunction(signature(vx="numeric"), src, plugin="Rcpp")
x <- seq(1.0, 3.0, by=1)

cbind(x, fun(x))
x
[1,] 0.0000000 0.0000000
[2,] 0.6931472 0.6931472
[3,] 1.0986123 1.0986123


// method 1
Rcpp::NumericVector invec(vx);
Rcpp::NumericVector outvec = Rcpp::clone(vx);
...

// method 2
Rcpp::NumericVector invec(vx);
Rcpp::NumericVector outvec = log(invec); // This is Rcpp sugar


### 3.4 Other Vector Classes

• LogicalVector: vector<bool>，但是要注意可以有 NA
• CharacterVector: vector<const char*>，并不是 vector<string>

## Chapter 4. Data Structures: Part Two

### 4.1 Rcpp::Named

someVec <- c(mean=1.23, dim=42.0, cnt=12)
someVec
mean dim cnt
1.23 42.00 12.00


src <- '
Rcpp::NumericVector x =
Rcpp::NumericVector::create(
Rcpp::Named("mean") = 1.23,
Rcpp::Named("dim") = 42,
Rcpp::Named("cnt") = 12
);
return x;
'

fun <- cxxfunction(signature(), src, plugin="Rcpp")
fun()
mean dim cnt
1.23 42.00 12.00


Rcpp::Named("mean") 部分又可以简写为：

	Rcpp::NumericVector x = NumericVector::create(
_["mean"] = 1.23,
_["dim"] = 42,
_["cnt"] = 12
);


### 4.4 Rcpp::Function

#### 4.4.1 Rcpp::Function 包装一个 R function

A Function object is needed whenever an R function—either supplied by the user or by accessing an R function—is employed.

src <- '
Function sort(x);
return sort(y, Named("decreasing", true));
'

fun <- cxxfunction(signature(x="function", y="ANY"), src, plugin="Rcpp")
fun(sort, sample(1:5, 10, TRUE))
[1] 5 5 5 3 3 3 2 2 2 1


Another useful point to note is that because the second argument y is never instantiated (即我们没有把 y 转成 Rcpp 的对象), we can pass different types of a suitable nature.

#### 4.4.2 Rcpp::Function 调用一个 R function

The Function class can also be used to access R functions directly. In the example below, we draw five random numbers from a t-distribution with three degrees of freedom. As we are accessing the random number generators, we need to ensure that it is in a proper state. The RNGScope class ensures this by initializing the random number generator by calling the GetRNGState() function from the class constructor, and by restoring the initial state via PutRNGState() via its destructor.

src <- '
RNGScope scp;
Rcpp::Function rt("rt");
return rt(5, 3);
'
fun <- cxxfunction(signature(), src, plugin="Rcpp")

set.seed(42)
fun()
[1] 2.339681 0.130995 -0.074028 -0.057701 -0.046482


### 4.5 Rcpp::Environment

Environment 主要负责 variable lookup、namespace 这类的职责。

#### 使用 Rcpp::Environment 定位到 R package 中的某个 functions

Rcpp::Environment stats("package:stats");	// 用 environment 定位到 package
Rcpp::Function rnorm = stats["rnorm"];		// 定位到 function

return rnorm(10, Rcpp::Named("sd", 100.0));


#### 使用 Rcpp::Environment 访问 R global environment 的 variable、创建新的 variable

Rcpp::Environment global = Rcpp::Environment::global_env();

std::vector<double> vx = global["x"];	// 访问 x

std::map<std::string,std::string> map;
map["foo"] = "oof";
map["bar"] = "rab";
global["y"] = map;						// 创建 y


## Chapter 5. Using Rcpp in Your Package

This chapter provides an overview of how to use Rcpp when writing an R package. It shows how using the function Rcpp.package.skeleton() can create a complete and self-sufficient example of a package using Rcpp. All components of the directory tree created by Rcpp.package.skeleton() are discussed in detail.

This chapter complements the Writing R Extensions manual which is the authoritative source on how to extend R in general.

## Chapter 6. Extending Rcpp

This chapter provides an overviewof the steps programmers should follow to extend Rcpp for use with their own classes and class libraries. The packages RcppArmadillo, RcppEigen, and RcppGSL provide working examples of how to extend Rcpp to work with, respectively, the Armadillo and Eigen C++ class libraries as well as the GNU Scientific Library.

The chapter ends with an illustration of how the RcppBDT package connects the date types of R with those of the Boost Date_Time library by extending Rcpp.

## Chapter 7. Modules

7.1.1 Exposing Functions Using Rcpp 讲的是用 Rcpp::as()Rcpp::wrap() 搞来搞去的很烦（不过其实是可以隐式调用的）。

7.1.2 Exposing Classes Using Rcpp 这个更麻烦（不过遇到的时候可以拿书上的内容参考一下）。

Rcpp modules provide a convenient and easy-to-use way to expose C++ functions and classes to R, grouped together in a single entity.

An Rcpp module is created in a cpp file using the RCPP_MODULE macro, which then provides declarative code of what the module exposes to R.

## Chapter 8. Sugar

Rcpp sugar is based on expression templates and lazy evaluation techniques.

Put succinctly, the motivation of Rcpp sugar is to bring a subset of the high-level R syntax to C++. 比如我们可以直接在 C++ 里像 R 一样直接写 vector 级别的运算，或者在 C++ 里用 apply，而不用写个 for 来搞。

## Chapter 9. RInside

The RInside package permits direct use of R inside of a C++application. 比 Rcpp Sugar 更进一步，但并不是在 C++ 中全面支持 R 语法，而是在 C++ 中构建了一个 embedded R instance（由 RInside class 表示）（所以情形就变成了 “在 C++ 的 R instance 中跑 R 代码”）。

The RcppArmadillo package implements an easy-to-use interface to the C++ Armadillo library.

Armadillo is a C++ linear algebra library aiming towards a good balance between speed and ease of use. The syntax is deliberately similar to Matlab. Integer, floating point and complex numbers are supported, as well as a subset of trigonometric and statistics functions.

## Chapter 11. RcppGSL

The RcppGSL package provides an easy-to-use interface between data structures from the GNU Scientific Library, or GSL for short, and R by building on facilities provided in the Rcpp package.

## Chapter 12. RcppEigen

The RcppEigen package provides an interface to the Eigen library.

Eigen is a modern C++ library for linear algebra, similar in scope as Armadillo, but with an even more fine-grained application programming interface (API).