chickadee » srfi-179 » array-permute

array-permute array permutationprocedure

Assumes that array is a valid array, permutation is a valid permutation, and that the dimensions of the array and the permutation are the same. The resulting array will have domain (interval-permute (array-domain array) permutation).

We begin with an example. Assume that the domain of array is represented by the interval $[0,4)\times[0,8)\times[0,21)\times [0,16)$, as in the example for interval-permute, and the permutation is #(3 0 1 2). Then the domain of the new array is the interval $[0,16)\times [0,4)\times[0,8)\times[0,21)$.

So the multi-index argument of the getter of the result of array-permute must lie in the new domain of the array, the interval $[0,16)\times [0,4)\times[0,8)\times[0,21)$. So if we define old-getter as (array-getter array), the definition of the new array must be in fact

(make-array (interval-permute (array-domain array)
                              '#(3 0 1 2))
            (lambda (l i j k)
              (old-getter i j k l)))

So you see that if the first argument if the new getter is in $[0,16)$, then indeed the fourth argument of old-getter is also in $[0,16)$, as it should be. This is a subtlety that I don't see how to overcome. It is the listing of the arguments of the new getter, the lambda, that must be permuted.

Mathematically, we can define $\pi^{-1}$, the inverse of a permutation $\pi$, such that $\pi^{-1}$ composed with $\pi$ gives the identity permutation. Then the getter of the new array is, in pseudo-code, (lambda multi-index (apply old-getter ($\pi^{-1}$ multi-index))). We have assumed that $\pi^{-1}$ takes a list as an argument and returns a list as a result.

Employing this same pseudo-code, if array is a specialized array and we denote the permutation by $\pi$, then array-permute returns the new specialized array

(specialized-array-share array
                         (interval-permute (array-domain array) π)
                         (lambda multi-index
                           (apply values (π-1 multi-index))))

The resulting array shares the body of array, as well as its safety and mutability.

Again employing this same pseudo-code, if array is not a specialized array, but is a mutable-array, then array-permute returns the new mutable

(make-array (interval-permute (array-domain array) π)
            (lambda multi-index
              (apply (array-getter array)
                     (π-1 multi-index)))
            (lambda (val . multi-index)
              (apply (array-setter array)
                     val
                     (π-1 multi-index))))

which employs the setter and the getter of the argument to array-permute.

Finally, if array is not a mutable array, then array-permute returns

(make-array (interval-permute (array-domain array) π)
            (lambda multi-index
              (apply (array-getter array)
                     (π-1 multi-index))))

It is an error to call array-permute if its arguments do not satisfy these conditions.