Skip to content

Commit 5e9c350

Browse files
authored
Don't dispatch on leftendpoint/rightendpoint in Evaluation (#239)
* Don't dispatch on leftendpoint/rightendpoint in Evaluation * Specialize ldiffbc/rdiffbc for polynomial spaces * Add bvp test
1 parent 95d33ab commit 5e9c350

File tree

10 files changed

+87
-84
lines changed

10 files changed

+87
-84
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ApproxFunOrthogonalPolynomials"
22
uuid = "b70543e2-c0d9-56b8-a290-0d4d6d4de211"
3-
version = "0.6.25"
3+
version = "0.6.26"
44

55
[deps]
66
ApproxFunBase = "fbd15aa5-315a-5a7d-a8a4-24992e37be05"
@@ -20,7 +20,7 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
2020
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2121

2222
[compat]
23-
ApproxFunBase = "0.8.1"
23+
ApproxFunBase = "0.8.16"
2424
ApproxFunBaseTest = "0.1"
2525
Aqua = "0.5"
2626
BandedMatrices = "0.16, 0.17"

src/ApproxFunOrthogonalPolynomials.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ import ApproxFunBase: Fun, SubSpace, WeightSpace, NoSpace, HeavisideSpace,
4242
block, blockstart, blockstop, blocklengths, isblockbanded,
4343
pointscompatible, affine_setdiff, complexroots,
4444
ℓ⁰, recα, recβ, recγ, ℵ₀, ∞, RectDomain,
45-
assert_integer, supportsinplacetransform, ContinuousSpace
45+
assert_integer, supportsinplacetransform, ContinuousSpace, SpecialEvalPtType,
46+
isleftendpoint, isrightendpoint, evaluation_point, boundaryfn, ldiffbc, rdiffbc,
47+
LeftEndPoint, RightEndPoint
4648

4749
import DomainSets: Domain, indomain, UnionDomain, FullSpace, Point,
4850
Interval, ChebyshevInterval, boundary, rightendpoint, leftendpoint,

src/Spaces/Chebyshev/ChebyshevOperators.jl

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,7 @@ recγ(::Type{T},::Chebyshev,k) where {T} = one(T)/2 # one(T) ensures we get co
1313

1414
## Evaluation
1515

16-
Evaluation(S::Chebyshev,x::typeof(leftendpoint),o::Integer) =
17-
ConcreteEvaluation(S,x,o)
18-
Evaluation(S::Chebyshev,x::typeof(rightendpoint),o::Integer) =
19-
ConcreteEvaluation(S,x,o)
20-
Evaluation(S::Chebyshev,x::Number,o::Integer) = ConcreteEvaluation(S,x,o)
21-
22-
Evaluation(S::NormalizedPolynomialSpace{<:Chebyshev},x::typeof(leftendpoint),o::Integer) =
23-
ConcreteEvaluation(S,x,o)
24-
Evaluation(S::NormalizedPolynomialSpace{<:Chebyshev},x::typeof(rightendpoint),o::Integer) =
25-
ConcreteEvaluation(S,x,o)
26-
Evaluation(S::NormalizedPolynomialSpace{<:Chebyshev},x::Number,o::Integer) = ConcreteEvaluation(S,x,o)
16+
Evaluation(S::MaybeNormalized{<:Chebyshev},x::Number,o::Integer) = ConcreteEvaluation(S,x,o)
2717

2818
function evaluatechebyshev(n::Integer,x::T) where T<:Number
2919
if n == 1
@@ -49,7 +39,21 @@ function forwardrecurrence(::Type{T},S::Chebyshev,r::AbstractUnitRange{<:Integer
4939
first(r) == 0 ? v : v[r .+ 1]
5040
end
5141

52-
function getindex(op::ConcreteEvaluation{<:Chebyshev{DD,RR},typeof(leftendpoint)},j::Integer) where {DD<:IntervalOrSegment,RR}
42+
function getindex(op::ConcreteEvaluation{<:Chebyshev{<:IntervalOrSegment},<:SpecialEvalPtType}, j::Integer)
43+
_getindex_eval_endpoints(op, evaluation_point(op), j)
44+
end
45+
function getindex(op::ConcreteEvaluation{<:Chebyshev{<:IntervalOrSegment},<:SpecialEvalPtType}, j::AbstractUnitRange)
46+
_getindex_eval_endpoints(op, evaluation_point(op), j)
47+
end
48+
49+
function _getindex_eval_endpoints(op, x, j)
50+
if isleftendpoint(x)
51+
_getindex_eval_leftendpoint(op, x, j)
52+
else
53+
_getindex_eval_rightendpoint(op, x, j)
54+
end
55+
end
56+
function _getindex_eval_leftendpoint(op::ConcreteEvaluation{<:Chebyshev{<:IntervalOrSegment}}, x, j::Integer)
5357
T=eltype(op)
5458
if op.order == 0
5559
ifelse(isodd(j), # right rule
@@ -60,8 +64,7 @@ function getindex(op::ConcreteEvaluation{<:Chebyshev{DD,RR},typeof(leftendpoint)
6064
op[j:j][1]
6165
end
6266
end
63-
64-
function getindex(op::ConcreteEvaluation{<:Chebyshev{DD,RR},typeof(rightendpoint)},j::Integer) where {DD<:IntervalOrSegment,RR}
67+
function _getindex_eval_rightendpoint(op::ConcreteEvaluation{<:Chebyshev{<:IntervalOrSegment}}, x, j::Integer)
6568
T=eltype(op)
6669
if op.order == 0
6770
one(T)
@@ -70,8 +73,7 @@ function getindex(op::ConcreteEvaluation{<:Chebyshev{DD,RR},typeof(rightendpoint
7073
op[j:j][1]
7174
end
7275
end
73-
74-
function getindex(op::ConcreteEvaluation{<:Chebyshev{DD,RR},typeof(leftendpoint)},k::AbstractUnitRange) where {DD<:IntervalOrSegment,RR}
76+
function _getindex_eval_leftendpoint(op::ConcreteEvaluation{<:Chebyshev{<:IntervalOrSegment}}, x, k::AbstractUnitRange)
7577
Base.require_one_based_indexing(k)
7678
T=eltype(op)
7779
x = op.x
@@ -94,9 +96,7 @@ function getindex(op::ConcreteEvaluation{<:Chebyshev{DD,RR},typeof(leftendpoint)
9496

9597
scal!(cst,ret)
9698
end
97-
98-
99-
function getindex(op::ConcreteEvaluation{<:Chebyshev{DD,RR},typeof(rightendpoint)},k::AbstractUnitRange) where {DD<:IntervalOrSegment,RR}
99+
function _getindex_eval_rightendpoint(op::ConcreteEvaluation{<:Chebyshev{<:IntervalOrSegment}}, x, k::AbstractUnitRange)
100100
Base.require_one_based_indexing(k)
101101
T=eltype(op)
102102
x = op.x

src/Spaces/Jacobi/JacobiOperators.jl

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,10 @@ getindex(T::ConcreteDerivative{<:Jacobi}, k::Integer, j::Integer) =
3030

3131
# Evaluation
3232

33-
Evaluation(S::Jacobi,x::typeof(leftendpoint),o::Integer) =
34-
ConcreteEvaluation(S,x,o)
35-
Evaluation(S::Jacobi,x::typeof(rightendpoint),o::Integer) =
36-
ConcreteEvaluation(S,x,o)
37-
Evaluation(S::Jacobi,x::Number,o::Integer) = ConcreteEvaluation(S,x,o)
38-
39-
Evaluation(S::NormalizedPolynomialSpace{<:Jacobi},x::typeof(leftendpoint),o::Integer) =
40-
ConcreteEvaluation(S,x,o)
41-
Evaluation(S::NormalizedPolynomialSpace{<:Jacobi},x::typeof(rightendpoint),o::Integer) =
42-
ConcreteEvaluation(S,x,o)
43-
Evaluation(S::NormalizedPolynomialSpace{<:Jacobi},x::Number,o::Integer) = ConcreteEvaluation(S,x,o)
33+
Evaluation(S::MaybeNormalized{<:Jacobi},x::Number,o::Integer) = ConcreteEvaluation(S,x,o)
34+
35+
ldiffbc(d::MaybeNormalized{<:Union{Chebyshev, Ultraspherical, Jacobi}},k) = Evaluation(d,LeftEndPoint,k)
36+
rdiffbc(d::MaybeNormalized{<:Union{Chebyshev, Ultraspherical, Jacobi}},k) = Evaluation(d,RightEndPoint,k)
4437

4538
## Integral
4639

src/Spaces/PolynomialSpace.jl

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -374,26 +374,12 @@ function forwardrecurrence(::Type{T},S::Space,r::AbstractRange,x::Number) where
374374
end
375375

376376
getindex(op::ConcreteEvaluation{<:PolynomialSpace}, k::Integer) = op[k:k][1]
377-
# avoid ambiguity
378-
for OP in (:leftendpoint, :rightendpoint)
379-
@eval getindex(op::ConcreteEvaluation{<:PolynomialSpace,typeof($OP)},k::Integer) =
380-
op[k:k][1]
381-
end
382-
383-
function getindex(op::ConcreteEvaluation{J,typeof(leftendpoint)},kr::AbstractRange) where J<:PolynomialSpace
384-
_getindex_evaluation(op, leftendpoint(domain(op)), kr)
385-
end
386377

387-
function getindex(op::ConcreteEvaluation{J,typeof(rightendpoint)},kr::AbstractRange) where J<:PolynomialSpace
388-
_getindex_evaluation(op, rightendpoint(domain(op)), kr)
389-
end
390-
391-
function getindex(op::ConcreteEvaluation{J,TT}, kr::AbstractRange) where {J<:PolynomialSpace,TT<:Number}
392-
_getindex_evaluation(op, op.x, kr)
393-
end
378+
_evalpt(op, x::Number) = x
379+
_evalpt(op, x::SpecialEvalPtType) = boundaryfn(x)(domain(op))
394380

395-
function _getindex_evaluation(op::ConcreteEvaluation{<:PolynomialSpace}, x, kr::AbstractRange)
396-
_getindex_evaluation(eltype(op), op.space, op.order, x, kr)
381+
function getindex(op::ConcreteEvaluation{<:PolynomialSpace},kr::AbstractRange)
382+
_getindex_evaluation(eltype(op), op.space, op.order, _evalpt(op, evaluation_point(op)), kr)
397383
end
398384

399385
function _getindex_evaluation(::Type{T}, sp, order, x, kr::AbstractRange) where {T}

src/Spaces/Ultraspherical/DirichletSpace.jl

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -143,72 +143,88 @@ conversion_rule(b::ChebyshevDirichlet,a::Chebyshev)=b
143143
## Evaluation Functional
144144

145145

146-
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{1,0,D,R},typeof(leftendpoint)}) where {D,R} = 0,0
147-
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{1,0,D,R},typeof(rightendpoint)}) where {D,R} = 0,ℵ₀
148-
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{0,1,D,R},typeof(leftendpoint)}) where {D,R} = 0,ℵ₀
149-
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{0,1,D,R},typeof(rightendpoint)}) where {D,R} = 0,0
150-
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{1,1,D,R},typeof(leftendpoint)}) where {D,R} = 0,1
151-
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{1,1,D,R},typeof(rightendpoint)}) where {D,R} = 0,1
146+
function bandwidths(B::ConcreteEvaluation{<:ChebyshevDirichlet{1,0},<:SpecialEvalPtType})
147+
pt = evaluation_point(B)
148+
if isleftendpoint(pt)
149+
0,0
150+
else
151+
0,ℵ₀
152+
end
153+
end
154+
function bandwidths(B::ConcreteEvaluation{<:ChebyshevDirichlet{0,1},<:SpecialEvalPtType})
155+
pt = evaluation_point(B)
156+
if isleftendpoint(pt)
157+
0,ℵ₀
158+
else
159+
0,0
160+
end
161+
end
162+
bandwidths(B::ConcreteEvaluation{<:ChebyshevDirichlet{1,1},<:SpecialEvalPtType}) = 0,1
152163

153-
function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{1,0,D,R},typeof(leftendpoint)},kr::AbstractRange) where {D,R}
154-
d = domain(B)
164+
function getindex(B::ConcreteEvaluation{<:ChebyshevDirichlet,<:SpecialEvalPtType}, kr::AbstractRange)
165+
_getindex_eval_endpoints(B, evaluation_point(B), kr)
166+
end
167+
168+
function _getindex_default(B::ConcreteEvaluation{<:ChebyshevDirichlet}, x, kr)
169+
S = Space(domain(B))
170+
O = Evaluation(S,x,B.order) * Conversion(domainspace(B),S)
171+
O[kr]
172+
end
155173

174+
function _getindex_eval_leftendpoint(B::ConcreteEvaluation{<:ChebyshevDirichlet{1,0}}, x, kr::AbstractRange)
156175
if B.order == 0
157176
eltype(B)[k==1 ? 1.0 : 0.0 for k=kr]
158177
else
159-
(Evaluation(d,B.x,B.order)*Conversion(domainspace(B)))[kr]
178+
_getindex_default(B, x, kr)
160179
end
161180
end
162181

163-
function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{1,0,D,R},typeof(rightendpoint)},kr::AbstractRange) where {D,R}
164-
d = domain(B)
165-
182+
function _getindex_eval_rightendpoint(B::ConcreteEvaluation{<:ChebyshevDirichlet{1,0}}, x, kr::AbstractRange)
166183
if B.order == 0
167184
eltype(B)[k==1 ? 1.0 : 2.0 for k=kr]
168185
else
169-
(Evaluation(d,B.x,B.order)*Conversion(domainspace(B)))[kr]
186+
_getindex_default(B, x, kr)
170187
end
171188
end
172189

173-
function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{0,1,D,R},typeof(leftendpoint)},kr::AbstractRange) where {D,R}
190+
function _getindex_eval_leftendpoint(B::ConcreteEvaluation{<:ChebyshevDirichlet{0,1}}, x, kr::AbstractRange)
174191
S = Space(domain(B))
175192

176193
if B.order == 0
177194
eltype(B)[k==1 ? 1.0 : -(-1)^k*2.0 for k=kr]
178195
else
179-
(Evaluation(S,B.x,B.order)*Conversion(domainspace(B),S))[kr]
196+
_getindex_default(B, x, kr)
180197
end
181198
end
182199

183-
function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{0,1,D,R},typeof(rightendpoint)},kr::AbstractRange) where {D,R}
200+
function _getindex_eval_rightendpoint(B::ConcreteEvaluation{<:ChebyshevDirichlet{0,1}}, x, kr::AbstractRange)
184201
S = Space(domain(B))
185202

186-
187203
if B.order == 0
188204
eltype(B)[k==1 ? 1.0 : 0.0 for k=kr]
189205
else
190-
(Evaluation(S,B.x,B.order)*Conversion(domainspace(B),S))[kr]
206+
_getindex_default(B, x, kr)
191207
end
192208
end
193209

194210

195-
function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{1,1,D,R},typeof(leftendpoint)},kr::AbstractRange) where {D,R}
211+
function _getindex_eval_leftendpoint(B::ConcreteEvaluation{<:ChebyshevDirichlet{1,1}}, x, kr::AbstractRange)
196212
S = Space(domain(B))
197213

198214
if B.order == 0
199215
eltype(B)[k==1 ? 1.0 : (k==2 ? -1.0 : 0.0) for k=kr]
200216
else
201-
getindex(Evaluation(S,B.x,B.order)*Conversion(domainspace(B),S),kr)
217+
_getindex_default(B, x, kr)
202218
end
203219
end
204220

205-
function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{1,1,D,R},typeof(rightendpoint)},kr::AbstractRange) where {D,R}
221+
function _getindex_eval_rightendpoint(B::ConcreteEvaluation{<:ChebyshevDirichlet{1,1}}, x, kr::AbstractRange)
206222
S = Space(domain(B))
207223

208224
if B.order == 0
209225
eltype(B)[k==1||k==2 ? 1.0 : 0.0 for k=kr]
210226
else
211-
getindex(Evaluation(S,B.x,B.order)*Conversion(domainspace(B),S),kr)
227+
_getindex_default(B, x, kr)
212228
end
213229
end
214230

src/Spaces/Ultraspherical/UltrasphericalOperators.jl

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -389,14 +389,4 @@ end
389389
ReverseOrientation(S::Ultraspherical) = ReverseOrientationWrapper(NegateEven(S,reverseorientation(S)))
390390
Reverse(S::Ultraspherical) = ReverseWrapper(NegateEven(S,S))
391391

392-
Evaluation(S::Ultraspherical,x::typeof(leftendpoint),o::Integer) =
393-
ConcreteEvaluation(S,x,o)
394-
Evaluation(S::Ultraspherical,x::typeof(rightendpoint),o::Integer) =
395-
ConcreteEvaluation(S,x,o)
396-
Evaluation(S::Ultraspherical,x::Number,o::Integer) = ConcreteEvaluation(S,x,o)
397-
398-
Evaluation(S::NormalizedPolynomialSpace{<:Ultraspherical},x::typeof(leftendpoint),o::Integer) =
399-
ConcreteEvaluation(S,x,o)
400-
Evaluation(S::NormalizedPolynomialSpace{<:Ultraspherical},x::typeof(rightendpoint),o::Integer) =
401-
ConcreteEvaluation(S,x,o)
402-
Evaluation(S::NormalizedPolynomialSpace{<:Ultraspherical},x::Number,o::Integer) = ConcreteEvaluation(S,x,o)
392+
Evaluation(S::MaybeNormalized{<:Ultraspherical},x::Number,o::Integer) = ConcreteEvaluation(S,x,o)

test/ChebyshevTest.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,15 @@ using ApproxFunOrthogonalPolynomials: forwardrecurrence
412412
D3p = @inferred ev(sp, ep(d), 3)
413413
@test Number(D3p * f) f'''(ep(d))
414414
end
415+
@test ldirichlet(sp) * f f(leftendpoint(domain(f)))
416+
@test rdirichlet(sp) * f f(rightendpoint(domain(f)))
417+
@test lneumann(sp) * f f'(leftendpoint(domain(f)))
418+
@test rneumann(sp) * f f'(rightendpoint(domain(f)))
419+
@inferred bvp(sp)[1]
415420
end
416421
end
417422

423+
418424
@testset "ChebyshevDirichlet" begin
419425
function Evaluation2(sp::ChebyshevDirichlet,x,ord)
420426
S=Space(domain(sp))

test/JacobiTest.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,11 @@ using Static
635635
D3p = @inferred ev(sp, ep(d), 3)
636636
@test Number(D3p * f) f'''(ep(d))
637637
end
638+
@test ldirichlet(sp) * f f(leftendpoint(domain(f)))
639+
@test rdirichlet(sp) * f f(rightendpoint(domain(f)))
640+
@test lneumann(sp) * f f'(leftendpoint(domain(f)))
641+
@test rneumann(sp) * f f'(rightendpoint(domain(f)))
642+
@inferred bvp(sp)[1]
638643
end
639644
end
640645
end

test/UltrasphericalTest.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ using Static
202202
D3p = @inferred ev(sp, ep(d), 3)
203203
@test Number(D3p * f) f'''(ep(d))
204204
end
205+
@test ldirichlet(sp) * f f(leftendpoint(domain(f)))
206+
@test rdirichlet(sp) * f f(rightendpoint(domain(f)))
207+
@test lneumann(sp) * f f'(leftendpoint(domain(f)))
208+
@test rneumann(sp) * f f'(rightendpoint(domain(f)))
209+
@inferred bvp(sp)[1]
205210
end
206211
end
207212
end

0 commit comments

Comments
 (0)