Skip to content

Commit 2721a0d

Browse files
authored
Faster indexing for Ultraspherical(0.5)Legendre (#259)
* Faster indexing for Ultraspherical(0.5)<->Legendre * short-circuit matching spaces in conversion
1 parent bc1ed81 commit 2721a0d

File tree

4 files changed

+85
-19
lines changed

4 files changed

+85
-19
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
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.32"
3+
version = "0.6.33"
44

55
[deps]
66
ApproxFunBase = "fbd15aa5-315a-5a7d-a8a4-24992e37be05"

src/Spaces/Jacobi/JacobiOperators.jl

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,14 @@ end
379379
function getindex(C::ConcreteConversion{<:Ultraspherical,<:Jacobi,T}, k::Integer, j::Integer) where {T}
380380
if j==k
381381
S=rangespace(C)
382-
jp=jacobip(T,k-1,S.a,S.b,one(T))
383-
um=strictconvert(Operator{T}, Evaluation(setcanonicaldomain(domainspace(C)),rightendpoint,0))[k]::T
384-
(um/jp)::T
382+
U=domainspace(C)
383+
if S.a == S.b == 0 && isequalhalf(order(U))
384+
oneunit(T)
385+
else
386+
jp=jacobip(T,k-1,S.a,S.b,one(T))
387+
um=strictconvert(Operator{T}, Evaluation(setcanonicaldomain(U),RightEndPoint,0))[k]::T
388+
(um/jp)::T
389+
end
385390
else
386391
zero(T)
387392
end
@@ -392,12 +397,18 @@ function BandedMatrix(S::SubOperator{T,ConcreteConversion{US,J,T},NTuple{2,UnitR
392397
kr,jr = parentindices(S)
393398
k=(kr jr)
394399

395-
sp=rangespace(parent(S))
396-
jp=jacobip(T,k.-1,sp.a,sp.b,one(T))
397-
um=Evaluation(T,setcanonicaldomain(domainspace(parent(S))),rightendpoint,0)[k]
398-
vals = um./jp
400+
C = parent(S)
401+
sp = rangespace(C)
402+
U = domainspace(C)
403+
if sp.a == 0 && sp.b == 0 && isequalhalf(order(U))
404+
ret[band(bandshift(S))] .= oneunit(T)
405+
else
406+
jp=jacobip(T,k.-1,sp.a,sp.b,one(T))
407+
um=Evaluation(T,setcanonicaldomain(U),RightEndPoint,0)[k]
408+
vals = um./jp
399409

400-
ret[band(bandshift(S))] = vals
410+
ret[band(bandshift(S))] = vals
411+
end
401412
ret
402413
end
403414

@@ -406,9 +417,14 @@ end
406417
function getindex(C::ConcreteConversion{<:Jacobi,<:Ultraspherical,T}, k::Integer, j::Integer) where {T}
407418
if j==k
408419
S=domainspace(C)
409-
jp=jacobip(T,k-1,S.a,S.b,one(T))
410-
um=Evaluation(T,setcanonicaldomain(rangespace(C)),rightendpoint,0)[k]
411-
jp/um::T
420+
U = rangespace(C)
421+
if S.a == S.b == 0 && isequalhalf(order(U))
422+
oneunit(T)
423+
else
424+
jp=jacobip(T,k-1,S.a,S.b,one(T))
425+
um=Evaluation(T,setcanonicaldomain(rangespace(C)),RightEndPoint,0)[k]
426+
jp/um::T
427+
end
412428
else
413429
zero(T)
414430
end
@@ -419,12 +435,17 @@ function BandedMatrix(S::SubOperator{T,ConcreteConversion{J,US,T},NTuple{2,UnitR
419435
kr,jr = parentindices(S)
420436
k=(kr jr)
421437

422-
sp=domainspace(parent(S))
423-
jp=jacobip(T,k.-1,sp.a,sp.b,one(T))
424-
um=Evaluation(T,setcanonicaldomain(rangespace(parent(S))),rightendpoint,0)[k]
425-
vals = jp./um
426-
427-
ret[band(bandshift(S))] = vals
438+
C = parent(S)
439+
sp=domainspace(C)
440+
U = rangespace(C)
441+
if sp.a == 0 && sp.b == 0 && isequalhalf(order(U))
442+
ret[band(bandshift(S))] .= oneunit(T)
443+
else
444+
jp=jacobip(T,k.-1,sp.a,sp.b,one(T))
445+
um=Evaluation(T,setcanonicaldomain(U),RightEndPoint,0)[k]
446+
vals = jp./um
447+
ret[band(bandshift(S))] = vals
448+
end
428449
ret
429450
end
430451

src/Spaces/PolynomialSpace.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,17 @@ function Conversion(L::S, M::NormalizedPolynomialSpace{S}) where S<:PolynomialSp
466466
end
467467
end
468468

469+
function Conversion(L::NormalizedPolynomialSpace{<:PolynomialSpace},
470+
M::NormalizedPolynomialSpace{<:PolynomialSpace})
471+
472+
L == M && return Conversion(L)
473+
474+
C1 = ConcreteConversion(L, canonicalspace(L))
475+
C2 = Conversion(canonicalspace(L), canonicalspace(M))
476+
C3 = ConcreteConversion(canonicalspace(M), M)
477+
ConversionWrapper(C3 * C2 * C1, L, M)
478+
end
479+
469480
function Fun(::typeof(identity), S::NormalizedPolynomialSpace)
470481
C = canonicalspace(S)
471482
f = Fun(identity, C)

test/JacobiTest.jl

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ include("testutils.jl")
124124
end
125125

126126
@testset for (S1, S2) in ((Legendre(), Jacobi(-0.5, -0.5)), (Jacobi(-0.5, -0.5), Legendre()),
127-
(Legendre(), Jacobi(1.5, 1.5)))
127+
(Legendre(), Jacobi(1.5, 1.5)), (Legendre(), Ultraspherical(0.5)),
128+
(Ultraspherical(0.5), Legendre()))
128129
@test Conversion(S1, S2) * Fun(x->x^4, S1) Fun(x->x^4, S2)
129130
end
130131

@@ -242,6 +243,39 @@ include("testutils.jl")
242243
@test domainspace(Y) == Legendre()
243244
@test Y * Fun(Legendre()) Fun(x->x^2, Legendre())
244245
end
246+
247+
@testset "getindex for ConcreteConversion" begin
248+
for m in (0,1)
249+
C = Conversion(Jacobi(m,m), Ultraspherical(m+0.5))
250+
@test isdiag(C)
251+
B = C[1:10, 1:10]
252+
for i in 1:10
253+
@test C[i,i] B[i,i]
254+
end
255+
256+
C = Conversion(Ultraspherical(m+0.5), Jacobi(m,m))
257+
@test isdiag(C)
258+
B = C[1:10, 1:10]
259+
for i in 1:10
260+
@test C[i,i] B[i,i]
261+
end
262+
end
263+
end
264+
265+
@testset "NormalizedJacobi and NormalizedUltraspherical" begin
266+
for m in (0,1)
267+
C = Conversion(NormalizedUltraspherical(m + 0.5), NormalizedJacobi(m,m))
268+
@test isdiag(C)
269+
@test C[1:10, 1:10] I
270+
end
271+
end
272+
@testset "Normalized and Unnormalized" begin
273+
C = Conversion(NormalizedUltraspherical(0.5), Legendre())
274+
@test C * Fun(x->x^4, NormalizedUltraspherical(0.5)) Fun(x->x^4, Legendre())
275+
276+
C = Conversion(Legendre(), NormalizedChebyshev())
277+
@test C * Fun(x->x^4, Legendre()) Fun(x->x^4, NormalizedChebyshev())
278+
end
245279
end
246280

247281
@testset "inplace transform" begin

0 commit comments

Comments
 (0)