13  他の言語とのインターフェース

13.1 CとFortran

SPHREPACKは球面調和函数ライブラリで、NCAR Classic Library for Geophysicsから取得できます。

gaqd.fを使ってガウス緯度を求めてみましょう。 CやFortranを呼び出すには、まずソースから共有ライブラリを作ります。 次のコマンドを実行すると、gaqd.soができます。

% R CMD SHLIB gaqd.f

Base RにはCやFortranを呼び出すためのFFI (Foreign Function Interfance)として、.C().Fortran()があります。 これらは引数をあらかじめ用意する必要がある上、変数はコピーされるので効率が良くありません。 ここでは、パッケージdotCall64を用います。 dotCall64は、64ビットの整数を扱えるので、2GB以上の配列を扱えます。

コンパイルされた函数を呼び出す.C64()は、CもFortranも扱えます。 引数の型をdouble, integer, int64からSIGNATUREに指定します。 INTENTには、read(読み込み)、read and write(読み書き)、write(書き込み)を意味するrrwwが指定できます。 - rは変数を用意する必要がありますが、コンパイルされた函数にポインタ(メモリの場所)が渡されるだけで、コピーはされません。 - rwはRオブジェクトのコピーが生成され、コンパイルされた函数はポインタを受け取ります。 - wに対応する変数は、vector_dc()、numeric_dc()integer_dc()`で割り付けることができます。 これらの仕組みにより、Rオブジェクトの生成を制御できます。

library(dotCall64)

dyn.load("gaqd.so")

gaqd <- function(nlat) {
  w <- 0
  lwork <- 0L
1  gaus <- .C64("gaqd",
2       c("integer", "double", "double", "double", "integer", "integer"),
3       nlat, theta = numeric_dc(nlat), wts = numeric_dc(nlat),
       w, lwork, ierror= integer_dc(1),
4       INTENT=c("rw", "w", "w", "r", "r", "w"))
  gaus[c(1, 2, 3, 6)]
}
1
サブルーチンの名前を渡します。
2
SIGNATUREとして引数の型を指定します。
3
ガウス余緯度thetaと重みwtsnumeric_dc()で長さnlatの倍精度浮動小数点数ベクトルを作っています。エラーコードierrorは長さ1の整数ベクトルを作っています。
4
返り値にnlatを含めるため、nlatrwで指定しています。thetawtswlworkは、ダミー変数なのでrとします。

13.2 Rcpp

Rcppを使うと、RからC/C++のコードを使えます。 RcppParallel: は並列プログラミング、 RcppEigenRcppArmadilloは線型代数演算を扱うC++ライブラリEigenArmadilloの機能を提供します。

13.3 Python

reticulateを使うと、PythonをRから呼び出すことができます。

例えば、Numpyのnpyファイルx.npyを読むには次のようにします。

library(reticulate)

np <- import("numpy")
x <- np$load("x.npy")