- 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.