Skip to content

Commit c32966c

Browse files
committed
improve support for dimension of vector domains
1 parent cd97bcf commit c32966c

11 files changed

+71
-92
lines changed

src/DomainSets.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export ..
5151
## Utils
5252

5353
# from util/common.jl
54-
export subeltype, dimension, prectype, numtype
54+
export prectype, numtype
5555
# from util/tensorproducts.jl
5656
export cartesianproduct
5757

@@ -82,6 +82,7 @@ export CartToPolarMap, PolarToCartMap
8282

8383
# from generic/domain.jl
8484
export Domain, EuclideanDomain, VectorDomain,
85+
dimension,
8586
approx_in,
8687
isclosed, iscompact,
8788
boundary, ∂,

src/domains/ball.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ The map `[cos(2πt), sin(2πt)]` from `[0,1)` to the unit circle in `ℝ^2`.
204204
"""
205205
struct UnitCircleMap{S,T} <: AbstractMap{S,T} end
206206

207-
parameterization(d::UnitCircle) = UnitCircleMap{subeltype(d),eltype(d)}()
207+
parameterization(d::UnitCircle) = UnitCircleMap{numtype(d),eltype(d)}()
208208

209209
domain(d::UnitCircleMap{S}) where {S} = Interval{:closed,:open,S}(0, 1)
210210

src/domains/point.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ boundary(d::Point) = d
3030

3131
point_in_domain(d::Point) = d.x
3232

33+
dimension(d::Point{Vector{T}}) where {T} = length(d.x)
34+
3335
for op in (:*,:+,:-)
3436
@eval begin
3537
$op(c::Number, d::Point) = Point($op(c,d.x))

src/generic/domain.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
# Definition of the abstract Domain type and its interface
22

33
eltype(::Type{<:Domain{T}}) where {T} = T
4-
subeltype(::Type{<:Domain{T}}) where {T} = subeltype(T)
54
prectype(::Type{<:Domain{T}}) where {T} = prectype(T)
65
numtype(::Type{<:Domain{T}}) where {T} = numtype(T)
7-
dimension(::Type{<:Domain{T}}) where {T} = dimension(T)
86

97
Domain(d) = convert(Domain, d)
108

119
"A `EuclideanDomain` is any domain whose eltype is `SVector{N,T}`."
1210
const EuclideanDomain{N,T} = Domain{SVector{N,T}}
1311

12+
"What is the Euclidean dimension of the domain?"
13+
dimension(::Domain{<:Number}) = 1
14+
dimension(::EuclideanDomain{N}) where {N} = N
15+
dimension(::Domain{<:NTuple{N,Any}}) where {N} = N
16+
1417
"""
1518
A `VectorDomain` is any domain whose eltype is `Vector{T}`. In this case
1619
the dimension of the domain is not included in its type.

src/generic/lazy.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ point_in_domain(d::LazyDomain) =
6969

7070
==(a::D, b::D) where {D<:LazyDomain} = elements(a) == elements(b)
7171

72+
73+
const LazyVectorDomain{T} = LazyDomain{Vector{T}}
74+
75+
function dimension(d::LazyVectorDomain)
76+
dim = dimension(element(d,1))
77+
@assert all(isequal(dim), map(dimension, elements(d)))
78+
dim
79+
end
80+
7281
"""
7382
Combine the outputs of `in` of member domains into a single output of the lazy
7483
domain.

src/generic/mapped_domain.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ elements(d::MappedDomain) = (source(d),)
3131
tointernalpoint(d::MappedDomain, x) = inverse_map(d) * x
3232
toexternalpoint(d::MappedDomain, y) = forward_map(d) * y
3333

34+
const MappedVectorDomain{D,T} = MappedDomain{D,Vector{T}}
35+
36+
# TODO: check whether the map alters the dimension
37+
dimension(d::MappedVectorDomain) = dimension(source(d))
38+
3439
# isopen(d::MappedDomain) = isopen(source(d))
3540
# isclosed(d::MappedDomain) = isclosed(source(d))
3641
#

src/generic/productdomain.jl

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,6 @@ function VcatDomain{N,T}(domains) where {N,T}
113113
VcatDomain{N,T,DIM,typeof(Tdomains)}(Tdomains)
114114
end
115115

116-
productdimension(d::VcatDomain{N}) where {N} = N
117-
118116
tointernalpoint(d::VcatDomain{N,T,DIM}, x) where {N,T,DIM} =
119117
convert_fromcartesian(x, Val{DIM}())
120118
toexternalpoint(d::VcatDomain{N,T,DIM}, y) where {N,T,DIM} =
@@ -148,12 +146,12 @@ function VectorProductDomain{T}(domains::Vector) where {T}
148146
VectorProductDomain{T,eltype(Tdomains)}(Tdomains)
149147
end
150148

151-
productdimension(d::VectorProductDomain) = numelements(d)
149+
dimension(d::VectorProductDomain) = numelements(d)
152150

153151
tointernalpoint(d::VectorProductDomain, x) =
154-
(@assert length(x) == productdimension(d); x)
152+
(@assert length(x) == dimension(d); x)
155153
toexternalpoint(d::VectorProductDomain, y) =
156-
(@assert length(y) == productdimension(d); y)
154+
(@assert length(y) == dimension(d); y)
157155

158156
infimum(d::ProductDomain) = toexternalpoint(d, map(infimum, elements(d)))
159157
supremum(d::ProductDomain) = toexternalpoint(d, map(supremum, elements(d)))
@@ -187,8 +185,6 @@ function TupleProductDomain{T}(domains) where {T<:Tuple}
187185
TupleProductDomain{T,typeof(Tdomains)}(Tdomains)
188186
end
189187

190-
productdimension(d::TupleProductDomain) = sum(map(dimension, elements(d)))
191-
192188
convert(::Type{Domain{T}}, d::TupleProductDomain{T}) where {T} = d
193189
convert(::Type{Domain{T}}, d::TupleProductDomain{S}) where {S,T} =
194190
TupleProductDomain{T}(elements(d))

src/util/common.jl

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,11 @@
11

22
##############################
3-
# Booleans in the type domain
3+
# Promotion helper functions
44
##############################
55

6-
# We introduce these types to compute with booleans in a type context.
7-
# They are not exported, but they are necessary when an external package wishes
8-
# to extend the embeddings and promotions of spaces in this package.
96
const True = Val{true}
107
const False = Val{false}
118

12-
# Simple boolean operations on the new types
13-
(|)(::Type{True}, ::Type{True}) = True
14-
(|)(::Type{True}, ::Type{False}) = True
15-
(|)(::Type{False}, ::Type{True}) = True
16-
(|)(::Type{False}, ::Type{False}) = False
17-
18-
# Return True if one of the arguments is True
19-
one_of(::Type{True}) = True
20-
one_of(::Type{False}) = False
21-
one_of(a::Type{Val{A}}, b::Type{Val{B}}) where {A,B} = |(one_of(a),one_of(b))
22-
one_of(a::Type{Val{A}}, b::Type{Val{B}}, c::Type{Val{C}}, d...) where {A,B,C} = one_of(a, one_of(b, c, d...))
23-
24-
# Convert the boolean type to a boolean value
25-
result(::Type{True}) = true
26-
result(::Type{False}) = false
27-
28-
29-
30-
##############################
31-
# Promotion helper functions
32-
##############################
33-
349
"Return True if S promotes to T, i.e., if promote_type(S,T) == T."
3510
promotes_to(S, T) = _promotes_to(S, T, promote_type(S,T))
3611
_promotes_to(::Type{S}, ::Type{T}, ::Type{T}) where {S,T} = True
@@ -105,25 +80,6 @@ const v = TypeFactory{SVector}()
10580

10681

10782

108-
###############
109-
# Subeltype
110-
###############
111-
112-
"Return the type of the elements of `x`."
113-
subeltype(x) = subeltype(typeof(x))
114-
subeltype(::Type{T}) where {T} = eltype(eltype(T))
115-
116-
###############
117-
# Dimension
118-
###############
119-
120-
dimension(x) = dimension(typeof(x))
121-
dimension(::Type{T}) where {T <: Number} = 1
122-
dimension(::Type{SVector{N,T}}) where {N,T} = N
123-
dimension(::Type{<:NTuple{N,Any}}) where {N} = N
124-
dimension(::Type{CartesianIndex{N}}) where {N} = N
125-
dimension(::Type{T}) where {T} = 1
126-
12783
#################
12884
# Precision type
12985
#################
@@ -136,8 +92,9 @@ prectype(::Type{NTuple{N,T}}) where {N,T} = prectype(T)
13692
prectype(::Type{Tuple{A}}) where {A} = prectype(A)
13793
prectype(::Type{Tuple{A,B}}) where {A,B} = prectype(A,B)
13894
prectype(::Type{Tuple{A,B,C}}) where {A,B,C} = prectype(A,B,C)
139-
prectype(::Type{Tuple{A,B,C,D}}) where {A,B,C,D} = prectype(A,B,C,D)
140-
prectype(T::Type{<:NTuple{N,Any}}) where {N} = prectype(map(prectype, T.parameters)...)
95+
@generated function prectype(T::Type{<:Tuple{Vararg}})
96+
quote $(promote_type(map(prectype, T.parameters[1].parameters)...)) end
97+
end
14198
prectype(::Type{T}) where {T<:AbstractFloat} = T
14299
prectype(::Type{T}) where {T} = prectype(float(T))
143100

@@ -148,10 +105,16 @@ prectype(a, b, c...) = prectype(prectype(a, b), c...)
148105
# Numeric type
149106
#################
150107

151-
"The numeric element type used in Euclidean spaces."
108+
"The numeric element type of x in a Euclidean space."
152109
numtype(x) = numtype(typeof(x))
153110
numtype(::Type{T}) where {T<:Number} = T
154111
numtype(::Type{T}) where {T} = eltype(T)
155-
numtype(T::Type{<:NTuple{N,Any}}) where {N} = promote_type(map(numtype, T.parameters)...)
112+
numtype(::Type{NTuple{N,T}}) where {N,T} = T
113+
numtype(::Type{Tuple{A,B}}) where {A,B} = promote_type(numtype(A), numtype(B))
114+
numtype(::Type{Tuple{A,B,C}}) where {A,B,C} = promote_type(numtype(A), numtype(B), numtype(C))
115+
numtype(::Type{Tuple{A,B,C,D}}) where {A,B,C,D} = promote_type(numtype(A), numtype(B), numtype(C), numtype(D))
116+
@generated function numtype(T::Type{<:Tuple{Vararg}})
117+
quote $(promote_type(T.parameters[1].parameters...)) end
118+
end
156119

157120
numtype(a...) = promote_type(map(numtype, a)...)

test/test_common.jl

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,34 @@
11

2-
function test_subeltype()
3-
@test subeltype([1,2,3]) == Int
4-
@test subeltype(([1,2,3], [4,5,6])) == Int
5-
@test subeltype(Array{Float64,2}) == Float64
6-
@test subeltype(Array{Array{BigFloat,1},2}) == BigFloat
7-
end
8-
9-
function test_dimension()
10-
@test dimension(Int) == 1
11-
@test dimension(SVector(1,2)) == 2
12-
@test dimension(SVector{2,Float64}) == 2
13-
@test dimension((1,2)) == 2
14-
@test dimension((1,2,3,4,5)) == 5
15-
@test dimension(Tuple{Int,Int,Float64,Float64,BigFloat}) == 5
16-
@test dimension((1,2,3,4,5)) == 5
17-
@test dimension(CartesianIndex(1,2)) == 2
18-
end
19-
20-
const SystemFloat = typeof(1.0)
21-
222
function test_prectype()
23-
@test prectype(1.0) == SystemFloat
3+
@test prectype(1.0) == Float64
244
@test prectype(big(1.0)) == BigFloat
255
@test prectype(1) == typeof(float(1))
266
@test prectype(SVector(1,2)) == typeof(float(1))
277
@test prectype(SVector(1,big(2))) == typeof(float(big(2)))
28-
@test prectype(1.0+2.0im) == SystemFloat
29-
@test prectype([1.0+2.0im, 3.0]) == SystemFloat
30-
@test prectype((1.0, 2.0, 3.0)) == SystemFloat
8+
@test prectype(1.0+2.0im) == Float64
9+
@test prectype([1.0+2.0im, 3.0]) == Float64
10+
@test prectype((1.0, 2.0, 3.0)) == Float64
3111
@test prectype((1.0, big(2.0), 3.0+im)) == BigFloat
12+
@test @inferred(prectype(1, 2.0)) == Float64
13+
@test @inferred(prectype((1, 2.0, 3, 40+im))) == Float64
3214
end
3315

3416
function test_numtype()
35-
@test numtype(1.0) == SystemFloat
17+
@test numtype(1.0) == Float64
3618
@test numtype(big(1.0)) == BigFloat
3719
@test numtype(1) == Int
20+
@test numtype([1,2,3], [4,5,6]) == Int
3821
@test numtype(SVector(1,2)) == Int
3922
@test numtype(SVector(1,big(2))) == BigInt
40-
@test numtype(1.0+2.0im) == Complex{SystemFloat}
41-
@test numtype([1.0+2.0im, 3.0]) == Complex{SystemFloat}
42-
@test numtype((1.0, 2.0, 3.0)) == SystemFloat
23+
@test numtype(Array{Float64,2}) == Float64
24+
@test numtype(1.0+2.0im) == Complex{Float64}
25+
@test numtype([1.0+2.0im, 3.0]) == Complex{Float64}
26+
@test numtype((1.0, 2.0, 3.0)) == Float64
4327
@test numtype(1.0, big(2.0), 3.0+im) == Complex{BigFloat}
4428
@test numtype((1.0, big(2.0), 3.0+im)) == Complex{BigFloat}
29+
@test @inferred(numtype(1, 2.0)) == Float64
30+
@test @inferred(numtype((1, 2.0, 3, 40+im))) == Complex{Float64}
4531
end
4632

47-
test_subeltype()
48-
test_dimension()
4933
test_prectype()
5034
test_numtype()

test/test_generic_domain.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ widen_eltype(::Type{Vector{T}}) where {T<:Number} = Vector{widen(T)}
88
# These tests check whether the given domain correctly implements the
99
# interface of a domain.
1010
function test_generic_domain(d::Domain)
11-
@test eltype(eltype(d)) == subeltype(d)
12-
@test isreal(d) == isreal(subeltype(d))
11+
@test isreal(d) == isreal(eltype(d))
12+
@test isreal(d) == isreal(numtype(d))
1313

1414
if !isempty(d)
1515
x = point_in_domain(d)

test/test_specific_domains.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ end
102102

103103
@test convert(Domain{Float64}, Point(1)) Point(1.0)
104104
@test Number(Point(1)) convert(Number, Point(1)) convert(Int, Point(1)) 1
105+
106+
@test dimension(Point([1,2,3]))==3
105107
end
106108

107109
@testset "intervals" begin
@@ -683,6 +685,9 @@ end
683685
D = rotate((-1.5.. 2.2) × (0.5 .. 0.7) × (-3.0 .. -1.0), π, π, π, v[.35, .65, -2.])
684686
@test v[0.9, 0.6, -2.5] D
685687
@test v[0.0, 0.6, 0.0] D
688+
689+
B = 2VectorUnitBall(10)
690+
@test dimension(B) == 10
686691
end
687692

688693
@testset "simplex" begin
@@ -872,6 +877,7 @@ end
872877
d1 = ProductDomain([0..1.0, 0..2.0])
873878
@test d1 isa VectorDomain{Float64}
874879
@test d1.domains isa Vector
880+
@test dimension(d1) == 2
875881
@test [0.1,0.2] d1
876882
@test v[0.1,0.2] d1
877883
@test point_in_domain(d1) d1
@@ -881,12 +887,14 @@ end
881887

882888
# Test an integer type as well
883889
d2 = ProductDomain([0..1, 0..2])
890+
@test dimension(d2) == 2
884891
@test [0.1,0.2] d2
885892
@test point_in_domain(d2) d2
886893

887894
bnd = boundary(d1)
888895
@test bnd isa VectorDomain
889896
@test bnd isa UnionDomain
897+
@test dimension(bnd) == 2
890898
@test [0.0, 0.5] bnd
891899
@test [1.0, 0.5] bnd
892900
@test [0.2, 0.0] bnd
@@ -899,6 +907,7 @@ end
899907
@test d1 isa TupleProductDomain
900908
@test d1.domains isa Tuple
901909
@test eltype(d1) == Tuple{Float64,Float64}
910+
@test dimension(d1) == 2
902911
@test (0.2,0.6) d1
903912
@test (0.2,0.8) d1
904913
@test (true,0.6) d1
@@ -913,13 +922,15 @@ end
913922
d2 = ProductDomain([true,false], 0..1)
914923
@test d2 isa TupleProductDomain
915924
@test d2.domains isa Tuple
925+
@test dimension(d2) == 2
916926
@test eltype(d2) == Tuple{Bool,Int}
917927
@test (true,0.4) d2
918928
@test (false,1.5) d2
919929

920930
bnd = boundary(d1)
921931
@test eltype(bnd) == Tuple{Float64,Float64}
922932
@test bnd isa UnionDomain
933+
@test dimension(bnd) == 2
923934
@test (0.0, 0.5) bnd
924935
@test (0.5, 0.5) bnd
925936
@test (0.3, 0.2) bnd
@@ -942,6 +953,8 @@ end
942953

943954
u1 = d1 d2
944955
u2 = u1 d3
956+
@test dimension(u1) == 2
957+
@test dimension(u2) == 2
945958

946959
u3 = d3 u1
947960
u4 = u1 u2
@@ -997,6 +1010,8 @@ end
9971010
i2 = d1 & d2
9981011
show(io,i2)
9991012
@test String(take!(io)) == "the intersection of 2 domains:\n\t1.\t: the 2-dimensional closed unit ball\n\t2.\t: -0.4..0.4 x -0.4..0.4\n"
1013+
@test dimension(i1) == 2
1014+
@test dimension(i2) == 2
10001015

10011016
i3 = d3 & i2
10021017
i4 = i2 & d3
@@ -1027,6 +1042,7 @@ end
10271042
d = d1\d2
10281043
show(io,d)
10291044
@test String(take!(io)) == "the difference of 2 domains:\n\t1.\t: the 2-dimensional closed unit ball\n\t2.\t: -0.5..0.5 x -0.1..0.1\n"
1045+
@test dimension(d) == 2
10301046

10311047
x = SVector(0.,.74)
10321048
y = SVector(0.,.25)

0 commit comments

Comments
 (0)