2010-05-26 93 views
2
(defun merge-matrix (matrix-1 matrix-2) 
    (if (not (or (eql (matrix-rows matrix-1) (matrix-rows matrix-2)) (null matrix-1) (null matrix-2))) (error "Invalid dimensions.")) 
    (cond 
     ((null matrix-1) (copy-tree matrix-2)) 
     ((null matrix-2) (copy-tree matrix-1)) 
     (t (let ((result (copy-tree matrix-1))) 
       (dotimes (i (matrix-rows matrix-1)) 
        (setf (nth i result) (nconc (nth i result) (nth i matrix-2)))) 
       result)))) 

(合併矩陣 '((3 1)(1 3))'((4 2)(11)))合併兩個矩陣...在LISP

*** - EVAL:可變NULL沒有值

我收到了如下的錯誤,我怎麼能解決這個問題,謝謝

+1

MATRIX-ROWS是什麼樣的?如果我使用(defun矩陣行(矩陣)(長度矩陣)),例如我得到答案((3 1 4 2)(1 3 1 1))。 – 2010-05-27 08:10:56

+0

函數應該做什麼? – yan 2011-01-28 22:58:02

回答

0

你得到錯誤信息提示s lisp正試圖將您的電話作爲變量對待null。例如,我可以通過像Frank Shearar那樣定義matrix-rows並刪除((null matrix-1) (copy-tree matrix-2)) s表達式中的括號來複制此行爲。我建議你檢查你的括號,手動或使用像SLIME這樣的東西,當我試圖編譯函數時給了我一個警告。

1

OP的代碼適用於我。不過,我感到有動力改善它,並且我實現了相同的想法(但功能更強大)。

語義與Matlab的vertcat相同。 該函數將所有參數附加到一個大矩陣中。

請注意,由於聲明我的代碼應該是超高效的。

(deftype mat() 
    "Non-square matrices. Last index is columns, i.e. row-major order." 
    `(simple-array single-float 2)) 

(defun are-all-elements-typep (type ls) 
    (reduce #'(lambda (b x) (and b (typep x type))) 
     ls)) 

(defun are-all-matrix-heights-equalp (ls) 
    (let ((first-height (array-dimension (first ls) 0))) 
    (reduce #'(lambda (b x) (and b 
       (= first-height 
        (array-dimension x 0)))) 
     ls))) 

(defun vertcat (&rest rest) 
    (declare (type cons rest)) 
    (unless (are-all-elements-typep 'mat rest) 
    (break "At least one of the arguments isn't a matrix.")) 
    (unless (are-all-matrix-heights-equalp rest) 
    (break "All Matrices must have the same number of rows.")) 
    (let* ((height (array-dimension (first rest) 0)) 
    (widths (mapcar #'(lambda (mat) (array-dimension mat 1)) rest)) 
    (result (make-array (list height 
        (reduce #'+ widths)) 
       :element-type 'single-float)) 
    (current-width 0)) 
    (dotimes (m (length rest)) 
     (let ((e (elt rest m))) 
    (destructuring-bind (y x) (array-dimensions e) 
    (dotimes (j y) 
     (dotimes (i x) 
     (setf (aref result j (+ current-width i)) 
      (aref e j i)))) 
    (incf current-width (elt widths m))))) 
    (the mat result))) 

#+nil 
(let ((a (make-array '(2 3) 
      :initial-contents '((1s0 2s0 3s0) 
        (2s0 4s0 5s0)) 
      :element-type 'single-float)) 
     (b (make-array '(2 2) 
      :initial-contents '((6s0 7s0) 
        (9s0 8s0)) 
      :element-type 'single-float))) 
    (vertcat a b a)) 
;=> #2A ((1.0 2.0 3.0 6.0 7.0 1.0 2.0 3.0) (2.0 4.0 5.0 9.0 8.0 2.0 4.0 5.0))