[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dennou-ruby:002996] Re: Ruby-Lapack



堀之内です。

うーむ、明らかに西澤版のほうが使いやすい。ちなみに、linalg ruby
でググって見たら、トップにでてきたのはなんと3年前に自分で書いた
解説文だったりしました。(http://jp.rubyist.net/magazine/?0006-RLR)
最後のほうでちょっと Linalg に触れてます。どうりで Linalg 記憶に
あるわけだ、というか、文章に書いたことを覚えていろよ、
ですね (^^;)  引用すると、

  Linalg の LAPACK モジュールは、FORTRAN77 による LAPACK のオリジナルラ
  イブラリーを1対1にラップする。その戦略は、Ruby/GSL や Ruby-SSL2 のそ
  れとは違い、ポインターのアドレスを Ruby の Integer オブジェクトとして
  ラップするというものである。FORTRAN77 の変数は C から見れば全てポイン
  ターである。このため、各引数のアドレスを Integer オブジェクトにするこ
  とで、 Ruby と FORTRAN 副プログラムの橋渡しをすることができるのである。
  これを利用して、Linalg では簡単なフィルターで LAPACK のヘッダーファイ
  ルを処理するだけで、LAPACK の全機能搭載を実現している (LAPACK は C 版
  もあるのでヘッダーファイルもあるのである)。

  この LAPACK モジュールは、そのままでは使いにくいし、危険でもあるので、 
  その上にラッパーを被せてある. それが Linalg の上位ライブラリーである。
  例えば行列に関しては、[行サイズ, 列サイズ, 中身のポインター] からなる 
  "?Matrix" (?=D,C,etc) クラスが用意されている. それに定義されているデー
  タ領域のポインターを返すメソッドを利用して、Ruby レベルで LAPACK モジュー
  ルのメソッドを呼ぶ。なお、上位ライブラリーにおいては、今のところ 
  LAPACK の全サブルーチンまではサポートされてない。

  上述のように LAPACK モジュールの関数はポインターベースであるため、 
  NArray / NMatrix や GSL::Matrix などといった、他の拡張ライブラリーで使
  うことも可能である。ただし、LAPACK のデータ構造は column-major である
  ため、行列についてはデータの詰め替え(transpose)が必要であり、また、デー
  タ領域のポインターを Integer で返すメソッドを追加する必要があ
  る. NArray で LAPACK がフルに使える、使いやすいモジュールが欲しいとこ
  ろである。

ということで、やっと登場した使いやすいライブラリが、西澤版と言う
ことですね。例をみると、1対1ラッパなんだけど、出力引数は戻り値に、
また、配列の大きさに関する引数は NArray から自動取得することに
なくしてる、というわけですね。その辺の基本ルールは、目立つところに
書いておくといいと思います。あと、自動で書き出される help を
まとめればドキュメント完成? (すみません、まだ試してないです。)

> ruby のソースを眺めてみると、なんと引数の最大値は15みたいです。

あれ、16かと思ってた。あまり長い場合は、配列にしろという
ことなんだと思います。間に合ってますか?

# 折角なので、RAA に登録し、ruby-list に流しませんか。

> 西澤です
> 
> ちょっと linalg を見てみました。
> 使いたいサブルーチンである dsyevr (倍精度対象行列の固有値固有ベクトル計算。必要な固有値固有ベクトルのみ計算する)を例にします。
> 
> 
> * 新しく作った Ruby-LAPACK
> require "numru/lapack"
> a = NArray[[1,2],[2,3]]
> m, w, z, isuppz, work, iwork, info, a = NumRu::Lapack.dsyevr("V", "I",
> "U", a, nil, nil, 1, 2, 0.0, 52, 20)
> 
> 
> * Linalg
> require "linalg"
> include Linalg::XData
> jobz = Char.new("N")
> range = Char.new("A")
> uplo = Char.new("U")
> n = XInteger.new(na.shape[0])
> a = DMatrix[[1,2],[2,3]]
> lda = XInteger.new(n.value)
> vl = DReal.new
> vu = DReal.new
> il = XInteger.new
> iu = XInteger.new
> abstol = DReal.new(0.0)
> m = XInteger.new
> w = DMatrix.reserve(n.value,1)
> v = DMatrix.reserve(n.value,n.value)
> ldz = XInteger.new(n.value)
> isuppz = IData.new(2*n.value)
> lwork = XInteger.new(52)
> work = DReal.new(lwork.value)
> liwork = XInteger.new(20)
> iwork = IData.new(liwork.value)
> info = XInteger.new
> Linalg::Lapack.dsyevr(jobz, range, uplo, n, a, lda, vl, vu, il, iu,
> abstol, m, w, v, ldz, isuppz, work, lwork, iwork, liwork, info)
> 
> 
> 現時点では、narray から DMatirx への変換が必要で、ループで値を代入するか、マーシャルダンプを利用するかです。
> NArray#to_doublereal_ptr メソッドを作れば narray をそのまま使えると思います。
> 
> 
> 
> これで Linalg版 dsyevr が実行できるはず、と思って実行してみたところ、
> `dsyevr': too many arguments (21) (ArgumentError)
> とのエラーが ^^;
> ruby のソースを眺めてみると、なんと引数の最大値は15みたいです。
> 
> 
> 
> 
> 2008/10/6 Takeshi Horinouchi <horinout@xxxxxxxxxxxxxxxxx>:
> > 堀之内です。
> >
> > 西澤さん、すみません、「LAPACK や BLAS のラッパ」を探すのを忘れて
> > ました。RAAで探したら次がでてきました。
> > http://raa.ruby-lang.org/project/linalg/
> > 見覚えがあるので、これでしょう。本体は、
> > http://linalg.rubyforge.org/
> > にあります。ちゃんとメンテされてるようです。
> >
> > NArrayは使わないようになってるんですかね。
> > もしよければ、今回作ったのと仕様を比較して
> > もらえませんか?
> >
> > # るびきちさんが作ってた気がするというのは
> >   やはり勘違いだったようです。
> >
> > 皆様: 異動しました。(何度も目にしてる方すみません)
> >
> >> 西澤です
> >>
> >> Ruby-Lapack をリリースしました。
> >> http://www.gfd-dennou.org/arch/ruby/products/ruby-lapack/index.html
> >>
> >> (ほぼ)すべてのサブルーチン、ファンクションをパックしてあります。
> >> ただし、ほとんどテストしていませんので、いろいろ動かないものがあるかもしれません。
> >>
> >> 単なる1:1ラッパーであり、
> >> 行列などのクラスを作ったりはしていません。
> >> 行列はNArrayとして引数に与えます。
> >>
> >> 引数なしで呼び出すと、ヘルプメッセージがプリントされます。
> >>
> >>
> >> --
> >> Seiya Nishizawa
> >> Department of Earth and Planetary Atmospheric Sciences, Kobe University
> >
> > 堀之内 武
> > 北海道大学 地球環境科学研究院 地球圏科学部門
> > 〒060-0810 札幌市北区北10条西5丁目
> >
> >
> >
> 
> 
> 
> -- 
> Seiya Nishizawa
> Department of Earth and Planetary Atmospheric Sciences, Kobe University

堀之内 武
北海道大学 地球環境科学研究院 地球圏科学部門
〒060-0810 札幌市北区北10条西5丁目