2009年12月15日火曜日

R 言語の FORTRAN 拡張を試す

試したのは一番簡単そうな .Fortran 関数。

まず、配列を受け取り、その中身を指定の値で埋める FORTRAN のサブルーチン "foo" を用意する。
      subroutine foo(a, n, x)
      implicit none
      real*8 a, x
      dimension a(n)
      integer n
      integer i
      do i = 1, n
         a(i) = x
      enddo
*      x = 100.d0
      end
mylib.f として保存し、 R CMD SHLIB mylib.f で共有ライブラリを作る
black-pearl:tmp shingo$ R CMD SHLIB mylib.f
gfortran -arch i386   -fPIC  -g -O2 -c mylib.f -o mylib.o
gcc -arch i386 -std=gnu99 -dynamiclib -Wl,-headerpad_max_install_names -mmacosx-version-min=10.4 -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/lib -o mylib.so mylib.o -lgfortran -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
ld: warning: duplicate dylib /usr/local/lib/libgcc_s.1.dylib
black-pearl:tmp shingo$ ls mylib.so
mylib.so
R を起動して、mylib.so を読み込む:
black-pearl:tmp shingo$ R
R version 2.9.2 (2009-08-24)
Copyright (C) 2009 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

> dyn.load("mylib.so")
ここでさっき作った FORTRAN のサブルーチン "foo" を呼ぶ:
> result <- .fortran="" as.double="" as.integer="" foo="" p="">

サブルーチン "foo" は平たく言うと以下 3 つ受け取るだけなので、
  • 配列の先頭アドレス
  • 配列サイズが記録されているアドレス
  • 埋め尽くしたい数を記録しているアドレス
R 側の .Fortran の引数内で "foo" が使うメモリ領域を用意している:
  • as.double(1:100)
  • as.integer(100)
  • as.double(1.0)
結果はリストで帰ってきて、"foo" へ渡した引数領域が格納されていた
> class(result)
[1] "list"
> length(result)
[1] 3
> length(result[1])
[1] 1
> length(result[[1]])
[1] 100
> length(result[[2]])
[1] 1
> length(result[[3]])
[1] 1
> result[[1]]
  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [38] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [75] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

0 件のコメント:

コメントを投稿