Armadillo with or without R

  • 準備:g++が使えるようにしておく Have g++ ready.
    • Windowsなら、Rtoolsを使ってR経由で使えるようにすればよい You can use Rtools for windows to get g++ ready.
  • さて。Rとは別にArmadilloを使った1枚のソースコードファイルがあるとする You have one file with one or more c++ functions using Armadillo library.
  • そのまま使うときと、RでRcppArmadilloで使うときとでは、どう違うかを比べてみる You can use the file directly as c++ and also you can modify it for RcppArmadillo version.
  • Rなし版 In case without R
    • 簡単だが、複数の関数を定義して、それを用いたmain()関数を持つようなファイル Following is a file with multiple c++ functions in it.
    • jisakudouble()は整数を二倍にする doubling int
    • jisakumat()は正方行列のサイズとセル値を決めるパラメタを受け取って、Armadilloが与えるarma::matを返す making square mat
    • main()はそのあたりをいじりつつ、標準出力する main() uses the above functions and display something.
#include <iostream>
#include <Armadillo>

int jisakudouble(int x){
    int y = x*2;
    return(y);
}

arma::mat jisakumat(int n = 3,int t=2){
    arma::mat m = arma::zeros<arma::mat>(n,n);
    int k = 0;
    for(int r=0; r<n; ++r)
       for(int c=0; c<n; ++c)
           m(r, c) = ++k + jisakudouble(t*r);
    return(m);
}

int main(void){
    // Standard input
    int n = 4;
    int t = 3;
    arma::mat m = jisakumat(n,t);
    m.print();
    std::cout << "Trace of the matrix is " << trace(m) << '\n';
}
g++ test.cpp
  • Rあり版 In case with R
  • さて。こんな動くC++ファイルがあったときに、RcppArmadillo利用に横滑りすることを考える。Reuse c++ file to make one for RcppArmadillo
    • 少しいじればよい
    • includeは(もうiostreamは不要)で、Armadillo関係は、Armadilloライブラリを読むのではなくて、RcppArmadilloパッケージのインストールのときについてきた、Armadilloとそれが利用する線形代数ライブラリへとつなぐためのヘッダファイル"RcppArmadillo.h"をincludeする You should switch from which includes Armadillo library to that is a header file connecting you to the whole Armadillo library with algebra libraries through RcppArmadillo package.
    • その他、ただのc++関数はいじる必要はなく You don't have to modify the functions that are just used by the main().
    • main()関数を、Rに返り値を返す関数にする必要がある You should change the main() to the function that returns something to R system.
    • Rの関数とするためには、次の2行をR化したい関数の前に置く Two lines just above the function as below.
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
//#include <Armadillo>
#include <RcppArmadillo.h>

int jisakudouble(int x){
    int y = x*2;
    return(y);
}

arma::mat jisakumat(int n = 3,int t=2){
    arma::mat m = arma::zeros<arma::mat>(n,n);
    int k = 0;
    for(int r=0; r<n; ++r){
       for(int c=0; c<n; ++c){
           m(r, c) = ++k + jisakudouble(t*r);
       }
   }
    return(m);
}

// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat toR(int n, int t){
    arma::mat m = jisakumat(n,t);
    return(m);
}
    • そのうえで、Rの方から Now you can make R function as,
sourceCpp("cpp2r.cpp")
    • とすれば、R側で Now you can use the function you made.
toR(3,4)
    • というような使い方ができるようになる
  • なお、C++を複数のファイルに書き分けてヘッダーファイルでつないで…というように作ってある場合には、Rの方で対応するのは、『C++混みのRパッケージ作成』となるので、sourceCpp()で、お手軽に、というわけにはいかない Sometimes you have a c++ program that is consisted of multiple files. You can not easily convert them to R-version with sourceCpp(). If you really want to convert them to R, you have to make a R-package containing C++.