Skip to content

Commit 66d10ff

Browse files
committed
ClenshawKron implemented
1 parent bc440cb commit 66d10ff

File tree

3 files changed

+67
-22
lines changed

3 files changed

+67
-22
lines changed

src/MultivariateOrthogonalPolynomials.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ using QuasiArrays: AbstractVector
44
using ClassicalOrthogonalPolynomials, FastTransforms, BlockBandedMatrices, BlockArrays, DomainSets,
55
QuasiArrays, StaticArrays, ContinuumArrays, InfiniteArrays, InfiniteLinearAlgebra,
66
LazyArrays, SpecialFunctions, LinearAlgebra, BandedMatrices, LazyBandedMatrices, ArrayLayouts,
7-
HarmonicOrthogonalPolynomials
7+
HarmonicOrthogonalPolynomials, RecurrenceRelationships
88

99
import Base: axes, in, ==, +, -, /, *, ^, \, copy, copyto!, OneTo, getindex, size, oneto, all, resize!, BroadcastStyle, similar, fill!, setindex!, convert, show, summary
1010
import Base.Broadcast: Broadcasted, broadcasted, DefaultArrayStyle
@@ -21,7 +21,7 @@ import LazyArrays: arguments, paddeddata, LazyArrayStyle, LazyLayout, PaddedLayo
2121
import LazyBandedMatrices: LazyBandedBlockBandedLayout, AbstractBandedBlockBandedLayout, AbstractLazyBandedBlockBandedLayout, _krontrav_axes, DiagTravLayout, invdiagtrav, ApplyBandedBlockBandedLayout
2222
import InfiniteArrays: InfiniteCardinal, OneToInf
2323

24-
import ClassicalOrthogonalPolynomials: jacobimatrix, Weighted, orthogonalityweight, HalfWeighted, WeightedBasis, pad, recurrencecoefficients, clenshaw, weightedgrammatrix
24+
import ClassicalOrthogonalPolynomials: jacobimatrix, Weighted, orthogonalityweight, HalfWeighted, WeightedBasis, pad, recurrencecoefficients, clenshaw, weightedgrammatrix, Clenshaw
2525
import HarmonicOrthogonalPolynomials: BivariateOrthogonalPolynomial, MultivariateOrthogonalPolynomial, Plan,
2626
PartialDerivative, AngularMomentum, BlockOneTo, BlockRange1, interlace,
2727
MultivariateOPLayout, MAX_PLOT_BLOCKS
@@ -36,6 +36,7 @@ export MultivariateOrthogonalPolynomial, BivariateOrthogonalPolynomial,
3636
grammatrix, oneto
3737

3838
include("ModalInterlace.jl")
39+
include("clenshawkron.jl")
3940
include("rect.jl")
4041
include("disk.jl")
4142
include("rectdisk.jl")

src/clenshawkron.jl

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2+
"""
3+
ClenshawKron(coefficientmatrix, (A₁,A₂), (B₁,B₂), (C₁,C₂), (X₁,X₂)))
4+
5+
represents the multiplication operator of a tensor product of two orthogonal polynomials. That is,
6+
if `f(x,y) = P(x)*F*Q(y)'` and `a(x,y) = R(x)*A*S(y)'` then
7+
8+
M = ClenshawKron(A, tuple.(recurrencecoefficients(R), recurrencecoefficients(S)), (jacobimatrix(P), jacobimatrix(Q))
9+
M * KronTrav(F)
10+
11+
Gives the coefficients of `a(x,y)*f(x,y)`.
12+
"""
13+
struct ClenshawKron{T, Coefs<:AbstractMatrix{T}, Rec<:NTuple{2,NTuple{3,AbstractVector}}, Jac<:NTuple{2,AbstractMatrix}} <: AbstractBandedBlockBandedMatrix{T}
14+
c::Coefs
15+
recurrencecoeffients::Rec
16+
X::Jac
17+
end
18+
19+
20+
copy(M::ClenshawKron) = M
21+
size(M::ClenshawKron) = (ℵ₀, ℵ₀)
22+
axes(M::ClenshawKron) = (blockedrange(oneto(∞)),blockedrange(oneto(∞)))
23+
blockbandwidths(M::ClenshawKron) = (size(M.c,1)-1,size(M.c,1)-1)
24+
subblockbandwidths(M::ClenshawKron) = (size(M.c,2)-1,size(M.c,2)-1)
25+
26+
function square_getindex(M::ClenshawKron, N::Block{1})
27+
# Consider P(x) = L^1_x \ 𝐞_0
28+
# So that if a(x,y) = P(x)*c*Q(y)' then we have
29+
# a(X,Y) = 𝐞_0' * inv(L^1_X') * c * Q(Y)'
30+
# So we first apply 1D clenshaw to each column
31+
32+
(A₁,B₁,C₁), (A₂,B₂,C₂) = M.recurrencecoeffients
33+
X,Y = M.X
34+
m,n = size(M.c)
35+
@assert m == n
36+
# Apply Clenshaw to each column
37+
g = (a,b,N) -> LazyBandedMatrices.krontrav(a[1:N,1:N], b[1:N,1:N])
38+
cols = [Clenshaw(M.c[1:m-j+1,j], A₁, B₁, C₁, X) for j=1:n]
39+
40+
M = m-2+Int(N) # over sample
41+
Q_Y = forwardrecurrence(n, A₂, B₂, C₂, Y[1:M,1:M])
42+
+(broadcast((a,b,N) -> LazyBandedMatrices.krontrav(a[1:N,1:N], b[1:N,1:N]), Q_Y, cols, Int(N))...)
43+
end
44+
45+
getindex(M::ClenshawKron, KR::BlockRange{1}, JR::BlockRange{1}) = square_getindex(M, max(maximum(KR), maximum(JR)))[KR,JR]
46+
getindex(M::ClenshawKron, K::Block{1}, J::Block{1}) = square_getindex(M, max(K, J))[K,J]
47+
getindex(M::ClenshawKron, Kk::BlockIndex{1}, Jj::BlockIndex{1}) = M[block(Kk), block(Jj)][blockindex(Kk), blockindex(Jj)]
48+
getindex(M::ClenshawKron, k::Int, j::Int) = M[findblockindex(axes(M,1),k), findblockindex(axes(M,2),j)]
49+
50+
Base.array_summary(io::IO, C::ClenshawKron{T}, inds::Tuple{Vararg{OneToInf{Int}}}) where T =
51+
print(io, Base.dims2string(length.(inds)), " ClenshawKron{$T} with $(size(C.c)) polynomial")

test/test_rect.jl

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
using MultivariateOrthogonalPolynomials, ClassicalOrthogonalPolynomials, StaticArrays, LinearAlgebra, BlockArrays, FillArrays, Base64, LazyBandedMatrices, Test
22
using ClassicalOrthogonalPolynomials: expand, coefficients, recurrencecoefficients
3-
using MultivariateOrthogonalPolynomials: weaklaplacian
3+
using MultivariateOrthogonalPolynomials: weaklaplacian, ClenshawKron
44
using ContinuumArrays: plotgridvalues
5+
using Base: oneto
56

67
@testset "RectPolynomial" begin
78
@testset "Evaluation" begin
@@ -168,27 +169,19 @@ using ContinuumArrays: plotgridvalues
168169

169170
a = (x,y) -> I + x + 2y + 3x^2 +4x*y + 5y^2
170171
𝐚 = expand(P,splat(a))
171-
A = a(X,Y)
172-
172+
173173
C = LazyBandedMatrices.paddeddata(LazyBandedMatrices.invdiagtrav(coefficients(𝐚)))
174-
m,n = size(C)
175-
using RecurrenceRelationshipArrays, RecurrenceRelationships
176-
X_T = jacobimatrix(T)
177-
X_U = jacobimatrix(U)
178-
cfs = [Clenshaw(C[1:m-j+1,j], recurrencecoefficients(T)..., X_T) for j=1:n]
179-
180-
181-
KR = Block.(1:3)
182174

183-
@test (KronTrav(Eye(∞),cfs[1]) + KronTrav(2X_U,cfs[2]) + KronTrav((4X_U^2 - I),cfs[3]))[KR,KR]
184-
KronTrav(Eye(3),cfs[1][1:3,1:3]) + KronTrav(2X_U[1:3,1:3],cfs[2][1:3,1:3])+ KronTrav((4X_U^2 - I)[1:3,1:3],cfs[3][1:3,1:3]) A[KR,KR]
175+
A = ClenshawKron(C, (recurrencecoefficients(T), recurrencecoefficients(U)), (jacobimatrix(T), jacobimatrix(U)))
185176

186-
g = (a,b,N) -> LazyBandedMatrices.krontrav(a[1:N,1:N], b[1:N,1:N])
187-
N = 10
188-
M = m-2+N # over sample
189-
@time U_X = forwardrecurrence(length(cfs), recurrencecoefficients(U)..., X_U[1:M,1:M]);
190-
@time Ks = broadcast(g, U_X, cfs, N);
191-
@time A_N = +(Ks...)
192-
@test A_N A[Block.(1:N),Block.(1:N)]
177+
178+
= a(X,Y)
179+
for (k,j) in ((Block.(oneto(5)),Block.(oneto(5))), Block.(oneto(5)),Block.(oneto(6)), (Block(2), Block(3)), (4,5),
180+
(Block(2)[2], Block(3)[3]), (Block(2)[2], Block(3)))
181+
@test A[k,j] Ã[k,j]
182+
end
183+
184+
@test A[Block(1,2)] Ã[Block(1,2)]
185+
@test A[Block(1,2)][1,2] Ã[Block(1,2)[1,2]]
193186
end
194187
end

0 commit comments

Comments
 (0)