Skip to content

Commit 53068cb

Browse files
authored
Specialize isdiag for certain ConversionWrappers (#287)
* Specialize isdiag for certain ConversionWrappers * isdiag for Jacobi ConversionWrapper * Bump version to v0.6.42 * Conversions between Jacobi and Ultraspherical * Specialize israggedbelow, fix Ultraspheriacl ConcreteConversion indexing * Specialize ConcreteConversion indexing for Union{Integer, HalfOddInteger} * Fix ambiguity
1 parent 4069a3d commit 53068cb

File tree

6 files changed

+135
-12
lines changed

6 files changed

+135
-12
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.41"
3+
version = "0.6.42"
44

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

src/ApproxFunOrthogonalPolynomials.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ import ApproxFunBase: Fun, SubSpace, WeightSpace, NoSpace, HeavisideSpace,
5656
isleftendpoint, isrightendpoint, evaluation_point, boundaryfn, ldiffbc, rdiffbc,
5757
LeftEndPoint, RightEndPoint, normalizedspace, promotedomainspace,
5858
bandmatrices_eigen, SymmetricEigensystem, SkewSymmetricEigensystem,
59-
mean # differs from Statistics.mean after https://github.com/JuliaApproximation/ApproxFunBase.jl/pull/506
59+
mean, # differs from Statistics.mean after https://github.com/JuliaApproximation/ApproxFunBase.jl/pull/506
60+
israggedbelow
6061

6162
import DomainSets: Domain, indomain, UnionDomain, FullSpace, Point,
6263
Interval, ChebyshevInterval, boundary, rightendpoint, leftendpoint,

src/Spaces/Jacobi/JacobiOperators.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,14 @@ end
192192

193193
bandwidths(::ConcreteConversion{<:Jacobi,<:Jacobi}) = (0,1)
194194

195-
195+
# These methods help with constant propagating the bandwidths of a KroneckerOperator
196+
isdiag(::ConversionWrapper{<:Chebyshev,<:Jacobi}) = false
197+
isdiag(::ConversionWrapper{<:Jacobi,<:Jacobi,<:Any,<:ConstantOperator}) = true
198+
isdiag(::ConversionWrapper{<:Union{Ultraspherical,Jacobi},<:Union{Ultraspherical,Jacobi}}) = false
199+
200+
# These operators are banded and UpperTriangular
201+
israggedbelow(::ConversionWrapper{<:Chebyshev,<:Jacobi}) = true
202+
israggedbelow(::ConversionWrapper{<:Union{Ultraspherical,Jacobi},<:Union{Ultraspherical,Jacobi}}) = true
196203

197204
function getindex(C::ConcreteConversion{<:Jacobi,<:Jacobi,T},k::Integer,j::Integer) where {T}
198205
L=C.domainspace

src/Spaces/Ultraspherical/UltrasphericalOperators.jl

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,10 @@ function getindex(M::ConcreteConversion{<:Chebyshev,U,T},
213213
end
214214

215215

216-
function getindex(M::ConcreteConversion{U1,U2,T},
217-
k::Integer,j::Integer) where {DD,RR,
218-
U1<:Ultraspherical{<:Integer,DD,RR},
219-
U2<:Ultraspherical{<:Integer,DD,RR},T}
216+
function _getindex(M::ConcreteConversion{U1,U2,T}, k, j) where {DD,RR,
217+
OT<:Union{Integer, HalfOddInteger},
218+
U1<:Ultraspherical{<:OT,DD,RR},
219+
U2<:Ultraspherical{<:OT,DD,RR},T}
220220
# we can assume that λ==m+1
221221
λ=order(rangespace(M))
222222
c=λ-one(T) # this supports big types
@@ -229,6 +229,17 @@ function getindex(M::ConcreteConversion{U1,U2,T},
229229
end
230230
end
231231

232+
function getindex(M::ConcreteConversion{U1,U2,T}, k::Integer, j::Integer) where {DD,RR,
233+
U1<:Ultraspherical{<:Integer,DD,RR},
234+
U2<:Ultraspherical{<:Integer,DD,RR},T}
235+
_getindex(M, k, j)
236+
end
237+
function getindex(M::ConcreteConversion{U1,U2,T}, k::Integer, j::Integer) where {DD,RR,
238+
U1<:Ultraspherical{<:HalfOddInteger,DD,RR},
239+
U2<:Ultraspherical{<:HalfOddInteger,DD,RR},T}
240+
_getindex(M, k, j)
241+
end
242+
232243
function getindex(M::ConcreteConversion{U1,U2,T},
233244
k::Integer,j::Integer) where {DD,RR,
234245
U1<:Ultraspherical{<:Any,DD,RR},
@@ -273,6 +284,13 @@ isdiag(::ConcreteConversion{<:Chebyshev,<:Ultraspherical}) = false
273284
isdiag(::ConcreteConversion{<:Ultraspherical,<:Chebyshev}) = false
274285
isdiag(::ConcreteConversion{<:Ultraspherical,<:Ultraspherical}) = false
275286

287+
# These methods help with constant propagating the bandwidths of a KroneckerOperator
288+
isdiag(::ConversionWrapper{<:Chebyshev,<:Ultraspherical}) = false
289+
isdiag(::ConversionWrapper{<:Ultraspherical,<:Ultraspherical, <:Any, <:ConstantOperator}) = true
290+
291+
# These operators are banded and UpperTriangular
292+
israggedbelow(::ConversionWrapper{<:Chebyshev,<:Ultraspherical}) = true
293+
276294
## coefficients
277295

278296
# return the space that has banded Conversion to the other
@@ -381,7 +399,7 @@ function getindex(M::ConcreteConversion{Ultraspherical{LT,DD,RR},
381399
zero(T)
382400
end
383401
else
384-
error("Not implemented")
402+
error("Not implemented for $M")
385403
end
386404
end
387405

test/JacobiTest.jl

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,63 @@ include("testutils.jl")
791791
@test ApproxFunBase.hasconversion(NormalizedChebyshev()*Legendre(), Chebyshev()*Legendre())
792792
@test ApproxFunBase.hasconversion(NormalizedChebyshev()*NormalizedLegendre(), Chebyshev()*Legendre())
793793
@test ApproxFunBase.hasconversion(Chebyshev()*Legendre(), NormalizedChebyshev()*NormalizedLegendre())
794+
795+
@testset "isbanded and israggedbelow for KroneckerOperator" begin
796+
function testspaces(d1, d2, r1, r2, res = Val(false))
797+
K = (Operator(I, d1) Operator(I, d2)) (r1 * r2)
798+
@test (@inferred (K -> Val(isbanded(K)))(K)) == res
799+
@test (@inferred (K -> Val(ApproxFunBase.israggedbelow(K)))(K)) == Val(true)
800+
f = Fun((x,y)->x*y, d1*d2)
801+
g = Fun((x,y)->x*y, r1*r2)
802+
@test K * f g
803+
end
804+
805+
d1, r1 = Chebyshev(), Legendre()
806+
d2, r2 = Chebyshev(), Chebyshev()
807+
testspaces(d1, d2, r1, r2)
808+
809+
d1, r1 = Legendre(), Chebyshev()
810+
testspaces(d1, d2, r1, r2)
811+
812+
d1, r1 = Chebyshev(), Jacobi(1,1)
813+
testspaces(d1, d2, r1, r2)
814+
815+
d1, r1 = Chebyshev(), Jacobi(Ultraspherical(1))
816+
d2, r2 = Chebyshev(), Chebyshev()
817+
testspaces(d1, d2, r1, r2)
818+
819+
d1, r1 = Chebyshev(), Jacobi(Ultraspherical(2))
820+
testspaces(d1, d2, r1, r2)
821+
822+
d1, r1 = Jacobi(Ultraspherical(1)), Jacobi(Ultraspherical(1))
823+
testspaces(d1, d2, r1, r2, Val(true))
824+
825+
d1, r1 = Jacobi(Ultraspherical(1)), Jacobi(Ultraspherical(2))
826+
testspaces(d1, d2, r1, r2)
827+
828+
d1, r1 = Jacobi(Ultraspherical(1)), Ultraspherical(2)
829+
testspaces(d1, d2, r1, r2)
830+
831+
d1, r1 = Ultraspherical(1), Jacobi(Ultraspherical(2))
832+
testspaces(d1, d2, r1, r2)
833+
834+
d1, r1 = Jacobi(Ultraspherical(1)), Jacobi(Ultraspherical(3))
835+
testspaces(d1, d2, r1, r2)
836+
837+
d1, r1 = Jacobi(Ultraspherical(1)), Jacobi(2,2)
838+
testspaces(d1, d2, r1, r2)
839+
840+
d1, r1 = Ultraspherical(1), Jacobi(2,2)
841+
testspaces(d1, d2, r1, r2)
842+
end
843+
844+
d1, r1 = Legendre(), Jacobi(2,2)
845+
d2, r2 = Chebyshev(), Chebyshev()
846+
K = (Operator(I, d1) Operator(I, d2)) (r1 r2)
847+
M = K[1:20, 1:20]
848+
for ind in CartesianIndices(M)
849+
@test K[ind] M[ind]
850+
end
794851
end
795852
end
796853

test/UltrasphericalTest.jl

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ module UltrasphericalTest
22

33
using ApproxFunOrthogonalPolynomials
44
using ApproxFunBase
5-
using Test
6-
using SpecialFunctions
5+
using BandedMatrices
6+
using HalfIntegers
77
using LinearAlgebra
8-
using Static
98
using OddEvenIntegers
10-
using HalfIntegers
9+
using SpecialFunctions
10+
using Static
11+
using Test
1112

1213
include("testutils.jl")
1314

@@ -187,6 +188,45 @@ include("testutils.jl")
187188
end
188189
end
189190
end
191+
192+
@testset "isbanded for KroneckerOperator" begin
193+
function testspaces(d1, d2, r1, r2, res = Val(false))
194+
K = (Operator(I, d1) Operator(I, d2)) (r1 * r2)
195+
@test (@inferred (K -> Val(isbanded(K)))(K)) == res
196+
@test (@inferred (K -> Val(ApproxFunBase.israggedbelow(K)))(K)) == Val(true)
197+
f = Fun((x,y)->x*y, d1*d2)
198+
g = Fun((x,y)->x*y, r1*r2)
199+
@test K * f g
200+
end
201+
d1, r1 = Chebyshev(), Ultraspherical(1)
202+
d2, r2 = Chebyshev(), Chebyshev()
203+
testspaces(d1, d2, r1, r2)
204+
205+
d1, r1 = Chebyshev(), Ultraspherical(2)
206+
testspaces(d1, d2, r1, r2)
207+
208+
d1, r1 = Ultraspherical(1), Ultraspherical(1)
209+
testspaces(d1, d2, r1, r2, Val(true))
210+
211+
d1, r1 = Ultraspherical(1), Ultraspherical(2)
212+
testspaces(d1, d2, r1, r2)
213+
214+
d1, r1 = Ultraspherical(1), Ultraspherical(3)
215+
testspaces(d1, d2, r1, r2)
216+
end
217+
218+
@testset "ConcreteConversion indexing" begin
219+
for (s1, s2) in ((Ultraspherical(Legendre()), Ultraspherical(Jacobi(1,1))),
220+
(Ultraspherical(1), Ultraspherical(2)),
221+
(Ultraspherical(static(1)), Ultraspherical(static(2))),
222+
)
223+
C = Conversion(s1, s2)
224+
M = C[1:4, 1:4]
225+
for ind in CartesianIndices(M)
226+
@test C[ind] M[ind]
227+
end
228+
end
229+
end
190230
end
191231

192232
@testset "Normalized space" begin

0 commit comments

Comments
 (0)