Skip to content

Commit 7039fb3

Browse files
authored
2 band Hilbert (#30)
* 2 band Hilbert * Work on HalfWeighted derivatives * Update Project.toml * tests should pass * Update runtests.jl * expansion for associated TwoBand * Update test_twoband.jl * v0.0.7
1 parent 4e9e773 commit 7039fb3

File tree

6 files changed

+148
-15
lines changed

6 files changed

+148
-15
lines changed

Project.toml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,33 @@
11
name = "SemiclassicalOrthogonalPolynomials"
22
uuid = "291c01f3-23f6-4eb6-aeb0-063a639b53f2"
33
authors = ["Sheehan Olver <[email protected]>"]
4-
version = "0.0.6"
4+
version = "0.0.7"
55

66
[deps]
77
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
88
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
99
ClassicalOrthogonalPolynomials = "b30e2e7b-c4ee-47da-9d5f-2c5c27239acd"
1010
ContinuumArrays = "7ae1f121-cc2c-504b-ac30-9b923412ae5c"
1111
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
12+
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
1213
HypergeometricFunctions = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
1314
InfiniteArrays = "4858937d-0d70-526a-a4dd-2d5cb5dd786c"
1415
LazyArrays = "5078a376-72f3-5289-bfd5-ec5146d43c02"
16+
LazyBandedMatrices = "d7e5e226-e90b-4449-9968-0f923699bf6f"
1517
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1618
QuasiArrays = "c4ea9172-b204-11e9-377d-29865faadc5c"
1719
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
1820

1921
[compat]
2022
ArrayLayouts = "0.6"
2123
BandedMatrices = "0.16"
22-
ClassicalOrthogonalPolynomials = "0.3"
23-
ContinuumArrays = "0.6.4"
24+
ClassicalOrthogonalPolynomials = "0.3.5"
25+
ContinuumArrays = "0.7"
2426
FillArrays = "0.11.5"
2527
HypergeometricFunctions = "0.3.4"
2628
InfiniteArrays = "0.10.2"
2729
LazyArrays = "0.21.3"
28-
QuasiArrays = "0.4.9"
30+
QuasiArrays = "0.5"
2931
SpecialFunctions = "0.10, 1.0"
3032
julia = "1.5"
3133

src/SemiclassicalOrthogonalPolynomials.jl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ module SemiclassicalOrthogonalPolynomials
22
using ClassicalOrthogonalPolynomials, FillArrays, LazyArrays, ArrayLayouts, QuasiArrays, InfiniteArrays, ContinuumArrays, LinearAlgebra, BandedMatrices,
33
SpecialFunctions, HypergeometricFunctions
44

5-
import Base: getindex, axes, size, \, /, *, +, -, summary, ==, copy, sum, unsafe_getindex
5+
import Base: getindex, axes, size, \, /, *, +, -, summary, ==, copy, sum, unsafe_getindex, convert, OneTo
66

77
import ArrayLayouts: MemoryLayout, ldiv, diagonaldata, subdiagonaldata, supdiagonaldata
88
import BandedMatrices: bandwidths, AbstractBandedMatrix, BandedLayout, _BandedMatrix
99
import LazyArrays: resizedata!, paddeddata, CachedVector, CachedMatrix, CachedAbstractVector, LazyMatrix, LazyVector, arguments, ApplyLayout, colsupport, AbstractCachedVector, AccumulateAbstractVector, LazyVector
1010
import ClassicalOrthogonalPolynomials: OrthogonalPolynomial, recurrencecoefficients, jacobimatrix, normalize, _p0, UnitInterval, orthogonalityweight, NormalizedBasisLayout,
1111
Bidiagonal, Tridiagonal, SymTridiagonal, symtridiagonalize, normalizationconstant, LanczosPolynomial,
12-
OrthogonalPolynomialRatio, Weighted, Expansion, UnionDomain, oneto
12+
OrthogonalPolynomialRatio, Weighted, Expansion, UnionDomain, oneto, Hilbert, WeightedOrthogonalPolynomial, HalfWeighted,
13+
Associated
1314
import InfiniteArrays: OneToInf, InfUnitRange
14-
import ContinuumArrays: basis, Weight, @simplify, AbstractBasisLayout, BasisLayout, MappedBasisLayout
15+
import ContinuumArrays: basis, Weight, @simplify, AbstractBasisLayout, BasisLayout, MappedBasisLayout, grid
1516
import FillArrays: SquareEye
1617

1718
export LanczosPolynomial, Legendre, Normalized, normalize, SemiclassicalJacobi, SemiclassicalJacobiWeight, WeightedSemiclassicalJacobi, OrthogonalPolynomialRatio, TwoBandJacobi, TwoBandWeight
@@ -161,12 +162,13 @@ end
161162

162163
SemiclassicalJacobi(t, a, b, c, P::SemiclassicalJacobi) = SemiclassicalJacobi(t, a, b, c, semiclassical_jacobimatrix(P, a, b, c))
163164
SemiclassicalJacobi(t, a, b, c) = SemiclassicalJacobi(t, a, b, c, semiclassical_jacobimatrix(t, a, b, c))
165+
SemiclassicalJacobi{T}(t, a, b, c) where T = SemiclassicalJacobi(convert(T,t), convert(T,a), convert(T,b), convert(T,b))
164166

165167
WeightedSemiclassicalJacobi(t, a, b, c, P...) = SemiclassicalJacobiWeight(t, a, b, c) .* SemiclassicalJacobi(t, a, b, c, P...)
166168

167169

168170
function semiclassical_jacobimatrix(t, a, b, c)
169-
T = promote_type(typeof(t), typeof(a), typeof(b), typeof(c))
171+
T = float(promote_type(typeof(t), typeof(a), typeof(b), typeof(c)))
170172
P = jacobi(b, a, UnitInterval{T}())
171173
iszero(c) && return symtridiagonalize(jacobimatrix(P))
172174
x = axes(P,1)
@@ -349,6 +351,10 @@ end
349351
# sqrt(1-(1-x)^2) == sqrt(2x-x^2) == sqrt(x)*sqrt(2-x)
350352
# sqrt(1-(1-x)^2) == sqrt(2x-x^2) == sqrt(x)*sqrt(2-x)
351353

354+
convert(::Type{WeightedOrthogonalPolynomial}, Q::HalfWeighted{:a,T,<:SemiclassicalJacobi}) where T = SemiclassicalJacobiWeight(Q.P.t, Q.P.a,zero(T),zero(T)) .* Q.P
355+
convert(::Type{WeightedOrthogonalPolynomial}, Q::HalfWeighted{:b,T,<:SemiclassicalJacobi}) where T = SemiclassicalJacobiWeight(Q.P.t, zero(T),Q.P.b,zero(T)) .* Q.P
356+
convert(::Type{WeightedOrthogonalPolynomial}, Q::HalfWeighted{:c,T,<:SemiclassicalJacobi}) where T = SemiclassicalJacobiWeight(Q.P.t, zero(T),zero(T),Q.P.c) .* Q.P
357+
352358
include("derivatives.jl")
353359

354360

src/twoband.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ function getindex(w::TwoBandWeight, x::Real)
2626
abs(x)^(2w.c) * (x^2- w.ρ^2)^w.b * (1-x^2)^w.a
2727
end
2828

29+
function sum(w::TwoBandWeight{T}) where T
30+
if 2w.a == 2w.b == -1 && 2w.c == 1
31+
convert(T,π)/2
32+
else
33+
error("not implemented")
34+
# 1/2 \[Pi] (-((\[Rho]^(1 + 2 b + 2 c)
35+
# Gamma[1 + b] Hypergeometric2F1Regularized[-a, 1/2 + c,
36+
# 3/2 + b + c, \[Rho]^2])/Gamma[1/2 - c]) + (
37+
# Gamma[1 + a] Hypergeometric2F1Regularized[-b, -(1/2) - a - b - c,
38+
# 1/2 - b - c, \[Rho]^2])/
39+
# Gamma[3/2 + a + b + c]) Sec[(b + c) \[Pi]]
40+
end
41+
end
42+
2943
"""
3044
TwoBandJacobi(a, b)
3145
@@ -82,3 +96,23 @@ function jacobimatrix(R::TwoBandJacobi{T}) where T
8296
L = R.P \ (SemiclassicalJacobiWeight(R.P.t,0,0,1) .* R.Q)
8397
Tridiagonal(Interlace(L.dv/L[1,1], (1-ρ^2) * L.ev), Zeros{T}(∞), Interlace((1-ρ^2) * L.dv,L.ev/L[1,1]))
8498
end
99+
100+
101+
@simplify function *(H::Hilbert, w::TwoBandWeight)
102+
if 2w.a == 2w.b == -1 && 2w.c == 1
103+
zeros(promote_type(eltype(H),eltype(w)), axes(w,1))
104+
else
105+
error("Not Implemented")
106+
end
107+
end
108+
109+
110+
function grid(L::SubQuasiArray{T,2,<:Associated{<:Any,<:TwoBandJacobi},<:Tuple{Inclusion,OneTo}}) where T
111+
g = grid(legendre(parent(L).P.ρ .. 1)[:,parentindices(L)[2]])
112+
[-g; g]
113+
end
114+
115+
116+
117+
LinearAlgebra.factorize(L::SubQuasiArray{<:Any,2,<:Associated{<:Any,<:TwoBandJacobi},<:Tuple{Inclusion,OneTo}}) =
118+
ContinuumArrays._factorize(BasisLayout(), L)

test/runtests.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import ClassicalOrthogonalPolynomials: recurrencecoefficients, orthogonalityweig
2020

2121
t = 2
2222
= SemiclassicalJacobi(t, 0, 0, 0)
23+
@testisa SemiclassicalJacobi{Float64}
24+
@test== SemiclassicalJacobi{Float64}(t,0,0,0)
25+
2326
@test P̃[0.1,1:10] P[2*0.1-1,1:10]/P[0.1,1]
2427
end
2528

@@ -29,6 +32,7 @@ end
2932
@test w[0.1] 0.1^a * (1-0.1)^b * (2-0.1)^c
3033
@test sum(w) 0.8387185832077594 #Mathematica
3134
@test Expansion(w)[0.1] w[0.1]
35+
@test copy(w) == w
3236
@test Expansion(w) == w
3337
@test w == Expansion(w)
3438
end
@@ -259,7 +263,7 @@ end
259263

260264
@testset "T and W" begin
261265
= (x,n) -> -X[n,n+1]*(T[x,n]*T[0,n+1] - T[x,n+1]*T[0,n])/x
262-
@test norm(diff(.([0.1,0.2,0.3],5) ./ W[[0.1,0.2,0.3],5]))  10E-14
266+
@test norm(diff(.([0.1,0.2,0.3],5) ./ W[[0.1,0.2,0.3],5]))  5E-13
263267

264268
L = _BandedMatrix(Vcat((-X.ev .* T[0,2:end])', (X.ev .* T[0,1:end])'), ∞, 1, 0)
265269
x = 0.1
@@ -276,7 +280,8 @@ end
276280
= Normalized(legendre(0..1))
277281
@test P̃[0.1,1:10] P[0.1,1:10]
278282
Q = SemiclassicalJacobi(2.0,0,0,1)
279-
Q \ P
283+
R = Q \ P
284+
@test Q[0.1,1:10]' * R[1:10,1:10] P[0.1,1:10]'
280285
x = axes(Q,1)
281286
X = Q \ (x .* Q)
282287
@time X[1:1000,1:1000];
@@ -321,6 +326,8 @@ end
321326
m = 5
322327
x = Inclusion(0..1)
323328
@test jacobimatrix(LanczosPolynomial(@. (2-x)^m))[1:10,1:10] jacobimatrix(Ps[m+1])[1:10,1:10]
329+
330+
@test SemiclassicalJacobi(2,0,0,2)[0.1,1:5] SemiclassicalJacobi(2,0,0,2,Ps[1])[0.1,1:5] Ps[3][0.1,1:5]
324331
end
325332

326333
@testset "Semiclassical operator asymptotics" begin

test/test_derivative.jl

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using SemiclassicalOrthogonalPolynomials, ClassicalOrthogonalPolynomials, LazyArrays, Test
22
import ClassicalOrthogonalPolynomials: recurrencecoefficients, _BandedMatrix, _p0, Weighted
33
import LazyArrays: Accumulate, AccumulateAbstractVector
4-
import SemiclassicalOrthogonalPolynomials: MulAddAccumulate
4+
import SemiclassicalOrthogonalPolynomials: MulAddAccumulate, HalfWeighted
55

66

77
@testset "Derivative" begin
@@ -29,12 +29,12 @@ import SemiclassicalOrthogonalPolynomials: MulAddAccumulate
2929

3030
for n = 3:10
3131
u = (D * (P̃ * [[zeros(n);1]; zeros(∞)]))
32-
@test norm((Q \ u)[1:n-2]) 1000eps()
32+
@test norm((Q \ u)[1:n-2]) 3E-12
3333
end
3434

3535
L = Q \ (D * P̃);
3636
# L is bidiagonal
37-
@test norm(triu(L[1:10,1:10],3))  1000eps()
37+
@test norm(triu(L[1:10,1:10],3))  3E-12
3838
@test L[:,5] isa Vcat
3939

4040
A,B,C = recurrencecoefficients(P);
@@ -120,7 +120,7 @@ import SemiclassicalOrthogonalPolynomials: MulAddAccumulate
120120
# accumulate_abs(*,
121121
end
122122

123-
@testset "annuli Weighted" begin
123+
@testset "Weighted" begin
124124
t = 2
125125
P = SemiclassicalJacobi(t, 0, 0, 0)
126126
Q = SemiclassicalJacobi(t, 1, 1, 1, P)
@@ -132,4 +132,65 @@ import SemiclassicalOrthogonalPolynomials: MulAddAccumulate
132132
h = 0.00001
133133
@test (D * Weighted(Q))[0.1,1:5] (Weighted(Q)[0.1+h,1:5] - Weighted(Q)[0.1,1:5])/h atol=100h
134134
end
135+
136+
@testset "HalfWeighted" begin
137+
t = 2
138+
P = SemiclassicalJacobi(t, 1, 1, 1)
139+
= Normalized(jacobi(1,1,0..1))
140+
x = axes(P,1)
141+
D = Derivative(x)
142+
143+
@test HalfWeighted{:a}(P)[0.1,1:10] 0.1*P[0.1,1:10]
144+
@test HalfWeighted{:b}(P)[0.1,1:10] (1-0.1)*P[0.1,1:10]
145+
@test HalfWeighted{:c}(P)[0.1,1:10] (t-0.1)*P[0.1,1:10]
146+
147+
t,a,b,c = 2,0.1,0.2,0.3
148+
P = SemiclassicalJacobi(t, a+1, b, c)
149+
Q = SemiclassicalJacobi(t,a,b+1,c+1)
150+
HP = HalfWeighted{:a}(P)
151+
HQ = HalfWeighted{:a}(Q)
152+
153+
A,B,C = recurrencecoefficients(P);
154+
α,β,γ = recurrencecoefficients(Q);
155+
156+
k = cumprod(A);
157+
κ = cumprod(α);
158+
j = Vector{Float64}(undef, 100)
159+
j[1] = B[1]
160+
for n = 1:length(j)-1
161+
j[n+1] = A[n+1]*j[n] + B[n+1]*k[n]
162+
end
163+
ξ = Vector{Float64}(undef, 100)
164+
ξ[1] = β[1]
165+
for n = 1:length(ξ)-1
166+
ξ[n+1] = α[n+1]*ξ[n] + β[n+1]*κ[n]
167+
end
168+
169+
h = 0.00001
170+
n = 1
171+
x = 0.1
172+
@test (HP[x+h,n]-HP[x,n])/h (a+1) * HQ[x,n] atol=10h
173+
n = 2
174+
@test P[x,n] k[1]*x + j[1]
175+
@test Q[x,n] κ[1]*x + ξ[1]
176+
@test HP[x,n] x^(a+1) * P[x,n]
177+
@test (HP[x+h,n]-HP[x,n])/h x^a * ((a+1)*(k[1]*x + j[1])+ x * k[1]) atol=10h
178+
@test (HP[x+h,n]-HP[x,n])/h x^a * ((a+2)*k[1]*x + (a+1)*j[1]) atol=10h
179+
@test (HP[x+h,n]-HP[x,n])/h x^a * ((a+2)*k[1]*(Q[x,n]-ξ[1])/κ[1] + (a+1)*j[1]) atol=10h
180+
@test (HP[x+h,n]-HP[x,n])/h x^a * ((a+2)*k[1]/κ[1]*Q[x,n]+ (-(a+2)*k[1]*ξ[1]/κ[1] + (a+1)*j[1])*Q[x,n-1]) atol=10h
181+
182+
n = 3
183+
@test (HP[x+h,n]-HP[x,n])/h x^a * ((a+n)*k[n-1]/κ[n-1]*Q[x,n]+ (-(a+n)*k[n-1]*ξ[n-1]/κ[n-1] + (a+n-1)*j[n-1])/κ[n-2]*Q[x,n-1]) atol=20h
184+
n = 4
185+
@test (HP[x+h,n]-HP[x,n])/h x^a * ((a+n)*k[n-1]/κ[n-1]*Q[x,n]+ (-(a+n)*k[n-1]*ξ[n-1]/κ[n-1] + (a+n-1)*j[n-1])/κ[n-2]*Q[x,n-1]) atol=100h
186+
187+
188+
d = AccumulateAbstractVector(*, A ./ α)
189+
# v1 = AccumulateAbstractVector(+, Vcat(1,α) ./ B)
190+
191+
@test (HP[x+h,n]-HP[x,n])/h x^a * ((a+n)*d[n-1]*Q[x,n]+ (-(a+n)*k[n-1]*ξ[n-1]/(κ[n-2]κ[n-1]) + (a+n-1)*j[n-1]/κ[n-2])*Q[x,n-1]) atol=100h
192+
193+
194+
# Bidiagonal(((P.a+1):∞) .* d, , :U)
195+
end
135196
end

test/test_twoband.jl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using SemiclassicalOrthogonalPolynomials, ClassicalOrthogonalPolynomials, Test
2-
import ClassicalOrthogonalPolynomials: orthogonalityweight
2+
import ClassicalOrthogonalPolynomials: orthogonalityweight, Weighted, associated
33

44
@testset "Two Band" begin
55
@testset "TwoBandWeight" begin
@@ -9,6 +9,7 @@ import ClassicalOrthogonalPolynomials: orthogonalityweight
99
@test_throws BoundsError w[-0.4]
1010
@test_throws BoundsError w[1.1]
1111
@test copy(w) == w
12+
@test_broken sum(w)
1213
end
1314
@testset "Chebyshev case" begin
1415
ρ = 0.5
@@ -21,5 +22,27 @@ import ClassicalOrthogonalPolynomials: orthogonalityweight
2122
@test copy(T) == T
2223
@test U T
2324
@test orthogonalityweight(T) == TwoBandWeight(ρ, -1/2, -1/2, 1/2)
25+
26+
# bug
27+
@test !issymmetric(jacobimatrix(T)[1:10,1:10])
28+
end
29+
30+
@testset "Hilbert" begin
31+
ρ = 0.5
32+
w = TwoBandWeight(ρ, -1/2, -1/2, 1/2)
33+
x = axes(w,1)
34+
H = inv.(x .- x')
35+
@test iszero(H*w)
36+
@test sum(w) == π/2
37+
38+
T = TwoBandJacobi(ρ, -1/2, -1/2, 1/2)
39+
Q = associated(T)
40+
@test (Q[0.6,1:100]' * (Q[:,Base.OneTo(100)] \ exp.(x))) exp(0.6)
41+
@test (Q[-0.6,1:100]' * (Q[:,Base.OneTo(100)] \ exp.(x))) exp(-0.6)
42+
43+
@test (Q * (Q \ exp.(x)))[0.6] exp(0.6)
44+
@test_broken Q \ (H * Weighted(T)) # need to deal with Hcat
45+
46+
@test_broken H*TwoBandWeight(ρ, 1/2, 1/2, -1/2)
2447
end
2548
end

0 commit comments

Comments
 (0)