Skip to content

Commit 1fd0adf

Browse files
authored
Improve singularities behaviour (#209)
* Improve singularities behaviour * work on singularities * v0.16 * Update test_monic.jl * fix tests * increase coverage * increase cov * Update ClassicalOrthogonalPolynomials.jl * remove literal power special case * increase cov
1 parent 8462dd4 commit 1fd0adf

14 files changed

+128
-94
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ClassicalOrthogonalPolynomials"
22
uuid = "b30e2e7b-c4ee-47da-9d5f-2c5c27239acd"
33
authors = ["Sheehan Olver <solver@mac.com>"]
4-
version = "0.15.1"
4+
version = "0.15.2"
55

66

77
[deps]

src/ClassicalOrthogonalPolynomials.jl

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import InfiniteLinearAlgebra: chop!, chop, pad, choplength, compatible_resize!,
3737
import ContinuumArrays: Basis, Weight, basis_axes, @simplify, AbstractAffineQuasiVector, ProjectionFactorization,
3838
grid, plotgrid, plotgrid_layout, plotvalues_layout, grid_layout, transform_ldiv, TransformFactorization, QInfAxes, broadcastbasis, ExpansionLayout, basismap,
3939
AffineQuasiVector, AffineMap, AbstractWeightLayout, AbstractWeightedBasisLayout, WeightedBasisLayout, WeightedBasisLayouts, demap, AbstractBasisLayout, BasisLayout,
40-
checkpoints, weight, unweighted, MappedBasisLayouts, sum_layout, invmap, plan_ldiv, layout_broadcasted, MappedBasisLayout, SubBasisLayout, broadcastbasis_layout,
40+
checkpoints, weight, unweighted, MappedBasisLayouts, sum_layout, invmap, plan_ldiv, layout_broadcasted, MappedBasisLayout, MappedWeightLayout, SubBasisLayout, broadcastbasis_layout,
4141
plan_grid_transform, plan_transform, MAX_PLOT_POINTS, MulPlan, grammatrix, AdjointBasisLayout, grammatrix_layout, plan_transform_layout, _cumsum
4242
import FastTransforms: Λ, ChebyshevGrid, chebyshevpoints, Plan, ScaledPlan, th_cheb2leg, pochhammer
4343
import RecurrenceRelationships: forwardrecurrence, forwardrecurrence!, clenshaw, clenshaw!,
@@ -197,27 +197,45 @@ recurrencecoefficients(Q) = recurrencecoefficients_layout(MemoryLayout(Q), Q)
197197

198198

199199

200+
singularities_layout(lay::BroadcastLayout, a) = singularitiesbroadcast(call(lay, a), map(singularities, arguments(lay, a))...)
201+
singularities_layout(::WeightedBasisLayouts, a) = singularities_layout(BroadcastLayout{typeof(*)}(), a)
202+
singularities_layout(::MappedWeightLayout, a) = view(singularities(demap(a)), basismap(a))
203+
singularities_layout(::WeightedOPLayout, a) = singularities(weight(a))
204+
singularities_layout(::ExpansionLayout, f) = singularities(basis(f))
205+
singularities_layout(lay, a) = NoSingularities() # assume no singularities
206+
200207
"""
201208
singularities(f)
202209
203210
gives the singularity structure of an expansion, e.g.,
204211
`JacobiWeight`.
205212
"""
206-
singularities(::AbstractWeightLayout, w) = w
207-
singularities(lay::BroadcastLayout, a) = singularitiesbroadcast(call(a), map(singularities, arguments(lay, a))...)
208-
singularities(::WeightedBasisLayouts, a) = singularities(BroadcastLayout{typeof(*)}(), a)
209-
singularities(::WeightedOPLayout, a) = singularities(weight(a))
210-
singularities(w) = singularities(MemoryLayout(w), w)
211-
singularities(::ExpansionLayout, f) = singularities(basis(f))
213+
singularities(w) = singularities_layout(MemoryLayout(w), w)
214+
212215

213-
singularitiesview(w, ::Inclusion) = w # for now just assume it doesn't change
214-
singularitiesview(w, ind) = view(w, ind)
215-
singularities(S::SubQuasiArray) = singularitiesview(singularities(parent(S)), parentindices(S)[1])
216216

217217
struct NoSingularities end
218218

219-
basis_singularities(ax, ::NoSingularities) = basis(ax)
220-
basis_singularities(ax, sing) = basis_singularities(sing)
219+
## default is to just assume no singularities
220+
singularitiesbroadcast(_...) = NoSingularities()
221+
222+
for op in (:+, :*)
223+
@eval singularitiesbroadcast(::typeof($op), A, B, C, D...) = singularitiesbroadcast(*, singularitiesbroadcast(*, A, B), C, D...)
224+
@eval singularitiesbroadcast(::typeof($op), ::NoSingularities, ::NoSingularities) = NoSingularities()
225+
end
226+
227+
singularitiesbroadcast(::typeof(*), ::NoSingularities, b) = b
228+
singularitiesbroadcast(::typeof(*), a, ::NoSingularities) = a
229+
230+
231+
# for singularitiesbroadcast(literal_pow), ^, ...)
232+
# singularitiesbroadcast(F::Function, G::Function, V::SubQuasiArray, K) = singularitiesbroadcast(F, G, parent(V), K)[parentindices(V)...]
233+
# singularitiesbroadcast(F, V::SubQuasiArray...) = singularitiesbroadcast(F, map(parent,V)...)[parentindices(V...)...]
234+
# singularitiesbroadcast(F, V::NoSingularities...) = NoSingularities() # default is to assume smooth
235+
236+
237+
238+
221239
basis_axes(ax::Inclusion{<:Any,<:AbstractInterval}, v) = convert(AbstractQuasiMatrix{eltype(v)}, basis_singularities(ax, singularities(v)))
222240

223241

src/choleskyQR.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ orthogonalityweight(Q::ConvertedOrthogonalPolynomial) = Q.weight
2626
# transform to P * inv(U) if needed for differentiation, etc.
2727
arguments(::ApplyLayout{typeof(*)}, Q::ConvertedOrthogonalPolynomial) = Q.P, ApplyArray(inv, Q.U)
2828

29-
OrthogonalPolynomial(w::AbstractQuasiVector) = OrthogonalPolynomial(w, orthogonalpolynomial(singularities(w)))
29+
OrthogonalPolynomial(w::AbstractQuasiVector) = OrthogonalPolynomial(w, orthogonalpolynomial_axis(axes(w,1), singularities(w)))
3030
function OrthogonalPolynomial(w::AbstractQuasiVector, P::AbstractQuasiMatrix)
3131
Q = normalized(P)
3232
X,U = cholesky_jacobimatrix(w, Q)
@@ -39,6 +39,8 @@ orthogonalpolynomial(w::SubQuasiArray) = orthogonalpolynomial(parent(w))[parenti
3939
OrthogonalPolynomial(w::Function, P::AbstractQuasiMatrix) = OrthogonalPolynomial(w.(axes(P,1)), P)
4040
orthogonalpolynomial(w::Function, P::AbstractQuasiMatrix) = orthogonalpolynomial(w.(axes(P,1)), P)
4141

42+
orthogonalpolynomial_axis(ax, ::NoSingularities) = legendre(ax)
43+
orthogonalpolynomial_axis(ax, w) = orthogonalpolynomial(w)
4244
resizedata!(P::ConvertedOrthogonalPolynomial, ::Colon, n::Int) = resizedata!(P.X.dv, n)
4345

4446

src/classical/chebyshev.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,12 @@ broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), ::ChebyshevWeight{kind,T}, ::
4949

5050
chebyshevt() = ChebyshevT()
5151
chebyshevt(d::AbstractInterval{T}) where T = ChebyshevT{float(T)}()[affine(d, ChebyshevInterval{T}()), :]
52+
chebyshevt(d::ChebyshevInterval{T}) where T = ChebyshevT{float(T)}()
5253
chebyshevt(d::Inclusion) = chebyshevt(d.domain)
5354
chebyshevt(S::AbstractQuasiMatrix) = chebyshevt(axes(S,1))
5455
chebyshevu() = ChebyshevU()
5556
chebyshevu(d::AbstractInterval{T}) where T = ChebyshevU{float(T)}()[affine(d, ChebyshevInterval{T}()), :]
57+
chebyshevu(d::ChebyshevInterval{T}) where T = ChebyshevU{float(T)}()
5658
chebyshevu(d::Inclusion) = chebyshevu(d.domain)
5759
chebyshevu(S::AbstractQuasiMatrix) = chebyshevu(axes(S,1))
5860

src/classical/jacobi.jl

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,7 @@ hasboundedendpoints(w::AbstractJacobiWeight) = w.a ≥ 0 && w.b ≥ 0
9292
singularities(a::AbstractAffineQuasiVector) = singularities(a.x)
9393

9494

95-
## default is to just assume no singularities
96-
singularitiesbroadcast(_...) = NoSingularities()
97-
98-
for op in (:+, :*)
99-
@eval singularitiesbroadcast(::typeof($op), A, B, C, D...) = singularitiesbroadcast(*, singularitiesbroadcast(*, A, B), C, D...)
100-
end
101-
102-
singularitiesbroadcast(::typeof(*), V::Union{NoSingularities,SubQuasiArray}...) = singularitiesbroadcast(*, map(_parent,V)...)[_parentindices(V...)...]
103-
104-
105-
_parent(::NoSingularities) = NoSingularities()
106-
_parent(a) = parent(a)
107-
_parentindices(a::NoSingularities, b...) = _parentindices(b...)
108-
_parentindices(a, b...) = parentindices(a)
109-
# for singularitiesbroadcast(literal_pow), ^, ...)
110-
singularitiesbroadcast(F::Function, G::Function, V::SubQuasiArray, K) = singularitiesbroadcast(F, G, parent(V), K)[parentindices(V)...]
111-
singularitiesbroadcast(F, V::Union{NoSingularities,SubQuasiArray}...) = singularitiesbroadcast(F, map(_parent,V)...)[_parentindices(V...)...]
95+
singularities(w::AbstractJacobiWeight) = w
11296

11397

11498
abstract type AbstractJacobi{T} <: OrthogonalPolynomial{T} end
@@ -208,10 +192,11 @@ julia> J[0,:]
208192
"""
209193
jacobi(a,b) = Jacobi(a,b)
210194
jacobi(a,b, d::AbstractInterval{T}) where T = Jacobi{float(promote_type(eltype(a),eltype(b),T))}(a,b)[affine(d,ChebyshevInterval{T}()), :]
195+
jacobi(a,b, d::ChebyshevInterval{T}) where T = Jacobi{float(promote_type(eltype(a),eltype(b),T))}(a,b)
211196

212197
Jacobi(P::Legendre{T}) where T = Jacobi(zero(T), zero(T))
213198

214-
basis_singularities(w::JacobiWeight) = Weighted(Jacobi(w.a, w.b))
199+
215200

216201

217202
"""

src/classical/legendre.jl

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,9 @@ end
7373
singularitiesbroadcast(::typeof(^), L::LegendreWeight, ::NoSingularities) = L
7474
singularitiesbroadcast(::typeof(/), ::NoSingularities, L::LegendreWeight) = L # can't find roots
7575

76-
singularities(::AbstractJacobi{T}) where T = LegendreWeight{T}()
77-
singularities(::Inclusion{T,<:ChebyshevInterval}) where T = LegendreWeight{T}()
78-
singularities(d::Inclusion{T,<:AbstractInterval}) where T = LegendreWeight{T}()[affine(d,ChebyshevInterval{T}())]
79-
singularities(::AbstractFillLayout, P) = LegendreWeight{eltype(P)}()
76+
basis_singularities(ax::Inclusion, ::NoSingularities) = legendre(ax)
77+
basis_singularities(ax, sing) = basis_singularities(sing) # fallback for back compatibility
8078

81-
basis_singularities(::LegendreWeight{T}) where T = Legendre{T}()
82-
basis_singularities(v::SubQuasiArray) = view(basis_singularities(parent(v)), parentindices(v)[1], :)
8379

8480
"""
8581
Legendre{T=Float64}(a,b)

src/classical/ultraspherical.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ orthogonalityweight(C::Ultraspherical) = UltrasphericalWeight(C.λ)
5656

5757
ultrasphericalc(n::Integer, λ, z) = Base.unsafe_getindex(Ultraspherical{polynomialtype(typeof(λ),typeof(z))}(λ), z, n+1)
5858
ultraspherical(λ, d::AbstractInterval{T}) where T = Ultraspherical{float(promote_type(eltype(λ),T))}(λ)[affine(d,ChebyshevInterval{T}()), :]
59+
ultraspherical(λ, d::ChebyshevInterval{T}) where T = Ultraspherical{float(promote_type(eltype(λ),T))}(λ)
5960

6061
==(a::Ultraspherical, b::Ultraspherical) = a.λ == b.λ
6162
==(::Ultraspherical, ::ChebyshevT) = false

src/lanczos.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ function LanczosPolynomial(w_in::AbstractQuasiVector, P::AbstractQuasiMatrix)
165165
LanczosPolynomial(w, Q, LanczosData(w, Q))
166166
end
167167

168-
LanczosPolynomial(w::AbstractQuasiVector) = LanczosPolynomial(w, normalized(orthogonalpolynomial(singularities(w))))
168+
LanczosPolynomial(w::AbstractQuasiVector) = LanczosPolynomial(w, normalized(orthogonalpolynomial_axis(axes(w,1), singularities(w))))
169169

170170
==(A::LanczosPolynomial, B::LanczosPolynomial) = A.w == B.w
171171
==(::LanczosPolynomial, ::OrthogonalPolynomial) = false # TODO: fix

test/runtests.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import ClassicalOrthogonalPolynomials: jacobimatrix, ∞, ChebyshevInterval, Leg
88
import LazyArrays: ApplyStyle, colsupport, MemoryLayout, arguments
99
import SemiseparableMatrices: VcatAlmostBandedLayout
1010
import QuasiArrays: MulQuasiMatrix
11-
import ClassicalOrthogonalPolynomials: oneto
11+
import ClassicalOrthogonalPolynomials: oneto, NoSingularities
1212
import InfiniteLinearAlgebra: KronTrav, Block
1313
import FastTransforms: clenshaw!
1414

@@ -18,15 +18,15 @@ Random.seed!(0)
1818
x = Inclusion(ChebyshevInterval())
1919
@test singularities(x) == singularities(exp.(x)) == singularities(x.^2) ==
2020
singularities(x .+ 1) == singularities(1 .+ x) == singularities(x .+ x) ==
21-
LegendreWeight()
21+
NoSingularities()
2222
@test singularities(exp.(x) .* JacobiWeight(0.1,0.2)) ==
2323
singularities(JacobiWeight(0.1,0.2) .* exp.(x)) ==
2424
JacobiWeight(0.1,0.2)
2525

2626
x = Inclusion(0..1)
2727
@test singularities(x) == singularities(exp.(x)) == singularities(x.^2) ==
2828
singularities(x .+ 1) == singularities(1 .+ x) == singularities(x .+ x) ==
29-
legendreweight(0..1)
29+
NoSingularities()
3030
end
3131

3232
include("test_chebyshev.jl")

test/test_chebyshev.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,11 @@ import BandedMatrices: isbanded
582582
@testset "diff of truncation" begin
583583
@test MemoryLayout(diff(ChebyshevT()[:,1:5]) * randn(5)) isa ExpansionLayout
584584
end
585+
586+
@testset "ChebyshevInterval constructior" begin
587+
@test chebyshevt(ChebyshevInterval()) ChebyshevT()
588+
@test chebyshevu(ChebyshevInterval()) ChebyshevU()
589+
end
585590
end
586591

587592
struct QuadraticMap{T} <: Map{T} end
@@ -612,7 +617,7 @@ ContinuumArrays.invmap(::InvQuadraticMap{T}) where T = QuadraticMap{T}()
612617
g = chebyshevt(0..1) * [1:3; zeros(∞)]
613618
@test_broken (f + g)[0.1] f[0.1] + g[0.1] # ContinuumArrays needs to check maps are equal
614619

615-
@test ClassicalOrthogonalPolynomials.singularities(T) === LegendreWeight()[QuadraticMap()]
620+
@test ClassicalOrthogonalPolynomials.singularities(T) isa NoSingularities
616621
end
617622

618623
@testset "block structure" begin

test/test_jacobi.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using ClassicalOrthogonalPolynomials, FillArrays, BandedMatrices, ContinuumArrays, QuasiArrays, LazyArrays, LazyBandedMatrices, FastGaussQuadrature, Test
2-
import ClassicalOrthogonalPolynomials: recurrencecoefficients, basis, MulQuasiMatrix, arguments, Weighted, HalfWeighted, grammatrix
2+
import ClassicalOrthogonalPolynomials: recurrencecoefficients, basis, MulQuasiMatrix, arguments, Weighted, HalfWeighted, grammatrix, singularities
33

44
@testset "Jacobi" begin
55
@testset "JacobiWeight" begin
@@ -552,4 +552,13 @@ import ClassicalOrthogonalPolynomials: recurrencecoefficients, basis, MulQuasiMa
552552
@test expand(W, x -> (1-x^2)*exp(x))[0.1] (1-0.1^2)*exp(0.1)
553553
@test grid(W, 5) == grid(W.P, 5)
554554
end
555+
556+
@testset "JacobiWeight singularities" begin
557+
@test singularities(JacobiWeight(1,2) .* Jacobi(2,3)) == JacobiWeight(1,2)
558+
@test singularities(jacobiweight(1,2,1..2) .* jacobi(2,3,1..2)) == singularities(view(JacobiWeight(1,2) .* Jacobi(2,3), affine(1..2, -1..1),:)) == jacobiweight(1,2,1..2)
559+
end
560+
561+
@testset "ChebyshevInterval constructior" begin
562+
@test jacobi(1,2,ChebyshevInterval()) Jacobi(1,2)
563+
end
555564
end

test/test_legendre.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,5 +217,16 @@ import QuasiArrays: MulQuasiArray
217217
@test (P¹ \ diff(P,1))[1:10,1:10] == (P¹ \ diff(P))[1:10,1:10]
218218
@test (P² \ diff(P,2))[1:10,1:10] (P² \ diff(diff(P)))[1:10,1:10]
219219
@test (P³ \ diff(P,3))[1:10,1:10] (P³ \ diff(diff(diff(P))))[1:10,1:10]
220+
221+
# cover back compatibilty
222+
@test_throws MethodError ClassicalOrthogonalPolynomials.basis_singularities(nothing, nothing)
223+
end
224+
225+
@testset "singularities expand" begin
226+
x = Inclusion(1..2)
227+
@test basis(expand(fill(2, x))) == basis(expand(broadcast(+, exp.(x), cos.(x), x))) == legendre(x)
228+
end
229+
@testset "ChebyshevInterval constructor" begin
230+
@test legendre(ChebyshevInterval()) Legendre()
220231
end
221232
end

test/test_monic.jl

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,59 @@ using ClassicalOrthogonalPolynomials
22
using Test
33
using ClassicalOrthogonalPolynomials: Monic, _p0, orthogonalityweight, recurrencecoefficients
44

5-
@testset "Basic definition" begin
6-
P1 = Legendre()
7-
P2 = Normalized(P1)
8-
P3 = Monic(P1)
9-
@test P3.P == P2
10-
@test Monic(P3) === P3
11-
@test axes(P3) == axes(Legendre())
12-
@test Normalized(P3) === P3.P
13-
@test _p0(P3) == 1
14-
@test orthogonalityweight(P3) == orthogonalityweight(P1)
15-
@test sprint(show, MIME"text/plain"(), P3) == "Monic(Legendre())"
16-
end
5+
@testset "Monic" begin
6+
@testset "Basic definition" begin
7+
P1 = Legendre()
8+
P2 = Normalized(P1)
9+
P3 = Monic(P1)
10+
@test P3.P == P2
11+
@test Monic(P3) === P3
12+
@test axes(P3) == axes(Legendre())
13+
@test Normalized(P3) === P3.P
14+
@test _p0(P3) == 1
15+
@test orthogonalityweight(P3) == orthogonalityweight(P1)
16+
@test sprint(show, MIME"text/plain"(), P3) == "Monic(Legendre())"
17+
end
1718

18-
@testset "evaluation" begin
19-
function _pochhammer(x, n)
20-
y = one(x)
21-
for i in 0:(n-1)
22-
y *= (x + i)
19+
@testset "evaluation" begin
20+
function _pochhammer(x, n)
21+
y = one(x)
22+
for i in 0:(n-1)
23+
y *= (x + i)
24+
end
25+
return y
26+
end
27+
jacobi_kn = (α, β, n) -> _pochhammer(n + α + β + 1, n) / (2.0^n * factorial(n))
28+
ultra_kn = (λ, n) -> 2^n * _pochhammer(λ, n) / factorial(n)
29+
chebt_kn = n -> n == 0 ? 1.0 : 2.0 .^ (n - 1)
30+
chebu_kn = n -> 2.0^n
31+
leg_kn = n -> 2.0^n * _pochhammer(1 / 2, n) / factorial(n)
32+
lag_kn = n -> (-1)^n / factorial(n)
33+
herm_kn = n -> 2.0^n
34+
_Jacobi(α, β, x, n) = Jacobi(α, β)[x, n+1] / jacobi_kn(α, β, n)
35+
_Ultraspherical(λ, x, n) = Ultraspherical(λ)[x, n+1] / ultra_kn(λ, n)
36+
_ChebyshevT(x, n) = ChebyshevT()[x, n+1] / chebt_kn(n)
37+
_ChebyshevU(x, n) = ChebyshevU()[x, n+1] / chebu_kn(n)
38+
_Legendre(x, n) = Legendre()[x, n+1] / leg_kn(n)
39+
_Laguerre(α, x, n) = Laguerre(α)[x, n+1] / lag_kn(n)
40+
_Hermite(x, n) = Hermite()[x, n+1] / herm_kn(n)
41+
Ps = [
42+
Jacobi(2.0, 5.0) (x, n)->_Jacobi(2.0, 5.0, x, n)
43+
Ultraspherical(1.7) (x, n)->_Ultraspherical(1.7, x, n)
44+
ChebyshevT() _ChebyshevT
45+
ChebyshevU() _ChebyshevU
46+
Legendre() _Legendre
47+
Laguerre(1.5) (x, n)->_Laguerre(1.5, x, n)
48+
Hermite() _Hermite
49+
]
50+
for (P, _P) in eachrow(Ps)
51+
Q = Monic(P)
52+
@test Q[0.2, 1] == 1.0
53+
@test Q[0.25, 2] _P(0.25, 1)
54+
@test Q[0.17, 3] _P(0.17, 2)
55+
@test Q[0.4, 17] _P(0.4, 16)
56+
@test Q[0.9, 21] _P(0.9, 20)
57+
# @inferred Q[0.2, 5] # no longer inferred
2358
end
24-
return y
25-
end
26-
jacobi_kn = (α, β, n) -> _pochhammer(n + α + β + 1, n) / (2.0^n * factorial(n))
27-
ultra_kn = (λ, n) -> 2^n * _pochhammer(λ, n) / factorial(n)
28-
chebt_kn = n -> n == 0 ? 1.0 : 2.0 .^ (n - 1)
29-
chebu_kn = n -> 2.0^n
30-
leg_kn = n -> 2.0^n * _pochhammer(1 / 2, n) / factorial(n)
31-
lag_kn = n -> (-1)^n / factorial(n)
32-
herm_kn = n -> 2.0^n
33-
_Jacobi(α, β, x, n) = Jacobi(α, β)[x, n+1] / jacobi_kn(α, β, n)
34-
_Ultraspherical(λ, x, n) = Ultraspherical(λ)[x, n+1] / ultra_kn(λ, n)
35-
_ChebyshevT(x, n) = ChebyshevT()[x, n+1] / chebt_kn(n)
36-
_ChebyshevU(x, n) = ChebyshevU()[x, n+1] / chebu_kn(n)
37-
_Legendre(x, n) = Legendre()[x, n+1] / leg_kn(n)
38-
_Laguerre(α, x, n) = Laguerre(α)[x, n+1] / lag_kn(n)
39-
_Hermite(x, n) = Hermite()[x, n+1] / herm_kn(n)
40-
Ps = [
41-
Jacobi(2.0, 5.0) (x, n)->_Jacobi(2.0, 5.0, x, n)
42-
Ultraspherical(1.7) (x, n)->_Ultraspherical(1.7, x, n)
43-
ChebyshevT() _ChebyshevT
44-
ChebyshevU() _ChebyshevU
45-
Legendre() _Legendre
46-
Laguerre(1.5) (x, n)->_Laguerre(1.5, x, n)
47-
Hermite() _Hermite
48-
]
49-
for (P, _P) in eachrow(Ps)
50-
Q = Monic(P)
51-
@test Q[0.2, 1] == 1.0
52-
@test Q[0.25, 2] _P(0.25, 1)
53-
@test Q[0.17, 3] _P(0.17, 2)
54-
@test Q[0.4, 17] _P(0.4, 16)
55-
@test Q[0.9, 21] _P(0.9, 20)
56-
# @inferred Q[0.2, 5] # no longer inferred
5759
end
5860
end

test/test_ultraspherical.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,7 @@ using ClassicalOrthogonalPolynomials: grammatrix
204204
@test (C \ diff(U,1))[1:10,1:10] == (C \ diff(U))[1:10,1:10]
205205
@test (C³ \ diff(U,2))[1:10,1:10] == (C³ \ diff(diff(U)))[1:10,1:10]
206206
end
207+
@testset "ChebyshevInterval constructior" begin
208+
@test ultraspherical(2,ChebyshevInterval()) Ultraspherical(2)
209+
end
207210
end

0 commit comments

Comments
 (0)