Warning: This is the manual of the legacy Guile 2.2 series. You may want to read the manual of the current stable series instead.
Next: Accessing Arrays from C, Previous: Shared Arrays, Up: Arrays [Contents][Index]
Mathematically, one can see an array of rank n (an n-array) as an array of lower rank where the elements are themselves arrays (‘cells’).
We speak of the first n-k dimensions of the array as the n-k-‘frame’ of the array, while the last k dimensions are the dimensions of the k-‘cells’. For example, a 3-array can be seen as a 2-array of vectors (1-arrays) or as a 1-array of matrices (2-arrays). In each case, the vectors or matrices are the 1-cells or 2-cells of the array. This terminology originates in the J language.
The more vague concept of a ‘slice’ refers to a subset of the array where some indices are fixed and others are left free. As a Guile data object, a cell is the same as a ‘prefix slice’ (the first n-k indices into the original array are fixed), except that a 0-cell is not a shared array of the original array, but a 0-slice (where all the indices into the original array are fixed) is.
Before version 2.0, Guile had a feature called ‘enclosed arrays’ to create special ‘array of arrays’ objects. The functions in this section do not need special types; instead, the frame rank is stated in each function call, either implicitly or explicitly.
If the length of idxlist equals the rank n of array,
return the element at (idx …)
, just like (array-ref
array idx …)
. If, however, the length k of idxlist
is smaller than n, then return the (n-k)-cell of
array given by idxlist, as a shared array.
For example:
(array-cell-ref #2((a b) (c d)) 0) ⇒ #(a b) (array-cell-ref #2((a b) (c d)) 1) ⇒ #(c d) (array-cell-ref #2((a b) (c d)) 1 1) ⇒ d (array-cell-ref #2((a b) (c d))) ⇒ #2((a b) (c d))
(apply array-cell-ref array indices)
is equivalent to
(let ((len (length indices))) (if (= (array-rank a) len) (apply array-ref a indices) (apply make-shared-array a (lambda t (append indices t)) (drop (array-dimensions a) len))))
Like (array-cell-ref array idx …)
, but return a 0-rank
shared array into ARRAY if the length of idxlist matches the
rank of array. This can be useful when using ARRAY as a
place to write to.
Compare:
(array-cell-ref #2((a b) (c d)) 1 1) ⇒ d (array-slice #2((a b) (c d)) 1 1) ⇒ #0(d) (define a (make-array 'a 2 2)) (array-fill! (array-slice a 1 1) 'b) a ⇒ #2((a a) (a b)). (array-fill! (array-cell-ref a 1 1) 'b) ⇒ error: not an array
(apply array-slice array indices)
is equivalent to
(apply make-shared-array a (lambda t (append indices t)) (drop (array-dimensions a) (length indices)))
If the length of idxlist equals the rank n of
array, set the element at (idx …)
of array to
x, just like (array-set! array x idx …)
. If,
however, the length k of idxlist is smaller than
n, then copy the (n-k)-rank array x
into the (n-k)-cell of array given by
idxlist. In this case, the last (n-k) dimensions of
array and the dimensions of x must match exactly.
This function returns the modified array.
For example:
(array-cell-set! (make-array 'a 2 2) b 1 1) ⇒ #2((a a) (a b)) (array-cell-set! (make-array 'a 2 2) #(x y) 1) ⇒ #2((a a) (x y))
Note that array-cell-set!
will expect elements, not arrays, when
the destination has rank 0. Use array-slice
for the opposite
behavior.
(array-cell-set! (make-array 'a 2 2) #0(b) 1 1) ⇒ #2((a a) (a #0(b))) (let ((a (make-array 'a 2 2))) (array-copy! #0(b) (array-slice a 1 1)) a) ⇒ #2((a a) (a b))
(apply array-cell-set! array x indices)
is equivalent to
(let ((len (length indices))) (if (= (array-rank array) len) (apply array-set! array x indices) (array-copy! x (apply array-cell-ref array indices))) array)
Each x must be an array of rank ≥ frame-rank, and the first frame-rank dimensions of each x must all be the same. array-slice-for-each calls op with each set of (rank(x) - frame-rank)-cells from x, in unspecified order.
array-slice-for-each allows you to loop over cells of any rank without having to carry an index list or construct shared arrays manually. The slices passed to op are always shared arrays of X, even if they are of rank 0, so it is possible to write to them.
This function returns an unspecified value.
For example, to sort the rows of rank-2 array a
:
(array-slice-for-each 1 (lambda (x) (sort! x <)) a)
As another example, let a
be a rank-2 array where each row is a
2-element vector (x,y). Let’s compute the arguments of these
vectors and store them in rank-1 array b
.
(array-slice-for-each 1 (lambda (a b) (array-set! b (atan (array-ref a 1) (array-ref a 0)))) a b)
(apply array-slice-for-each frame-rank op x)
is equivalent to
(let ((frame (take (array-dimensions (car x)) frank))) (unless (every (lambda (x) (equal? frame (take (array-dimensions x) frank))) (cdr x)) (error)) (array-index-map! (apply make-shared-array (make-array #t) (const '()) frame) (lambda i (apply op (map (lambda (x) (apply array-slice x i)) x)))))
Same as array-slice-for-each
, but the arguments are traversed
sequentially and in row-major order.
Next: Accessing Arrays from C, Previous: Shared Arrays, Up: Arrays [Contents][Index]