Skip to content

Commit dd8bbb2

Browse files
authored
Separate type of parameters in Jacobi (#220)
* Update Project.toml * Update test_dynamicpolynomials.jl * Separate type of parameters in Jacobi * Import polynomialtype * fix tests * Update jacobi.jl * Update jacobi.jl * Update Project.toml
1 parent e9ee566 commit dd8bbb2

File tree

9 files changed

+48
-44
lines changed

9 files changed

+48
-44
lines changed

Project.toml

Lines changed: 3 additions & 3 deletions
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 <[email protected]>"]
4-
version = "0.13.9"
4+
version = "0.14.0"
55

66
[deps]
77
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -52,8 +52,8 @@ LazyArrays = "2.2"
5252
LazyBandedMatrices = "0.10, 0.11"
5353
MutableArithmetics = "1"
5454
QuasiArrays = "0.11"
55-
RecurrenceRelationshipArrays = "0.1"
56-
RecurrenceRelationships = "0.1"
55+
RecurrenceRelationshipArrays = "0.1.2"
56+
RecurrenceRelationships = "0.1.1"
5757
SpecialFunctions = "1.0, 2"
5858
julia = "1.10"
5959

src/ClassicalOrthogonalPolynomials.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import ContinuumArrays: Basis, Weight, basis_axes, @simplify, Identity, Abstract
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!,
44-
check_clenshaw_recurrences
44+
check_clenshaw_recurrences, polynomialtype
4545
import RecurrenceRelationshipArrays: initiateforwardrecurrence, Clenshaw
4646
import FastGaussQuadrature: jacobimoment
4747

@@ -254,7 +254,6 @@ function layout_broadcasted(::Tuple{PolynomialLayout,AbstractOPLayout}, ::typeof
254254
end
255255

256256

257-
258257
# function broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), a::BroadcastQuasiVector, C::OrthogonalPolynomial)
259258
# axes(a,1) == axes(C,1) || throw(DimensionMismatch())
260259
# # re-expand in OP basis

src/classical/chebyshev.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ chebyshevu(S::AbstractQuasiMatrix) = chebyshevu(axes(S,1))
6161
6262
computes the `n`-th Chebyshev polynomial of the first kind at `z`.
6363
"""
64-
chebyshevt(n::Integer, z) = Base.unsafe_getindex(ChebyshevT{typeof(z)}(), z, n+1)
64+
chebyshevt(n::Integer, z) = Base.unsafe_getindex(ChebyshevT{polynomialtype(typeof(z))}(), z, n+1)
6565
"""
6666
chebyshevt(n, z)
6767
6868
computes the `n`-th Chebyshev polynomial of the second kind at `z`.
6969
"""
70-
chebyshevu(n::Integer, z) = Base.unsafe_getindex(ChebyshevU{typeof(z)}(), z, n+1)
70+
chebyshevu(n::Integer, z) = Base.unsafe_getindex(ChebyshevU{polynomialtype(typeof(z))}(), z, n+1)
7171

7272
chebysevtweight(d::AbstractInterval{T}) where T = ChebyshevTWeight{float(T)}[affine(d,ChebyshevInterval{T}())]
7373
chebysevuweight(d::AbstractInterval{T}) where T = ChebyshevUWeight{float(T)}[affine(d,ChebyshevInterval{T}())]

src/classical/hermite.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ axes(::Hermite{T}) where T = (Inclusion{T}(ℝ), oneto(∞))
4646
computes the `n`-th Hermite polynomial, orthogonal with
4747
respec to `exp(-x^2)`, at `z`.
4848
"""
49-
hermiteh(n::Integer, z) = Base.unsafe_getindex(Hermite{typeof(z)}(), z, n+1)
49+
hermiteh(n::Integer, z) = Base.unsafe_getindex(Hermite{polynomialtype(typeof(z))}(), z, n+1)
5050

5151
broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), ::HermiteWeight{T}, ::Hermite{V}) where {T,V} = Weighted(Hermite{promote_type(T,V)}())
5252

src/classical/jacobi.jl

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,14 @@ The quasi-matrix representing Jacobi polynomials, where the first axes represent
136136
The eltype, when not specified, will be converted to a floating point data type.
137137
# Examples
138138
```jldoctest
139-
julia> J=Jacobi(0,0) # The eltype will be converted to float
140-
Jacobi(0.0, 0.0)
139+
julia> J=Jacobi(0, 0) # The eltype will be converted to float
140+
Jacobi(0, 0)
141141
142142
julia> axes(J)
143143
(Inclusion(-1.0 .. 1.0 (Chebyshev)), OneToInf())
144144
145145
julia> J[0,:] # Values of polynomials at x=0
146-
ℵ₀-element view(::Jacobi{Float64}, 0.0, :) with eltype Float64 with indices OneToInf():
146+
ℵ₀-element view(::Jacobi{Float64, $Int}, 0.0, :) with eltype Float64 with indices OneToInf():
147147
1.0
148148
0.0
149149
-0.5
@@ -162,12 +162,14 @@ julia> J0[0],J0[0.5]
162162
(1.0, 1.0)
163163
```
164164
"""
165-
struct Jacobi{T} <: AbstractJacobi{T}
166-
a::T
167-
b::T
168-
Jacobi{T}(a, b) where T = new{T}(convert(T,a), convert(T,b))
165+
struct Jacobi{T,V} <: AbstractJacobi{T}
166+
a::V
167+
b::V
168+
Jacobi{T,V}(a, b) where {T,V} = new{T,V}(convert(V,a), convert(V,b))
169169
end
170170

171+
Jacobi{T}(a::V, b::V) where {T,V} = Jacobi{T,V}(a, b)
172+
Jacobi{T}(a, b) where T = Jacobi{T}(promote(a,b)...)
171173
Jacobi(a::V, b::T) where {T,V} = Jacobi{float(promote_type(T,V))}(a, b)
172174

173175
AbstractQuasiArray{T}(w::Jacobi) where T = Jacobi{T}(w.a, w.b)
@@ -181,13 +183,13 @@ The [`Jacobi`](@ref) polynomials affine-mapped to interval `d`.
181183
# Examples
182184
```jldoctest
183185
julia> J = jacobi(1, 1, 0..1)
184-
Jacobi(1.0, 1.0) affine mapped to 0 .. 1
186+
Jacobi(1, 1) affine mapped to 0 .. 1
185187
186188
julia> axes(J)
187189
(Inclusion(0 .. 1), OneToInf())
188190
189191
julia> J[0,:]
190-
ℵ₀-element view(::Jacobi{Float64}, -1.0, :) with eltype Float64 with indices OneToInf():
192+
ℵ₀-element view(::Jacobi{Float64, $Int}, -1.0, :) with eltype Float64 with indices OneToInf():
191193
1.0
192194
-2.0
193195
3.0
@@ -215,8 +217,8 @@ basis_singularities(w::JacobiWeight) = Weighted(Jacobi(w.a, w.b))
215217
computes the `n`-th Jacobi polynomial, orthogonal with
216218
respec to `(1-x)^a*(1+x)^b`, at `z`.
217219
"""
218-
jacobip(n::Integer, a, b, z) = Base.unsafe_getindex(Jacobi{promote_type(typeof(a), typeof(b), typeof(z))}(a,b), z, n+1)
219-
normalizedjacobip(n::Integer, a, b, z) = Base.unsafe_getindex(Normalized(Jacobi{promote_type(typeof(a), typeof(b), typeof(z))}(a,b)), z, n+1)
220+
jacobip(n::Integer, a, b, z) = Base.unsafe_getindex(Jacobi{polynomialtype(typeof(a), typeof(b), typeof(z))}(a,b), z, n+1)
221+
normalizedjacobip(n::Integer, a, b, z) = Base.unsafe_getindex(Normalized(Jacobi{polynomialtype(typeof(a), typeof(b), typeof(z))}(a,b)), z, n+1)
220222

221223
OrthogonalPolynomial(w::JacobiWeight) = Jacobi(w.a, w.b)
222224
orthogonalityweight(P::Jacobi) = JacobiWeight(P.a, P.b)
@@ -273,15 +275,16 @@ axes(::AbstractJacobi{T}) where T = (Inclusion{T}(ChebyshevInterval{real(T)}()),
273275
==(P::Legendre, Q::Jacobi) = Jacobi(P) == Q
274276
==(P::Jacobi, Q::Legendre) = P == Jacobi(Q)
275277
==(A::WeightedJacobi, B::WeightedJacobi) = A.args == B.args
276-
==(A::WeightedJacobi, B::Jacobi{T}) where T = A == JacobiWeight(zero(T),zero(T)).*B
278+
==(A::WeightedJacobi, B::Jacobi{T,V}) where {T,V} = A == JacobiWeight(zero(V),zero(V)).*B
277279
==(A::WeightedJacobi, B::Legendre) = A == Jacobi(B)
278280
==(A::Legendre, B::WeightedJacobi) = Jacobi(A) == B
279-
==(A::Jacobi{T}, B::WeightedJacobi) where T = JacobiWeight(zero(T),zero(T)).*A == B
281+
==(A::Jacobi{T,V}, B::WeightedJacobi) where {T,V} = JacobiWeight(zero(V),zero(V)).*A == B
280282
==(A::Legendre, B::Weighted{<:Any,<:AbstractJacobi}) = A == B.P
281283
==(A::Weighted{<:Any,<:AbstractJacobi}, B::Legendre) = A.P == B
282284

283285
show(io::IO, P::Jacobi) = summary(io, P)
284-
summary(io::IO, P::Jacobi) = print(io, "Jacobi($(P.a), $(P.b))")
286+
summary(io::IO, P::Jacobi{Float64}) = print(io, "Jacobi($(P.a), $(P.b))")
287+
summary(io::IO, P::Jacobi{T}) where T = print(io, "Jacobi{$T}($(P.a), $(P.b))")
285288

286289
###
287290
# transforms
@@ -523,22 +526,22 @@ diff(S::Jacobi; dims=1) = ApplyQuasiMatrix(*, Jacobi(S.a+1,S.b+1), _BandedMatrix
523526

524527
function diff(S::Jacobi{T}, m::Integer; dims=1) where T
525528
D = _BandedMatrix((pochhammer.((S.a + S.b+1):∞, m)/convert(T, 2)^m)', ℵ₀, -m, m)
526-
ApplyQuasiMatrix(*, Jacobi(S.a+m,S.b+m), D)
529+
ApplyQuasiMatrix(*, Jacobi{T}(S.a+m,S.b+m), D)
527530
end
528531

529532

530533
#L_6^t
531-
function diff(WS::HalfWeighted{:a,<:Any,<:Jacobi}; dims=1)
534+
function diff(WS::HalfWeighted{:a,T,<:Jacobi}; dims=1) where T
532535
S = WS.P
533536
a,b = S.a, S.b
534-
ApplyQuasiMatrix(*, HalfWeighted{:a}(Jacobi(a-1,b+1)), Diagonal(-(a:∞)))
537+
ApplyQuasiMatrix(*, HalfWeighted{:a}(Jacobi{T}(a-1,b+1)), Diagonal(-(a:∞)))
535538
end
536539

537540
#L_6
538-
function diff(WS::HalfWeighted{:b,<:Any,<:Jacobi}; dims=1)
541+
function diff(WS::HalfWeighted{:b,T,<:Jacobi}; dims=1) where T
539542
S = WS.P
540543
a,b = S.a, S.b
541-
ApplyQuasiMatrix(*, HalfWeighted{:b}(Jacobi(a+1,b-1)), Diagonal(b:∞))
544+
ApplyQuasiMatrix(*, HalfWeighted{:b}(Jacobi{T}(a+1,b-1)), Diagonal(b:∞))
542545
end
543546

544547
for ab in (:(:a), :(:b))
@@ -549,7 +552,7 @@ for ab in (:(:a), :(:b))
549552
end
550553

551554

552-
function diff(WS::Weighted{<:Any,<:Jacobi}; dims=1)
555+
function diff(WS::Weighted{T,<:Jacobi}; dims=1) where T
553556
# L_1^t
554557
S = WS.P
555558
a,b = S.a, S.b
@@ -560,13 +563,13 @@ function diff(WS::Weighted{<:Any,<:Jacobi}; dims=1)
560563
elseif iszero(b)
561564
diff(HalfWeighted{:a}(S))
562565
else
563-
ApplyQuasiMatrix(*, Weighted(Jacobi(a-1, b-1)), _BandedMatrix((-2*(1:∞))', ℵ₀, 1,-1))
566+
ApplyQuasiMatrix(*, Weighted(Jacobi{T}(a-1, b-1)), _BandedMatrix((-2*(1:∞))', ℵ₀, 1,-1))
564567
end
565568
end
566569

567570

568571
# Jacobi(a-1,b-1)\ (D*w*Jacobi(a,b))
569-
function diff(WS::WeightedJacobi; dims=1)
572+
function diff(WS::WeightedJacobi{T}; dims=1) where T
570573
w,S = WS.args
571574
a,b = S.a, S.b
572575
if isorthogonalityweighted(WS) # L_1^t
@@ -582,22 +585,22 @@ function diff(WS::WeightedJacobi; dims=1)
582585
# D * ((1+x)^w.b * P^(a,b)) == D * ((1+x)^(w.b-b) * (1+x)^b * P^(a,b))
583586
# == (1+x)^(w.b-1) * (w.b-b) * P^(a,b) + (1+x)^(w.b-b) * D*((1+x)^b*P^(a,b))
584587
# == (1+x)^(w.b-1) * P^(a+1,b) ((w.b-b) * C2 + C1 * W)
585-
W = HalfWeighted{:b}(Jacobi(a+1, b-1)) \ diff(HalfWeighted{:b}(S))
586-
J = Jacobi(a+1,b) # range Jacobi
587-
C1 = J \ Jacobi(a+1, b-1)
588-
C2 = J \ Jacobi(a,b)
588+
W = HalfWeighted{:b}(Jacobi{T}(a+1, b-1)) \ diff(HalfWeighted{:b}(S))
589+
J = Jacobi{T}(a+1,b) # range Jacobi
590+
C1 = J \ Jacobi{T}(a+1, b-1)
591+
C2 = J \ Jacobi{T}(a,b)
589592
ApplyQuasiMatrix(*, JacobiWeight(w.a,w.b-1) .* J, (w.b-b) * C2 + C1 * W)
590593
elseif iszero(w.b)
591-
W = HalfWeighted{:a}(Jacobi(a-1, b+1)) \ diff(HalfWeighted{:a}(S))
592-
J = Jacobi(a,b+1) # range Jacobi
593-
C1 = J \ Jacobi(a-1, b+1)
594-
C2 = J \ Jacobi(a,b)
594+
W = HalfWeighted{:a}(Jacobi{T}(a-1, b+1)) \ diff(HalfWeighted{:a}(S))
595+
J = Jacobi{T}(a,b+1) # range Jacobi
596+
C1 = J \ Jacobi{T}(a-1, b+1)
597+
C2 = J \ Jacobi{T}(a,b)
595598
ApplyQuasiMatrix(*, JacobiWeight(w.a-1,w.b) .* J, -(w.a-a) * C2 + C1 * W)
596599
elseif iszero(a) && iszero(b) # Legendre
597600
# D * ((1+x)^w.b * (1-x)^w.a * P))
598601
# == (1+x)^(w.b-1) * (1-x)^(w.a-1) * ((1-x) * (w.b) * P - (1+x) * w.a * P + (1-x^2) * D * P)
599602
# == (1+x)^(w.b-1) * (1-x)^(w.a-1) * ((1-x) * (w.b) * P - (1+x) * w.a * P + P * L * W)
600-
J = Jacobi(a+1,b+1) # range space
603+
J = Jacobi{T}(a+1,b+1) # range space
601604
W = J \ diff(S)
602605
X = jacobimatrix(S)
603606
L = S \ Weighted(J)
@@ -608,9 +611,9 @@ function diff(WS::WeightedJacobi; dims=1)
608611
# == (1+x)^(w.b-1) * (1-x)^(w.a-1) * ((1-x) * (w.b-b) * P^(a,b) + (1+x) * (a-w.a) * P^(a,b))
609612
# + (1+x)^(w.b-b) * (1-x)^(w.a-a) * D * ((1+x)^b * (1-x)^a * P^(a,b)))
610613

611-
W = Weighted(Jacobi(a-1,b-1)) \ diff(Weighted(S))
614+
W = Weighted(Jacobi{T}(a-1,b-1)) \ diff(Weighted(S))
612615
X = jacobimatrix(S)
613-
C = S \ Jacobi(a-1,b-1)
616+
C = S \ Jacobi{T}(a-1,b-1)
614617
(JacobiWeight(w.a-1,w.b-1) .* S) * (((w.b-b+a-w.a)*I+(a-w.a-w.b+b) * X) + C*W)
615618
end
616619
end

src/classical/laguerre.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ axes(::Laguerre{T}) where T = (Inclusion(HalfLine{T}()), oneto(∞))
4545
computes the `n`-th generalized Laguerre polynomial, orthogonal with
4646
respec to `x^α * exp(-x)`, at `z`.
4747
"""
48-
laguerrel(n::Integer, α, z::Number) = Base.unsafe_getindex(Laguerre{promote_type(typeof(α), typeof(z))}(α), z, n+1)
48+
laguerrel(n::Integer, α, z::Number) = Base.unsafe_getindex(Laguerre{polynomialtype(typeof(α), typeof(z))}(α), z, n+1)
4949

5050
"""
5151
laguerrel(n, z)

src/classical/ultraspherical.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const WeightedUltraspherical{T} = WeightedBasis{T,<:UltrasphericalWeight,<:Ultra
5454

5555
orthogonalityweight(C::Ultraspherical) = UltrasphericalWeight(C.λ)
5656

57-
ultrasphericalc(n::Integer, λ, z) = Base.unsafe_getindex(Ultraspherical{promote_type(typeof(λ),typeof(z))}(λ), z, n+1)
57+
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}()), :]
5959

6060
==(a::Ultraspherical, b::Ultraspherical) = a.λ == b.λ

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ end
8484

8585
@testset "Issue #179" begin
8686
@test startswith(sprint(show, MIME"text/plain"(), Chebyshev()[0.3, :]; context=(:compact=>true, :limit=>true)), "ℵ₀-element view(::ChebyshevT{Float64}, 0.3, :)")
87-
@test startswith(sprint(show, MIME"text/plain"(), Jacobi(0.2, 0.5)[-0.7, :]; context=(:compact=>true, :limit=>true)), "ℵ₀-element view(::Jacobi{Float64}, -0.7, :)")
87+
@test startswith(sprint(show, MIME"text/plain"(), Jacobi(0.2, 0.5)[-0.7, :]; context=(:compact=>true, :limit=>true)), "ℵ₀-element view(::Jacobi{Float64, Float64}, -0.7, :)")
8888
end
8989

9090
include("test_dynamicpolynomials.jl")

test/test_dynamicpolynomials.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ using DynamicPolynomials, ClassicalOrthogonalPolynomials, Test
99
@test chebyshevu(5,x) == ultrasphericalc(5,1,x) == 6x - 32x^3 + 32x^5
1010
@test legendrep(5,x) (15x - 70x^3 + 63x^5)/8
1111
@test hermiteh(5,x) == 120x - 160x^3 + 32x^5
12+
@test jacobip(5,1,0,x) (5 + 35x - 70x^2 - 210x^3 + 105x^4 + 231x^5)/16
13+
@test jacobip(5,0.1,-0.2,x) 3*(3306827 + 75392855x - 37466770x^2 - 350553810x^3 + 47705335x^4 + 314855211x^5)/128000000
1214
end

0 commit comments

Comments
 (0)