使用 cppFunction 的內嵌函式

用 Rcpp 最佳化 R 程式碼

Romain François

Consulting Datactive, ThinkR

evalCpp 的限制

evalCpp("40 + 2")
42
evalCpp("PI")
3.141593
evalCpp("exp(1)")
2.718282
用 Rcpp 最佳化 R 程式碼

cppFunction

cppFunction() 定義一個 C++ 函式

library(Rcpp)
cppFunction("int fun(){
   int x = 37 ;
   return x ;
}" )

從 R 呼叫該函式

fun()
37
用 Rcpp 最佳化 R 程式碼
cppFunction("int fun(){
   int x = 37 ;
   return x ;
}", verbose = TRUE )
Generated code for function definition: 
 ------------------------------------------------------
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
int fun(){
  int x = 37 ;
  return x ;
}

Generated extern "C" functions 
 -----------------------------------------------------
#include <Rcpp.h>
// fun
int fun();
RcppExport SEXP sourceCpp_1_fun() {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    rcpp_result_gen = Rcpp::wrap(fun());
    return rcpp_result_gen;
END_RCPP
}
用 Rcpp 最佳化 R 程式碼
Generated R functions 
 -----------------------------------------------

`.sourceCpp_1_DLLInfo` <- dyn.load('/private/var/folders/r_/1b2gjtsd7j92jbbpz4t7ps340000gn/T
/Rtmpl8dL6H/sourceCpp-x86_64-apple-darwin15.6.0-0.12.16/sourcecpp_4bb22c766031/sourceCpp_2.so')

fun <- Rcpp:::sourceCppFunction(function() {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_fun')

rm(`.sourceCpp_1_DLLInfo`)

Building shared library
 ----------------------------------------------------

DIR: /private/var/folders/r_/1b2gjtsd7j92jbbpz4t7ps340000gn/T/Rtmpl8dL6H/sourceCpp-x86_64-
apple-darwin15.6.0-0.12.16/sourcecpp_4bb22c766031

/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB -o 'sourceCpp_2.so'  'file4bb247d077c.cpp'  
clang++  -I/Library/Frameworks
/R.framework/Resources/include -DNDEBUG   -I"/Library/Frameworks/R.framework/Versions/3.4/
Resources/library/Rcpp/include" -I"/private/var/folders/r_/1b2gjtsd7j92jbbpz4t7ps340000gn/
T/Rtmpl8dL6H/sourceCpp-x86_64-apple-darwin15.6.0-0.12.16" -I/usr/local/include   -fPIC  
-Wno-unused-result -Wno-c++11-inline
-namespace -O3 -c file4bb247d077c.cpp -o file4bb247d077c.o
clang++ -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module 
-multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib
-o sourceCpp_2.so file4bb247d077c.o -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework 
-Wl,CoreFoundation
用 Rcpp 最佳化 R 程式碼

cppFunction

cppFunction() 定義一個 C++ 函式

library(Rcpp)
cppFunction("int fun(){
   int x = 37 ;
   return x ;
}" )

從 R 呼叫該函式。

fun()
37
用 Rcpp 最佳化 R 程式碼

R 是動態型別

x <- "hello"
x
typeof(x)
"hello"

"character"
x <- 42L
x
typeof(x)
42

"integer"

C++ 是靜態型別。

// 將 x 定義為 double

double x = 42.0 ;

// 不能再把它改定義為 int
// ----> 這樣會無法編譯

int x = 14 ;
用 Rcpp 最佳化 R 程式碼

函式引數與回傳值的型別宣告

    引數 x 與 y 的型別:double
               |         |
               v         v
double add( double x, double y ){

    // 函式本體
    // ...

}
用 Rcpp 最佳化 R 程式碼

函式引數與回傳值的型別宣告

 回傳型別:double
   |
   v  
double add( double x, double y ){

    // 函式本體
    // ...
    // ...
}
用 Rcpp 最佳化 R 程式碼

函式引數與回傳值的型別宣告

 回傳型別:double
  |
  |  函式名稱:add
  |   |
  |   |    引數 x 與 y 的型別:double
  |   |      |         |
  v   v      v         v
double add( double x, double y ){

    // 函式本體
    // ...
    // ...
}
用 Rcpp 最佳化 R 程式碼

加法範例

將兩個 double 相加的 C++ 函式。

cppFunction( "
double add( double x, double y){ 
    double res = x + y ; 
    return res ;}
" )
add( 30, 12 ) 

對應的 R 程式碼

addr <- function(x, y) {
    res <- x + y
    res}
用 Rcpp 最佳化 R 程式碼

一起來練習吧!

用 Rcpp 最佳化 R 程式碼

Preparing Video For Download...