4,509
edits
No edit summary |
|||
(3 intermediate revisions by 3 users not shown) | |||
Line 3: | Line 3: | ||
== Description == | == Description == | ||
For a call <source lang=apl inline>f⌺s</source> the right operand <source lang=apl inline>s</source> can in general be a two-row [[matrix]] of strictly positive integers, where the first row describes the dimensions of the rectangles that will be passed to <source lang=apl inline>f</source> and the second row describes the movement along the different [[axis|axes]]. When using stencil <source lang=apl inline>(f⌺s)Y</source> the right operand <source lang=apl inline>s</source> in general has <source lang=apl inline>≢⍴Y</source> columns. If it has fewer, the rectangles are cut out of the [[major cell]]s of the <source lang=apl inline>(≢⍴Y) - ≢1⌷s</source> axis of <source lang=apl inline>Y</source>. If <source lang=apl inline>s</source> is a vector or scalar it describes only the size of the rectangles and the movement defaults to 1. Rectangles are centred on [[element]]s of <source lang=apl inline>Y</source> whose [[index|indices]] differ by the movements in <source lang=apl inline>s</source> (defaulting to 1), starting with the first element in [[ravel order]]. For a matrix, this is the top left. For even window sizes, the centring is instead on the space between elements or [[cell]]s. Along the edges of the [[argument]] array, the windows are thus subject to be padded with [[fill element]]s. The number of fill elements in along each axis is given as a vector left argument on each call of <source lang=apl inline>f</source> for the respective [[subarray]]. | For a call <source lang=apl inline>f⌺s</source> the right operand <source lang=apl inline>s</source> can in general be a two-row [[matrix]] of strictly positive integers, where the first row describes the dimensions of the rectangles that will be passed to <source lang=apl inline>f</source> and the second row describes the movement along the different [[axis|axes]]. When using stencil <source lang=apl inline>(f⌺s)Y</source> the right operand <source lang=apl inline>s</source> in general has <source lang=apl inline>≢⍴Y</source> columns. If it has fewer, the rectangles are cut out of the [[major cell]]s of the <source lang=apl inline>(≢⍴Y) - ≢1⌷s</source> axis of <source lang=apl inline>Y</source>. If <source lang=apl inline>s</source> is a vector or scalar it describes only the size of the rectangles and the movement defaults to 1. Rectangles are centred on [[element]]s of <source lang=apl inline>Y</source> whose [[index|indices]] differ by the movements in <source lang=apl inline>s</source> (defaulting to 1), starting with the first element in [[ravel order]]. For a matrix, this is the top left. For even window sizes, the centring is instead on the space between elements or [[cell]]s. Along the edges of the [[argument]] array, the windows are thus subject to be padded with [[fill element]]s. | ||
The number of fill elements in along each axis is given as a vector left argument on each call of <source lang=apl inline>f</source> for the respective [[subarray]]. This is designed such that [[Drop]] (<source lang=apl inline>↓</source>) can take the left and right arguments to remove padding: | |||
<source lang=apl> | |||
({⊂⍵}⌺3 3)3 4⍴⍳12 | |||
┌──────┬───────┬────────┬───────┐ | |||
│0 0 0 │0 0 0 │0 0 0 │0 0 0 │ | |||
│0 1 2 │1 2 3 │2 3 4 │3 4 0 │ | |||
│0 5 6 │5 6 7 │6 7 8 │7 8 0 │ | |||
├──────┼───────┼────────┼───────┤ | |||
│0 1 2│1 2 3│ 2 3 4│ 3 4 0│ | |||
│0 5 6│5 6 7│ 6 7 8│ 7 8 0│ | |||
│0 9 10│9 10 11│10 11 12│11 12 0│ | |||
├──────┼───────┼────────┼───────┤ | |||
│0 5 6│5 6 7│ 6 7 8│ 7 8 0│ | |||
│0 9 10│9 10 11│10 11 12│11 12 0│ | |||
│0 0 0│0 0 0│ 0 0 0│ 0 0 0│ | |||
└──────┴───────┴────────┴───────┘ | |||
({⊂⍺}⌺3 3)3 4⍴⍳12 | |||
┌────┬────┬────┬─────┐ | |||
│1 1 │1 0 │1 0 │1 ¯1 │ | |||
├────┼────┼────┼─────┤ | |||
│0 1 │0 0 │0 0 │0 ¯1 │ | |||
├────┼────┼────┼─────┤ | |||
│¯1 1│¯1 0│¯1 0│¯1 ¯1│ | |||
└────┴────┴────┴─────┘ | |||
({⊂⍺↓⍵}⌺3 3)3 4⍴⍳12 | |||
┌────┬───────┬────────┬─────┐ | |||
│1 2 │1 2 3 │2 3 4 │3 4 │ | |||
│5 6 │5 6 7 │6 7 8 │7 8 │ | |||
├────┼───────┼────────┼─────┤ | |||
│1 2│1 2 3│ 2 3 4│ 3 4│ | |||
│5 6│5 6 7│ 6 7 8│ 7 8│ | |||
│9 10│9 10 11│10 11 12│11 12│ | |||
├────┼───────┼────────┼─────┤ | |||
│5 6│5 6 7│ 6 7 8│ 7 8│ | |||
│9 10│9 10 11│10 11 12│11 12│ | |||
└────┴───────┴────────┴─────┘ | |||
</source> | |||
== Examples == | == Examples == | ||
Line 26: | Line 64: | ||
In the following example, each neighbourhood is immediately [[ravel]]led and [[sum]]med: | In the following example, each neighbourhood is immediately [[ravel]]led and [[sum]]med: | ||
<source lang=apl> | <source lang=apl> | ||
{+/,⍵}⌺3 3⊢3 3⍴⍳9 | {+/,⍵}⌺3 3⊢3 3⍴⍳9 | ||
12 21 16 27 45 33 24 39 28 | 12 21 16 27 45 33 24 39 28 | ||
</source> | </source> | ||
Line 42: | Line 80: | ||
life ← {3=s-⍵∧4=s←{+/,⍵}⌺3 3⊢⍵} | life ← {3=s-⍵∧4=s←{+/,⍵}⌺3 3⊢⍵} | ||
{'.⍠'[⍵]}¨ (⍳8) {life⍣⍺⊢⍵}¨ ⊂glider | {'.⍠'[⍵]}¨ (⍳8) {life⍣⍺⊢⍵}¨ ⊂glider | ||
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ | ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ | ||
│..⍠..│.⍠...│..⍠..│.....│.....│.....│.....│.....│ | │..⍠..│.⍠...│..⍠..│.....│.....│.....│.....│.....│ | ||
Line 61: | Line 99: | ||
=== Publications === | === Publications === | ||
* [[Dyalog '16]] presentation by [[Roger Hui]]: [https://www.dyalog.com/user-meetings/dyalog16.htm#D06 New Primitive Functions and Operators] | * [[Dyalog '16]] presentation by [[Roger Hui]]: [https://www.dyalog.com/user-meetings/dyalog16.htm#D06 New Primitive Functions and Operators] | ||
* [[Dyalog Ltd.|Dyalog]] blog | * [[Dyalog Ltd.|Dyalog]] blog posts by Roger Hui: [https://www.dyalog.com/blog/2017/07/stencil-lives/ Stencil Lives], [https://www.dyalog.com/blog/2020/06/towards-improvements-to-stencil/ Towards Improvements to ''Stencil''] | ||
== References == | == References == | ||
<references/> | <references/> | ||
{{APL built-ins}}[[Category:Primitive operators]] | {{APL built-ins}}[[Category:Primitive operators]] |