- 数値およびオブジェクトの多次元配列
NArray は、多次元配列のクラスです。
配列の要素の型として、
- 8,16,32 bit 整数
- 単精度/倍精度の実数/複素数、
- Rubyオブジェクト
をサポートしています。
1要素の取出しは、a[ 12, 34 ] のように各次元のインデックスを指定します。
部分配列は、a[ 10..15, 5..-1 ] のように範囲指定で取り出せます。
- 演算の記述
+,-,*,/,%,** の演算は、要素ごとに適用します。
たとえば、2つの NArray クラスのインスタンス a,b があって
c = a + b
と書くと、c は [a[0]+b[0], a[1]+b[1], ... ]
という要素を含む NArray クラスの インスタンスになります。
c = a + 1
とすると、c は [a[0]+1, a[1]+1, ... ] となります。
また、sin などの数学関数は
NMathモジュールで提供しており、
要素ごとに計算した結果を NArrayで返します。
- 高速演算
上記の a + 1 と同じことは 普通の Array クラスでも、
c = a.collect{|i| i+1}
などとすることで実現しますが、スピードは全然違います。
要素が50万個の整数配列の場合、SPARC 10では、
NArrayだと 0.3秒ですが、Arrayでは 57秒もかかります。
NArray ver 0.5.0 では、以前より
速くなりました。
- 拡張インデックス
IDLにない機能として、サイズ1の次元は演算相手の配列のサイズに合わせて
繰返し適用するというものがあります。(NumPyにはあります)。
たとえばサイズが[n,1]と[1,m]の配列で演算を行なうと、
結果は [n,m] の配列となります。
しばしばxとyの関数として2次元の配列を作りたいことがあります。
このときx、yをそれぞれ[n,1]と[1,m]という形にしておけば、
x**2 + y**2
と単に書くだけで、"**"の演算までは1次元で行ない、
"+"の演算のところで自動的に[n,m]に拡張されます。
IDLでは最初から[n,m]の配列を用意しなければなりません。
- 実装
NArrayは次の要素を含むC構造体として実現しています。
- 次元数 (rank)
- 各次元の要素数 (shape)
- 全要素数 (total)
- 型 (type)
- 要素を格納するメモリーブロック (ptr)
メモリーブロックはCの配列そのものなので、
そのまま他のライブラリに渡す、という使い方もできます。
(例としてFFTWへのインタフェースを備えています。)
ご意見ご提案等がありましたらお知らせ下さい。