Skip to content

Commit c29fe02

Browse files
authored
Fix ultraspherical Integral indexing (#212)
* ultraspherical integral indexing * Add Legendre tests * type inference in integral * Check for inference only on v1.8+
1 parent ee2cf8f commit c29fe02

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

src/Spaces/Ultraspherical/UltrasphericalOperators.jl

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ function Integral(sp::Ultraspherical{<:Any,<:IntervalOrSegment}, m::Number)
6565
ConcreteIntegral(sp,m)
6666
else # Convert up
6767
nsp = Ultraspherical(m,domain(sp))
68-
IntegralWrapper(ConcreteIntegral(nsp,m)*Conversion(sp,nsp),m)
68+
Integralop = ConcreteIntegral(nsp,m)
69+
C = Conversion(sp,nsp)
70+
IntegralWrapper(Integralop * C, m, sp, rangespace(Integralop))
6971
end
7072
end
7173

@@ -100,8 +102,10 @@ linesum(f::Fun{<:Ultraspherical{LT,DD}}) where {LT,DD<:IntervalOrSegment} =
100102
sum(setcanonicaldomain(f))*arclength(d)/2
101103

102104

103-
rangespace(D::ConcreteIntegral{<:Ultraspherical{LT,DD}}) where {LT,DD<:IntervalOrSegment} =
104-
order(domainspace(D)) == 1 ? Chebyshev(domain(D)) : Ultraspherical(order(domainspace(D))-D.order,domain(D))
105+
function rangespace(D::ConcreteIntegral{<:Ultraspherical{LT,DD}}) where {LT,DD<:IntervalOrSegment}
106+
k = order(domainspace(D))-D.order
107+
k == 0 ? Chebyshev(domain(D)) : Ultraspherical(k, domain(D))
108+
end
105109

106110
function getindex(Q::ConcreteIntegral{<:Ultraspherical{LT,DD}},k::Integer,j::Integer) where {LT,DD<:IntervalOrSegment}
107111
T=eltype(Q)
@@ -112,7 +116,12 @@ function getindex(Q::ConcreteIntegral{<:Ultraspherical{LT,DD}},k::Integer,j::Int
112116

113117
if λ == 1 && k==j+1
114118
C = complexlength(d)/2
115-
strictconvert(T,C./(k-1))
119+
strictconvert(T, C/(k-1))
120+
elseif λ == m && k == j + m
121+
C = complexlength(d)/2
122+
U1toC = C/(k-1)
123+
UmtoU1 = pochhammer(one(T)*λ,-(m-1))*(complexlength(d)/4)^(m-1)
124+
strictconvert(T, U1toC * UmtoU1)
116125
elseif λ > 1 && k==j+m
117126
strictconvert(T,pochhammer(one(T)*λ,-m)*(complexlength(d)/4)^m)
118127
else
@@ -300,8 +309,11 @@ end
300309

301310
# TODO: include in getindex to speed up
302311
function Integral(sp::Chebyshev{DD},m::Integer) where {DD<:IntervalOrSegment}
303-
IntegralWrapper(TimesOperator([Integral(Ultraspherical(m,domain(sp)),m),
304-
Conversion(sp,Ultraspherical(m,domain(sp)))]),m)
312+
usp = Ultraspherical(m,domain(sp))
313+
I = Integral(usp,m)
314+
C = Conversion(sp,usp)
315+
T = TimesOperator(I, C)
316+
IntegralWrapper(T, m, sp, sp)
305317
end
306318

307319

test/UltrasphericalTest.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,5 +234,27 @@ using Static
234234
gexp = gexp - coefficients(gexp)[1]
235235
@test g gexp
236236
end
237+
238+
@testset for n in 3:6, d in ((), (0..1,)),
239+
sp in (Chebyshev(d...), Ultraspherical(1, d...), Ultraspherical(0.5, d...))
240+
f = Fun(sp, Float64[zeros(n); 2])
241+
@test Integral(1) * (Derivative(1) * f) f
242+
@test Integral(2) * (Derivative(2) * f) f
243+
@test Integral(3) * (Derivative(3) * f) f
244+
@test Derivative(1) * (Integral(1) * f) f
245+
@test Derivative(2) * (Integral(2) * f) f
246+
@test Derivative(3) * (Integral(3) * f) f
247+
end
248+
249+
if VERSION >= v"1.8"
250+
@inferred Integral(Chebyshev(), 3)
251+
@inferred (() -> Integral(Ultraspherical(1), 3))()
252+
@inferred (() -> Integral(Ultraspherical(3), 1))()
253+
# without constant propagation, this should be a small union
254+
TA = typeof(Integral(Ultraspherical(3), 1))
255+
TB = typeof(Integral(Ultraspherical(1), 3))
256+
@inferred Union{TA, TB} Integral(Ultraspherical(3), 1)
257+
@inferred Union{TA, TB} Integral(Ultraspherical(1), 3)
258+
end
237259
end
238260
end

0 commit comments

Comments
 (0)