11
2- const JACOBI_OR_LEGENDRE = Union{Legendre,AbstractJacobi}
2+ isequaldict1 (b1:: Legendre , b2:: AbstractJacobi ) =
3+ length (b1)== length (b2) && jacobi_α (b2) == 0 && jacobi_β (b2) == 0
4+ isequaldict2 (b1:: AbstractJacobi , b2:: Legendre ) = isequaldict1 (b2, b1)
35
4- isequaldict (b1:: JACOBI_OR_LEGENDRE , b2:: JACOBI_OR_LEGENDRE ) =
5- length (b1)== length (b2) &&
6- jacobi_α (b1) == jacobi_α (b2) &&
7- jacobi_β (b1) == jacobi_β (b2)
6+ isequaldict1 (b1:: ChebyshevU , b2:: Ultraspherical ) = length (b1)== length (b2) && ultraspherical_λ (b2) == 1
7+ isequaldict2 (b1:: Ultraspherical , b2:: ChebyshevU ) = isequaldict1 (b2, b1)
8+
9+ isequaldict1 (b1:: Ultraspherical{T} , b2:: Jacobi ) where T =
10+ length (b1)== length (b2) && ultraspherical_λ (b1) == one (T)/ 2 && (jacobi_α (b2) == jacobi_β (b2) == 0 )
11+ isequaldict2 (b1:: Jacobi , b2:: Ultraspherical ) = isequaldict1 (b2, b1)
812
913const RECURRENCEBASIS = Union{Monomials,OrthogonalPolynomials}
1014
@@ -18,7 +22,11 @@ function conversion1(::Type{T}, src::RECURRENCEBASIS, dest::RECURRENCEBASIS; opt
1822 E = extension_operator (T, dest1, dest)
1923 E * conversion (T, src, dest1; options... )
2024 else
21- conversion_using_recurrences (T, src, dest; options... )
25+ if isequaldict (src, dest)
26+ IdentityOperator (src)
27+ else
28+ conversion_using_recurrences (T, src, dest; options... )
29+ end
2230 end
2331end
2432
@@ -82,9 +90,121 @@ function conversion_using_recurrences(::Type{T}, src::Jacobi, dest::Ultraspheric
8290 diag = T[jacobi_to_ultraspherical (k- 1 , jacobi_α (src)) for k in 1 : length (src)]
8391 ArrayOperator (Diagonal (diag), src, dest)
8492 else
85- generic_conversion_using_recurrences (T, src, dest)
93+ generic_conversion_using_recurrences (T, src, dest; options... )
94+ end
95+ end
96+
97+ function conversion_using_recurrences (:: Type{T} , src:: Ultraspherical , dest:: Jacobi ; options... ) where T
98+ if (jacobi_α (dest) == jacobi_β (dest)) && (jacobi_α (src) ≈ jacobi_α (dest))
99+ inv (conversion_using_recurrences (T, dest, src); options... )
100+ else
101+ generic_conversion_using_recurrences (T, src, dest; options... )
102+ end
103+ end
104+
105+
106+ # Conversion from one ultraspherical basis to the ultraspherical basis with lambda+1
107+ # Implementation of formula (3.3) of Olver and Townsend, A fast and well-conditioned spectral method,
108+ # SIAM Review, 2013.
109+ function banded_ultraspherical_to_ultraspherical (:: Type{T} , n, λ) where T
110+ A = BandedMatrix {T} (undef, (n,n), (0 ,2 ))
111+ if n > 0
112+ A[1 ,1 ] = 1
113+ end
114+ if n > 1
115+ A[2 ,2 ] = λ / (λ+ 1 )
116+ A[1 ,2 ] = 0
117+ end
118+ for k in 2 : n- 1
119+ K = k+ 1
120+ A[K,K] = λ / (λ+ k)
121+ A[K- 1 ,K] = 0
122+ A[K- 2 ,K] = - λ / (λ+ k)
123+ end
124+ A
125+ end
126+
127+ # Convert from ChebyshevT expansion to ultraspherical expansion with lambda=1
128+ function banded_chebyshevt_to_ultraspherical (:: Type{T} , n) where T
129+ A = BandedMatrix {T} (undef, (n,n), (0 ,2 ))
130+ if n > 0
131+ A[1 ,1 ] = 1
132+ end
133+ onehalf = one (T)/ 2
134+ if n > 1
135+ A[1 ,2 ] = 0
136+ A[2 ,2 ] = onehalf
137+ end
138+ for k in 2 : n- 1
139+ A[k+ 1 ,k+ 1 ] = onehalf
140+ A[k- 1 ,k+ 1 ] = - onehalf
141+ A[k,k+ 1 ] = 0
142+ end
143+ A
144+ end
145+
146+ function conversion_using_recurrences (:: Type{T} , src:: Ultraspherical , dest:: Ultraspherical ; options... ) where T
147+ @assert length (src) == length (dest)
148+ if ultraspherical_λ (src) ≈ ultraspherical_λ (dest)- 1
149+ ArrayOperator (banded_ultraspherical_to_ultraspherical (T, length (src), ultraspherical_λ (src)), src, dest)
150+ else
151+ generic_conversion_using_recurrences (T, src, dest; options... )
152+ end
153+ end
154+
155+ function conversion_using_recurrences (:: Type{T} , src:: ChebyshevT , dest:: Ultraspherical ; options... ) where T
156+ @assert length (src) == length (dest)
157+ if ultraspherical_λ (dest) == 1
158+ ArrayOperator (banded_chebyshevt_to_ultraspherical (T, length (src)), src, dest)
159+ else
160+ generic_conversion_using_recurrences (T, src, dest; options... )
161+ end
162+ end
163+
164+ function diagonal_chebyshevt_to_jacobi (:: Type{T} , n:: Int ) where T
165+ A = T[chebyshevt_to_jacobi (k, T) for k in 0 : n- 1 ]
166+ Diagonal (A)
167+ end
168+
169+ function conversion_using_recurrences (:: Type{T} , src:: ChebyshevT , dest:: Jacobi ; options... ) where T
170+ @assert length (src) == length (dest)
171+ onehalf = one (T)/ 2
172+ if jacobi_α (dest) ≈ - onehalf && jacobi_β (dest) ≈ - onehalf
173+ ArrayOperator (diagonal_chebyshevt_to_jacobi (T, length (src)), src, dest)
174+ else
175+ generic_conversion_using_recurrences (T, src, dest; options... )
86176 end
87177end
88178
89- conversion_using_recurrences (:: Type{T} , src:: Ultraspherical , dest:: Jacobi ; options... ) where T =
90- inv (conversion_using_recurrences (T, dest, src); options... )
179+ function conversion_using_recurrences (:: Type{T} , src:: Jacobi , dest:: ChebyshevT ; options... ) where T
180+ onehalf = one (T)/ 2
181+ if jacobi_α (src) ≈ - onehalf && jacobi_β (src) ≈ - onehalf
182+ inv (conversion_using_recurrences (T, dest, src; options... ))
183+ else
184+ generic_conversion_using_recurrences (T, src, dest; options... )
185+ end
186+ end
187+
188+ function diagonal_chebyshevu_to_jacobi (:: Type{T} , n:: Int ) where T
189+ A = T[chebyshevu_to_jacobi (k, T) for k in 0 : n- 1 ]
190+ Diagonal (A)
191+ end
192+
193+ function conversion_using_recurrences (:: Type{T} , src:: ChebyshevU , dest:: Jacobi ; options... ) where T
194+ @assert length (src) == length (dest)
195+ onehalf = one (T)/ 2
196+ if jacobi_α (dest) ≈ onehalf && jacobi_β (dest) ≈ onehalf
197+ ArrayOperator (diagonal_chebyshevu_to_jacobi (T, length (src)), src, dest)
198+ else
199+ generic_conversion_using_recurrences (T, src, dest; options... )
200+ end
201+ end
202+
203+ function conversion_using_recurrences (:: Type{T} , src:: Jacobi , dest:: ChebyshevU ; options... ) where T
204+ onehalf = one (T)/ 2
205+ if jacobi_α (src) ≈ onehalf && jacobi_β (src) ≈ onehalf
206+ inv (conversion_using_recurrences (T, dest, src; options... ))
207+ else
208+ generic_conversion_using_recurrences (T, src, dest; options... )
209+ end
210+ end
0 commit comments