仮想計算機構

IT業界と無縁な派遣社員のブログ

多次元配列

Schemeで多次元配列を使ってみる。

まずはサイズ(2, 3)の配列aを定義。値はすべて0で初期化します。

(use gauche.array)
(define a (make-array (shape 0 2 0 30))
(print a)
(print "array size : " (array-size a))

実行結果は以下のとおり。

#,(<array> (0 2 0 3) 0 0 0 0 0 0)
array size : 6

配列そのものは奇妙な形をしている印象を受けます。そもそも配列のサイズを指定するのになぜ (shape 0 2 0 3) なんて書き方をするのかという問題ですが、これは1つ目の次元(軸というべきか)のインデックスが0以上2未満で、2つ目の次元のインデックスが0以上3未満であるということを表現しているらしい。つまり (shape 2 3) なんて書き方をしてしまえば、それはインデックスが2以上3未満の1次元配列を定義していることになってしまうわけで、これは注意する必要がありそうです。以上のことから、shapeそのものも (D x 2) の配列であるというリファレンス*1の記述の意味もわかってきます。D次元配列の各インデックスの上限(+1?)と下限を定める必要があるから、shapeがサイズ(D x 2)の配列になるわけですね。なるほどなるほど。

 さて、配列の宣言はできましたが、配列の中身をいじるにはどうすればいいのでしょうか。次のコードでは、配列の要素を参照したり、要素を書き換えたりしています。

(print "a[0][1] : "(array-ref a 0 1))
(array-set! a 0 1 3)
(print "a[0][1] : " (array-ref a 0 1))

a[0][1] : 0
a[0][1] : 3

 意外と簡単ですがarray-refって書くのちょっと面倒ですね。。。

気を取り直して最後にmake-arrayを使わない方法について見ていきます。配列aではすべての要素を0で初期化しましたが、以下のように書けば要素ごとに値を指定できるようです。

(define b (array (shape 0 2 0 30 1 2 3 4 5))
(print b)
(print "b[1][2] : "(array-ref b 1 2))

#,(<array> (0 2 0 3) 0 1 2 3 4 5)
b[1][2] : 5 

 

というわけで今回は配列の簡単な部分だけを学習しました。Schemeにはvectorなんかもあるので、そちらも学んでarrayと何がどう違うのか理解を深めていきたいところです。