3

普通的 lisp 新手。编写 lisp 代码与编写 c++/java 完全不同,正如我之前编写的那样。

我正在尝试在 common lisp 中编写一个简单的矩阵类进行练习。像这样的一些代码:

(defun make-matrix (row col)
  (make-list row :initial-element (make-list col :initial-element nil)))

(defun init-matrix (matrix init-value)
  (labels ((set-element-value (lst)
                              (if (and lst
                                       (listp lst))
                                  (mapcar #'set-element-value lst)
                                (setf lst init-value))))
    (set-element-value matrix)))

(defun matrix+ (&rest matrices)
  (apply #'mapcar (lambda (&rest rows)
                    (apply #'mapcar #'+ rows)) matrices))

我的问题是我可以编写一个矩阵+,在没有“应用”的情况下接受不同数量的参数,还是以更好的方式?在某种程度上,lisp 应该是?

矩阵*怎么样,有人可以给我看一些很棒的代码,接受矩阵*中的任意数量的参数吗?谢谢。

4

2 回答 2

5

Common Lisp 有 n 维数组。我会将它们用于矩阵运算。

见:MAKE-ARRAY, AREF, ...

通常我还会编写一个二进制(带两个参数)矩阵运算。使用 thenREDUCE对矩阵列表进行操作。

CL-USER > (make-array '(3 5) :initial-element 0)
#2A((0 0 0 0 0) (0 0 0 0 0) (0 0 0 0 0))

上面创建了一个大小为 3x5 的二​​维数组,初始内容为 0。

于 2012-07-12T10:48:54.523 回答
3

矩阵乘法。我不能保证这是最好的例子,但它真的很简单。这是因为您使用数组而不是列表。此外,当然,您可以优化方阵或特殊情况,如单位矩阵等。但这只是为了简单,而不是高效等。

(defun matrix* (&rest matrices)
  (assert (cdr matrices) nil
          "You will achieve nothing by multiplying a single matrix.")
  (reduce
   #'(lambda (a b)
       (assert (= (array-dimension a 0) (array-dimension b 1)) nil
               "The number of rows in the first matrix should be the number ~
                of columns in the second matrix")
       (let ((result
              (make-array
               (list (array-dimension a 1) (array-dimension b 0))
               :initial-element 0)))
         (dotimes (i (array-dimension a 1) result)
           (dotimes (j (array-dimension b 0))
             (dotimes (k (array-dimension a 0))
               (incf (aref result i j) (* (aref a k i) (aref b j k))))))))
   matrices))

(format t "result: ~s~&" (matrix* #2A((1 2) (3 4)) #2A((5 6) (7 8))))
;; #2A((23 31) (34 46)) =
;; (1 * 5 + 3 * 6 = 23) (1 * 7 + 3 * 8 = 31)
;; (2 * 5 + 4 * 6 = 34) (2 * 7 + 4 * 8 = 46)
于 2012-07-12T16:23:17.223 回答