SATN45 A number of language extensions are available in the May 1983 release of SHARP APL:
The Rank Operator Definition The operator On (⍤) previously only applied to two functions to provide Composition. It now accepts an integer right argument (as in ,⍤2 ) to specify the rank, or ranks, of the subarrays to which the function applies. For example: a←2 3 4⍴⍳24 ,⍤2 a 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ,⍤¯1 a 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 As illustrated above, a nonnegative argument specifies the number of final axes to which the function applies. A negative argument specifies the complementary rank, i.e., the number of leading axes to be excluded. The magnitude of the argument serves only to limit the number of axes; for the a given above, f⍤4 a ←→ f⍤3 a , and f⍤¯4 a ←→ f⍤¯3 a . In the dyadic case two ranks (or complementary ranks) are specified. For example: e←2 2⍴'abcd' f←2 2⍴'1234' e,⍤1 2 f ab 12 34 cd 12 34 e,⍤0 0 f a1 b2 c3 d4 The most general right argument of ⍤ is a threeelement vector whose successive elements specify the monadic, left, and right ranks. A shorter argument r is extended so that f⍤r ←→ f⍤(⌽3⍴⌽r) . If the right argument of On is a scalar, and the resulting derived function is used dyadically, that number will specify the rank of both arguments. An expression such as f⍤r a introduces the possibility of juxtaposing constants (r and a). If r is a constant, and if the expression defining a begins with a constant, then the division between the two constants must be made clear to prevent them from being treated as a single vector. For example, the sequence a←2 3 4⍴⍳24 r←2 ,⍤r a cannot be written in a single line as ,⍤2 2 3 4⍴⍳24 but must be written in a form which separates the vector constants. For example: ,⍤(2) 2 3 4⍴⍳24 ,⍤2 (2 3 4)⍴⍳24 ,⍤2 a←2 3 4⍴⍳24 ,⍤2⊢ 2 3 4⍴⍳24 If a function has rank r , then the subarrays along the last r axes of its arguments are the cells of the array. The remaining axes are the frame of the array. Consider the expression ⌹a , where a has the shape 8 7 6 5 4 .
In contrast, consider the expression ⌊a , using the same array a .
A function applies independently to each cell (or pair of cells, if dyadic) to produce result cells, which must be of common shape. The result is formed by assembling the frame of result cells into an array. If a function f has rank r , then the result of f ⍵ is determined by:
The frames of the arguments of a dyadic function must match in shape, or one of them must be a scalar. If the frame is a scalar, it is extended by reshaping it to match the shape of the other frame. This is a generalization of scalar extension. By convention, if the frame is empty (i.e. 0∊(r)↓⍴⍵ ),
then the empty vector is used as the result cell shape.
Examples Common uses for the Rank operator include:
The following examples illustrate uses of the Rank operator. v←⍳5 ⋄ x←10×⍳4 ⋄ y←100×⍳3 ⋄ w←v ⋄ m←3 4⍴⍳12 ⋄ n←?m ⋄ b←3 4 5⍴⍳60 q←2 5⍴'abcdeedbca' ⋄ ⎕ps←1 1 3 3 Examples with Enclose m 1 2 3 4 5 6 7 8 9 10 11 12 <⍤0 m Enclose each (scalar) element ¯ ¯ ¯ ¯ 1 2 3 4 _ _ _ _ ¯ ¯ ¯ ¯ 5 6 7 8 _ _ _ _ ¯ ¯¯ ¯¯ ¯¯ 9 10 11 12 _ __ __ __ <⍤1 m Enclose rows ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯ 1 2 3 4 5 6 7 8 9 10 11 12 _______ _______ __________ gp <⍤2 b Enclose matrices ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯  1 2 3 4 5 21 22 23 24 25 41 42 43 44 45  6 7 8 9 10 26 27 28 29 30 46 47 48 49 50 11 12 13 14 15 31 32 33 34 35 51 52 53 54 55 16 17 18 19 20 36 37 38 39 40 56 57 58 59 60 ______________ ______________ ______________ Examples with Link v 1 2 3 4 5 w 1 2 2 3 2 v ⊃⍤0 w Similar to (<⍤>v),[1.5] <⍤>w ¯ ¯ 1 1 2 2 3 2 4 3 5 2 _ _ m ⊃⍤1 n Similar to (<⍤1 m),[1.5] <⍤1 n ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯ 1 2 3 4 1 2 3 4 _______ _______ ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯ 5 6 7 8 2 4 6 1 _______ _______ ¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯ 9 10 11 12 1 6 8 1 __________ _______ Examples with Grade n 1 2 3 4 2 4 6 1 1 6 8 1 ⍋⍤1 n Upgrade each row independently 1 2 3 4 4 1 2 3 1 4 2 3 ⍉ ⍋⍤1 ⍉n Independent upgrade 1 1 1 2 of each column 3 2 2 3 2 3 3 1 q abcde edcba q ⍋⍤1 'abcdef' Upgrade with multiple 1 2 3 4 5 6 collating sequences 5 4 3 2 1 6 An example with Ravel ,⍤2 b Ravel each matrix 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 An example with Rotate (1⍳4)⌽⍤1 2 b 1 2 3 4 5 10 6 7 8 9 14 15 11 12 13 18 19 20 16 17 21 22 23 24 25 30 26 27 28 29 34 35 31 32 33 38 39 40 36 37 41 42 43 44 45 50 46 47 48 49 54 55 51 52 53 58 59 60 56 57 Examples with Catenate y 100 200 300 y ,⍤0 2 b Catenate scalars to matrices 100 1 2 3 4 5 100 6 7 8 9 10 100 11 12 13 14 15 100 16 17 18 19 20 200 21 22 23 24 25 200 26 27 28 29 30 200 31 32 33 34 35 200 36 37 38 39 40 300 41 42 43 44 45 300 46 47 48 49 50 300 51 52 53 54 55 300 56 57 58 59 60 m ,⍤0 n Same as m,[2.5] n 1 1 2 2 3 3 4 4 5 2 6 4 7 6 8 1 9 1 10 6 11 8 12 1 Examples with Reshape 5 4 ⍴⍤1 2 b Reshape each plane 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 (5×¯1↑⍴m) ⍴⍤1 m Five sidebyside copies 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8 9 10 11 12 9 10 11 12 9 10 11 12 9 10 11 12 9 10 11 12 Examples with Take 7 ↑⍤1 m Take on all rows; 1 2 3 4 0 0 0 the same as ((¯1↓⍴m),7)↑m 5 6 7 8 0 0 0 9 10 11 12 0 0 0 ⍉ 7 ↑⍤1 ⍉ m Take on all columns; 1 2 3 4 the same as (7,1↓⍴m)↑m 5 6 7 8 9 10 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 ↑⍤1 2 b Take on each matrix 1 2 3 6 7 8 21 22 23 26 27 28 41 42 43 46 47 48 Examples with Match b ≡⍤1 ⊖b Compare vectors 0 0 0 0 1 1 1 1 0 0 0 0 b ≡⍤2 ⊖b Compare matrices 0 1 0 Examples with Membership (⍳3) ∊⍤0 2 b First scalar member of first 1 0 0 plane, 2nd of 2nd plane, etc. (⍳7) ∊⍤1 2 b Usual member of vector, 1 1 1 1 1 1 1 repeated for each matrix 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Examples with Iota m 1 2 3 4 5 6 7 8 9 10 11 12 n 1 2 3 4 2 4 6 1 1 6 8 1 m ⍳⍤1 n Independent search on rows; 1 2 3 4 as in m[1;]⍳n[1;], etc. 5 5 2 5 5 5 5 5 c←3 3⍴'keirbeeem' Table lookup, as in ⎕io++/∧\d∨.≠⍉c d←2 3⍴'rbercm' (d∧.=⍉c)⍳⍤(1) 1 2 4 Examples with Addition x 10 20 30 40 x +⍤1 m Add scalars to rows, 11 22 33 44 as in, m+(⍴m)⍴x 15 26 37 48 19 30 41 52 y 100 200 300 ⍉ y+⍤1 ⍉m Add scalars to columns 101 102 103 104 as in,m+⍉(⌽⍴m)⍴⍉y 205 206 207 208 309 310 311 312 y +⍤0 2 b Add scalars to matrices 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 An example with Representation 10 10⊤v 0 0 0 0 0 1 2 3 4 5 10 10 ⊤⍤1 0 v A different representation 0 1 0 2 0 3 0 4 0 5 Domains of Operators ⍤ , ⍥ , ¨ The left argument of the operators ⍤ , ⍥ , ¨ may be any primitive function except execute (⍎). The valid right arguments of ⍤ include any scalar or vector of integers containing at most three elements. A primitive function g is a valid right argument of ⍤ and ⍥ (and of ¨ if it has an assigned inverse) if its relevant ranks (left and right in the case of ⍺ f⍥g ⍵ , and monadic in all other cases) have been assigned. The following table shows function ranks, denoting infinite rank by ¯ , and unassigned rank by ⍝ : ⌹ < > ⍴ , ⍉ ∊ ⍋ ⍒ ? ⊤ ⍕ ≡ ⊢ ⊣ ⊃ Function 2 ¯ 0 ¯ ¯ ¯ ⍝ ¯ ¯ 0 ⍝ ¯ ⍝ ¯ ¯ ¯ Monadic ¯ 0 0 ⍝ ¯ ⍝ 0 ¯ ¯ ⍝ ¯ ⍝ ¯ ¯ ¯ ¯ Left 2 0 0 ⍝ ¯ ⍝ ¯ ¯ ¯ ⍝ ¯ ⍝ ¯ ¯ ¯ ¯ Right The functions ⊥ ⍳ ⌽ ⊖ ↑ ↓ ⍎ are not included in this table because their ranks have not been assigned. All scalar primitive functions have rank 0 and are therefore in the right domains of ⍤ and ⍥ . A monadic function g is in the right domain of ¨ if it is in the right domain of ⍤ and also occurs in the following table of assigned inverses: +  ÷ * ~ < ⍉ ⊢ ⌹ > ⍟ Function +  ÷ ⍟ ~ > ⍉ ⊢ ⌹ < * Inverse Lev ⊣ and Dex ⊢ Definition: The dyadic functions Lev ⊣ and Dex ⊢ return their left and right arguments, respectively. Each symbol points toward the argument it returns. The names are derived form the Latin words meaning ‘on the left side’ (laevus) and ‘on the right side’ (dexter). The monadic case of ⊢ is an identity function. It returns its argument unchanged. The monadic case of ⊣ returns no result, and is thus equivalent to ⍎'' . ⊣a will work, but z←⊣a will give a result error . Both cases of each function have infinite rank, and thus can be used with the operators On, Over, and With.Application: A) Many system functions both cause side effects (like defining functions) and return explicit results. If the result is not needed, it can be discarded using Lev. For example, the statement [∘] junk←⎕ex namelist can also be written as [∘] ⊣⎕ex namelist B) Lev, when used dyadically,
provides a statement connection facility.
Unlike diamond, the statement on the right side
of the Lev function will execute first.
Link ⊃ Definition: The monadic function ⊃ is a conditional enclose. If the argument is simple (not enclosed), then it is enclosed. If the argument is nonsimple, it is returned unchanged. The dyadic function ⊃ is called Link. It encloses its left argument, applies the conditional enclose to the right argument, and catenates the results. These rules can be summarized by the following.
Both cases of ⊃ have infinite rank, enabling it to be used as the right function argument in composition. Note that in the expression ⍺⊃⍵ , the symbol ⊃ (like the symbol < in <⍵ ) opens toward the argument to be enclosed. If the right argument (⍵) is simple, the shape of the result will always be 2. If the right argument (⍵) is not simple, the shape of the result will be ((⍴⍴⍵)↑1)+⍴⍵ . This is due to the scalar extension of the left argument when the catenation occurs. The following example illustrates this point. ⎕ps←1 1 3 3 g←2 5⍴'0123456789' h←<⍤(0) 3 4⍴'abcdefghijkl' ⍴h⊃g 2 h⊃g ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯ ¯ ¯ ¯ ¯ 01234 a b c d 56789 _ _ _ _ _____   ¯ ¯ ¯ ¯ e f g h _ _ _ _   ¯ ¯ ¯ ¯ i j k l _ _ _ _ _______________ ⍴g⊃h 3 5 g⊃h ¯¯¯¯¯ ¯ ¯ ¯ ¯ 01234 a b c d 56789 _ _ _ _ _____ ¯¯¯¯¯ ¯ ¯ ¯ ¯ 01234 e f g h 56789 _ _ _ _ _____ ¯¯¯¯¯ ¯ ¯ ¯ ¯ 01234 i j k l 56789 _ _ _ _ _____ Application: A) Monadic ⊃ can be used to test whether an array is simple. simple⋄ ~⍵≡⍵ B) Dyadic ⊃ can be used to create enclosed arrays without having to explicitly enclose and catenate the elements.
Note that the new way is more readable and uses fewer functions.
Matrix Inverse and Matrix Division ⌹ Definition: In the past, the functions denoted by ⌹ were limited to working with arguments whose rank was less than or equal to 2. The definition of Matrix Inverse is still based on inverting rank 2 arrays. But now, it can be applied to multiple matrices in a single operation, rather than by looping.
This example shows that the new Matrix Inverse function inverts the matrices along the last two axes of the argument. Since Matrix Division is defined in terms of Matrix Inverse ( ⍺⌹⍵ ≡ (⌹⍵)+.×⍺ ) its definition is extended in a similar manner. The rules for determining the argument and result shapes are given below. (The degenerate cases where 2>⍴⍴⍵ work as before and are not included in this table.)
Application: To solve several systems of equations which have different coefficients, but the same constants, try an expression like the following. constantvector⌹coeffmatrix1,[0.5] coeffmatrix2 To solve several systems of equations which have the same coefficients, but different constants, try an expression like the following. (constantvector1,[1.5] constantvector2)⌹coeffmatrix Examples: a←2 2 2⍴0 1 1 2 3 5 8 13 ⌹a ¯2 1 1 0 ¯13 5 8 ¯3 b←2 2⍴1 0 0 1 b⌹a ¯2 1 1 0 ¯13 5 8 ¯3 c←2 3 4⍴⍳24 c⌹a 11 10 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7 8 9 10 11 12 52 44 36 28 20 12 4 ¯4 ¯12 ¯20 ¯28 ¯36 ¯31 ¯26 ¯21 ¯16 ¯11 ¯6 ¯1 4 9 14 19 24 Acknowledgements: The following people contributed to this SATN: R. Bernecky, K.E. Iverson, E.E. McDonnell, R.C. Metzger, J.H. Schueler. Errata
First appeared as SHARP APL Technical Note 45,
Language Extensions of May 1983,
