Skip to content

Commit 111c7a2

Browse files
committed
New clenshaw works
1 parent 32085f7 commit 111c7a2

File tree

2 files changed

+191
-0
lines changed

2 files changed

+191
-0
lines changed

src/MultivariateOrthogonalPolynomials.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import Base: values,getindex,setindex!,*, +, -, ==,<,<=,>,
1212

1313
import BandedMatrices: inbands_getindex, inbands_setindex!
1414

15+
import BlockArrays: blocksizes, BlockSizes, getblock, global2blockindex
16+
1517
# ApproxFun general import
1618
import ApproxFun: BandedMatrix, order, blocksize,
1719
linesum,complexlength, BandedBlockBandedMatrix,
@@ -66,6 +68,8 @@ include("c_tri2cheb.jl")
6668
include("Triangle.jl")
6769
include("DirichletTriangle.jl")
6870

71+
# include("clenshaw.jl")
72+
6973
# include("SphericalHarmonics.jl")
7074

7175
include("show.jl")

src/clenshaw.jl

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
####
2+
# Here we implement multivariable clenshaw
3+
#
4+
# It's hard-coded for Triangles right now.
5+
####
6+
struct ClenshawRecurrenceData{T, S}
7+
space::S
8+
B̃ˣ::Vector{BandedMatrix{T,Matrix{T}}}
9+
B̃ʸ::Vector{BandedMatrix{T,Matrix{T}}}
10+
B::Vector{BandedMatrix{T,Matrix{T}}} # B̃ˣAˣ + B̃ʸAʸ
11+
C::Vector{BandedMatrix{T,Matrix{T}}} #B̃ˣCˣ + B̃ʸCʸ
12+
end
13+
14+
ClenshawRecurrenceData{T}(sp, N) where T = ClenshawRecurrenceData{T, typeof(sp)}(sp, N)
15+
ClenshawRecurrenceData(sp, N) = ClenshawRecurrenceData{prectype(sp)}(sp, N)
16+
17+
function ClenshawRecurrenceData{T,S}(sp::S, N) where {T,S<:JacobiTriangle}
18+
B̃ˣ = Vector{BandedMatrix{T,Matrix{T}}}(undef, N-1)
19+
B̃ʸ = Vector{BandedMatrix{T,Matrix{T}}}(undef, N-1)
20+
B = Vector{BandedMatrix{T,Matrix{T}}}(undef, N-1)
21+
C = Vector{BandedMatrix{T,Matrix{T}}}(undef, N-2)
22+
Jx_∞, Jy_∞ = jacobioperators(sp)
23+
Jx, Jy = BandedBlockBandedMatrix(Jx_∞[Block.(1:N), Block.(1:N-1)]'),
24+
BandedBlockBandedMatrix(Jy_∞[Block.(1:N), Block.(1:N-1)]')
25+
26+
27+
for K = 1:N-1
28+
Ax,Ay = view(Jx,Block(K,K)), view(Jy,Block(K,K))
29+
Bx,By = view(Jx,Block(K,K+1)), view(Jy,Block(K,K+1))
30+
b₂ = By[K,K+1]
31+
32+
B̃ˣ[K] = BandedMatrix{T}(Zeros(K+1,K), (2,0))
33+
B̃ʸ[K] = BandedMatrix{T}(Zeros(K+1,K), (2,0))
34+
B[K] = BandedMatrix{T}(undef, (K+1,K), (2,0))
35+
36+
B̃ˣ[K][band(0)] .= inv.(view(Bx, band(0)))
37+
B̃ˣ[K][end,end] = - inv(b₂) * By[K,K]/Bx[K,K]
38+
B̃ʸ[K][end,end] = inv(b₂)
39+
40+
if K > 1
41+
Cx,Cy = view(Jx,Block(K,K-1)), view(Jy,Block(K,K-1))
42+
C[K-1] = BandedMatrix{T}(undef, (K+1,K-1), (2,0))
43+
B̃ˣ[K][end,end-1] = - inv(b₂) * By[K,K-1]/Bx[K-1,K-1]
44+
C[K-1] .= Mul(B̃ˣ[K] , Cx)
45+
C[K-1] .= Mul(B̃ʸ[K] , Cy) .+ C[K-1]
46+
end
47+
48+
B[K] .= Mul(B̃ˣ[K] , Ax)
49+
B[K] .= Mul(B̃ʸ[K] , Ay) .+ B[K]
50+
end
51+
52+
ClenshawRecurrenceData{T,S}(sp, B̃ˣ, B̃ʸ, B, C)
53+
end
54+
55+
struct ClenshawRecurrence{T, DATA} <: AbstractBlockMatrix{T}
56+
data::DATA
57+
x::T
58+
y::T
59+
end
60+
61+
ClenshawRecurrence(sp, N, x, y) = ClenshawRecurrence(ClenshawRecurrenceData(sp,N), x, y)
62+
63+
blocksizes(U::ClenshawRecurrence) = BlockSizes(1:(length(U.data.B̃ˣ)+1),1:(length(U.data.B̃ˣ)+1))
64+
65+
blockbandwidths(::ClenshawRecurrence) = (0,2)
66+
subblockbandwidths(::ClenshawRecurrence) = (0,2)
67+
68+
@inline function getblock(U::ClenshawRecurrence{T}, K::Int, J::Int) where T
69+
J == K && return BandedMatrix(Eye{T}(K,K))
70+
J == K+1 && return BandedMatrix(transpose(U.data.B[K] - U.x*U.data.B̃ˣ[K] - U.y*U.data.B̃ʸ[K]))
71+
J == K+2 && return BandedMatrix(transpose(U.data.C[K]))
72+
return BandedMatrix(Zeros{T}(K,J))
73+
end
74+
75+
@inline function getindex(block_arr::ClenshawRecurrence, blockindex::BlockIndex{2})
76+
@inbounds block = getblock(block_arr, blockindex.I...)
77+
@boundscheck checkbounds(block, blockindex.α...)
78+
@inbounds v = block[blockindex.α...]
79+
return v
80+
end
81+
82+
function getindex(U::ClenshawRecurrence, i::Int, j::Int)
83+
@boundscheck checkbounds(U, i...)
84+
@inbounds v = U[global2blockindex(blocksizes(U), (i, j))]
85+
return v
86+
end
87+
88+
@time A = ClenshawRecurrence(JacobiTriangle(), 10, 0.1, 0.2);
89+
A.data.B[2]
90+
@time M = BandedBlockBandedMatrix(A)
91+
92+
Jx_∞, Jy_∞ = jacobioperators(sp)
93+
Jx, Jy = BandedBlockBandedMatrix(Jx_∞[Block.(1:N), Block.(1:N-1)]'),
94+
BandedBlockBandedMatrix(Jy_∞[Block.(1:N), Block.(1:N-1)]')
95+
Ax, Ay = Jx[Block(K,K)], Jy[Block(K,K)]
96+
= [Matrix(A.data.B̃ˣ[2]) Matrix(A.data.B̃ʸ[2])]
97+
98+
B̃ˣ = A.data.B̃ˣ
99+
B̃ʸ = A.data.B̃ʸ
100+
101+
B̃ˣ[K],Ax , B̃ʸ[K],Ay
102+
103+
104+
105+
106+
f = Fun(Triangle(), randn(size(A,1)))
107+
# P= plan_evaluate(f)
108+
@time P(0.1,0.2)
109+
110+
P = PseudoBlockArray([Fun(JacobiTriangle(), [zeros(k-1); 1])(0.1,0.2) for k=1:sum(1:10)], 1:10)
111+
112+
A'*P
113+
114+
N = 10
115+
sp = JacobiTriangle()
116+
117+
x,y = 0.1,0.2
118+
Jx*P - (x*P)[1:45] |> norm
119+
120+
Jy*P - (y*P)[1:45] |> norm
121+
122+
123+
A.data.B̃ˣ
124+
125+
126+
K = 2; B̃*[Matrix(Jx[Block(K,K+1)]); Matrix(Jy[Block(K,K+1)])]
127+
128+
129+
A.data.B[2]
130+
B̃ˣ[2]
131+
A.data.B̃ˣ[2]*Matrix(Jx[Block(K,K)]) + A.data.B̃ʸ[2] * Matrix(Jy[Block(K,K)])
132+
*[Matrix(Jx[Block(K,K)]); Matrix(Jy[Block(K,K)])]
133+
*[Matrix(Jx[Block(K,K)]-x*I); Matrix(Jy[Block(K,K)] - y*I)]
134+
135+
K
136+
137+
B = A.data.B
138+
139+
B[K] .= Mul(B̃ˣ[K] , Ax)
140+
B[K] .= Mul(B̃ʸ[K] , Ay) .+ B[K]
141+
(A')[Block(3,2)]
142+
143+
144+
A.data
145+
146+
*[Matrix(Jx[Block(K,K)]); Matrix(Jy[Block(K,K)])]
147+
148+
B[K]
149+
150+
B̃ˣ[K] * Ax + B̃ʸ[K] * Ay
151+
Matrix(M)'*P
152+
153+
P'*f.coefficients
154+
155+
P'*f.coefficients
156+
157+
UpperTriangular(M)\f.coefficients
158+
159+
v = randn(5050)
160+
161+
@time UpperTriangular(M) \ v
162+
163+
A[Block(3,4)]
164+
165+
166+
167+
168+
@time BandedBlockBandedMatrix(A)
169+
170+
A'*P
171+
172+
(A')
173+
174+
x,y = 0.1,0.2
175+
176+
x*P[Block(1)]
177+
178+
Ax*P[Block(1)] + Bx*P[Block(2)]
179+
180+
Jx[Block.(1:5), Block.(1:5)]'*P
181+
182+
183+
184+
185+
186+
187+
sum(1:5)

0 commit comments

Comments
 (0)