Rubyに関する小ネタ、気づき、メモなど。
NArray#to_f
to_fは倍精度実数ではなく単精度実数配列を返すので注意!
整数配列から倍精度実数配列に変換しようとすると、NArrayはスカラー値とのcoerceが効かないので
narray + 0.0
等は使えない。どうすれば??
方法1
NArray.float(*narray.shape) + narray
方法2
NArray.to_na(narray.to_f.to_a)
方法2は絶対値の大きな整数では精度が低下する恐れがある。
Ruby 1.9.x になって Array#to_s の挙動が変わった
1.9ではArray#to_sはArray#inspectの別名となった。
print等に配列をそのまま渡す場合等に問題が発生する。
Array#joinを使えば旧バージョンのArray#to_sと同様の結果が得られる。
Ruby 1.9.x で Range#include? を使うときの落とし穴
cygwin への ruby 1.9 のインストール
注:内容古し。今はrvmを使うのが吉。
最新版(ruby-1.9.1-p378.tar.bz2)をダウンロード、展開。
cd ruby-1.9.1-p378
./configure --program-suffix=19 optflags="-O3 -march=native"
make
make install
これで /usr/local/ の下にインストールされる。
この場合、ruby関連の実行ファイルの末尾には19が付く。
例えばruby本体はruby19、gemはgem19、irbはirb19として実行できるので、
ruby1.8との共存も問題なさそう。
最適化オプションが"-O2"だと parse.c のコンパイルでgccが固まってしまう場合があるので、"-O3"が無難。
makeの途中でなぜか segmentation fault が出てしまう場合がある。
その場合は、"-march=native" を削除するか "-march=i686" と書き換える。
Cygwin への NArray, Ruby/GSL のインストール
修正:2011年7月13日
gemでもインストールできるが、ソースの修正等が面倒。
そのため手作業で行ってみる。
NArrayインストール
最新版をダウンロード、展開し、そのディレクトリへ移動。
ruby extconf.rb
make
make install
Ruby/GSLをインストール
GSL と plotutils が cygwin にインストールされていることを確認。
Ruby/GSLの最新版をダウンロード、展開し、そのディレクトリへ移動。
rb-gsl-1.14.7では、そのままでは
matrix_complex.c:1523: error: conflicting types for ‘gsl_matrix_complex_equal’
/usr/include/gsl/gsl_matrix_complex_double.h:227: error: previous declaration of
‘gsl_matrix_complex_equal’ was here
vector_complex.c:1989: error: conflicting types for ‘gsl_vector_complex_equal’
/usr/include/gsl/gsl_vector_complex_double.h:167: error: previous declaration of
‘gsl_vector_complex_equal’ was here
のように ext/matrix_complex.c と ext/vector_complex.c がコンパイルできない。
以下のように修正。
ext/matrix_complex.cの1523行目と1558行目の
gsl_matrix_complex_equal
を
xgsl_matrix_complex_equal
に修正。
ext/vector_complex.cの1989行目と2022行目の
gsl_vector_complex_equal
を
xgsl_vector_complex_equal
に修正。(教訓:GSLをC言語から使う場合、gsl_で始まる識別子を使わない。将来のバージョンで名前が衝突する可能性がある。)
さらに、先にコンパイルしたnarrayのディレクトリからlibnarray.aを持ってきてextディレクトリ中にコピーする。
そして
ruby setup.rb
NArray, NMatrix/NVector を相互変換したい
例えば、あるNArrayオブジェクトに対してある部分では要素ごとの乗算を行いたいが、
別の部分では行列としての乗算を行いたい、など、NArray, NMatrix/NVectorを
相互に変換したくなる場合がよくある。
そんな時はreferメソッドを使おう。aがNArrayオブジェクトだとすると、
NMatrix.refer a
で、aと同じデータを参照するNMatrixオブジェクトが作られる。
同様に、bがNMatrixオブジェクトだとすると、
NArray.refer b
で、bと同じデータを参照するNArrayオブジェクトが作られる(NVectorも同様)。
配列データそのものは複製されないので、効率的に動作する。
ただし、複製ではなく参照なので、referで生成したオブジェクトを変更すると、
元の内容まで変更されてしまうので注意。
任意のオブジェクトをBool値へ変換する
Rubyでは真偽値が必要なコンテキストでは、nilとfalseは偽、それ以外は真として扱われる。
では、あるオブジェクトhogeが真であればtrue、そうでなければfalseがどうしても欲しい場合にはどうすれば良いか。
hoge ? true : false
はダサすぎる。そんなときは…
方法その1:&演算子を使う(RubyリファレンスマニュアルのTrueClass参照。)
true & hoge
方法その2:二重否定
!!hoge
配列の中身に重複があるかどうかを調べる
a.uniq == a とする。
irb(main):001:0> a = [2,3,4,3,1,1]
=> [2, 3, 4, 3, 1, 1]
irb(main):002:0> a.uniq
=> [2, 3, 4, 1]
irb(main):003:0> a.uniq == a
=> false
irb(main):004:0> a = [2,3,4,1,0,5]
=> [2, 3, 4, 1, 0, 5]
irb(main):005:0> a.uniq
=> [2, 3, 4, 1, 0, 5]
irb(main):006:0> a.uniq == a
=> true
配列のサイズが大きい場合は a.uniq.size == a.size とした方が効率が良いだろう。
setを使う方法もある。
require "set"
Set.new(a).size == a.size
でもuniqの方が速いようだ。
Ruby どちらが速い?
最終更新:2011年07月13日 13:51