|
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
|