comparison RegionIndices/src/RegionIndices.jl @ 214:08b07c6eeec7 package_refactor

Move index.jl to its own package
author Jonatan Werpers <jonatan@werpers.com>
date Wed, 26 Jun 2019 11:10:12 +0200
parents index.jl@9fc9167e9a4c
children 03375aa30edd
comparison
equal deleted inserted replaced
213:0bf761485f40 214:08b07c6eeec7
1 module RegionIndices
2
3 abstract type Region end
4 struct Interior <: Region end
5 struct Lower <: Region end
6 struct Upper <: Region end
7 struct Unknown <: Region end
8
9 struct Index{R<:Region, T<:Integer}
10 i::T
11
12 Index{R,T}(i::T) where {R<:Region,T<:Integer} = new{R,T}(i)
13 Index{R}(i::T) where {R<:Region,T<:Integer} = new{R,T}(i)
14 Index(i::T, ::Type{R}) where {R<:Region,T<:Integer} = Index{R,T}(i)
15 Index(t::Tuple{T, DataType}) where {R<:Region,T<:Integer} = Index{t[2],T}(t[1]) # TBD: This is not very specific in what types are allowed in t[2]. Can this be fixed?
16 end
17
18 # Index(R::Type{<:Region}) = Index{R}
19
20 ## Vill kunna skriva
21 ## IndexTupleType(Int, (Lower, Interior))
22 Index(R::Type{<:Region}, T::Type{<:Integer}) = Index{R,T}
23 IndexTupleType(T::Type{<:Integer},R::NTuple{N, DataType} where N) = Tuple{Index.(R, T)...}
24
25 Base.convert(::Type{T}, i::Index{R,T} where R) where T = i.i
26 Base.convert(::Type{CartesianIndex}, I::NTuple{N,Index} where N) = CartesianIndex(convert.(Int, I))
27
28 Base.Int(I::Index) = I.i
29
30 function Index(i::Integer, boundary_width::Integer, dim_size::Integer)
31 return Index{getregion(i,boundary_width,dim_size)}(i)
32 end
33
34 IndexTuple(t::Vararg{Tuple{T, DataType}}) where T<:Integer = Index.(t)
35
36 # TODO: Use the values of the region structs, e.g. Lower(), for the region parameter instead of the types.
37 # For example the following works:
38 # (Lower(),Upper()) isa NTuple{2, Region} -> true
39 # typeof((Lower(),Upper())) -> Tuple{Lower,Upper}
40 function regionindices(gridsize::NTuple{Dim,Integer}, closuresize::Integer, region::NTuple{Dim,DataType}) where Dim
41 return regionindices(gridsize, ntuple(x->closuresize,Dim), region)
42 end
43
44 function regionindices(gridsize::NTuple{Dim,Integer}, closuresize::NTuple{Dim,Integer}, region::NTuple{Dim,DataType}) where Dim
45 regions = map(getrange,gridsize,closuresize,region)
46 return CartesianIndices(regions)
47 end
48
49 function getregion(i::Integer, boundary_width::Integer, dim_size::Integer)
50 if 0 < i <= boundary_width
51 return Lower
52 elseif boundary_width < i <= dim_size-boundary_width
53 return Interior
54 elseif dim_size-boundary_width < i <= dim_size
55 return Upper
56 else
57 error("Bounds error") # TODO: Make this more standard
58 end
59 end
60
61 function getrange(gridsize::Integer, closuresize::Integer, region::DataType)
62 if region == Lower
63 r = 1:closuresize
64 elseif region == Interior
65 r = (closuresize+1):(gridsize - closuresize)
66 elseif region == Upper
67 r = (gridsize - closuresize + 1):gridsize
68 else
69 error("Unspecified region")
70 end
71 return r
72 end
73
74 end # module