Map Lisp:多维数组元素操作

Map Lisp:多维数组元素操作,map,lisp,multidimensional-array,loops,Map,Lisp,Multidimensional Array,Loops,在Common Lisp中,将元素操作应用于多维数组的“正确”构造是什么 以下示例有助于说明我正在尝试做的事情: A) 假设我想将数组中的每个元素增加1: 0 1 2 1 2 3 3 4 5 -> 4 5 6 6 7 8 7 8 9 B) 假设我要添加2个数组: 1 2 -1 -1 0 1 3 4 + -2 -2 -> 1 2 5 6 -3 -3 2 3 (B) (setq M#2A((12)(34)(56))) (setq N#2A((-1-1)(-2-2)

在Common Lisp中,将元素操作应用于多维数组的“正确”构造是什么

以下示例有助于说明我正在尝试做的事情:

A) 假设我想将数组中的每个元素增加1:

0 1 2    1 2 3
3 4 5 -> 4 5 6
6 7 8    7 8 9
B) 假设我要添加2个数组:
1 2   -1 -1    0 1
3 4 + -2 -2 -> 1 2
5 6   -3 -3    2 3

(B)
(setq M#2A((12)(34)(56)))
(setq N#2A((-1-1)(-2-2)(-3-3)))
(阵列映射+M N)

(C)
(setq M#2A((01)(23)))
(setq N#2A((4-1)(0)))
(setq O#2A((0)(81)))
(arraymap#max M N O)


我尝试了一些map和loop的构造,但似乎不起作用,因为多维数组不是序列类型。

有四种方法可以做到这一点:

  • 基于数组维度编写一个ARRAY-MAP函数,并迭代这些维度

  • 使用,它可以像矢量一样查看数组

  • 使用置换的一维数组进行操作

使用置换阵列的示例:

(defun array-map (function &rest arrays)
  "maps the function over the arrays.
   Assumes that all arrays are of the same dimensions.
   Returns a new result array of the same dimension."
  (flet ((make-displaced-array (array)
           (make-array (reduce #'* (array-dimensions array))
                       :displaced-to array)))
    (let* ((displaced-arrays (mapcar #'make-displaced-array arrays))
           (result-array (make-array (array-dimensions (first arrays))))
           (displaced-result-array (make-displaced-array result-array)))
      (declare (dynamic-extent displaced-arrays displaced-result-array))
      (apply #'map-into displaced-result-array function displaced-arrays)
      result-array)))
使用它:

CL-USER 3 > (array-map #'1+ #2A((0 1 2) (3 4 5) (6 7 8)))

#2A((1 2 3) (4 5 6) (7 8 9))

CL-USER 4 > (array-map #'+ #2A((1 2) (3 4) (5 6)) #2A((-1 -1) (-2 -2) (-3 -3)) )

#2A((0 1) (1 2) (2 3))
  • 使用特定于实现的内部操作来实现高效的阵列操作

对于任何来这里寻找这个问题最新答案的人:定义
aops:each
(和
aops:each*
)它完全符合OP的要求。

啊,太棒了。您可能会说这类似于使用matlab风格的“ind2sub”和“sub2ind”函数的隐式。
(setq M #2A((1 2) (3 4) (5 6)))
(setq N #2A((-1 -1) (-2 -2) (-3 -3)))
(arraymap #'+ M N)
(setq M #2A((0 1) (2 3)))
(setq N #2A((4 -1) (0 0)))
(setq O #2A((0 0) (8 1)))
(arraymap #'max M N O)
(defun array-map (function &rest arrays)
  "maps the function over the arrays.
   Assumes that all arrays are of the same dimensions.
   Returns a new result array of the same dimension."
  (flet ((make-displaced-array (array)
           (make-array (reduce #'* (array-dimensions array))
                       :displaced-to array)))
    (let* ((displaced-arrays (mapcar #'make-displaced-array arrays))
           (result-array (make-array (array-dimensions (first arrays))))
           (displaced-result-array (make-displaced-array result-array)))
      (declare (dynamic-extent displaced-arrays displaced-result-array))
      (apply #'map-into displaced-result-array function displaced-arrays)
      result-array)))
CL-USER 3 > (array-map #'1+ #2A((0 1 2) (3 4 5) (6 7 8)))

#2A((1 2 3) (4 5 6) (7 8 9))

CL-USER 4 > (array-map #'+ #2A((1 2) (3 4) (5 6)) #2A((-1 -1) (-2 -2) (-3 -3)) )

#2A((0 1) (1 2) (2 3))