Skip to content

Commit 612e8e5

Browse files
authored
Simplify union for spaces (#139)
* Simplify union for spaces * Add ambiguous union tests * ambiguity in empty/any domain unions
1 parent a6c38b2 commit 612e8e5

File tree

5 files changed

+62
-31
lines changed

5 files changed

+62
-31
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
name: CI
2+
3+
concurrency:
4+
group: build-${{ github.event.pull_request.number || github.ref }}
5+
cancel-in-progress: true
6+
27
on:
38
create:
49
tags:

src/Domain.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
export Domain, SegmentDomain, tocanonical, fromcanonical, fromcanonicalD, ∂
42
export chebyshevpoints, fourierpoints, isambiguous, arclength
53
export components, component, ncomponents
@@ -21,6 +19,8 @@ struct EmptyDomain <: Domain{Nothing} end
2119
==(::AnyDomain, ::AnyDomain) = true
2220
==(::EmptyDomain, ::EmptyDomain) = true
2321

22+
const AnyOrEmptyDomain = Union{AnyDomain, EmptyDomain}
23+
2424
isambiguous(::AnyDomain) = true
2525
dimension(::AnyDomain) = 1
2626
dimension(::EmptyDomain) = 0
@@ -32,21 +32,21 @@ arclength(::DomainSets.EmptySpace) = false
3232

3333
isempty(::AnyDomain) = false
3434

35-
reverseorientation(a::Union{AnyDomain,EmptyDomain}) = a
35+
reverseorientation(a::AnyOrEmptyDomain) = a
3636

37-
canonicaldomain(a::Union{AnyDomain,EmptyDomain}) = a
37+
canonicaldomain(a::AnyOrEmptyDomain) = a
3838

3939
indomain(x::Domain,::EmptyDomain) = false
4040

4141
convert(::Type{Domain{T}}, ::AnyDomain) where T = Domain(T)
4242

43+
# empty domain should have priority over over any domain
44+
_promoteanyemptydomain(::AnyDomain, ::AnyDomain) = AnyDomain()
45+
_promoteanyemptydomain(::AnyOrEmptyDomain, ::AnyOrEmptyDomain) = EmptyDomain()
4346

44-
union(::AnyDomain, d::Domain) = d
45-
union(d::Domain, ::AnyDomain) = d
46-
47-
union(::EmptyDomain, ::EmptyDomain) = EmptyDomain()
48-
union(::EmptyDomain, a::Domain) = a
49-
union(a::Domain, ::EmptyDomain) = a
47+
union(a::AnyOrEmptyDomain, b::AnyOrEmptyDomain) = _promoteanyemptydomain(a, b)
48+
union(::AnyOrEmptyDomain, a::Domain) = a
49+
union(a::Domain, ::AnyOrEmptyDomain) = a
5050

5151
##General routines
5252
isempty(::EmptyDomain) = true

src/Space.jl

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -145,22 +145,14 @@ for op in (:tocanonical,:fromcanonical,:tocanonicalD,:fromcanonicalD,:invfromcan
145145
@eval ($op)(sp::Space,x...)=$op(domain(sp),x...)
146146
end
147147

148-
mappoint(a::Space,b::Space,x)=mappoint(domain(a),domain(b),x)
149-
mappoint(a::Space,b::Domain,x)=mappoint(domain(a),b,x)
150-
mappoint(a::Domain,b::Space,x)=mappoint(a,domain(b),x)
151-
148+
_domain(s::Space) = domain(s)
149+
_domain(s) = s
150+
mappoint(a, b, x) = mappoint(map(_domain, (a, b, x))...)
152151

152+
_conversion_rule(a, b) = spacescompatible(a, b) ? a : NoSpace()
153153

154154
for FUNC in (:conversion_rule,:maxspace_rule,:union_rule)
155-
@eval begin
156-
function $FUNC(a,b)
157-
if spacescompatible(a,b)
158-
a
159-
else
160-
NoSpace()
161-
end
162-
end
163-
end
155+
@eval $FUNC(a, b) = _conversion_rule(a, b)
164156
end
165157

166158

@@ -250,8 +242,8 @@ end
250242
# this is used primarily for addition of two funs
251243
# that may be incompatible
252244
union(a::AmbiguousSpace, b::AmbiguousSpace) = b
253-
union(a::AmbiguousSpace, b::Space) = b
254-
union(a::Space, b::AmbiguousSpace) = a
245+
union_by_union_rule(a::AmbiguousSpace, b::Space) = b
246+
union_by_union_rule(a::Space, b::AmbiguousSpace) = a
255247

256248

257249
function union_by_union_rule(a::Space,b::Space)
@@ -287,12 +279,7 @@ function union(a::Space, b::Space)
287279
a b
288280
end
289281

290-
union(a::Space) = a
291-
292-
union(a::Space,b::Space,c::Space) = union(union(a,b),c)
293-
union(a::Space,b::Space,c::Space,d::Space...) =
294-
union(union(a,b),c,d...)
295-
282+
union(a::Space, bs::Space...) = foldl(union, bs, init = a)
296283

297284
# tests whether a Conversion operator exists
298285
hasconversion(a,b) = maxspace(a,b) == b

test/SpacesTest.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ import ApproxFunBase: PointSpace, HeavisideSpace, PiecewiseSegment, dimension, V
2525
fany = convert(T, f)
2626
@test fany isa T
2727
@test (@inferred oftype(f, fany)) isa typeof(f)
28+
29+
# some trivial cases
30+
s = PointSpace(1:3)
31+
@test conversion_type(s, s) == s
32+
@test maxspace(s, s) == s
2833
end
2934

3035
A = @inferred f * Multiplication(f)
@@ -58,6 +63,16 @@ import ApproxFunBase: PointSpace, HeavisideSpace, PiecewiseSegment, dimension, V
5863
f2 = Fun(Foo(), PointSpace(1:10), 10)
5964
@test coefficients(f1) == coefficients(f2)
6065
end
66+
67+
@testset "union" begin
68+
@testset "trivial" begin
69+
s = PointSpace(0:3)
70+
@test union(s) == s
71+
@test union(s, s) == s
72+
@test union(s, s, s) == s
73+
@test union(s, s, s, s) == s
74+
end
75+
end
6176
end
6277

6378
@testset "Derivative operator for HeavisideSpace" begin
@@ -141,4 +156,13 @@ import ApproxFunBase: PointSpace, HeavisideSpace, PiecewiseSegment, dimension, V
141156
@test (@inferred ApproxFunBase.promotespaces(v)) == v
142157
end
143158
end
159+
160+
@testset "AmbiguousSpace" begin
161+
a = PointSpace(1:3)
162+
for b in Any[ApproxFunBase.UnsetSpace(), ApproxFunBase.NoSpace()]
163+
@test union(a, b) == a
164+
@test union(b, a) == a
165+
@test union(b, b) == b
166+
end
167+
end
144168
end

test/runtests.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,21 @@ end
6666
@test Segment(1,-1) .^ 2 Segment(1,0)
6767
@test Segment(1,2) .^ 2 Segment(1,4)
6868
@test sqrt.(Segment(1,2)) Segment(1,sqrt(2))
69+
70+
@testset "union" begin
71+
a = ApproxFunBase.EmptyDomain()
72+
b = ApproxFunBase.AnyDomain()
73+
74+
@test union(a, a) == a
75+
@test union(a, b) == a
76+
@test union(b, a) == a
77+
@test union(b, b) == b
78+
79+
@testset for d in Any[a, b]
80+
@test union(d, 1..2) == 1..2
81+
@test union(1..2, d) == 1..2
82+
end
83+
end
6984
end
7085

7186
@time include("MatrixTest.jl")

0 commit comments

Comments
 (0)