Skip to content

Commit 1f64473

Browse files
authored
Add type parameter to Jacobi (#158)
* Add type parameter to Jacobi * Add tests * fix multiplication bug * Version bump to v0.6.0
1 parent acd736a commit 1f64473

File tree

7 files changed

+64
-36
lines changed

7 files changed

+64
-36
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.5.22"
3+
version = "0.6.0"
44

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

src/Spaces/Jacobi/Jacobi.jl

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ export Jacobi, NormalizedJacobi, Legendre, NormalizedLegendre
55
`Jacobi(b,a)` represents the space spanned by Jacobi polynomials `P_k^{(a,b)}`,
66
which are orthogonal with respect to the weight `(1+x)^β*(1-x)^α`
77
"""
8-
struct Jacobi{D<:Domain,R} <: PolynomialSpace{D,R}
9-
b::R
10-
a::R
8+
struct Jacobi{D<:Domain,R,T} <: PolynomialSpace{D,R}
9+
b::T
10+
a::T
1111
domain::D
12-
Jacobi{D,R}(b,a,d) where {D,R} = new{D,R}(b,a,d)
12+
Jacobi{D,R}(b::T,a::T,d::D) where {D,R,T} = new{D,R,T}(b,a,d)
1313
end
1414
Jacobi(b::T,a::T,d::Domain) where {T} =
1515
Jacobi{typeof(d),promote_type(T,real(prectype(d)))}(b, a, d)
16-
Legendre(domain) = Jacobi(0.,0.,domain)
16+
Legendre(domain) = Jacobi(0,0,domain)
1717
Legendre() = Legendre(ChebyshevInterval())
1818
Jacobi(b,a,d::Domain) = Jacobi(promote(b,a)...,d)
1919
Jacobi(b,a,d) = Jacobi(b,a,Domain(d))
@@ -38,16 +38,18 @@ NormalizedUltraspherical(NS::NormalizedPolynomialSpace{<:Jacobi}) =
3838
NormalizedJacobi(NS::NormalizedPolynomialSpace{<:Union{Ultraspherical, Chebyshev}}) =
3939
NormalizedPolynomialSpace(Jacobi(NS.space))
4040

41-
Base.promote_rule(::Type{Jacobi{D,R1}},::Type{Jacobi{D,R2}}) where {D,R1,R2} =
42-
Jacobi{D,promote_type(R1,R2)}
43-
convert(::Type{Jacobi{D,R1}},J::Jacobi{D,R2}) where {D,R1,R2} =
44-
Jacobi{D,R1}(J.b,J.a,J.domain)
41+
Base.promote_rule(::Type{Jacobi{D,R1,T1}},::Type{Jacobi{D,R2,T2}}) where {D,R1,R2,T1,T2} =
42+
Jacobi{D,promote_type(R1,R2),promote_type(T1,T2)}
43+
convert(::Type{Jacobi{D,R1,T1}},J::Jacobi{D,R2,T2}) where {D,R1,R2,T1,T2} =
44+
Jacobi{D,R1}(T1(J.b)::T1, T1(J.a)::T1, J.domain)::Jacobi{D,R1,T1}
4545

4646

4747
spacescompatible(a::Jacobi,b::Jacobi) = a.a b.a && a.b b.b && domainscompatible(a,b)
4848

49+
isapproxinteger_addhalf(a) = isapproxinteger(a+0.5)
50+
isapproxinteger_addhalf(::Integer) = false
4951
function canonicalspace(S::Jacobi)
50-
if isapproxinteger(S.a+0.5) && isapproxinteger(S.b+0.5)
52+
if isapproxinteger_addhalf(S.a) && isapproxinteger_addhalf(S.b)
5153
Chebyshev(domain(S))
5254
else
5355
# return space with parameters in (-1,0.]

src/Spaces/Jacobi/JacobiOperators.jl

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ for (Func,Len,Sum) in ((:DefiniteIntegral,:complexlength,:sum),(:DefiniteLineInt
9898
@eval begin
9999
$Func(S::Jacobi{<:IntervalOrSegment}) = $ConcFunc(S)
100100

101-
function getindex::$ConcFunc{Jacobi{D,R},T},k::Integer) where {D<:IntervalOrSegment,R,T}
101+
function getindex::$ConcFunc{<:Jacobi{<:IntervalOrSegment},T}, k::Integer) where {T}
102102
dsp = domainspace(Σ)
103103

104104
if dsp.b == dsp.a == 0
@@ -109,7 +109,7 @@ for (Func,Len,Sum) in ((:DefiniteIntegral,:complexlength,:sum),(:DefiniteLineInt
109109
end
110110
end
111111

112-
function bandwidths::$ConcFunc{Jacobi{D,R}}) where {D<:IntervalOrSegment,R}
112+
function bandwidths::$ConcFunc{<:Jacobi{<:IntervalOrSegment}})
113113
if domainspace(Σ).b == domainspace(Σ).a == 0
114114
0,0 # first entry
115115
else
@@ -187,10 +187,10 @@ end
187187

188188
# return the space that has banded Conversion to the other
189189
function conversion_rule(A::Jacobi,B::Jacobi)
190-
if !isapproxinteger(A.a-B.a) || !isapproxinteger(A.b-B.b)
191-
NoSpace()
192-
else
190+
if isapproxinteger(A.a-B.a) && isapproxinteger(A.b-B.b)
193191
Jacobi(min(A.b,B.b),min(A.a,B.a),domain(A))
192+
else
193+
NoSpace()
194194
end
195195
end
196196

@@ -212,8 +212,11 @@ function Conversion(A::Jacobi,B::PolynomialSpace)
212212
ConversionWrapper(TimesOperator(Conversion(J,B),Conversion(A,J)))
213213
end
214214

215+
isequalminhalf(x) = x == -0.5
216+
isequalminhalf(::Integer) = false
217+
215218
function Conversion(A::Jacobi,B::Chebyshev)
216-
if A.a == A.b == -0.5
219+
if isequalminhalf(A.a) && isequalminhalf(A.b)
217220
ConcreteConversion(A,B)
218221
elseif A.a == A.b == 0
219222
ConversionWrapper(
@@ -230,7 +233,7 @@ function Conversion(A::Jacobi,B::Chebyshev)
230233
end
231234

232235
function Conversion(A::Chebyshev,B::Jacobi)
233-
if B.a == B.b == -0.5
236+
if isequalminhalf(B.a) && isequalminhalf(B.b)
234237
ConcreteConversion(A,B)
235238
elseif B.a == B.b == 0
236239
ConversionWrapper(
@@ -248,10 +251,10 @@ end
248251

249252

250253
function Conversion(A::Jacobi,B::Ultraspherical)
251-
if A.a == A.b == -0.5
254+
if isequalminhalf(A.a) && isequalminhalf(A.b)
252255
ConversionWrapper(Conversion(Chebyshev(domain(A)),B)*
253256
ConcreteConversion(A,Chebyshev(domain(A))))
254-
elseif A.a == A.b == order(B)-0.5
257+
elseif isequalminhalf(A.a - order(B)) && isequalminhalf(A.b - order(B))
255258
ConcreteConversion(A,B)
256259
elseif A.a == A.b == 0
257260
ConversionWrapper(
@@ -268,10 +271,10 @@ function Conversion(A::Jacobi,B::Ultraspherical)
268271
end
269272

270273
function Conversion(A::Ultraspherical,B::Jacobi)
271-
if B.a == B.b == -0.5
274+
if isequalminhalf(B.a) && isequalminhalf(B.b)
272275
ConversionWrapper(ConcreteConversion(Chebyshev(domain(A)),B)*
273276
Conversion(A,Chebyshev(domain(A))))
274-
elseif B.a == B.b == order(A)-0.5
277+
elseif isequalminhalf(B.a - order(A)) && isequalminhalf(B.b - order(A))
275278
ConcreteConversion(A,B)
276279
elseif B.a == B.b == 0
277280
ConversionWrapper(
@@ -391,9 +394,8 @@ function BandedMatrix(S::SubOperator{T,ConcreteConversion{J,US,T},Tuple{UnitRang
391394
end
392395

393396

394-
395-
396-
397+
isapproxminhalf(a) = a -0.5
398+
isapproxminhalf(::Integer) = false
397399

398400
function union_rule(A::Jacobi,B::Jacobi)
399401
if domainscompatible(A,B)
@@ -414,14 +416,14 @@ end
414416

415417
function union_rule(A::Chebyshev,B::Jacobi)
416418
if domainscompatible(A, B)
417-
if isapprox(B.a,-0.5) && isapprox(B.b,-0.5)
419+
if isapproxminhalf(B.a) && isapproxminhalf(B.b)
418420
# the spaces are the same
419421
A
420422
else
421423
union(Jacobi(A),B)
422424
end
423425
else
424-
if isapprox(B.a,-0.5) && isapprox(B.b,-0.5)
426+
if isapproxminhalf(B.a) && isapproxminhalf(B.b)
425427
union(A, Chebyshev(domain(B)))
426428
else
427429
NoSpace()
@@ -431,14 +433,14 @@ end
431433
function union_rule(A::Ultraspherical,B::Jacobi)
432434
m=order(A)
433435
if domainscompatible(A, B)
434-
if isapprox(B.a,m-0.5) && isapprox(B.b,m-0.5)
436+
if isapproxminhalf(B.a-m) && isapproxminhalf(B.b-m)
435437
# the spaces are the same
436438
A
437439
else
438440
union(Jacobi(A),B)
439441
end
440442
else
441-
if isapprox(B.a,m-0.5) && isapprox(B.b,m-0.5)
443+
if isapproxminhalf(B.a-m) && isapproxminhalf(B.b-m)
442444
union(A, Ultraspherical(m, domain(B)))
443445
else
444446
NoSpace()
@@ -449,21 +451,21 @@ end
449451
for (OPrule,OP) in ((:conversion_rule,:conversion_type), (:maxspace_rule,:maxspace))
450452
@eval begin
451453
function $OPrule(A::Chebyshev,B::Jacobi)
452-
if B.a -0.5 && B.b -0.5
454+
if isapproxminhalf(B.a) && isapproxminhalf(B.b)
453455
# the spaces are the same
454456
A
455-
elseif isapproxinteger(B.a+0.5) && isapproxinteger(B.b+0.5)
457+
elseif isapproxinteger_addhalf(B.a) && isapproxinteger_addhalf(B.b)
456458
$OP(Jacobi(A),B)
457459
else
458460
NoSpace()
459461
end
460462
end
461463
function $OPrule(A::Ultraspherical,B::Jacobi)
462464
m = order(A)
463-
if B.a m-0.5 && B.b m-0.5
465+
if isapproxminhalf(B.a - m) && isapproxminhalf(B.b - m)
464466
# the spaces are the same
465467
A
466-
elseif isapproxinteger(B.a+0.5) && isapproxinteger(B.b+0.5)
468+
elseif isapproxinteger_addhalf(B.a) && isapproxinteger_addhalf(B.b)
467469
$OP(Jacobi(A),B)
468470
else
469471
NoSpace()

src/Spaces/Ultraspherical/UltrasphericalOperators.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,12 @@ function Conversion(A::Chebyshev,B::Ultraspherical)
134134
end
135135
end
136136

137+
138+
isequalhalf(x) = x == 0.5
139+
isequalhalf(::Integer) = false
140+
137141
function Conversion(A::Ultraspherical,B::Chebyshev)
138-
if order(A) == 1//2
142+
if isequalhalf(order(A))
139143
ConcreteConversion(A,B)
140144
else
141145
error("Not implemented")

test/JacobiTest.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,4 +462,15 @@ using StaticArrays: SVector
462462
end
463463
end
464464
end
465+
466+
@testset "type inference" begin
467+
x = @inferred ApproxFunBase.maxspace(Jacobi(1,1), Jacobi(2,2))
468+
@test x == Jacobi(2,2)
469+
470+
x = @inferred ApproxFunBase.union_rule(Chebyshev(), Jacobi(1,1))
471+
@test x == Jacobi(-0.5, -0.5)
472+
473+
x = @inferred ApproxFunBase.conversion_rule(Jacobi(1,1), Jacobi(2,2))
474+
@test x == Jacobi(1,1)
475+
end
465476
end

test/UltrasphericalTest.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ using ApproxFunOrthogonalPolynomials: jacobip
166166
end
167167
end
168168

169+
@testset "Multiplication" begin
170+
M = Multiplication(Fun(), Ultraspherical(0.5))
171+
f = Fun(Ultraspherical(0.5))
172+
f2 = Fun(x->x^2, Ultraspherical(0.5))
173+
@test M * f f2
174+
end
175+
169176
@testset "Integral" begin
170177
d = 0..1
171178
A = @inferred Integral(0..1)

test/showtest.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ using ApproxFunBase
44
@test repr(NormalizedChebyshev()) == "NormalizedChebyshev()"
55
@test repr(Ultraspherical(1)) == "Ultraspherical(1)"
66
@test repr(Legendre()) == "Legendre()"
7-
@test repr(Jacobi(1,2)) == "Jacobi(1.0,2.0)"
7+
@test repr(Jacobi(1,2)) == "Jacobi(1,2)"
8+
@test repr(Jacobi(1.0,2.0)) == "Jacobi(1.0,2.0)"
89

910
@test repr(Chebyshev(0..1)) == "Chebyshev(0..1)"
1011
@test repr(NormalizedChebyshev(0..1)) == "NormalizedChebyshev(0..1)"
1112
@test repr(Ultraspherical(1,0..1)) == "Ultraspherical(1,0..1)"
1213
@test repr(Legendre(0..1)) == "Legendre(0..1)"
13-
@test repr(Jacobi(1,2,0..1)) == "Jacobi(1.0,2.0,0..1)"
14+
@test repr(Jacobi(1,2,0..1)) == "Jacobi(1,2,0..1)"
15+
@test repr(Jacobi(1.0,2.0,0..1)) == "Jacobi(1.0,2.0,0..1)"
1416

1517
io = IOBuffer()
1618
@testset "Derivative" begin

0 commit comments

Comments
 (0)