ベクトルのベクトルで構成される2次元配列(行列)を作成します。
(setq zero-row [0 0 0 0 0])
=> [0 0 0 0 0]
(setq zero-mat (make-vector 4 zero-row))
=> [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
行2を変更された要素を含むベクトルに置き換えることにより、行2、列3(0インデックス)の要素を42に設定します。
(aset zero-mat 2 [0 0 0 42 0])
=> [0 0 0 42 0]
zero-mat
=> [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 42 0] [0 0 0 0 0]]
できます。
次に、このアプローチを使用して、このような2次元配列の(i、j)番目の要素を設定する関数を作成します。
(defun matrix-set (mat i j elt)
"Set the (i, j)-th element of mat to elt. mat is a vector of the row vectors. Indexing is 0-based in each component."
(let ((vect (aref mat i)))
(aset vect j elt)
(aset mat i vect)
mat))
しかし、これは機能しません:
(setq zero-row [0 0 0 0 0])
=> [0 0 0 0 0]
(setq zero-mat (make-vector 4 zero-row))
=> [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
(matrix-set zero-mat 2 3 42)
=> [[0 0 0 42 0] [0 0 0 42 0] [0 0 0 42 0] [0 0 0 42 0]]
配列のすべての行が同じベクトルにリンクされているように見えるため、そのベクトルを変更するとすべての行が変更されます。
したがって、2つの質問があります。(1)これが2番目のケースで発生するのに、最初のケースでは発生しないのはなぜですか。(2)これを修正するにはどうすればよいですか(このように表された2次元配列の(i、j)番目のエントリにアクセスできるように)?
(私はもともと、上記のようにベクトルのベクトルとして表される2つの行列を追加するための小さなルーチンを作成していましたが、同じ問題が発生しました。上記の簡略化された例により、問題がより明確になると思います。)