2017-07-19 1 views
1

Toutes les fonctions de la carte comme mapcar, mapcan, mapc, etc. nécessitent des listes comme entrées. Je travaille avec des tableaux 2D, et je préférerais ne pas jouer avec le rang de mes tableaux étant donné les tailles souvent grandes (50 000 x 1 000 parfois).Recherche d'un moyen de mapper une fonction sur un tableau Lisp 2D

J'ai besoin d'un moyen d'appliquer une fonction comme (log n) à chaque élément de la matrice 2D et générer un tableau 2D résultant.

Toute aide ou direction est très appréciée.

Travailler dans AllegroCL (Common Lisp)

Répondre

5

Qu'est-ce que vous avez besoin est une combinaison de

Quelque chose comme ceci:

(defun array-map (function array 
        &optional (retval (make-array (array-dimensions array)))) 
    "Apply FUNCTION to each element of ARRAY. 
Return a new array, or write into the optional 3rd argument." 
    (dotimes (i (array-total-size array) retval) 
    (setf (row-major-aref retval i) 
      (funcall function (row-major-aref array i))))) 

Exemple:

(defparameter a (make-array '(2 3) :initial-contents '((1 2 3) (4 5 6)))) 
a 
==> #2A((1 2 3) (4 5 6)) 
(array-map #'sqrt a) 
==> #2A((1 1.4142135 1.7320508) (2 2.236068 2.4494898)) 
a ; does not change! 
==> #2A((1 2 3) (4 5 6)) 

Vous pouvez également utiliser array-map similaire à map-into:

(array-map #'1+ a a) 
==> #2A((2 3 4) (5 6 7)) 
a ; modified, no new storage is allocated 
==> #2A((2 3 4) (5 6 7)) 

Remarque que array-map fonctionnera sur n'importe quelle dimension de tableau, des vecteurs aux matrices à 10d & c.

exercice: mettre en œuvre array-multi-map acceptant une fonction d'un nombre quelconque d'argument et un nombre quelconque de rangées, de sorte que

(array-multi-map #'+ #A((1 2 3) (4 5 6)) #A((11 22 33) (44 55 66))) 
==> #A((12 24 36) (48 60 72)) 

PS. L'ensemble CLHS Chapter 15 Arrays ou CLtL2 Chapter 17 Arrays mérite d'être étudié.

+0

Il peut être utile de laisser l'utilisateur spécifier le type d'élément pour le nouveau tableau. – jkiiski

+0

@jkiiski: J'y ai pensé, mais j'ai décidé contre. Si l'utilisateur veut ce niveau de contrôle, il peut passer 'retval'. En déduire le type de tableau à partir du type de tableau d'argument peut empêcher l'exemple 'sqrt' de fonctionner parce que le tableau d'entrée peut être spécialisé en entiers. – sds

+0

C'est génial. Je vous remercie. J'aime que c'est très simple et facilement réalisable malgré des fonctions plus compliquées. – RufLife