6.13 Folds, Reductions and Expansions
6.13.1 Axis Folds
procedure
(array-axis-fold arr k f) → (Array A)
arr : (Array A) k : Integer f : (A A -> A) (array-axis-fold arr k f init) → (Array B) arr : (Array A) k : Integer f : (A B -> B) init : B
The three-argument variant uses the first value of each row in axis k as init. It therefore requires axis k to have positive length.
Examples: | ||||||||||||
|
If you need control over the order of evaluation in axis k’s rows, see array-axis-reduce.
syntax
(array-axis-sum arr k)
(array-axis-sum arr k init)
syntax
(array-axis-prod arr k)
(array-axis-prod arr k init)
arr : (Array Number)
k : Integer
init : Number
syntax
(array-axis-min arr k)
(array-axis-min arr k init)
syntax
(array-axis-max arr k)
(array-axis-max arr k init)
arr : (Array Real)
k : Integer
init : Real
Examples: | |||||||||||||||
|
procedure
(array-axis-count arr k pred?) → (Array Index)
arr : (Array A) k : Integer pred? : (A -> Any)
Examples: | |||||||||
|
procedure
(array-axis-and arr k) → (Array (U A Boolean))
arr : (Array A) k : Integer
procedure
(array-axis-or arr k) → (Array (U A #f))
arr : (Array A) k : Integer
> (define second? (ann #f Boolean))
> (define arr (parameterize ([array-strictness #f]) (build-array #(2) (λ: ([js : Indexes]) (cond [(zero? (vector-ref js 0)) #f] [else (set! second? #t) #t])))))
> (array-axis-and arr 0) - : (Array Boolean)
(array #f)
> second? - : Boolean
#f
6.13.2 Whole-Array Folds
Examples: | |||||||||||||||||||
|
procedure
(array-all-fold arr f) → A
arr : (Array A) f : (A A -> A) (array-all-fold arr f init) → A arr : (Array A) f : (A A -> A) init : A
(array-ref (array-fold arr (λ: ([arr : (Array A)] [k : Index]) (array-axis-fold arr k f))) #())
Examples: | ||||||||||||
|
syntax
(array-all-sum arr)
(array-all-sum arr init)
syntax
(array-all-prod arr)
(array-all-prod arr init)
arr : (Array Number)
init : Number
syntax
(array-all-min arr)
(array-all-min arr init)
syntax
(array-all-max arr)
(array-all-max arr init)
arr : (Array Real)
init : Real
Examples: | |||||||||||||||
|
procedure
(array-all-and arr) → (U A Boolean)
arr : (Array A)
procedure
(array-all-or arr) → (U A #f)
arr : (Array A)
Examples: | |||||||||||||||
|
(parameterize ([array-strictness #f]) (array-ref (array-fold arr array-axis-and) #()))
syntax
(array-count pred? arrs ...)
arrs : (Array Ts)
pred? : (Ts ... -> Any)
Examples: | |||||||||
|
syntax
(array-andmap pred? arrs ...)
syntax
(array-ormap pred? arrs ...)
arrs : (Array Ts)
pred? : (Ts ... -> Any)
> (array-andmap equal? (array #[#[0 1] #[0 1] #[0 1] #[0 1]]) (array #[0 1])) - : Boolean
#t
> (array-ormap equal? (array #[#[0 2] #[2 3] #[1 1] #[2 3]]) (array #[0 1])) - : Boolean
#t
> (array-ormap equal? (array->list-array (array #[#[0 2] #[2 3] #[1 1] #[2 3]])) (array->list-array (array #[0 1]))) - : Boolean
#f
(parameterize ([array-strictness #f]) (array-all-and (array-map pred? arrs ...)))
6.13.3 General Reductions and Expansions
procedure
(array-axis-reduce arr k h) → (Array B)
arr : (Array A) k : Integer h : (Index (Integer -> A) -> B)
The arguments to h are the length of axis k and a procedure that retrieves elements from that axis’s rows by their indexes in axis k. It should return the elements of the resulting array.
> (define arr (index-array #(3 3)))
> arr - : (Array Index)
(array #[#[0 1 2] #[3 4 5] #[6 7 8]])
> (array-axis-reduce arr 1 (λ: ([dk : Index] [proc : (Integer -> Real)]) (for/fold: ([s : Real 0]) ([jk (in-range dk)]) (+ s (sqr (proc jk)))))) - : (Array Real)
(array #[5 50 149])
> (array-axis-sum (array-map sqr arr) 1) - : (Array Nonnegative-Integer)
(array #[5 50 149])
> (array-map (inst reverse Index) (array-axis-fold arr 1 (inst cons Index (Listof Index)) empty)) - : (Array (Listof Index))
(array #['(0 1 2) '(3 4 5) '(6 7 8)])
> (array-axis-reduce arr 1 (inst build-list Index)) - : (Array (Listof Index))
(array #['(0 1 2) '(3 4 5) '(6 7 8)])
Every fold, including array-axis-fold, is ultimately defined using array-axis-reduce or its unsafe counterpart.
procedure
(array-axis-expand arr k dk g) → (Array B)
arr : (Array A) k : Integer dk : Integer g : (A Index -> B)
Conceptually, g is applied dk times to each element in each row of axis k, once for each nonnegative index jk < dk.
> (define arr (array #['#(a b c) '#(d e f) '#(g h i)]))
> (array-axis-expand arr 1 3 vector-ref) - : (Array Any)
(array #[#['a 'b 'c] #['d 'e 'f] #['g 'h 'i]])
> (array-axis-expand (list->array '(1 2 3 4)) 1 5 expt) - : (Array Positive-Integer)
(array #[#[1 1 1 1 1] #[1 2 4 8 16] #[1 3 9 27 81] #[1 4 16 64 256]])
This function is a dual of array-axis-reduce in that it can be used to invert applications of array-axis-reduce. To do so, g should be a destructuring function that is dual to the constructor passed to array-axis-reduce. Example dual pairs are vector-ref and build-vector, and list-ref and build-list.
(Do not pass list-ref to array-axis-expand if you care about performance, though. See list-array->array for a more efficient solution.)
procedure
(array->list-array arr [k]) → (Array (Listof A))
arr : (Array A) k : Integer = 0
Examples: | ||||||||||||
|
procedure
(list-array->array arr [k]) → (Array A)
arr : (Array (Listof A)) k : Integer = 0
Examples: | |||||||||
|
For fixed k, this function and array->list-array are mutual inverses with respect to their array arguments.