@@ -45,3 +45,131 @@ function getindex(C::ConcreteConversion{<:HeavisideSpace,
4545 k:: Integer ,j:: Integer )
4646 k ≤ dimension (domainspace (C)) && j== k ? one (eltype (C)) : zero (eltype (C))
4747end
48+
49+ # Fast conversion between common bases using FastTransforms
50+
51+ # The chebyshev-ultraspherical transforms are currently very slow,
52+ # see https://github.com/JuliaApproximation/FastTransforms.jl/issues/204
53+ # We therefore go through hoops to only call these for non-integral Ultraspherical orders
54+
55+ function _changepolybasis (v:: StridedVector{T} ,
56+ C:: MaybeNormalized{<:Chebyshev{<:ChebyshevInterval}} ,
57+ U:: MaybeNormalized{<:Ultraspherical{<:Any,<:ChebyshevInterval}} ,
58+ ) where {T<: AbstractFloat }
59+
60+ normcheb = C isa NormalizedPolynomialSpace
61+ normultra = U isa NormalizedPolynomialSpace
62+ Uc = normultra ? _stripnorm (U) : U
63+ Cc = normcheb ? _stripnorm (C) : C
64+ if order (U) == 1
65+ v = normcheb ? ApproxFunBase. mul_coefficients (ConcreteConversion (C, Cc), v) : v
66+ vc = ultraconversion (v)
67+ normultra ? ApproxFunBase. mul_coefficients! (ConcreteConversion (Uc, U), vc) : vc
68+ elseif order (U) isa Union{Integer, StaticInt}
69+ coefficients (v, C, Ultraspherical (1 ,domain (U)), U)
70+ else
71+ cheb2ultra (v, strictconvert (T, order (U)); normcheb, normultra)
72+ end
73+ end
74+ function _changepolybasis (v:: StridedVector{T} ,
75+ U:: MaybeNormalized{<:Ultraspherical{<:Any,<:ChebyshevInterval}} ,
76+ C:: MaybeNormalized{<:Chebyshev{<:ChebyshevInterval}} ) where {T<: AbstractFloat }
77+
78+ normultra = U isa NormalizedPolynomialSpace
79+ normcheb = C isa NormalizedPolynomialSpace
80+ Uc = normultra ? _stripnorm (U) : U
81+ Cc = normcheb ? _stripnorm (C) : C
82+ if order (U) == 1
83+ v = normultra ? ApproxFunBase. mul_coefficients (ConcreteConversion (U, Uc), v) : v
84+ vc = ultraiconversion (v)
85+ normcheb ? ApproxFunBase. mul_coefficients! (ConcreteConversion (Cc, C), vc) : vc
86+ elseif order (U) isa Union{Integer, StaticInt}
87+ coefficients (v, U, Ultraspherical (1 ,domain (U)), C)
88+ else
89+ ultra2cheb (v, strictconvert (T, order (U)); normultra, normcheb)
90+ end
91+ end
92+ function _changepolybasis (v:: StridedVector{T} ,
93+ U1:: MaybeNormalized{<:Ultraspherical{<:Any,<:ChebyshevInterval}} ,
94+ U2:: MaybeNormalized{<:Ultraspherical{<:Any,<:ChebyshevInterval}} ,
95+ ) where {T<: AbstractFloat }
96+
97+ if isinteger (order (U1) - order (U2))
98+ defaultcoefficients (v, U1, U2)
99+ else
100+ norm1 = U1 isa NormalizedPolynomialSpace
101+ norm2 = U2 isa NormalizedPolynomialSpace
102+ ultra2ultra (v, strictconvert (T, order (U1)), strictconvert (T, order (U2)); norm1, norm2)
103+ end
104+ end
105+
106+ function _changepolybasis (v:: StridedVector{T} ,
107+ C:: MaybeNormalized{<:Chebyshev{<:ChebyshevInterval}} ,
108+ J:: MaybeNormalized{<:Jacobi{<:ChebyshevInterval}} ,
109+ ) where {T<: AbstractFloat }
110+
111+ normcheb = C isa NormalizedPolynomialSpace
112+ normjac = J isa NormalizedPolynomialSpace
113+ Jc = _stripnorm (J)
114+ if Jc. a == 0 && Jc. b == 0
115+ cheb2leg (v; normcheb, normleg = normjac)
116+ else
117+ cheb2jac (v, strictconvert (T,Jc. a), strictconvert (T,Jc. b); normcheb, normjac)
118+ end
119+ end
120+ function _changepolybasis (v:: StridedVector{T} ,
121+ J:: MaybeNormalized{<:Jacobi{<:ChebyshevInterval}} ,
122+ C:: MaybeNormalized{<:Chebyshev{<:ChebyshevInterval}} ,
123+ ) where {T<: AbstractFloat }
124+
125+ normcheb = C isa NormalizedPolynomialSpace
126+ normjac = J isa NormalizedPolynomialSpace
127+ Jc = _stripnorm (J)
128+ if Jc. a == 0 && Jc. b == 0
129+ leg2cheb (v; normcheb, normleg = normjac)
130+ else
131+ jac2cheb (v, strictconvert (T,Jc. a), strictconvert (T,Jc. b); normcheb, normjac)
132+ end
133+ end
134+ function _changepolybasis (v:: StridedVector{T} ,
135+ U:: MaybeNormalized{<:Ultraspherical{<:Any,<:ChebyshevInterval}} ,
136+ J:: MaybeNormalized{<:Jacobi{<:ChebyshevInterval}} ,
137+ ) where {T<: AbstractFloat }
138+
139+ normultra = U isa NormalizedPolynomialSpace
140+ normjac = J isa NormalizedPolynomialSpace
141+ Jc = _stripnorm (J)
142+ ultra2jac (v, strictconvert (T,order (U)), strictconvert (T,Jc. a), strictconvert (T,Jc. b);
143+ normultra, normjac)
144+ end
145+ function _changepolybasis (v:: StridedVector{T} ,
146+ J:: MaybeNormalized{<:Jacobi{<:ChebyshevInterval}} ,
147+ U:: MaybeNormalized{<:Ultraspherical{<:Any,<:ChebyshevInterval}} ,
148+ ) where {T<: AbstractFloat }
149+
150+ normjac = J isa NormalizedPolynomialSpace
151+ normultra = U isa NormalizedPolynomialSpace
152+ Jc = _stripnorm (J)
153+ jac2ultra (v, strictconvert (T,Jc. a), strictconvert (T,Jc. b), strictconvert (T,order (U));
154+ normultra, normjac)
155+ end
156+ function _changepolybasis (v:: StridedVector{T} ,
157+ J1:: MaybeNormalized{<:Jacobi{<:ChebyshevInterval}} ,
158+ J2:: MaybeNormalized{<:Jacobi{<:ChebyshevInterval}} ,
159+ ) where {T<: AbstractFloat }
160+
161+ norm1 = J1 isa NormalizedPolynomialSpace
162+ norm2 = J2 isa NormalizedPolynomialSpace
163+ J1c = _stripnorm (J1)
164+ J2c = _stripnorm (J2)
165+ jac2jac (v, strictconvert (T,J1c. a), strictconvert (T,J1c. b), strictconvert (T,J2c. a), strictconvert (T,J2c. b);
166+ norm1, norm2)
167+ end
168+ _changepolybasis (v, a, b) = defaultcoefficients (v, a, b)
169+
170+ function coefficients (f:: AbstractVector{T} ,
171+ a:: MaybeNormalized{<:Union{Chebyshev,Ultraspherical,Jacobi}} ,
172+ b:: MaybeNormalized{<:Union{Chebyshev,Ultraspherical,Jacobi}} ) where T
173+ spacescompatible (a,b) && return f
174+ _changepolybasis (f, a, b)
175+ end
0 commit comments