Tile Operator Based on the cut operator.
The computation is sometimes referred to as tessellation, moving window, or
stencil
code.
0. Desiderata
1. Definition Dyadic operator: ⍺⍺ T ⍵⍵ ⊢⍵ The left operand function ⍺⍺ is applied to (possibly overlapping) tiles. In general, the right operand ⍵⍵ is a 2-row integer matrix with up to ⍴⍴⍵ columns. The first row are the tile sizes; the second row are the “movements”, how much to move the tile in each step. The columns of ⍵⍵ apply independently to the axes of ⍵ . If ⍵⍵ has fewer columns than the rank of ⍵ then it applies to the leading axes. A scalar or vector ⍵⍵ is treated as ⍉(⍪⍵⍵),1 (as if the movements are 1). If s is a tile size then ⍵ behaves as if padded with ⌊(s-1)÷2 fill elements. ⍺⍺ is invoked dyadically with a vector left argument indicating for each axis the number of fill elements and on what side. When the movement is 1, each element of ⍵ in its turn is the middle of a tile. The predominant cases are a tile size which is odd and a movement of 1. This text is composed with ⎕io←1 .
The tile operator works in either index-origin.
2. Examples 2.1 Common Case: Odd Size and Movement = 1 ⎕←s←{⊂⍵}T 3 ⍳8 ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │0 1 2│1 2 3│2 3 4│3 4 5│4 5 6│5 6 7│6 7 8│7 8 0│ └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ ⍴s 8 {(¯2↑⍕⍺),' f ',⍕⍵}T 3 ⍳8 1 f 0 1 2 0 f 1 2 3 0 f 2 3 4 0 f 3 4 5 0 f 4 5 6 0 f 5 6 7 0 f 6 7 8 ¯1 f 7 8 0 ⍝ ↑ middle {⊂⍺⍵}T 5 ⍳6 ┌─────────────┬─────────────┬─────────────┬─────────────┬─ │┌─┬─────────┐│┌─┬─────────┐│┌─┬─────────┐│┌─┬─────────┐│ ││2│0 0 1 2 3│││1│0 1 2 3 4│││0│1 2 3 4 5│││0│2 3 4 5 6││... │└─┴─────────┘│└─┴─────────┘│└─┴─────────┘│└─┴─────────┘│ └─────────────┴─────────────┴─────────────┴─────────────┴─ ─┬─────────────┬──────────────┬──────────────┐ │┌─┬─────────┐│┌──┬─────────┐│┌──┬─────────┐│ ... ││0│3 4 5 6 7│││¯1│4 5 6 7 0│││¯2│5 6 7 0 0││ │└─┴─────────┘│└──┴─────────┘│└──┴─────────┘│ ─┴─────────────┴──────────────┴──────────────┘ {(¯2↑⍕⍺),' f ',⍕⍵}T 5 ⍳6 2 f 0 0 1 2 3 1 f 0 1 2 3 4 0 f 1 2 3 4 5 0 f 2 3 4 5 6 ¯1 f 3 4 5 6 0 ¯2 f 4 5 6 0 0 In contrast to the cut operator, the tile operator:
{⊂⍺⍵}T 3 5 ⊢4 6⍴⍳24 ![]() {⍵[2;3]}T 3 5 ⊢4 6⍴⍳24 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 dot←{('.',⎕a)[(' ',⎕a)⍳⍵]} {⊂(2 0 3 0⍕⍺)(dot ⍵)}T 3 5 ⊢ 4 6⍴⎕a ![]() {⍵[2;3]}T 3 5 ⊢ 4 6⍴⎕a ABCDEF GHIJKL MNOPQR STUVWX 2.2 Even Size For even tile sizes, the “middle” consists of two elements which are moved according to the movement parameter (equal to 1 in these examples). ⎕←s←{⊂⍵}T 2 ⍳8 ┌───┬───┬───┬───┬───┬───┬───┐ │1 2│2 3│3 4│4 5│5 6│6 7│7 8│ └───┴───┴───┴───┴───┴───┴───┘ ⍴s 7 {(¯2↑⍕⍺),' f ',⍕⍵}T 2 ⍳8 0 f 1 2 0 f 2 3 0 f 3 4 0 f 4 5 0 f 5 6 0 f 6 7 0 f 7 8 ⍝ ↑ ↑ middle ⎕←s←{⊂⍵}T 4 ⍳8 ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┐ │0 1 2 3│1 2 3 4│2 3 4 5│3 4 5 6│4 5 6 7│5 6 7 8│6 7 8 0│ └───────┴───────┴───────┴───────┴───────┴───────┴───────┘ ⍴s 7 {(¯2↑⍕⍺),' f ',⍕⍵}T 4 ⍳8 1 f 0 1 2 3 0 f 1 2 3 4 0 f 2 3 4 5 0 f 3 4 5 6 0 f 4 5 6 7 0 f 5 6 7 8 ¯1 f 6 7 8 0 ⍝ ↑ ↑ middle ⎕←s←{⊂⍵}T 6 ⍳8 ┌───────────┬───────────┬───────────┬───────────┬─ │0 0 2 3 4 5│0 2 3 4 5 6│2 3 4 5 6 7│3 4 5 6 7 8│... └───────────┴───────────┴───────────┴───────────┴─ ─┬───────────┬───────────┬───────────┐ ... │4 5 6 7 8 9│5 6 7 8 9 0│6 7 8 9 0 0│ ─┴───────────┴───────────┴───────────┘ ⍴s 7 {(¯2↑⍕⍺),' f ',⍕⍵}T 6 ⍳8 2 f 0 0 1 2 3 4 1 f 0 1 2 3 4 5 0 f 1 2 3 4 5 6 0 f 2 3 4 5 6 7 0 f 3 4 5 6 7 8 ¯1 f 4 5 6 7 8 0 ¯2 f 5 6 7 8 0 0 ⍝ ↑ ↑ middle 2.3 Movement ≠ 1 {⊂⍵}T(⍪3 2) ⍳8 ┌─────┬─────┬─────┬─────┐ │0 1 2│2 3 4│4 5 6│6 7 8│ └─────┴─────┴─────┴─────┘ {(¯2↑⍕⍺),' f ',⍕⍵}T(⍪3 2) ⍳8 1 f 0 1 2 0 f 2 3 4 0 f 4 5 6 0 f 6 7 8 ⍝ ↑ middle {⊂⍵}T(⍪5 2) ⍳8 ┌─────────┬─────────┬─────────┬─────────┐ │0 0 1 2 3│1 2 3 4 5│3 4 5 6 7│5 6 7 8 0│ └─────────┴─────────┴─────────┴─────────┘ {(¯2↑⍕⍺),' f ',⍕⍵}T(⍪5 2) ⍳8 2 f 0 0 1 2 3 0 f 1 2 3 4 5 0 f 3 4 5 6 7 ¯1 f 5 6 7 8 0 ⍝ ↑ middle The last results are not symmetric with respect to the shards, but that is a “fault” of the right argument. A symmetric result obtains from a right argument with an appropriate length. {⊂⍵}T(⍪5 2) ⍳9 ┌─────────┬─────────┬─────────┬─────────┬─────────┐ │0 0 1 2 3│1 2 3 4 5│3 4 5 6 7│5 6 7 8 9│7 8 9 0 0│ └─────────┴─────────┴─────────┴─────────┴─────────┘ {(¯2↑⍕⍺),' f ',⍕⍵}T(⍪5 2) ⍳9 2 f 0 0 1 2 3 0 f 1 2 3 4 5 0 f 3 4 5 6 7 0 f 5 6 7 8 9 ¯2 f 7 8 9 0 0 ⍝ ↑ middle 2.4 Even Size and Movement ≠ 1 {⊂⍵}T(⍪4 2) ⍳8 ┌───────┬───────┬───────┬───────┐ │0 1 2 3│2 3 4 5│4 5 6 7│6 7 8 0│ └───────┴───────┴───────┴───────┘ {(¯2↑⍕⍺),' f ',⍕⍵}T(⍪4 2) ⍳8 1 f 0 1 2 3 0 f 2 3 4 5 0 f 4 5 6 7 ¯1 f 6 7 8 0 ⍝ ↑ ↑ middle {⊂⍵}T(⍪6 2) ⍳8 ┌───────────┬───────────┬───────────┬───────────┐ │0 0 1 2 3 4│1 2 3 4 5 6│3 4 5 6 7 8│5 6 7 8 0 0│ └───────────┴───────────┴───────────┴───────────┘ {(⍕⍺),' f ',⍕⍵}T(⍪6 2) ⍳8 2 f 0 0 1 2 3 4 0 f 1 2 3 4 5 6 0 f 3 4 5 6 7 8 ¯2 f 5 6 7 8 0 0 ⍝ ↑ ↑ middle {⊂⍵}T(⍪5 4) ⍳16 ┌─────────┬─────────┬───────────┬──────────────┐ │0 0 1 2 3│3 4 5 6 7│7 8 9 10 11│11 12 13 14 15│ └─────────┴─────────┴───────────┴──────────────┘ {(¯2↑⍕⍺),' f',3 0⍕⍵}T(⍪5 4) ⍳16 2 f 0 0 1 2 3 0 f 3 4 5 6 7 0 f 7 8 9 10 11 0 f 11 12 13 14 15 ⍝ ↑ middle {⊂⍵}T(⍪5 4) ⍳17 ┌─────────┬─────────┬───────────┬──────────────┬────────────┐ │0 0 1 2 3│3 4 5 6 7│7 8 9 10 11│11 12 13 14 15│15 16 17 0 0│ └─────────┴─────────┴───────────┴──────────────┴────────────┘ {(¯2↑⍕⍺),' f',3 0⍕⍵}T(⍪5 4) ⍳17 2 f 0 0 1 2 3 0 f 3 4 5 6 7 0 f 7 8 9 10 11 0 f 11 12 13 14 15 ¯2 f 15 16 17 0 0 ⍝ ↑ middle 3. Model assert←{⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕SIGNAL 8 ⋄ shy←0} T←{ (⍺⍺{f←⍺⍺ ⋄ (3.2=⎕nc⊂,'f')>'⍺'∊⎕cr'f'}⍬)⍺⍺{⍺ ⍺⍺ ⍵}{ ⎕io←0 ⍝ ⎕io delenda est assert 0<⍴⍴⍵: assert 2≥⍴⍴⍵⍵: assert(2>⍴⍴⍵⍵)∨2=≢⍵⍵: assert 0<⍵⍵: assert ⍵⍵≡⌊⍵⍵: (s m)←↓(⍉1,⍨⍪)⍣(2>≢⍴⍵⍵)⊢⍵⍵ ⍝ size and movement assert(≢s)≤⍴⍴⍵: assert s≤(≢s)↑⍴⍵: ws←(≢s)↑⍴⍵ n←⌈m÷⍨ws-~2|s j←⊃∘.,/⊂⍤0¨↓¨(m×⍳¨n)∘.+¨⍳¨s ⍝ indices for each cell c←⌊2÷⍨s-1 y←(ws+2×c)↑(-ws+c)↑⍵ ⍝ argument padded with fills ⍺:↑⍺⍺{⍬ ⍺⍺ ⍵⌷y}¨j ⍝ left arg ⍬ if ⍺⍺ is a dfn ... d←0⌈((m×n-1)+s-1)-ws+c-1 ⍝ ... and ⍺ does not occur in it p←0~⍨¨0⌈c- m×⍳¨c ⍝ # pad elements on the left q←0~⍨¨0⌊d-⍨⌽¨m×⍳¨d ⍝ # pad elements on the right i←,¨⍣(1=≢⍴⍵)⊃∘.,/p,¨((n-(≢¨p)+≢¨q)⍴¨0),¨q ↑i ⍺⍺{⍺ ⍺⍺ ⍵⌷y}¨j }⍵⍵⊢⍵ } 3.1 Tests z←test_tile io;⎕io;f;g;h;i;x ⍝ tests on the tile operator ⎕io←io x←1+?17⍴100 f←{⎕io←0 ⋄ ↓(c,⍵,c←(⌊⍺÷2)⍴0)[(⍳≢⍵)∘.+⍳⍺]} h←{i←⎕io+⌊⍺÷2 ⋄ ⍵≡{⍵[i]}T ⍺⊢⍵} assert 1 3 5 7 9 h⍤0 1⊢x h←{(⍺ f ⍵)≡⍺⍺ T ⍺⊢⍵} assert 1 3 5 7 9{⊂⍵}h⍤0 1⊢x h←{(↑⍺ f ⍵)≡⍺⍺ T ⍺⊢⍵} assert 1 3 5 7 9{⍵}h⍤0 1⊢x assert 1 3 5 7 9⊢h⍤0 1⊢x g←{,¨(⌽i),(0⍴⍨(≢⍵)-2×≢i),-i←(⍳⌊⍺÷2)+~⎕io} h←{(⍺(g,(⍪f))⍵)≡⍺⍺ T ⍺⊢⍵} assert 1 3 5 7 9{⍺ ⍵}h⍤0 1⊢x assert 1 3 5 7 9((⊂⊣),(⊂⊢))h⍤0 1⊢x f←{t←k↓(-k←0,⌊2÷⍨⍺-1)↓⊢T ⍺⊢⍵ ⋄ 1=2|⍺:t≡⍪⍵ ⋄ t≡(¯1↓⍵),⍪1↓⍵} assert 1 2 3 4 5 6 7 8 f⍤0 1⊢x f←{∧/,(0=¯1↓t)∨(0=1↓t)∨(⊃⌽⍺)=-2-⌿t←{⍵}T(⍪⍺)⊢⍵} assert(↑1 2 3 4 5 6 7 8∘.,2 3 4)f⍤1⊢1+⍳≢x f←{ t←{⍺ ⍵}T(⍪⍺)⊢⍵ i←,↑t[;⎕io] ⋄ y←t[;1+⎕io] ((⍒i)≡⍳≢i)∧∧/∧/¨0=i↑¨y } assert(↑1 2 3 4 5 6 7 8∘.,2 3 4)f⍤1⊢x x←?12 17 5 7⍴100 assert(⍴x)≡⍴{⊂⍵}T 3 7 5 3⊢x assert x≡{⍵[1+⎕io;3+⎕io;2+⎕io;1+⎕io]}T 3 7 5 3⊢x z←1⊣2 ⎕nq'.' 'wscheck' 4. Symbol ⊞ (Unicode 0x229E) is a possible symbol for the tile operator.
5. Optimizations
|