1+ export Tiling, encode
2+
3+ import Base: length, -
4+
5+ """
6+ Tiling(ranges::NTuple{N, Tr}) where {N, Tr}
7+ Using a tuple of `ranges` to simulate a tiling.
8+ The length of `ranges` indicates the dimension of tilling.
9+ # Example
10+ ```julia
11+ julia> t = Tiling((1:2:5, 10:5:20))
12+ Tiling{2,StepRange{Int64,Int64}}((1:2:5, 10:5:20), [1 3; 2 4])
13+ julia> encode(t, (2, 12)) # encode into an Int
14+ 1
15+ julia> encode(t, (2, 18))
16+ 3
17+ julia> t2 = t - (1, 3) # shift a little to get a new Tiling
18+ Tiling{2,StepRange{Int64,Int64}}((0:2:4, 7:5:17), [1 3; 2 4])
19+ ```
20+ """
21+ struct Tiling{N,Tr<: AbstractRange }
22+ ranges:: NTuple{N,Tr}
23+ inds:: LinearIndices{N,NTuple{N,Base.OneTo{Int}}}
24+ Tiling (ranges:: NTuple{N,Tr} ) where {N,Tr} =
25+ new {N,Tr} (ranges, LinearIndices (Tuple (length (r) - 1 for r in ranges)))
26+ end
27+
28+ """
29+ (-)(t::Tiling, xs)
30+ Shift `t` along each dimension by each element in `xs`.
31+ """
32+ function Base.:- (t:: Tiling , xs)
33+ Tiling (Tuple (r .- x for (r, x) in zip (t. ranges, xs)))
34+ end
35+
36+ Base. length (t:: Tiling ) = reduce (* , (length (r) - 1 for r in t. ranges))
37+
38+ encode (range:: AbstractRange , x) = floor (Int, div (x - range[1 ], step (range)) + 1 )
39+
40+
41+ # TODO : use @generator here!
42+ encode (t:: Tiling{1} , x:: Number ) = encode (t. ranges[1 ], x)
43+ encode (t:: Tiling{1} , xs) = encode (t. ranges[1 ], xs[1 ])
44+ encode (t:: Tiling{2} , xs) =
45+ t. inds[CartesianIndex (encode (t. ranges[1 ], xs[1 ]), encode (t. ranges[2 ], xs[2 ]))]
46+ encode (t:: Tiling{3} , xs) =
47+ t. inds[CartesianIndex (
48+ encode (t. ranges[1 ], xs[1 ]),
49+ encode (t. ranges[2 ], xs[2 ]),
50+ encode (t. ranges[3 ], xs[3 ]),
51+ )]
0 commit comments