- array-curry array inner-dimensionprocedure
If array is an array whose domain is an interval $[l_0,u_0)\times\cdots\times[l_{d-1},u_{d-1})$, and inner-dimension is an exact integer strictly between $0$ and $d$, then array-curry returns an immutable array with domain $[l_0,u_0)\times\cdots\times[l_{d-\text{inner-dimension}-1},u_{d-\text{inner-dimension}-1})$, each of whose entries is in itself an array with domain $[l_{d-\text{inner-dimension}},u_{d-\text{inner-dimension}})\times\cdots\times[l_{d-1},u_{d-1})$.
For example, if A and B are defined by
(define interval (make-interval '#(10 10 10 10))) (define A (make-array interval list)) (define B (array-curry A 1)) (define A_ (array-getter A)) (define B_ (array-getter B))
so
(A_ i j k l) => (list i j k l)
then B is an immutable array with domain (make-interval '#(10 10 10)), each of whose elements is itself an (immutable) array and
(equal? (A_ i j k l) ((array-getter (B_ i j k)) l)) => #t
for all multi-indices i j k l in interval.
The subarrays are immutable, mutable, or specialized according to whether the array argument is immutable, mutable, or specialized.
More precisely, if
0 < inner-dimension < (interval-dimension (array-domain array))
then array-curry returns a result as follows.
If the input array is specialized, then array-curry returns
(call-with-values (lambda () (interval-projections (array-domain array) inner-dimension)) (lambda (outer-interval inner-interval) (make-array outer-interval (lambda outer-multi-index (specialized-array-share array inner-interval (lambda inner-multi-index (apply values (append outer-multi-index inner-multi-index))))))))
Otherwise, if the input array is mutable, then array-curry returns
(call-with-values (lambda () (interval-projections (array-domain array) inner-dimension)) (lambda (outer-interval inner-interval) (make-array outer-interval (lambda outer-multi-index (make-array inner-interval (lambda inner-multi-index (apply (array-getter array) (append outer-multi-index inner-multi-index))) (lambda (v . inner-multi-index) (apply (array-setter array) v (append outer-multi-index inner-multi-index))))))))
Otherwise, array-curry returns
(call-with-values (lambda () (interval-projections (array-domain array) inner-dimension)) (lambda (outer-interval inner-interval) (make-array outer-interval (lambda outer-multi-index (make-array inner-interval (lambda inner-multi-index (apply (array-getter array) (append outer-multi-index inner-multi-index))))))))
It is an error to call array-curry if its arguments do not satisfy these conditions.
If array is a specialized array, the subarrays of the result inherit their safety and mutability from array.
Note: Let's denote by B the result of (array-curry A k). While the result of calling (array-getter B) is an immutable, mutable, or specialized array according to whether A itself is immutable, mutable, or specialized, B is always an immutable array, where (array-getter B), which returns an array, is computed anew for each call. If (array-getter B) will be called multiple times with the same arguments, it may be useful to store these results in a specialized array for fast repeated access.
Please see the note in the discussion of array-tile.
Example:
(define a (make-array (make-interval '#(10 10)) list)) (define a_ (array-getter a)) (a_ 3 4) => (3 4) (define curried-a (array-curry a 1)) (define curried-a_ (array-getter curried-a)) ((array-getter (curried-a_ 3)) 4) => (3 4)