Skip to content

Commit 94d5843

Browse files
authored
Support two-interval Hilbert (#62)
* Support two-interval Hilbert * store each colsupport * tests pass * Update Project.toml * Update Project.toml * improve coverage * Update test_stieltjes.jl
1 parent eb2d8dd commit 94d5843

File tree

7 files changed

+87
-27
lines changed

7 files changed

+87
-27
lines changed

Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ ArrayLayouts = "0.7"
2929
BandedMatrices = "0.16.5"
3030
BlockArrays = "0.16"
3131
BlockBandedMatrices = "0.10"
32-
ContinuumArrays = "0.9"
32+
ContinuumArrays = "0.9.1"
3333
DomainSets = "0.5"
3434
FFTW = "1.1"
3535
FastGaussQuadrature = "0.4.3"
@@ -39,8 +39,8 @@ HypergeometricFunctions = "0.3.4"
3939
InfiniteArrays = "0.11.1"
4040
InfiniteLinearAlgebra = "0.5.8"
4141
IntervalSets = "0.5"
42-
LazyArrays = "0.21.14"
43-
LazyBandedMatrices = "0.6"
42+
LazyArrays = "0.21.15"
43+
LazyBandedMatrices = "0.6.5"
4444
QuasiArrays = "0.7"
4545
SpecialFunctions = "1.0"
4646
julia = "1.6"

src/classical/chebyshev.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ WeightedChebyshev() = WeightedChebyshevT()
4444
chebyshevt() = ChebyshevT()
4545
chebyshevt(d::AbstractInterval{T}) where T = ChebyshevT{float(T)}()[affine(d, ChebyshevInterval{T}()), :]
4646
chebyshevt(d::Inclusion) = chebyshevt(d.domain)
47+
chebyshevt(S::AbstractQuasiMatrix) = chebyshevt(axes(S,1))
4748
chebyshevu() = ChebyshevU()
4849
chebyshevu(d::AbstractInterval{T}) where T = ChebyshevU{float(T)}()[affine(d, ChebyshevInterval{T}()), :]
4950
chebyshevu(d::Inclusion) = chebyshevu(d.domain)
51+
chebyshevu(S::AbstractQuasiMatrix) = chebyshevu(axes(S,1))
5052

5153
"""
5254
chebyshevt(n, z)

src/interlace.jl

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

141141
@simplify function *(D::Derivative, S::AbstractInterlaceBasis)
142142
axes(D,2) == axes(S,1) || throw(DimensionMismatch())
143-
args = arguments.(Ref(ApplyLayout{typeof(*)}()), Derivative.(axes.(S.args,1)) .* S.args)
143+
args = arguments.(*, Derivative.(axes.(S.args,1)) .* S.args)
144144
all(length.(args) .== 2) || error("Not implemented")
145145
interlacebasis(S, map(first, args)...) * BlockBroadcastArray{promote_type(eltype(D),eltype(S))}(Diagonal, unitblocks.(last.(args))...)
146146
end

src/stieltjes.jl

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ const Hilbert{T,D1,D2} = BroadcastQuasiMatrix{T,typeof(inv),Tuple{ConvKernel{T,I
6363
const LogKernel{T,D1,D2} = BroadcastQuasiMatrix{T,typeof(log),Tuple{BroadcastQuasiMatrix{T,typeof(abs),Tuple{ConvKernel{T,Inclusion{T,D1},Inclusion{T,D2}}}}}}
6464
const PowKernel{T,D1,D2,F<:Real} = BroadcastQuasiMatrix{T,typeof(^),Tuple{BroadcastQuasiMatrix{T,typeof(abs),Tuple{ConvKernel{T,Inclusion{T,D1},Inclusion{T,D2}}}},F}}
6565

66-
6766
@simplify function *(H::Hilbert{<:Any,<:ChebyshevInterval,<:ChebyshevInterval}, w::ChebyshevTWeight)
6867
T = promote_type(eltype(H), eltype(w))
6968
zeros(T, axes(w,1))
@@ -137,6 +136,19 @@ end
137136
end
138137
end
139138

139+
@simplify function *(H::Hilbert, S::PiecewiseInterlace)
140+
axes(H,2) == axes(S,1) || throw(DimensionMismatch())
141+
@assert length(S.args) == 2
142+
a,b = S.args
143+
xa,xb = axes(a,1),axes(b,1)
144+
Ha_a = inv.(xa .- xa') * a
145+
Ha_b = inv.(xb .- xa') * a
146+
Hb_a = inv.(xa .- xb') * b
147+
Hb_b = inv.(xb .- xb') * b
148+
c,d = Hb_a.args[1], Ha_b.args[1]
149+
A,B,C,D = unitblocks(c \ Ha_a), unitblocks(c \ Hb_a), unitblocks(d \ Ha_b), unitblocks(d \ Hb_b)
150+
PiecewiseInterlace(c,d) * BlockBroadcastArray{promote_type(eltype(H),eltype(S))}(hvcat, 2, A, B, C, D)
151+
end
140152

141153
###
142154
# LogKernel
@@ -216,18 +228,28 @@ mutable struct HilbertVandermonde{T,MM} <: AbstractCachedMatrix{T}
216228
M::MM
217229
data::Matrix{T}
218230
datasize::NTuple{2,Int}
231+
colsupport::Vector{Int}
219232
end
220233

221-
HilbertVandermonde(M, data::Matrix) = HilbertVandermonde(M, data, size(data))
234+
HilbertVandermonde(M, data::Matrix) = HilbertVandermonde(M, data, size(data), Int[])
222235
size(H::HilbertVandermonde) = (ℵ₀,ℵ₀)
236+
function colsupport(H::HilbertVandermonde, j)
237+
resizedata!(H, H.datasize[1], maximum(j))
238+
1:maximum(H.colsupport[j])
239+
end
240+
241+
copy(H::HilbertVandermonde) = HilbertVandermonde(H.M, copy(H.data), H.datasize, H.colsupport)
223242

224243
function cache_filldata!(H::HilbertVandermonde{T}, kr, jr) where T
225244
n,m = H.datasize
226-
isempty(kr) && return
227245
isempty(jr) && return
228-
H.data[(n+1):maximum(kr),1:m] .= zero(T)
246+
resize!(H.colsupport, max(length(H.colsupport), maximum(jr)))
247+
248+
isempty(kr) || (H.data[(n+1):maximum(kr),1:m] .= zero(T))
229249
for j in (m+1):maximum(jr)
230-
H.data[kr,j] .= (H.M * [H.data[:,j-1]; Zeros{T}(∞)])[kr]
250+
u = H.M * [H.data[:,j-1]; Zeros{T}(∞)]
251+
H.colsupport[j] = maximum(colsupport(u,1))
252+
isempty(kr) || (H.data[kr,j] .= u[kr])
231253
end
232254
end
233255

test/test_chebyshev.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,13 @@ import ContinuumArrays: MappedWeightedBasisLayout, Map
111111
T = Chebyshev()[2x .- 1,:]
112112
@test (T*(T\x))[0.1] 0.1
113113
@test (T* (T \ exp.(x)))[0.1] exp(0.1)
114-
@test chebyshevt(0..1) == T
114+
@test chebyshevt(0..1) == chebyshevt(Inclusion(0..1)) == chebyshevt(T) == T
115115

116116
Tn = Chebyshev()[2x .- 1, [1,3,4]]
117117
@test (axes(Tn,1) .* Tn).args[2][1:5,:] (axes(T,1) .* T).args[2][1:5,[1,3,4]]
118118

119119
U = chebyshevu(0..1)
120+
@test chebyshevu(0..1) == chebyshevu(Inclusion(0..1)) == chebyshevu(T) == U
120121
@test (U*(U\x))[0.1] 0.1
121122
@test (U* (U \ exp.(x)))[0.1] exp(0.1)
122123

test/test_interlace.jl

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,46 @@ using ClassicalOrthogonalPolynomials, BlockArrays, LazyBandedMatrices, Test
22
import ClassicalOrthogonalPolynomials: PiecewiseInterlace
33

44
@testset "Piecewise" begin
5-
T1,T2 = chebyshevt((-1)..0), chebyshevt(0..1)
6-
U1,U2 = chebyshevu((-1)..0), chebyshevu(0..1)
7-
T = PiecewiseInterlace(T1, T2)
8-
U = PiecewiseInterlace(U1, U2)
9-
D = U \ (Derivative(axes(T,1))*T)
10-
C = U \ T
5+
@testset "two-interval ODE" begin
6+
T1,T2 = chebyshevt((-1)..0), chebyshevt(0..1)
7+
U1,U2 = chebyshevu((-1)..0), chebyshevu(0..1)
8+
T = PiecewiseInterlace(T1, T2)
9+
U = PiecewiseInterlace(U1, U2)
10+
D = U \ (Derivative(axes(T,1))*T)
11+
C = U \ T
1112

12-
A = BlockVcat(T[-1,:]',
13-
BlockBroadcastArray(vcat,unitblocks(T1[end,:]),-unitblocks(T2[begin,:]))',
14-
D-C)
15-
N = 20
16-
M = BlockArray(A[Block.(1:N+1), Block.(1:N)])
13+
A = BlockVcat(T[-1,:]',
14+
BlockBroadcastArray(vcat,unitblocks(T1[end,:]),-unitblocks(T2[begin,:]))',
15+
D-C)
16+
N = 20
17+
M = BlockArray(A[Block.(1:N+1), Block.(1:N)])
1718

18-
u = M \ [exp(-1); zeros(size(M,1)-1)]
19-
x = axes(T,1)
19+
u = M \ [exp(-1); zeros(size(M,1)-1)]
20+
x = axes(T,1)
2021

21-
F = factorize(T[:,Block.(Base.OneTo(N))])
22-
@test F \ exp.(x) (T \ exp.(x))[Block.(1:N)] u
22+
F = factorize(T[:,Block.(Base.OneTo(N))])
23+
@test F \ exp.(x) (T \ exp.(x))[Block.(1:N)] u
24+
end
25+
26+
@testset "two-interval Weighted Derivative" begin
27+
T1,T2 = chebyshevt((-2)..(-1)), chebyshevt(0..1)
28+
U1,U2 = chebyshevu((-2)..(-1)), chebyshevu(0..1)
29+
W = PiecewiseInterlace(Weighted(T1), Weighted(T2))
30+
U = PiecewiseInterlace(U1, U2)
31+
x = axes(W,1)
32+
D = Derivative(x)
33+
@test_broken U\D*W isa BlockBroadcastArray
34+
end
35+
36+
@testset "two-interval Hilbert" begin
37+
T1,T2 = chebyshevt((-2)..(-1)), chebyshevt(0..2)
38+
U1,U2 = chebyshevu((-2)..(-1)), chebyshevu(0..2)
39+
W = PiecewiseInterlace(Weighted(U1), Weighted(U2))
40+
T = PiecewiseInterlace(T1, T2)
41+
x = axes(W,1)
42+
H = T \ inv.(x .- x') * W;
43+
44+
c = W \ broadcast(x -> exp(x)* (0  x  2 ? sqrt(2-x)*sqrt(x) : sqrt(-1-x)*sqrt(x+2)), x)
45+
@test T[0.5,1:200]'*(H*c)[1:200] -6.064426633490422
46+
end
2347
end

test/test_stieltjes.jl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ end
196196
t = axes(U,1)
197197
x = Inclusion(2..3)
198198
T = chebyshevt(2..3)
199-
H = T \ inv.(x .- t') * W
199+
H = T \ inv.(x .- t') * W;
200+
@test last(colsupport(H,6)) 40
201+
@test T[2.3,1:100]'*(H * (W \ @.(sqrt(1-t^2)exp(t))))[1:100] 0.9068295340935111
200202
@test T[2.3,1:100]' * H[1:100,1:100] (inv.(2.3 .- t') * W)[:,1:100]
201203
end
202204

@@ -207,7 +209,16 @@ end
207209
x = Inclusion(2..3)
208210
T = chebyshevt(2..3)
209211
H = T \ inv.(x .- t') * W
210-
@test T[2.3,1:100]' * H[1:100,1:100] (inv.(2.3 .- t') * W)[:,1:100]
212+
N = 100
213+
@test T[2.3,1:N]' * H[1:N,1:N] (inv.(2.3 .- t') * W)[:,1:N]
214+
215+
U = chebyshevu((-2)..(-1))
216+
W = Weighted(U)
217+
T = chebyshevt(0..2)
218+
x = axes(T,1)
219+
t = axes(W,1)
220+
H = T \ inv.(x .- t') * W
221+
@test T[0.5,1:N]'*(H * (W \ @.(sqrt(-1-t)*sqrt(t+2)*exp(t))))[1:N] 0.047390454610749054
211222
end
212223
end
213224
end

0 commit comments

Comments
 (0)