Modifying rank and depth#
This notebook covers the monadic definitions of ↑
, ↓
, ⊂
and ⊃
. Whose return values tend to differ in rank or depth from their arguments.
Mix#
Monadic ↑
(Mix) is a useful function for creating higher rank arrays. Mix assembles the items of an array into a higher-rank array with one less level of nesting. For example, given a vector of vectors, it returns a matrix with each vector as a row.
↑(1 2 3)(4 2 2)'abc'
↑((1 2)(3 4))((5 6)(7 8))
If the vectors in the argument are different in shape a fill element is used to pad the array to a rectangle. The fill element is the type of the first element.
The typical number is 0
, and the typical character is ' '
. The type of an array is the array of the types of its elements - The same array, but where each simple scalar is replaced by it’s type.
↑(1 2 3)(3 3)(4 3 2)'x'
↑((1 2)(3 4)(5 6))((7 8) 9)
The fill element for (7 8) 9
is the type of 7 8
; 0 0
When mixing a vector of higher rank arrays, the result will have a rank one more than the array of greatest rank in the argument. Mixing a vector of matrices will create a 3 dimensional array where each matrix is a plane.
↑(2 2⍴'abcd')(2 2⍴'efgh')(2 2⍴'ijkl')
Again, if the shapes are not all the same, the mismatched arrays are filled with the prototype of their first element:
↑(3 2⍴1 2 3)(2 3⍴'abc')(2 2⍴'x')
Here, the shape of each layer is 3 3
which is the smallest shape that the all the layers can be extended to. The rows of the first element get extended, the columns of the second, and both rows and columns are extended on the last element.
If the ranks of the arrays in the argument are different, the shapes are padded with 1
s. For example a length 4 vector may become a 1 by 4 matrix. After the ranks are extended the shapes are then checked and extended as before
↑(1 2 3)(2 2 2⍴'A')(3 2⍴4 5 6)
If an array A
has shape X
and the shape of each item (after extension) in A
is Y
, then ⍴↑A
is X,Y
. The shapes X
and Y
are mixed.
Split#
Monadic ↓
(Split) is the counterpart to mix. It converts a higher rank array into a nested array. The result of split will have a rank one less than the argument, unless the argument is scalar, in which case the rank will remain 0
.
The shape of an array is split at the last element by split. For example, an array of shape 1 2 3 4
will be split into an array of shape 1 2 3
. What happens to the 4
? The last element of the shape becomes the shape of the items at depth 1 in the result.
↓2 2⍴1 2 3 4
↓3 3 3⍴⍳27
↓↑(1 2 3)'abc'(3 4)
↓3 3⍴(2 2⍴1) 3
If the argument is a vector V
, it’s rank is 1. Splitting it will result in an array of shape ⍬
whose contents have the shape of V
; a scalar that itself contains a vector. These are known as enclosed vectors or, more generally, nested scalars.
↓7 6 2
⍴⍴ ↓7 6 2
Numbers and characters are known as simple scalars, because their depth is 0. Splitting a simple scalar does nothing, the result is the argument itself. However, splitting nested scalars increases their (absolute) depth by 1.
↓1
↓↓4 5
Mix also will do nothing to a simple scalar, but will decrease the depth of nested scalars by 1.
↑1
↑↓↓1 2 3
↑↓'APL'
A common use of mix and split is to perform matrix operations on a vector of vectors. For example transpose:
↓⍉↑ 'abcd' 'efgh' 'ijkl'
Enclose#
Monadic ⊂
(enclose) is used simply to enclose any array to form a scalar. It will increase the depth of an array by 1, unless applied to simple scalar where it has no effect
⊂1 2 3
This is useful in conjunction with scalar functions. Or any function that treat scalars differently.
4 5 6+1 2 3
4 5 6 + ⊂1 2 3
Here, 1 2 3
is added to each of 4 5 6
separately.
2 2⍴2 3⍴'xy'
2 2⍴⊂2 3⍴'xy'
Simple scalars cannot be enclosed.
⊂1
Disclose#
Monadic ⊃
(disclose, also called first) is the counterpart to ⊂
. It will take the first item at depth 1 from an array. For a nested array, this has the effect of undoing an enclose (disclosing).
⊃⊂'abcd'
⊃⊂⊂5 4 3 2 1
⊃6 2 3 1
⊃3 3⍴⊂6 5⍴'APL'