Lisp: operations with multiple array elements

What is the “correct” construction in Common Lisp for applying elementary operations to multidimensional arrays?

The following examples will help illustrate what I'm trying to do:

A) Suppose I want to increase each element of an array by one:

0 1 2    1 2 3
3 4 5 -> 4 5 6
6 7 8    7 8 9

B) Suppose I want to add 2 arrays:

1 2   -1 -1    0 1
3 4 + -2 -2 -> 1 2
5 6   -3 -3    2 3

C) Suppose I want to find the largest elements from multiple arrays, elementwise:

max( 0 1 , 4 -1 , 0 0 ) -> 4 1
     2 3   0  0   8 1      8 3

Basically, I think I'm looking for some kind of "arraymap" function that will be used as follows: (arraymap f A1 A2 ... An)where f takes n arguments as input and Ai accept arrays of the same size.

In the above examples, it will be used as follows:

AND)

(setq M #2A((0 1 2) (3 4 5) (6 7 8)))
(arraymap #'incf M)

AT)

(setq M #2A((1 2) (3 4) (5 6)))
(setq N #2A((-1 -1) (-2 -2) (-3 -3)))
(arraymap #'+ M N)

WITH)

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

, , , , .

+5
1

:

:

(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))
  • , .
+8

All Articles