A note on reduction in Dyalog APL

Reduce

In APL, reduce f⌿ on a vector (1D array) can be thought as evaluating the vector with f inserted between adjacent elements.

f⌿ a b c d
←→ a f b f c f d
←→ a f (b f (c f d))

The last ←→ shows that APL evaluates from right to left. As a result, f⌿ is right reduce (or right fold).

As long as f is commutative, like +, the result of right reduce is the same as the one from left reduce. But when f is not commutative, like , (concatenate), the result would be different. The good news is that left reduce can be expressed in term of right reduce.

((a f b) f c) f d
←→ d f⍨ (c f⍨ (b f⍨ a))
←→ d f⍨ c f⍨ b f⍨ a
←→ f⍨⌿ d c b a
←→ f⍨⌿⌽ a b c d

Here, f⍨ is the function f with its left and right arguments swapped, and reverses its right argument.

Windowed reduce

In fact, f⌿ is ambivalent, meaning it can be monadic or dyadic. When used dyadically, f⌿ takes an integer as its left argument. Now, f⌿ is windowed reduce. That is, x f⌿ y reduces every window of length x with f.

3 f⌿ a b c d
←→ (f⌿ a b c) (f⌿ b c d)
←→ (a f (b f c)) (b f (c f d))

Windowed right reduce can be written in terms of its left counterpart as well.

((a f b) f c) ((b f c) f d)
←→ (c f⍨ b f⍨ a) (d f⍨ c f⍨ b)
←→ (f⍨⌿ c b a) (f⍨⌿ d c b)
←→ ⌽ (f⍨⌿ d c b) (f⍨⌿ c b a)
←→ ⌽ 3f⍨⌿ d c b a
←→ ⌽ 3f⍨⌿ ⌽ a b c d

When the left argument is negative, the windows are reversed before the reductions.

¯3 f⌿ a b c d
←→ (f⌿⌽ a b c) (f⌿⌽ b c d)
←→ (f⌿ c b a) (f⌿ d c b)
←→ (c f (b f a)) (d f (c f b))

This is useful when one wants to calculate adjacent difference.

    ¯2 -⌿ 1 1 2 3 5 8 13 21
0 1 1 2 3 5 8

Here is how the negative case is related to the positive case.

¯3 f⌿ a b c d
←→ (f⌿ c b a) (f⌿ d c b)
←→ ⌽ (f⌿ d c b) (f⌿ c b a)
←→ ⌽ 3 f⌿ d c b a
←→ ⌽ 3 f⌿ ⌽ a b c d

In general, ⌽ x f⌿ v ←→ (-x) f⌿ ⌽ v.

This means windowed right reduce can also be represented using windowed reduce with negative left argument.

((a f b) f c) ((b f c) f d)
←→ ⌽ 3 f⍨⌿ ⌽ a b c d
←→ ¯3 f⍨⌿ a b c d

You can try these equations here.