試したのは一番簡単そうな .Fortran 関数。
まず、配列を受け取り、その中身を指定の値で埋める FORTRAN のサブルーチン "foo" を用意する。
mylib.f として保存し、 R CMD SHLIB mylib.f で共有ライブラリを作る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
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 つ受け取るだけなので、
- 配列の先頭アドレス
- 配列サイズが記録されているアドレス
- 埋め尽くしたい数を記録しているアドレス
- as.double(1:100)
- as.integer(100)
- as.double(1.0)
> 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
参考リンク
- Writing R Extensions Sec. 5.2, 5.3
- Seeking for my unique color. -- CでRの拡張したら速すぎて(40〜50倍)吹いたwww
- ぬいぐるみライフ(仮)-- Extend R with C!!! (tsukuba.R#6 mickey24 氏 LT)
0 件のコメント:
コメントを投稿