2010-05-26 6 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)))) 

(fusion-matrice '((3 1) (3 1))' ((4 2) (1 1)))fusion de deux matrices ... en LISP

*** - EVAL: NULL variable n'a pas de valeur

Je reçois une erreur comme ça comment je peux résoudre le problème, merci

+1

À quoi ressemble MATRIX-ROWS? Si j'utilise (defun matrix-rows (matrice) (matrice de longueur)) par exemple j'obtiens la réponse ((3 1 4 2) (1 3 1 1)). –

+0

Qu'est-ce que la fonction est censée faire? – yan

Répondre

0

le message d'erreur que vous obtenez suggèrent s que Lisp essaie de traiter l'un de vos appels comme null en tant que variable. J'ai été en mesure de répliquer ce comportement en définissant matrix-rows comme Frank Shearar l'a fait et en supprimant les parenthèses autour de l'expression-s ((null matrix-1) (copy-tree matrix-2)), par exemple. Je vous suggère de vérifier vos parenthèses, soit manuellement ou en utilisant quelque chose comme SLIME, qui m'a donné un avertissement lorsque j'ai essayé de compiler la fonction.

1

Le code OP fonctionne pour moi. Cependant je me suis senti motivé pour l'améliorer et j'ai mis en place la même idée (mais un peu plus puissante).

La sémantique est la même que celle de Matcat. La fonction ajoute tous les arguments dans une grande matrice.

Notez qu'en raison des déclarations mon code devrait être super efficace.

(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))