@@ -8,19 +8,19 @@ using ContinuumArrays, QuasiArrays, LazyArrays, FillArrays, BandedMatrices, Bloc
88 LazyBandedMatrices, HypergeometricFunctions
99
1010import Base: @_inline_meta , axes, getindex, unsafe_getindex, convert, prod, * , / , \ , + , - ,
11- IndexStyle, IndexLinear, == , OneTo, tail, similar, copyto!, copy,
11+ IndexStyle, IndexLinear, == , OneTo, tail, similar, copyto!, copy, setindex,
1212 first, last, Slice, size, length, axes, IdentityUnitRange, sum, _sum, cumsum,
1313 to_indices, _maybetail, tail, getproperty, inv, show, isapprox, summary
1414import Base. Broadcast: materialize, BroadcastStyle, broadcasted, Broadcasted
1515import LazyArrays: MemoryLayout, Applied, ApplyStyle, flatten, _flatten, adjointlayout,
1616 sub_materialize, arguments, sub_paddeddata, paddeddata, PaddedLayout, resizedata!, LazyVector, ApplyLayout, call,
1717 _mul_arguments, CachedVector, CachedMatrix, LazyVector, LazyMatrix, axpy!, AbstractLazyLayout, BroadcastLayout,
1818 AbstractCachedVector, AbstractCachedMatrix, paddeddata, cache_filldata!,
19- simplifiable, PaddedArray
19+ simplifiable, PaddedArray, converteltype
2020import ArrayLayouts: MatMulVecAdd, materialize!, _fill_lmul!, sublayout, sub_materialize, lmul!, ldiv!, ldiv, transposelayout, triangulardata,
2121 subdiagonaldata, diagonaldata, supdiagonaldata, mul, rowsupport, colsupport
2222import LazyBandedMatrices: SymTridiagonal, Bidiagonal, Tridiagonal, unitblocks, BlockRange1, AbstractLazyBandedLayout
23- import LinearAlgebra: pinv, factorize, qr, adjoint, transpose, dot
23+ import LinearAlgebra: pinv, factorize, qr, adjoint, transpose, dot, mul!
2424import BandedMatrices: AbstractBandedLayout, AbstractBandedMatrix, _BandedMatrix, bandeddata
2525import FillArrays: AbstractFill, getindex_value, SquareEye
2626import DomainSets: components
@@ -29,20 +29,20 @@ import QuasiArrays: cardinality, checkindex, QuasiAdjoint, QuasiTranspose, Inclu
2929 ApplyQuasiArray, ApplyQuasiMatrix, LazyQuasiArrayApplyStyle, AbstractQuasiArrayApplyStyle,
3030 LazyQuasiArray, LazyQuasiVector, LazyQuasiMatrix, LazyLayout, LazyQuasiArrayStyle,
3131 _getindex, layout_getindex, _factorize, AbstractQuasiArray, AbstractQuasiMatrix, AbstractQuasiVector,
32- AbstractQuasiFill, _dot
32+ AbstractQuasiFill, _dot, _equals, QuasiArrayLayout, PolynomialLayout
3333
3434import InfiniteArrays: OneToInf, InfAxes, Infinity, AbstractInfUnitRange, InfiniteCardinal, InfRanges
3535import InfiniteLinearAlgebra: chop!, chop
3636import ContinuumArrays: Basis, Weight, basis, @simplify , Identity, AbstractAffineQuasiVector, ProjectionFactorization,
37- inbounds_getindex, grid, plotgrid, transform, transform_ldiv, TransformFactorization, QInfAxes, broadcastbasis, Expansion ,
38- AffineQuasiVector, AffineMap, WeightLayout, WeightedBasisLayout, WeightedBasisLayouts, demap, AbstractBasisLayout, BasisLayout,
39- checkpoints, weight, unweightedbasis , MappedBasisLayouts, __sum, invmap
37+ inbounds_getindex, grid, plotgrid, transform_ldiv, TransformFactorization, QInfAxes, broadcastbasis, ExpansionLayout, basismap ,
38+ AffineQuasiVector, AffineMap, WeightLayout, AbstractWeightedBasisLayout, WeightedBasisLayout, WeightedBasisLayouts, demap, AbstractBasisLayout, BasisLayout,
39+ checkpoints, weight, unweighted , MappedBasisLayouts, __sum, invmap, plan_ldiv, layout_broadcasted, MappedBasisLayout, SubBasisLayout, _broadcastbasis
4040import FastTransforms: Λ, forwardrecurrence, forwardrecurrence!, _forwardrecurrence!, clenshaw, clenshaw!,
41- _forwardrecurrence_next, _clenshaw_next, check_clenshaw_recurrences, ChebyshevGrid, chebyshevpoints
41+ _forwardrecurrence_next, _clenshaw_next, check_clenshaw_recurrences, ChebyshevGrid, chebyshevpoints, Plan
4242
4343import FastGaussQuadrature: jacobimoment
4444
45- import BlockArrays: blockedrange, _BlockedUnitRange, unblock, _BlockArray, block, blockindex, BlockSlice
45+ import BlockArrays: blockedrange, _BlockedUnitRange, unblock, _BlockArray, block, blockindex, BlockSlice, blockvec
4646import BandedMatrices: bandwidths
4747
4848export OrthogonalPolynomial, Normalized, orthonormalpolynomial, LanczosPolynomial,
@@ -66,42 +66,53 @@ cardinality(::EuclideanDomain) = ℵ₁
6666cardinality (:: Union{DomainSets.RealNumbers,DomainSets.ComplexNumbers} ) = ℵ₁
6767cardinality (:: Union{DomainSets.Integers,DomainSets.Rationals,DomainSets.NaturalNumbers} ) = ℵ₀
6868
69- transform_ldiv (A:: AbstractQuasiArray{T} , f:: AbstractQuasiArray{V} , :: Tuple{<:Any,InfiniteCardinal{0}} ) where {T,V} =
70- adaptivetransform_ldiv (convert (AbstractQuasiArray{promote_type (T,V)}, A), f)
69+ include (" adaptivetransform.jl" )
7170
71+ const WeightedBasis{T, A<: AbstractQuasiVector , B<: Basis } = BroadcastQuasiMatrix{T,typeof (* ),<: Tuple{A,B} }
72+ abstract type OrthogonalPolynomial{T} <: Basis{T} end
73+ abstract type AbstractOPLayout <: AbstractBasisLayout end
74+ struct OPLayout <: AbstractOPLayout end
75+ MemoryLayout (:: Type{<:OrthogonalPolynomial} ) = OPLayout ()
7276
73- setaxis (c, :: OneToInf ) = c
74- setaxis (c, ax:: BlockedUnitRange ) = PseudoBlockVector (c, (ax,))
75-
76- function adaptivetransform_ldiv (A:: AbstractQuasiArray{U} , f:: AbstractQuasiArray{V} ) where {U,V}
77- T = promote_type (U,V)
7877
79- r = checkpoints (A)
80- fr = f[r]
81- maxabsfr = norm (fr,Inf )
8278
83- tol = 20 eps ( real (T) )
79+ sublayout ( :: AbstractOPLayout , :: Type{<:Tuple{<:AbstractAffineQuasiVector,<:Slice}} ) = MappedOPLayout ( )
8480
85- for n = 2 .^ (4 : ∞)
86- An = A[:,oneto (n)]
87- cfs = An \ f
88- maxabsc = maximum (abs, cfs)
89- if maxabsc == 0 && maxabsfr == 0
90- return zeros (T,∞)
91- end
81+ struct MappedOPLayout <: AbstractOPLayout end
82+ struct WeightedOPLayout{Lay<: AbstractOPLayout } <: AbstractWeightedBasisLayout end
9283
93- un = A * [cfs; Zeros {T} (∞)]
94- # we allow for transformed coefficients being a different size
95- # #TODO : how to do scaling for unnormalized bases like Jacobi?
96- if maximum (abs,@views (cfs[n- 2 : end ])) < 10 tol* maxabsc &&
97- all (norm .(un[r] - fr, 1 ) .< tol * n * maxabsfr* 1000 )
98- return setaxis ([chop! (cfs, tol); zeros (T,∞)], axes (A,2 ))
99- end
100- end
101- error (" Have not converged" )
84+ isorthogonalityweighted (:: WeightedOPLayout , _) = true
85+ function isorthogonalityweighted (:: AbstractWeightedBasisLayout , wS)
86+ w,S = arguments (wS)
87+ w == orthogonalityweight (S)
10288end
10389
104- abstract type OrthogonalPolynomial{T} <: Basis{T} end
90+ isorthogonalityweighted (wS) = isorthogonalityweighted (MemoryLayout (wS), wS)
91+
92+
93+ _equals (:: MappedOPLayout , :: MappedOPLayout , P, Q) = demap (P) == demap (Q) && basismap (P) == basismap (Q)
94+ _equals (:: MappedOPLayout , :: MappedBasisLayouts , P, Q) = demap (P) == demap (Q) && basismap (P) == basismap (Q)
95+ _equals (:: MappedBasisLayouts , :: MappedOPLayout , P, Q) = demap (P) == demap (Q) && basismap (P) == basismap (Q)
96+
97+ _broadcastbasis (:: typeof (+ ), :: MappedOPLayout , :: MappedOPLayout , P, Q) where {L,M} = _broadcastbasis (+ , MappedBasisLayout (), MappedBasisLayout (), P, Q)
98+ _broadcastbasis (:: typeof (+ ), :: MappedOPLayout , M:: MappedBasisLayout , P, Q) where L = _broadcastbasis (+ , MappedBasisLayout (), M, P, Q)
99+ _broadcastbasis (:: typeof (+ ), L:: MappedBasisLayout , :: MappedOPLayout , P, Q) where M = _broadcastbasis (+ , L, MappedBasisLayout (), P, Q)
100+ __sum (:: MappedOPLayout , A, dims) = __sum (MappedBasisLayout (), A, dims)
101+
102+ # demap to avoid Golub-Welsch fallback
103+ ContinuumArrays. transform_ldiv_if_columns (L:: Ldiv{MappedOPLayout,Lay} , ax:: OneTo ) where Lay = ContinuumArrays. transform_ldiv_if_columns (Ldiv {MappedBasisLayout,Lay} (L. A,L. B), ax)
104+ ContinuumArrays. transform_ldiv_if_columns (L:: Ldiv{MappedOPLayout,ApplyLayout{typeof(hcat)}} , ax:: OneTo ) = ContinuumArrays. transform_ldiv_if_columns (Ldiv {MappedBasisLayout,UnknownLayout} (L. A,L. B), ax)
105+
106+ _equals (:: AbstractOPLayout , :: AbstractWeightedBasisLayout , _, _) = false # Weighedt-Legendre doesn't exist
107+ _equals (:: AbstractWeightedBasisLayout , :: AbstractOPLayout , _, _) = false # Weighedt-Legendre doesn't exist
108+
109+ _equals (:: WeightedOPLayout , :: WeightedOPLayout , wP, wQ) = unweighted (wP) == unweighted (wQ)
110+ _equals (:: WeightedOPLayout , :: WeightedBasisLayout , wP, wQ) = unweighted (wP) == unweighted (wQ) && weight (wP) == weight (wQ)
111+ _equals (:: WeightedBasisLayout , :: WeightedOPLayout , wP, wQ) = unweighted (wP) == unweighted (wQ) && weight (wP) == weight (wQ)
112+ _equals (:: WeightedBasisLayout{<:AbstractOPLayout} , :: WeightedBasisLayout{<:AbstractOPLayout} , A, B) = A. f == B. f && all (A. args .== B. args)
113+
114+
115+ copy (L:: Ldiv{MappedOPLayout,Lay} ) where Lay<: MappedBasisLayouts = copy (Ldiv {MappedBasisLayout,Lay} (L. A,L. B))
105116
106117# OPs are immutable
107118copy (a:: OrthogonalPolynomial ) = a
@@ -146,12 +157,6 @@ function recurrencecoefficients(Q::AbstractQuasiMatrix{T}) where T
146157end
147158
148159
149- const WeightedOrthogonalPolynomial{T, A<: AbstractQuasiVector , B<: OrthogonalPolynomial } = WeightedBasis{T, A, B}
150-
151- function isorthogonalityweighted (wS:: WeightedOrthogonalPolynomial )
152- w,S = wS. args
153- w == orthogonalityweight (S)
154- end
155160
156161"""
157162 singularities(f)
@@ -162,9 +167,9 @@ gives the singularity structure of an expansion, e.g.,
162167singularities (:: WeightLayout , w) = w
163168singularities (lay:: BroadcastLayout , a) = singularitiesbroadcast (call (a), map (singularities, arguments (lay, a))... )
164169singularities (:: WeightedBasisLayouts , a) = singularities (BroadcastLayout {typeof(*)} (), a)
170+ singularities (:: WeightedOPLayout , a) = singularities (weight (a))
165171singularities (w) = singularities (MemoryLayout (w), w)
166- singularities (f:: Expansion ) = singularities (basis (f))
167- singularities (S:: WeightedOrthogonalPolynomial ) = singularities (S. args[1 ])
172+ singularities (:: ExpansionLayout , f) = singularities (basis (f))
168173
169174singularities (S:: SubQuasiArray ) = singularities (parent (S))[parentindices (S)[1 ]]
170175
@@ -184,83 +189,32 @@ function massmatrix(P::SubQuasiArray{<:Any,2,<:Any,<:Tuple{AbstractAffineQuasiVe
184189 massmatrix (Q)/ kr. A
185190end
186191
187- _weighted (w, P) = w .* P
188- weighted (P:: AbstractQuasiMatrix ) = _weighted (orthogonalityweight (P), P)
192+ weighted (P:: AbstractQuasiMatrix ) = Weighted (P)
189193
190194OrthogonalPolynomial (w:: Weight ) = error (" Override for $(typeof (w)) " )
191195
192196@simplify * (B:: Identity , C:: OrthogonalPolynomial ) = C* jacobimatrix (C)
193197
194- function broadcasted (:: LazyQuasiArrayStyle{2 } , :: typeof (* ), x:: Inclusion , C:: OrthogonalPolynomial )
198+ function layout_broadcasted (:: Tuple{PolynomialLayout,AbstractOPLayout } , :: typeof (* ), x:: Inclusion , C)
195199 x == axes (C,1 ) || throw (DimensionMismatch ())
196200 C* jacobimatrix (C)
197201end
198202
203+
204+
199205# function broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), a::BroadcastQuasiVector, C::OrthogonalPolynomial)
200206# axes(a,1) == axes(C,1) || throw(DimensionMismatch())
201207# # re-expand in OP basis
202208# broadcast(*, C * (C \ a), C)
203209# end
204210
205- function broadcasted (:: LazyQuasiArrayStyle{2} , :: typeof (* ), a:: AbstractAffineQuasiVector , C:: OrthogonalPolynomial )
206- x = axes (C,1 )
207- axes (a,1 ) == x || throw (DimensionMismatch ())
208- broadcast (* , C * (C \ a), C)
209- end
210-
211- function broadcasted (:: LazyQuasiArrayStyle{2} , :: typeof (* ), x:: Inclusion , C:: WeightedOrthogonalPolynomial )
212- x == axes (C,1 ) || throw (DimensionMismatch ())
213- w,P = C. args
214- P2, J = (x .* P). args
215- @assert P == P2
216- (w .* P) * J
217- end
218-
219- # #
220- # Multiplication for mapped and subviews x .* view(P,...)
221- # #
222-
223- function broadcasted (:: LazyQuasiArrayStyle{2} , :: typeof (* ), x:: Inclusion , C:: SubQuasiArray{<:Any,2,<:Any,<:Tuple{<:AbstractAffineQuasiVector,<:Any}} )
224- T = promote_type (eltype (x), eltype (C))
225- x == axes (C,1 ) || throw (DimensionMismatch ())
226- P = parent (C)
227- kr,jr = parentindices (C)
228- y = axes (P,1 )
229- Y = P \ (y .* P)
230- X = kr. A \ (Y - kr. b * Eye {T} (∞))
231- P[kr, :] * view (X,:,jr)
232- end
233-
234- function broadcasted (:: LazyQuasiArrayStyle{2} , :: typeof (* ), x:: Inclusion , C:: SubQuasiArray{<:Any,2,<:Any,<:Tuple{<:AbstractAffineQuasiVector,<:Slice}} )
235- T = promote_type (eltype (x), eltype (C))
236- x == axes (C,1 ) || throw (DimensionMismatch ())
237- P = parent (C)
238- kr,_ = parentindices (C)
239- y = axes (P,1 )
240- Y = P \ (y .* P)
241- X = kr. A \ (Y - kr. b * Eye {T} (∞))
242- P[kr, :] * X
243- end
244-
245-
246- # function broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), f::AbstractQuasiVector, C::SubQuasiArray{<:Any,2,<:Any,<:Tuple{<:AbstractAffineQuasiVector,<:Slice}})
247- # T = promote_type(eltype(f), eltype(C))
248- # axes(f,1) == axes(C,1) || throw(DimensionMismatch())
249- # P = parent(C)
250- # kr,jr = parentindices(C)
251- # (f[invmap(kr)] .* P)[kr,jr]
211+ # function broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), a::AbstractAffineQuasiVector, C::OrthogonalPolynomial)
212+ # x = axes(C,1)
213+ # axes(a,1) == x || throw(DimensionMismatch())
214+ # broadcast(*, C * (C \ a), C)
252215# end
253216
254- # function broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), f::AbstractQuasiVector, C::SubQuasiArray{<:Any,2,<:Any,<:Tuple{<:AbstractAffineQuasiVector,<:Any}})
255- # T = promote_type(eltype(f), eltype(C))
256- # axes(f,1) == axes(C,1) || throw(DimensionMismatch())
257- # P = parent(C)
258- # kr,jr = parentindices(C)
259- # (f[invmap(kr)] .* P)[kr,jr]
260- # end
261217
262- broadcasted (:: LazyQuasiArrayStyle{2} , :: typeof (* ), f:: Broadcasted , C:: SubQuasiArray{<:Any,2,<:Any,<:Tuple{<:AbstractAffineQuasiVector,<:Any}} ) =
263- broadcast (* , materialize (f), C)
264218
265219function jacobimatrix (C:: SubQuasiArray{T,2,<:Any,<:Tuple{AbstractAffineQuasiVector,Slice}} ) where T
266220 P = parent (C)
@@ -315,22 +269,22 @@ function golubwelsch(V::SubQuasiArray)
315269 x,w
316270end
317271
318- function factorize (L:: SubQuasiArray{T,2,<:Normalized,<:Tuple{Inclusion,OneTo}} ) where T
272+ function factorize (L:: SubQuasiArray{T,2,<:Normalized,<:Tuple{Inclusion,OneTo}} , dims ... ; kws ... ) where T
319273 x,w = golubwelsch (L)
320274 TransformFactorization (x, L[x,:]' * Diagonal (w))
321275end
322276
323277
324- function factorize (L:: SubQuasiArray{T,2,<:OrthogonalPolynomial,<:Tuple{Inclusion,OneTo}} ) where T
278+ function factorize (L:: SubQuasiArray{T,2,<:OrthogonalPolynomial,<:Tuple{Inclusion,OneTo}} , dims ... ; kws ... ) where T
325279 Q = Normalized (parent (L))[parentindices (L)... ]
326280 D = L \ Q
327- F = factorize (Q)
281+ F = factorize (Q, dims ... ; kws ... )
328282 TransformFactorization (F. grid, D* F. plan)
329283end
330284
331- function factorize (L:: SubQuasiArray{T,2,<:OrthogonalPolynomial,<:Tuple{<:Inclusion,<:AbstractUnitRange}} ) where T
285+ function factorize (L:: SubQuasiArray{T,2,<:OrthogonalPolynomial,<:Tuple{<:Inclusion,<:AbstractUnitRange}} , dims ... ; kws ... ) where T
332286 _,jr = parentindices (L)
333- ProjectionFactorization (factorize (parent (L)[:,oneto (maximum (jr))]), jr)
287+ ProjectionFactorization (factorize (parent (L)[:,oneto (maximum (jr))], dims ... ; kws ... ), jr)
334288end
335289
336290function \ (A:: SubQuasiArray{<:Any,2,<:OrthogonalPolynomial} , B:: SubQuasiArray{<:Any,2,<:OrthogonalPolynomial} )
@@ -346,11 +300,11 @@ function \(A::SubQuasiArray{<:Any,2,<:OrthogonalPolynomial,<:Tuple{Any,Slice}},
346300end
347301
348302# assume we can expand w_B in wA to reduce to polynomial multiplication
349- function \ (wA:: WeightedOrthogonalPolynomial , wB:: WeightedOrthogonalPolynomial )
350- _,A = arguments (wA)
351- w_B,B = arguments (wB)
352- A \ ((A * (wA \ w_B)) .* B)
353- end
303+ # function \(wA::WeightedOrthogonalPolynomial, wB::WeightedOrthogonalPolynomial)
304+ # _,A = arguments(wA)
305+ # w_B,B = arguments(wB)
306+ # A \ ((A * (wA \ w_B)) .* B)
307+ # end
354308
355309# # special expansion routines for constants and x
356310function _op_ldiv (P:: AbstractQuasiMatrix{V} , f:: AbstractQuasiFill{T,1} ) where {T,V}
0 commit comments