@@ -53,13 +53,19 @@ struct ZernikeWeight{T} <: Weight{T}
5353 b:: T
5454end
5555
56+
5657"""
5758 ZernikeWeight(b)
5859
5960is a quasi-vector representing `(1-r^2)^b`
6061"""
6162
6263ZernikeWeight (b) = ZernikeWeight (zero (b), b)
64+ ZernikeWeight {T} (b) where T = ZernikeWeight {T} (zero (T), b)
65+ ZernikeWeight {T} () where T = ZernikeWeight {T} (zero (T))
66+ ZernikeWeight () = ZernikeWeight {Float64} ()
67+
68+ copy (w:: ZernikeWeight ) = w
6369
6470axes (:: ZernikeWeight{T} ) where T = (Inclusion (UnitDisk {T} ()),)
6571
@@ -186,50 +192,55 @@ getindex(W::WeightedZernikeLaplacianDiag, k::Integer) = W[findblockindex(axes(W,
186192 WZ. P * Diagonal (WeightedZernikeLaplacianDiag {eltype(eltype(WZ))} ())
187193end
188194
189- struct ZernikeConversion{T} <: AbstractBandedBlockBandedMatrix{T} end
190195
191- axes (Z:: ZernikeConversion ) = (blockedrange (oneto (∞)), blockedrange (oneto (∞)))
196+ """
197+ ModalInterlace
198+ """
199+ struct ModalInterlace{T} <: AbstractBandedBlockBandedMatrix{T}
200+ ops
201+ bandwidths:: NTuple{2,Int}
202+ end
203+
204+ axes (Z:: ModalInterlace ) = (blockedrange (oneto (∞)), blockedrange (oneto (∞)))
192205
193- blockbandwidths (:: ZernikeConversion ) = ( 0 , 2 )
194- subblockbandwidths (:: ZernikeConversion ) = (0 ,0 )
206+ blockbandwidths (R :: ModalInterlace ) = R . bandwidths
207+ subblockbandwidths (:: ModalInterlace ) = (0 ,0 )
195208
196209
197- function Base. view (W :: ZernikeConversion {T} , KJ:: Block{2} ) where T
210+ function Base. view (R :: ModalInterlace {T} , KJ:: Block{2} ) where T
198211 K,J = KJ. n
199212 dat = Matrix {T} (undef,1 ,J)
200- if J == K
213+ l,u = blockbandwidths (R)
214+ if iseven (J- K) && - l ≤ J - K ≤ u
215+ sh = (J- K)÷ 2
201216 if isodd (K)
202- R0 = Normalized ( Jacobi ( 1 , 0 )) \ Normalized ( Jacobi ( 0 , 0 ))
203- dat[1 ,1 ] = R0[K ÷ 2 + 1 ,K ÷ 2 + 1 ]
217+ k = K ÷ 2 + 1
218+ dat[1 ,1 ] = R . ops[ 1 ][k,k + sh ]
204219 end
205- for m in range (2 - iseven (K); step= 2 , length= J÷ 2 )
206- Rm = Normalized (Jacobi (1 ,m)) \ Normalized (Jacobi (0 ,m))
207- j = K÷ 2 - m÷ 2 + isodd (K)
208- dat[1 ,m] = dat[1 ,m+ 1 ] = Rm[j,j]
209- end
210- elseif J == K + 2
211- if isodd (K)
212- R0 = Normalized (Jacobi (1 ,0 )) \ Normalized (Jacobi (0 ,0 ))
213- j = K÷ 2 + 1
214- dat[1 ,1 ] = R0[j,j+ 1 ]
215- end
216- for m in range (2 - iseven (K); step= 2 , length= K÷ 2 )
217- Rm = Normalized (Jacobi (1 ,m)) \ Normalized (Jacobi (0 ,m))
218- j = K÷ 2 - m÷ 2 + isodd (K)
219- dat[1 ,m] = dat[1 ,m+ 1 ] = Rm[j,j+ 1 ]
220+ for m in range (2 - iseven (K); step= 2 , length= J÷ 2 - max (0 ,sh))
221+ k = K÷ 2 - m÷ 2 + isodd (K)
222+ dat[1 ,m] = dat[1 ,m+ 1 ] = R. ops[m+ 1 ][k,k+ sh]
220223 end
221224 else
222225 fill! (dat, zero (T))
223226 end
224- dat ./= sqrt (2 one (T))
225227 _BandedMatrix (dat, K, 0 , 0 )
226228end
227229
228- getindex (R:: ZernikeConversion , k:: Integer , j:: Integer ) = R[findblockindex .(axes (R),(k,j))... ]
230+ getindex (R:: ModalInterlace , k:: Integer , j:: Integer ) = R[findblockindex .(axes (R),(k,j))... ]
229231
230232function \ (A:: Zernike{T} , B:: Zernike{V} ) where {T,V}
231- A. a == B. a && A. b == B. b && return Eye {promote_type(T,V)} (∞)
233+ TV = promote_type (T,V)
234+ A. a == B. a && A. b == B. b && return Eye {TV} (∞)
232235 @assert A. a == 0 && A. b == 1
233236 @assert B. a == 0 && B. b == 0
234- ZernikeConversion {promote_type(T,V)} ()
237+ ModalInterlace {TV} ((Normalized .(Jacobi {TV} .(1 ,0 : ∞)) .\ Normalized .(Jacobi {TV} .(0 ,0 : ∞))) ./ sqrt (convert (TV, 2 )), (0 ,2 ))
238+ end
239+
240+ function \ (A:: Zernike{T} , B:: Weighted{V,Zernike{V}} ) where {T,V}
241+ TV = promote_type (T,V)
242+ A. a == B. P. a == A. b == B. P. b == 0 && return Eye {TV} (∞)
243+ @assert A. a == A. b == 0
244+ @assert B. P. a == 0 && B. P. b == 1
245+ ModalInterlace {TV} ((Normalized .(Jacobi {TV} .(0 , 0 : ∞)) .\ HalfWeighted {:a} .(Normalized .(Jacobi {TV} .(1 , 0 : ∞)))) ./ sqrt (convert (TV, 2 )), (2 ,0 ))
235246end
0 commit comments