RからGSL(WinXP用)

Windows XPでCプログラムからdllを作成するときに、Cプログラム内で GSL(GNU Scientific Library) が提供する関数を使えるようにする。ちなみに、Cygwin は使わず、MinGWMSYSを使います。

  • RからC言語を利用する際の一般的な手順は、Rから他言語利用を参照ください。
  • 少なくとも私の環境(R 2.3.1および2.4.0、日本語WinXP SP2 & Pentium Mと英語版WinXP SP2 & Pentium 4)では下記の手順で動作しましたが、他の環境で成功するかは分かりません。
  • 内容の誤りや別の方法、成功した、など、適宜修正・報告していただければ幸いです。
  • R のパッケージに gsl という GSL ライブラリーへの wrapper (と説明)がありますが、GSL のコンパイルは各自やるとして、もしかして最後(実際に使用するくだり)あたりを簡単にしてくれるのでは。 -- 使ったことのない人? 2006-09-28 (木) 16:31:29
  • パッケージgslのマニュアルを確認してみました。このパッケージ、GSLが提供する特殊関数と疑似乱数列発生関数へのラッパー集ですね。例示したベッセル関数は、gslを使えば、わざわざCでコードを書いてdllを作成するという手間は省略できそうです(Rの組み込み関数を使うのが一番簡単ですが)。GSLの他の機能(私の場合特にベクトルや行列処理)を使いたい場合には、gslにはそのためのラッパーが含まれていませんので、Cコード->dllという手順は省略できそうにありません。 -- ジェットラグ? 2006-09-28 (木) 17:08:54
  • ついでに好奇心からですが教えて下さい。GSL ライブラリーを特に使いたい動機はなんでしょう。なにか、魅力的なものがありますでしょうか。 -- 使ったことのない人? 2006-09-28 (木) 19:23:24
  • 「格好良さそうだから」という理由は別にして、GSLを使う最大の理由は、C言語で行列やベクトル計算をしてくれる関数群を利用するためです。行列演算に特化したMeschachというライブラリもありますが、こちらはインストールがうまくいかずに利用を断念しました。他のライブラリをご存じでしたらご教示いただければ幸いです。 -- ジェットラグ? 2006-09-28 (木) 21:33:05
  • 以下の記事によると Meshach は行列演算がかなり早いらしい。GSL は比較されていないけど。R の組み込みライブラリはどうなんだろう。IBM developerworks article -- 使ったことのない人? 2006-09-29 (金) 14:11:33
  • この記事によれば、Meschachはかなり早いですね。行列演算に限らず、RからCを使う場合、皆さんはどのようなライブラリを使われているんでしょうか?こういうノウハウが蓄積されれば、役立ちそうですね。 -- ジェットラグ? 2006-09-29 (金) 19:32:47
  • R2.10.1で試しました。Makevars.winを"PKG_LIBS = -L/usr/local/lib -lgsl -lgslcblas"に修正する必要があるようです。 -- なかの? 2010-05-03 (月) 21:30:06

下準備

MinGW、MSYSおよびActive Perlのインストール

MinGWとMSYSはWindows用バイナリが用意されているので、それを使いましょう。 ダウンロードはhttp://www.mingw.org/download.shtmlから、

MinGWは Priveous -> MinGW -> bin -> MinGW-3.1.0-1.exe,
MSYSは Current -> MSYS -> bin -> MSYS-1.0.10.exe,

をダウンロード。ダブルクリックして、デフォルトのままインストールして問題ありませんでした。

  • MinGW-5.0.3.exeを使うと、途中でエラーが出て正常にインストールできませんでした。

Active Perlは、http://www.activestate.com/Products/ActivePerl/Download.htmlから、

Free Download -> Continue

とたどって、適切なバージョン(私の環境ではver. 5.8.8.819, Windows (X86) MSI) をダウンロードし、c:/Perlへインストールます。最後にパスを追加するかどうか聞かれるので、追加しておきましょう。

環境変数PATHの修正

環境変数PATHの先頭に次の一行

c:/MSYS/1.0/bin;c:/MinGW/bin;
(Perlのインストールでパスを追加していない場合は、c:/MSYS/1.0/bin;c:/MinGW/bin;c:/Perl/bin;)

を追加する。必ず先頭に追加してください。R_HOME/binへもパスを通しておきます。これらのパスが正しく設定されていないと、あとで説明するR CMD SHLIBでdllファイルを作成することができません。

GSLのインストール

GSLソースコードの入手

http://ftp.gnu.org/gnu/gsl/から、最新のもの(2006.9.20現在gsl-1.8.tar.gz)をダウンロードして適当な場所 (例えばc:/temp)などに保存する。

ソースコードの伸張とmake、インストール

gsl-1.8.tar.gzをc:/tempに保存したとして、 MSYSを起動し、プロンプト($)で以下のように入力する。

$ cd c:/temp
$ tar zxvf gsl-1.8.tar.gz -C /c

c:/にgsl-1.8フォルダができる。MSYSで カレントディレクトリをc:/gsl-1.8に変更し、configureをする。

$ cd c:/gsl-1.8
$ ./configure

自動的に進行するので、しばし待つ。再びプロンプトが現れたら

$ make

をすると、再び自動的に進行するので、これまたしばし待つ(10分以上掛かります)。問題なければ

$ make install

でインストールされる。最後に

$ make clean

をすると余計なファイルを消してくれる。

  • GSLのインストールはこれでお終いです。MSYSはこれ以降使わないので、$ logoutか、ウインドウを閉じて終了させます。

Makevars.winファイルの作成

作業ディレクトリ(コンパイルしようとするxxx.cがあるフォルダ)に、以下の内容を含むMakevars.winファイルをエディタで作成する。

 EXTRA_LIBS = -L/usr/local/lib -lgsl -lgslcblas
 PKG_CPPFLAGS = -I/usr/local/include
  • EXTRA_LIBSはlibgsl.aとlibgslcblas.aのありかを指定する(デフォルトではc:/MSYS/1.0/local/lib)。
  • PKG_CPPFLAGSは、xxx.cファイルで#includeしたgsl_*.hのありかを示す(デフォルトではc:/MSYS/1.0/local/include/gsl)。
  • Makevars.winファイルの役割は"Writing R Extensions"や "R Installation and Administration"を参照のこと。
  • R 2.4.0では、"PKG_LIBS="が正常に読み込まれなくなりました。代わりに"EXTRA_LIBS="を使いましょう。"EXTRA_LIBS="は、ver. 2.3.1および2.4.0とも正常に働きます。
  • R 2.4.1では、"PKG_LIBS="が使えるように再度変更されました。

これで準備は完了。

例:ベッセル関数

mybess.cを、例えばc:/testに作成する。 こんな感じ。

#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>

void mybessel(double *x, double *y)
   {
     *y = gsl_sf_bessel_J0 (*x);
   }

mybess.cと同じディレクトリにMakevar.winがあることを確認して、DOS窓から次のコマンドを入力。

C:\test>R CMD SHLIB mybess.c

以下のようなメッセージが表示されて、dllファイルが作成される。

making mybess.d from mybess.c
gcc  -I/usr/local/include -Ic:/R-2.3.1/include -Wall -O2   -c mybess.c -o mybess.o
gcc  -shared -s  -o mybess.dll mybess.def mybess.o  -Lc:/R-2.3.1/bin -L/usr/local/lib -lgsl -lgslcblas  -lR

なおR Ver. 2.4.0では、最初に"/bin/sh.exe: latex: command not found"というエラーが表示されるものの、無視して差し支えないようです。

RからCへ変数を引き渡すラッパーを作成する。

 bess = function(x) {
    .C("mybessel", as.double(x), result = double(1))$result
 }

次にRを起動して、動作を確認する。

 > setwd("c:/test")
 > dyn.load("mybess.dll")
 > bess = function(x) {
    .C("mybessel", as.double(x), result = double(1))$result
 }
 > bess(5)       # GSLのベッセル関数による計算結果
 [1] -0.1775968
 > besselJ(5,0)  # Rの組み込み関数による計算結果
 [1] -0.1775968

めでたしめでたし。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Google
WWW を検索 OKADAJP.ORG を検索
Last-modified: 2015-03-01 (日) 01:15:59 (1717d)