Skip to content

Commit 0fdd095

Browse files
authored
Ultraspherical conversion in Jacobi (#190)
* Ultraspherical conversion in Jacobi * Specialize Chebyshev cases * change equality to approx * Add Legendre conversion tests
1 parent 26de0e1 commit 0fdd095

File tree

3 files changed

+83
-27
lines changed

3 files changed

+83
-27
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.9"
3+
version = "0.6.10"
44

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

src/Spaces/Jacobi/JacobiOperators.jl

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,22 @@ function Conversion(L::Jacobi,M::Jacobi)
142142
domain(L) == domain(M) || domain(L) == reverseorientation(domain(M)) ||
143143
throw(ArgumentError("Domains must be the same"))
144144

145-
if isapproxinteger(L.a-M.a) && isapproxinteger(L.b-M.b)
146-
dm=domain(M)
147-
if isapprox(M.a,L.a) && isapprox(M.b,L.b)
148-
ConversionWrapper(Operator(I,L))
149-
elseif (isapprox(M.b,L.b+1) && isapprox(M.a,L.a)) ||
150-
(isapprox(M.b,L.b) && isapprox(M.a,L.a+1))
151-
ConcreteConversion(L,M)
152-
elseif M.b >= L.b && M.a >= L.a
145+
dm=domain(M)
146+
dl=domain(L)
147+
148+
if isapproxinteger(L.a-M.a) && isapproxinteger(L.b-M.b) && M.b >= L.b && M.a >= L.a
149+
if isapprox(L.a,M.a) && isapprox(L.b,M.b)
150+
return ConversionWrapper(Operator(I,L))
151+
elseif (isapprox(L.b+1,M.b) && isapprox(L.a,M.a)) ||
152+
(isapprox(L.b,M.b) && isapprox(L.a+1,M.a))
153+
return ConcreteConversion(L,M)
154+
elseif L.a L.b -0.5 && M.a M.b
155+
return Conversion(L,Chebyshev(dl),Ultraspherical(M),M)
156+
elseif L.a L.b && M.a M.b -0.5
157+
return Conversion(L,Ultraspherical(L),Chebyshev(dm),M)
158+
elseif L.a L.b && M.a M.b
159+
return Conversion(L,Ultraspherical(L),Ultraspherical(M),M)
160+
else
153161
# We split this into steps where a and b are changed by 1:
154162
# Define the intermediate space J = Jacobi(M.b, L.a, dm)
155163
# Conversion(L, M) == Conversion(J, M) * Conversion(L, J)
@@ -158,17 +166,19 @@ function Conversion(L::Jacobi,M::Jacobi)
158166
CLJ = [ConcreteConversion(Jacobi(b-1,L.a,dm), Jacobi(b, L.a, dm)) for b in M.b:-1:L.b+1]
159167
CJM = [ConcreteConversion(Jacobi(M.b,a-1,dm), Jacobi(M.b, a, dm)) for a in M.a:-1:L.a+1]
160168
C = [CJM; CLJ]
161-
ConversionWrapper(TimesOperator(C))
162-
else
163-
error("Implement for $L$M")
169+
return ConversionWrapper(TimesOperator(C))
170+
end
171+
elseif isapproxinteger_addhalf(L.a - M.a) && isapproxinteger_addhalf(L.b - M.b)
172+
if L.a L.b && M.a M.b -0.5
173+
return Conversion(L,Ultraspherical(L),Chebyshev(dm),M)
174+
elseif L.a L.b -0.5 && M.a M.b && M.a >= L.a
175+
return Conversion(L,Chebyshev(dl),Ultraspherical(M),M)
176+
elseif L.a L.b && M.a M.b && M.a >= L.a
177+
return Conversion(L,Ultraspherical(L),Ultraspherical(M),M)
164178
end
165-
elseif L.a L.b 0 && M.a M.b 0.5
166-
Conversion(L,Ultraspherical(L),Ultraspherical(M),M)
167-
elseif L.a L.b 0 && M.a M.b -0.5
168-
Conversion(L,Ultraspherical(L),Chebyshev(M),M)
169-
else # L.a - M.a ≈ L.b - M.b
170-
error("Implement for $L$M")
171179
end
180+
181+
error("Implement for $L$M")
172182
end
173183

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

test/JacobiTest.jl

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,64 @@ using Static
4848
testtransforms(Jacobi(-0.5,-0.5))
4949
@test norm(Fun(Fun(exp),Jacobi(-.5,-.5))-Fun(exp,Jacobi(-.5,-.5))) < 300eps()
5050

51-
@testset for d in [-1..1, 0..1]
52-
f = Fun(x->x^2, Chebyshev(d))
53-
C = space(f)
54-
for J1 in (Jacobi(-0.5, -0.5, d), Legendre(d),
55-
Jacobi(0.5, 0.5, d), Jacobi(2.5, 1.5, d))
56-
for J in (J1, NormalizedPolynomialSpace(J1))
57-
g = Fun(f, J)
58-
if !any(isnan, coefficients(g))
59-
@test Conversion(C, J) * f g
51+
@testset for d in (-1..1, 0..1, ChebyshevInterval())
52+
@testset "Chebyshev" begin
53+
f = Fun(x->x^2, Chebyshev(d))
54+
C = space(f)
55+
for J1 in (Jacobi(-0.5, -0.5, d), Legendre(d),
56+
Jacobi(0.5, 0.5, d), Jacobi(2.5, 1.5, d))
57+
@testset for J in (J1, NormalizedPolynomialSpace(J1))
58+
g = Fun(f, J)
59+
if !any(isnan, coefficients(g))
60+
@test Conversion(C, J) * f g
61+
end
6062
end
6163
end
6264
end
65+
@testset "legendre" begin
66+
f = Fun(x->x^2, Legendre(d))
67+
C = space(f)
68+
for J1 in (Jacobi(-0.5, -0.5, d), Legendre(d),
69+
Jacobi(0.5, 0.5, d), Jacobi(1, 1, d))
70+
@testset for J in (J1, NormalizedPolynomialSpace(J1))
71+
g = Fun(f, J)
72+
if !any(isnan, coefficients(g))
73+
@test Conversion(C, J) * f g
74+
end
75+
end
76+
end
77+
end
78+
@testset "Ultraspherical(0.5)" begin
79+
f = Fun(x->x^2, Ultraspherical(0.5,d))
80+
U = space(f)
81+
for J1 in (Jacobi(-0.5, -0.5, d), Legendre(d),
82+
Jacobi(0.5, 0.5, d))
83+
@testset for J in (J1, NormalizedPolynomialSpace(J1))
84+
g = Fun(f, J)
85+
if !any(isnan, coefficients(g))
86+
@test Conversion(U, J) * f g
87+
end
88+
end
89+
end
90+
end
91+
@testset "Ultraspherical(1)" begin
92+
f = Fun(x->x^2, Ultraspherical(1,d))
93+
U = space(f)
94+
for J1 in (Legendre(d), Jacobi(0.5, 0.5, d), Jacobi(1.5, 0.5, d),
95+
Jacobi(0.5, 1.5, d))
96+
@testset for J in (J1,)
97+
g = Fun(f, J)
98+
if !any(isnan, coefficients(g))
99+
@test Conversion(U, J) * f g
100+
end
101+
end
102+
end
103+
end
104+
end
105+
106+
@testset for (S1, S2) in ((Legendre(), Jacobi(-0.5, -0.5)), (Jacobi(-0.5, -0.5), Legendre()),
107+
(Legendre(), Jacobi(1.5, 1.5)))
108+
@test Conversion(S1, S2) * Fun(x->x^4, S1) Fun(x->x^4, S2)
63109
end
64110

65111
@testset "inference tests" begin

0 commit comments

Comments
 (0)