Next: 9 シーケンスデータ
Up: 8 CommonLispのデータとその比較手続き
Previous: 8.6 構造体
8.7 配列
配列データも同様で等しいかどうかは,equalpを使います.
<cl> (setq a (make-array '(2 2)
:initial-element '((a b) (c d))))
#2a((((A B) (C D)) ((A B) (C D)))
(((A B) (C D)) ((A B) (C D))))
<cl> (setq b (make-array '(2 2)
:initial-element '((a b) (c d))))
#2a((((A B) (C D)) ((A B) (C D)))
(((A B) (C D)) ((A B) (C D))))
<cl> (eq a b)
NIL
<cl> (equal a b)
NIL
<cl> (equalp a b)
T
リスト行列ではなく,この配列データ
で行列を表して,四則演算を定義することを考えてみます.
配列の要素はarefでアクセスし,配列の大きさは,array-dimensionsで
得ることができます.
<cl> (setq a (make-array '(3 2)
:initial-contents
'((1 2) (3 4) (5 6))))
#2A((1 2) (3 4) (5 6))
<cl> (array-dimensions a)
(3 2)
配列の足し算a+,引き算a-は次のように定義できます.
(defun a+ (a b)
(let* ((dim (array-dimensions a))
(c (make-array dim)))
(dotimes (i (car dim))
(dotimes (j (cadr dim))
(setf (aref c i j) (+ (aref a i j) (aref b i j)))))
c))
(defun a- (a b)
(let* ((dim (array-dimensions a))
(c (make-array dim)))
(dotimes (i (car dim))
(dotimes (j (cadr dim))
(setf (aref c i j) (- (aref a i j) (aref b i j)))))
c))
<cl> a
#2A((1 2) (3 4) (5 6))
<cl> (a+ a a)
#2A((2 4) (6 8) (10 12))
<cl> (a- a a)
#2A((0 0) (0 0) (0 0))
転置行列array-transpose,掛け算a*も同様に定義できます.
(defun array-transpose (a)
(let* ((dim (array-dimensions a))
(c (make-array (reverse dim))))
(dotimes (i (car dim))
(dotimes (j (cadr dim))
(setf (aref c j i) (aref a i j))))
c))
(defun a* (a b)
(let* ((dima (array-dimensions a))
(dimb (array-dimensions b))
(l (car dima))
(m (cadr dima))
(n (cadr dimb))
(c (make-array (list l n))))
(dotimes (i l)
(dotimes (j n)
(setf (aref c i j) 0)
(dotimes (k m)
(setf (aref c i j)
(+ (aref c i j)
(* (aref a i k)
(aref b k j)))))))
c))
計算例は、次のようになります。
<cl> a
#2A((1 2) (3 4) (5 6))
<cl> (array-transpose a)
#2A((1 3 5) (2 4 6))
<cl> (a* a (array-transpose a))
#2A((5 11 17) (11 25 39) (17 39 61))
generated through LaTeX2HTML. M.Inaba 平成18年5月7日