Ruby いろいろ

※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

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? を使うときの落とし穴

数字または文字列以外のRangeを使う場合は注意しなければいけない。
http://www.clear-code.com/blog/2010/3/25.html


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 どちらが速い?

別ページにしました。
Ruby どちらが速い?


ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。