Skip to content

Commit a51bef3

Browse files
committed
Revert "Merge branch 'master' into master"
This reverts commit 0bb78e2.
1 parent 0bb78e2 commit a51bef3

File tree

4 files changed

+25
-108
lines changed

4 files changed

+25
-108
lines changed

src/SemiclassicalOrthogonalPolynomials.jl

Lines changed: 21 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ import Base: getindex, axes, size, \, /, *, +, -, summary, ==, copy, sum, unsafe
77

88
import ArrayLayouts: MemoryLayout, ldiv, diagonaldata, subdiagonaldata, supdiagonaldata
99
import BandedMatrices: bandwidths, AbstractBandedMatrix, BandedLayout, _BandedMatrix
10-
import LazyArrays: resizedata!, paddeddata, CachedVector, CachedMatrix, CachedAbstractVector, LazyMatrix, LazyVector, arguments, ApplyLayout, colsupport, AbstractCachedVector, ApplyArray,
10+
import LazyArrays: resizedata!, paddeddata, CachedVector, CachedMatrix, CachedAbstractVector, LazyMatrix, LazyVector, arguments, ApplyLayout, colsupport, AbstractCachedVector,
1111
AccumulateAbstractVector, LazyVector, AbstractCachedMatrix, BroadcastLayout
1212
import ClassicalOrthogonalPolynomials: OrthogonalPolynomial, recurrencecoefficients, jacobimatrix, normalize, _p0, UnitInterval, orthogonalityweight, NormalizedOPLayout,
1313
Bidiagonal, Tridiagonal, SymTridiagonal, symtridiagonalize, normalizationconstant, LanczosPolynomial,
1414
OrthogonalPolynomialRatio, Weighted, WeightLayout, UnionDomain, oneto, WeightedBasis, HalfWeighted,
1515
golubwelsch, AbstractOPLayout, weight, WeightedOPLayout
1616
import SingularIntegrals: Associated, associated, Hilbert
17-
1817
import InfiniteArrays: OneToInf, InfUnitRange
1918
import ContinuumArrays: basis, Weight, @simplify, AbstractBasisLayout, BasisLayout, MappedBasisLayout, grid, plotgrid, _equals, ExpansionLayout
2019
import FillArrays: SquareEye
@@ -95,13 +94,20 @@ RaisedOP(Q, y::Number) = RaisedOP(Q, OrthogonalPolynomialRatio(Q,y))
9594
function jacobimatrix(P::RaisedOP{T}) where T
9695
= P.
9796
X = jacobimatrix(P.Q)
98-
a,b = view(X,band(0)), view(X,band(1)) # a,b = diagonaldata(X), supdiagonaldata(X)
97+
a,b = diagonaldata(X), supdiagonaldata(X)
9998
# non-normalized lower diag of Jacobi
10099
v = Vcat(zero(T),b .* ℓ)
101100
c = BroadcastVector((ℓ,a,b,sa,v) ->*a + b - b*^2 - sa*+*v, ℓ, a, b, a[2:∞], v)
102101
Tridiagonal(c, BroadcastVector((ℓ,a,b,v) -> a - b *+ v, ℓ,a,b,v), b)
103102
end
104103

104+
105+
106+
107+
108+
109+
110+
105111
"""
106112
the bands of the Jacobi matrix
107113
"""
@@ -136,6 +142,7 @@ SemiclassicalJacobiBand{dv}(a,b,ℓ) where dv = SemiclassicalJacobiBand{dv,promo
136142
copy(r::SemiclassicalJacobiBand) = r # immutable
137143

138144

145+
139146
"""
140147
SemiclassicalJacobi(t, a, b, c)
141148
@@ -170,7 +177,7 @@ function semiclassical_jacobimatrix(t, a, b, c)
170177
if a == 0 && b == 0 && c == -1
171178
# for this special case we can generate the Jacobi operator explicitly
172179
N = (1:∞)
173-
α = neg1c_αcfs(t) # cached coefficients
180+
α = T.(neg1c_αcfs(t)) # cached coefficients
174181
A = Vcat((α[1]+1)/2 , -N./(N.*4 .- 2).*α .+ (N.+1)./(N.*4 .+ 2).*α[2:end].+1/2)
175182
C = -(N)./(N.*4 .- 2)
176183
B = Vcat((α[1]^2*3-α[1]*α[2]*2-1)/6 , -(N)./(N.*4 .+ 2).*α[2:end]./α)
@@ -180,15 +187,10 @@ function semiclassical_jacobimatrix(t, a, b, c)
180187
P = jacobi(b, a, UnitInterval{T}())
181188
iszero(c) && return symtridiagonalize(jacobimatrix(P))
182189
x = axes(P,1)
183-
if iseven(c) # QR case
184-
return qr_jacobimatrix(x->(t.-x).^(c÷2), Normalized(jacobi(a,b,UnitInterval{T}())))
185-
elseif isodd(c)
186-
return semiclassical_jacobimatrix(SemiclassicalJacobi(t, a, b, c-1), a, b, c)
187-
else # if c is not an even integer, use Lanczos for now
188-
return jacobimatrix(LanczosPolynomial(@.(x^a * (1-x)^b * (t-x)^c), P))
189-
end
190+
jacobimatrix(LanczosPolynomial(@.(x^a * (1-x)^b * (t-x)^c), P))
190191
end
191192

193+
192194
function symraised_jacobimatrix(Q, y)
193195
= OrthogonalPolynomialRatio(Q,y)
194196
X = jacobimatrix(Q)
@@ -197,35 +199,9 @@ function symraised_jacobimatrix(Q, y)
197199
end
198200

199201
function semiclassical_jacobimatrix(Q::SemiclassicalJacobi, a, b, c)
200-
# special cases
201-
if iszero(a) && iszero(b) && c == -1 # (a,b,c) = (0,0,-1) special case
202+
if iszero(a) && iszero(b) && c == -1 # (a,b,c) = (0,0,-1) special case
202203
semiclassical_jacobimatrix(Q.t, a, b, c)
203-
elseif iszero(c) # classical Jacobi polynomial special case
204-
jacobimatrix(SemiclassicalJacobi(Q.t, Q.a, Q.b, Q.c))
205-
elseif a == Q.a && b == Q.b && c == Q.c # same basis
206-
jacobimatrix(Q)
207-
end
208-
209-
# QR decomposition approach for raising
210-
Δa = a-Q.a
211-
Δb = b-Q.b
212-
Δc = c-Q.c
213-
if iseven(a-Q.a) && iseven(b-Q.b) && iseven(c-Q.c) && Δa0 && Δb0 && Δc0
214-
M = Diagonal(Ones(∞))
215-
if !iszero(Δa)
216-
M = ApplyArray(*,M,(Q.X)^((a-Q.a)÷2))
217-
end
218-
if !iszero(Δb)
219-
M = ApplyArray(*,M,(I-Q.X)^((b-Q.b)÷2))
220-
end
221-
if !iszero(Δc)
222-
M = ApplyArray(*,M,(Q.t*I-Q.X)^((c-Q.c)÷2))
223-
end
224-
return qr_jacobimatrix(M,Q,false)
225-
end
226-
227-
# Fallback from decomposition methods
228-
if a == Q.a+1 && b == Q.b && c == Q.c # raising by 1
204+
elseif a == Q.a+1 && b == Q.b && c == Q.c # raising by 1
229205
symraised_jacobimatrix(Q, 0)
230206
elseif a == Q.a && b == Q.b+1 && c == Q.c
231207
symraised_jacobimatrix(Q, 1)
@@ -237,18 +213,20 @@ function semiclassical_jacobimatrix(Q::SemiclassicalJacobi, a, b, c)
237213
symlowered_jacobimatrix(Q, :a)
238214
elseif a == Q.a && b == Q.b-1 && c == Q.c
239215
symlowered_jacobimatrix(Q, :b)
240-
elseif a > Q.a # iterative raising by 1
216+
elseif a > Q.a # iterative raising
241217
semiclassical_jacobimatrix(SemiclassicalJacobi(Q.t, Q.a+1, Q.b, Q.c, Q), a, b, c)
242218
elseif b > Q.b
243219
semiclassical_jacobimatrix(SemiclassicalJacobi(Q.t, Q.a, Q.b+1, Q.c, Q), a, b, c)
244220
elseif c > Q.c
245221
semiclassical_jacobimatrix(SemiclassicalJacobi(Q.t, Q.a, Q.b, Q.c+1, Q), a, b, c)
246-
elseif b < Q.b # iterative lowering by 1
222+
elseif b < Q.b # iterative lowering
247223
semiclassical_jacobimatrix(SemiclassicalJacobi(Q.t, Q.a, Q.b-1, Q.c, Q), a, b, c)
248224
elseif c < Q.c
249225
semiclassical_jacobimatrix(SemiclassicalJacobi(Q.t, Q.a, Q.b, Q.c-1, Q), a, b, c)
250226
elseif a < Q.a
251227
semiclassical_jacobimatrix(SemiclassicalJacobi(Q.t, Q.a-1, Q.b, Q.c, Q), a, b, c)
228+
elseif a == Q.a && b == Q.b && c == Q.c # same basis
229+
jacobimatrix(Q)
252230
else
253231
error("Not Implemented")
254232
end
@@ -314,46 +292,6 @@ function semijacobi_ldiv(P::SemiclassicalJacobi, Q)
314292
(P \ R) * _p0(R̃) * (R̃ \ Q)
315293
end
316294

317-
# returns conversion operator from SemiclassicalJacobi P to SemiclassicalJacobi Q.
318-
function semijacobi_ldiv(Q::SemiclassicalJacobi,P::SemiclassicalJacobi)
319-
@assert Q.t P.t
320-
# For polynomial modifications, use Cholesky. Use Lanzos otherwise.
321-
M = Diagonal(Ones(∞))
322-
(Q == P) && return M
323-
Δa = Q.a-P.a
324-
Δb = Q.b-P.b
325-
Δc = Q.c-P.c
326-
if iseven(Δa) && iseven(Δb) && iseven(Δc)
327-
if !iszero(Q.a-P.a)
328-
M = ApplyArray(*,M,(P.X)^((Q.a-P.a)÷2))
329-
end
330-
if !iszero(Q.b-P.b)
331-
M = ApplyArray(*,M,(I-P.X)^((Q.b-P.b)÷2))
332-
end
333-
if !iszero(Q.c-P.c)
334-
M = ApplyArray(*,M,(Q.t*I-P.X)^((Q.c-P.c)÷2))
335-
end
336-
K = qr(M).R
337-
return ApplyArray(*, Diagonal(sign.(view(K,band(0))).*Fill(abs.(1/K[1]),∞)), K) # match our normalization choice P_0(x) = 1
338-
elseif isinteger(Δa) && isinteger(Δb) && isinteger(Δc)
339-
if !iszero(Q.a-P.a)
340-
M = ApplyArray(*,M,(P.X)^(Q.a-P.a))
341-
end
342-
if !iszero(Q.b-P.b)
343-
M = ApplyArray(*,M,(I-P.X)^(Q.b-P.b))
344-
end
345-
if !iszero(Q.c-P.c)
346-
M = ApplyArray(*,M,(Q.t*I-P.X)^(Q.c-P.c))
347-
end
348-
K = cholesky(Symmetric(M)).U
349-
return ApplyArray(*, Diagonal(Fill(1/K[1],∞)), K) # match our normalization choice P_0(x) = 1
350-
else # fallback option for non-integer weight modification
351-
R = SemiclassicalJacobi(P.t, mod(P.a,-1), mod(P.b,-1), mod(P.c,-1))
352-
= toclassical(R)
353-
return (P \ R) * _p0(R̃) * (R̃ \ Q)
354-
end
355-
end
356-
357295
struct SemiclassicalJacobiLayout <: AbstractOPLayout end
358296
MemoryLayout(::Type{<:SemiclassicalJacobi}) = SemiclassicalJacobiLayout()
359297

@@ -385,7 +323,6 @@ function copy(L::Ldiv{SemiclassicalJacobiLayout,SemiclassicalJacobiLayout})
385323
(inv(M_Q) * L') * M_P
386324
end
387325

388-
\(A::SemiclassicalJacobi, B::SemiclassicalJacobi) = semijacobi_ldiv(A, B)
389326
\(A::LanczosPolynomial, B::SemiclassicalJacobi) = semijacobi_ldiv(A, B)
390327
\(A::SemiclassicalJacobi, B::LanczosPolynomial) = semijacobi_ldiv(A, B)
391328
function \(w_A::WeightedSemiclassicalJacobi, w_B::WeightedSemiclassicalJacobi)
@@ -519,27 +456,7 @@ function SemiclassicalJacobiFamily{T}(data::Vector, t, a, b, c) where T
519456
end
520457

521458
SemiclassicalJacobiFamily(t, a, b, c) = SemiclassicalJacobiFamily{float(promote_type(typeof(t),eltype(a),eltype(b),eltype(c)))}(t, a, b, c)
522-
function SemiclassicalJacobiFamily{T}(t, a, b, c) where T
523-
ℓa = length(a)
524-
ℓb = length(b)
525-
ℓc = length(c)
526-
# We need to start with a hierarchy containing two entries
527-
if ℓa > 1 && ℓb > 1 && ℓc > 1
528-
return SemiclassicalJacobiFamily{T}([SemiclassicalJacobi{T}(t, first(a), first(b), first(c)),SemiclassicalJacobi{T}(t, a[2], b[2], c[2])], t, a, b, c)
529-
elseif ℓb > 1 && ℓc > 1
530-
return SemiclassicalJacobiFamily{T}([SemiclassicalJacobi{T}(t, first(a), first(b), first(c)),SemiclassicalJacobi{T}(t, first(a), b[2], c[2])], t, a, b, c)
531-
elseif ℓa > 1 && ℓc > 1
532-
return SemiclassicalJacobiFamily{T}([SemiclassicalJacobi{T}(t, first(a), first(b), first(c)),SemiclassicalJacobi{T}(t, a[2], first(b), c[2])], t, a, b, c)
533-
elseif ℓa > 1 && ℓb > 1
534-
return SemiclassicalJacobiFamily{T}([SemiclassicalJacobi{T}(t, first(a), first(b), first(c)),SemiclassicalJacobi{T}(t, a[2], b[2], first(c))], t, a, b, c)
535-
elseif ℓc > 1
536-
return SemiclassicalJacobiFamily{T}([SemiclassicalJacobi{T}(t, first(a), first(b), first(c)),SemiclassicalJacobi{T}(t, first(a), first(b), c[2])], t, a, b, c)
537-
elseif ℓa > 1
538-
return SemiclassicalJacobiFamily{T}([SemiclassicalJacobi{T}(t, first(a), first(b), first(c)),SemiclassicalJacobi{T}(t, a[2], first(b), first(c))], t, a, b, c)
539-
else #if ℓb > 1
540-
return SemiclassicalJacobiFamily{T}([SemiclassicalJacobi{T}(t, first(a), first(b), first(c)),SemiclassicalJacobi{T}(t, first(a), b[2], first(c))], t, a, b, c)
541-
end
542-
end
459+
SemiclassicalJacobiFamily{T}(t, a, b, c) where T = SemiclassicalJacobiFamily{T}([SemiclassicalJacobi{T}(t, first(a), first(b), first(c))], t, a, b, c)
543460

544461
Base.broadcasted(::Type{SemiclassicalJacobi}, t::Number, a::Number, b::Number, c::Number) = SemiclassicalJacobi(t, a, b, c)
545462
Base.broadcasted(::Type{SemiclassicalJacobi{T}}, t::Number, a::Number, b::Number, c::Number) where T = SemiclassicalJacobi{T}(t, a, b, c)
@@ -555,7 +472,7 @@ _broadcast_getindex(a::Number,k) = a
555472
function LazyArrays.cache_filldata!(P::SemiclassicalJacobiFamily, inds::AbstractUnitRange)
556473
t,a,b,c = P.t,P.a,P.b,P.c
557474
for k in inds
558-
P.data[k] = SemiclassicalJacobi(t, _broadcast_getindex(a,k), _broadcast_getindex(b,k), _broadcast_getindex(c,k), P.data[k-2])
475+
P.data[k] = SemiclassicalJacobi(t, _broadcast_getindex(a,k), _broadcast_getindex(b,k), _broadcast_getindex(c,k), P.data[k-1])
559476
end
560477
P
561478
end

src/lowering.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###########
2-
# Generic fallback methods for obtaining Jacobi matrices with one of the a, b and c parameters lowered by 1.
2+
# Generic methods for obtaining Jacobi matrices with one of the a, b and c parameters lowered by 1.
33
# passing symbols :a, :b or :c into lowindex determines which parameter is lowered
44
######
55
function initialα_gen(P::SemiclassicalJacobi, lowindex::Symbol)
@@ -163,8 +163,8 @@ end
163163

164164
###########
165165
# Methods for the special case of computing SemiclassicalJacobi(t,0,0,-1)
166-
# As this can be built from SemiclassicalJacobi(t,0,0,0) which is just shifted and normalized Legendre(), we have more explicit methods at our disposal due to explicitly known coefficients for the Legendre bases.
167166
######
167+
# As this can be built from SemiclassicalJacobi(t,0,0,0) which is just shifted and normalized Legendre(), we have more explicit methods at our disposal due to explicitly known coefficients for the Legendre bases.
168168

169169
###
170170
# α coefficients implementation, cached, direct and via recurrences

src/twoband.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ function jacobimatrix(R::TwoBandJacobi{T}) where T
9898
# M = (L / L[1,1])' # equal to R.Q \ R.P
9999

100100
Tridiagonal(Interlace(L.dv/L[1,1], (ρ^2-1) * L.ev), Zeros{T}(∞), Interlace((1-ρ^2) * L.dv,L.ev/(-L[1,1])))
101+
# Tridiagonal(Interlace(L.dv/L[1,1], (1-ρ^2) * L.ev), Zeros{T}(∞), Interlace((1-ρ^2) * L.dv, L.ev/L[1,1]))
101102
end
102103

103104

test/runtests.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ end
117117
@testset "Mass matrix" begin
118118
@test (T'*(w_T .* T))[1:10,1:10] sum(w_T)I
119119
M = W'*(w_W .* W)
120-
@test (sum(w_T)*inv(R[1:10,1:10])'L[1:10,1:10]) M[1:10,1:10]
120+
@test (sum(w_T)*inv(R)'L)[1:10,1:10] M[1:10,1:10]
121121
@test T[0.1,1:10]' W[0.1,1:10]' * R[1:10,1:10]
122122
end
123123
end
@@ -450,4 +450,3 @@ end
450450
include("test_derivative.jl")
451451
include("test_twoband.jl")
452452
include("test_lowering.jl")
453-

0 commit comments

Comments
 (0)