@@ -8,19 +8,19 @@ using ContinuumArrays, QuasiArrays, LazyArrays, FillArrays, BandedMatrices, Bloc
8
8
LazyBandedMatrices, HypergeometricFunctions
9
9
10
10
import 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,
12
12
first, last, Slice, size, length, axes, IdentityUnitRange, sum, _sum, cumsum,
13
13
to_indices, _maybetail, tail, getproperty, inv, show, isapprox, summary
14
14
import Base. Broadcast: materialize, BroadcastStyle, broadcasted, Broadcasted
15
15
import LazyArrays: MemoryLayout, Applied, ApplyStyle, flatten, _flatten, adjointlayout,
16
16
sub_materialize, arguments, sub_paddeddata, paddeddata, PaddedLayout, resizedata!, LazyVector, ApplyLayout, call,
17
17
_mul_arguments, CachedVector, CachedMatrix, LazyVector, LazyMatrix, axpy!, AbstractLazyLayout, BroadcastLayout,
18
18
AbstractCachedVector, AbstractCachedMatrix, paddeddata, cache_filldata!,
19
- simplifiable, PaddedArray
19
+ simplifiable, PaddedArray, converteltype
20
20
import ArrayLayouts: MatMulVecAdd, materialize!, _fill_lmul!, sublayout, sub_materialize, lmul!, ldiv!, ldiv, transposelayout, triangulardata,
21
21
subdiagonaldata, diagonaldata, supdiagonaldata, mul, rowsupport, colsupport
22
22
import 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!
24
24
import BandedMatrices: AbstractBandedLayout, AbstractBandedMatrix, _BandedMatrix, bandeddata
25
25
import FillArrays: AbstractFill, getindex_value, SquareEye
26
26
import DomainSets: components
@@ -29,20 +29,20 @@ import QuasiArrays: cardinality, checkindex, QuasiAdjoint, QuasiTranspose, Inclu
29
29
ApplyQuasiArray, ApplyQuasiMatrix, LazyQuasiArrayApplyStyle, AbstractQuasiArrayApplyStyle,
30
30
LazyQuasiArray, LazyQuasiVector, LazyQuasiMatrix, LazyLayout, LazyQuasiArrayStyle,
31
31
_getindex, layout_getindex, _factorize, AbstractQuasiArray, AbstractQuasiMatrix, AbstractQuasiVector,
32
- AbstractQuasiFill, _dot
32
+ AbstractQuasiFill, _dot, _equals, QuasiArrayLayout, PolynomialLayout
33
33
34
34
import InfiniteArrays: OneToInf, InfAxes, Infinity, AbstractInfUnitRange, InfiniteCardinal, InfRanges
35
35
import InfiniteLinearAlgebra: chop!, chop
36
36
import 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
40
40
import 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
42
42
43
43
import FastGaussQuadrature: jacobimoment
44
44
45
- import BlockArrays: blockedrange, _BlockedUnitRange, unblock, _BlockArray, block, blockindex, BlockSlice
45
+ import BlockArrays: blockedrange, _BlockedUnitRange, unblock, _BlockArray, block, blockindex, BlockSlice, blockvec
46
46
import BandedMatrices: bandwidths
47
47
48
48
export OrthogonalPolynomial, Normalized, orthonormalpolynomial, LanczosPolynomial,
@@ -66,42 +66,53 @@ cardinality(::EuclideanDomain) = ℵ₁
66
66
cardinality (:: Union{DomainSets.RealNumbers,DomainSets.ComplexNumbers} ) = ℵ₁
67
67
cardinality (:: Union{DomainSets.Integers,DomainSets.Rationals,DomainSets.NaturalNumbers} ) = ℵ₀
68
68
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" )
71
70
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 ()
72
76
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)
78
77
79
- r = checkpoints (A)
80
- fr = f[r]
81
- maxabsfr = norm (fr,Inf )
82
78
83
- tol = 20 eps ( real (T) )
79
+ sublayout ( :: AbstractOPLayout , :: Type{<:Tuple{<:AbstractAffineQuasiVector,<:Slice}} ) = MappedOPLayout ( )
84
80
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
92
83
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)
102
88
end
103
89
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))
105
116
106
117
# OPs are immutable
107
118
copy (a:: OrthogonalPolynomial ) = a
@@ -146,12 +157,6 @@ function recurrencecoefficients(Q::AbstractQuasiMatrix{T}) where T
146
157
end
147
158
148
159
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
155
160
156
161
"""
157
162
singularities(f)
@@ -162,9 +167,9 @@ gives the singularity structure of an expansion, e.g.,
162
167
singularities (:: WeightLayout , w) = w
163
168
singularities (lay:: BroadcastLayout , a) = singularitiesbroadcast (call (a), map (singularities, arguments (lay, a))... )
164
169
singularities (:: WeightedBasisLayouts , a) = singularities (BroadcastLayout {typeof(*)} (), a)
170
+ singularities (:: WeightedOPLayout , a) = singularities (weight (a))
165
171
singularities (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))
168
173
169
174
singularities (S:: SubQuasiArray ) = singularities (parent (S))[parentindices (S)[1 ]]
170
175
@@ -184,83 +189,32 @@ function massmatrix(P::SubQuasiArray{<:Any,2,<:Any,<:Tuple{AbstractAffineQuasiVe
184
189
massmatrix (Q)/ kr. A
185
190
end
186
191
187
- _weighted (w, P) = w .* P
188
- weighted (P:: AbstractQuasiMatrix ) = _weighted (orthogonalityweight (P), P)
192
+ weighted (P:: AbstractQuasiMatrix ) = Weighted (P)
189
193
190
194
OrthogonalPolynomial (w:: Weight ) = error (" Override for $(typeof (w)) " )
191
195
192
196
@simplify * (B:: Identity , C:: OrthogonalPolynomial ) = C* jacobimatrix (C)
193
197
194
- function broadcasted (:: LazyQuasiArrayStyle{2 } , :: typeof (* ), x:: Inclusion , C:: OrthogonalPolynomial )
198
+ function layout_broadcasted (:: Tuple{PolynomialLayout,AbstractOPLayout } , :: typeof (* ), x:: Inclusion , C)
195
199
x == axes (C,1 ) || throw (DimensionMismatch ())
196
200
C* jacobimatrix (C)
197
201
end
198
202
203
+
204
+
199
205
# function broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), a::BroadcastQuasiVector, C::OrthogonalPolynomial)
200
206
# axes(a,1) == axes(C,1) || throw(DimensionMismatch())
201
207
# # re-expand in OP basis
202
208
# broadcast(*, C * (C \ a), C)
203
209
# end
204
210
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)
252
215
# end
253
216
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
261
217
262
- broadcasted (:: LazyQuasiArrayStyle{2} , :: typeof (* ), f:: Broadcasted , C:: SubQuasiArray{<:Any,2,<:Any,<:Tuple{<:AbstractAffineQuasiVector,<:Any}} ) =
263
- broadcast (* , materialize (f), C)
264
218
265
219
function jacobimatrix (C:: SubQuasiArray{T,2,<:Any,<:Tuple{AbstractAffineQuasiVector,Slice}} ) where T
266
220
P = parent (C)
@@ -315,22 +269,22 @@ function golubwelsch(V::SubQuasiArray)
315
269
x,w
316
270
end
317
271
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
319
273
x,w = golubwelsch (L)
320
274
TransformFactorization (x, L[x,:]' * Diagonal (w))
321
275
end
322
276
323
277
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
325
279
Q = Normalized (parent (L))[parentindices (L)... ]
326
280
D = L \ Q
327
- F = factorize (Q)
281
+ F = factorize (Q, dims ... ; kws ... )
328
282
TransformFactorization (F. grid, D* F. plan)
329
283
end
330
284
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
332
286
_,jr = parentindices (L)
333
- ProjectionFactorization (factorize (parent (L)[:,oneto (maximum (jr))]), jr)
287
+ ProjectionFactorization (factorize (parent (L)[:,oneto (maximum (jr))], dims ... ; kws ... ), jr)
334
288
end
335
289
336
290
function \ (A:: SubQuasiArray{<:Any,2,<:OrthogonalPolynomial} , B:: SubQuasiArray{<:Any,2,<:OrthogonalPolynomial} )
@@ -346,11 +300,11 @@ function \(A::SubQuasiArray{<:Any,2,<:OrthogonalPolynomial,<:Tuple{Any,Slice}},
346
300
end
347
301
348
302
# 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
354
308
355
309
# # special expansion routines for constants and x
356
310
function _op_ldiv (P:: AbstractQuasiMatrix{V} , f:: AbstractQuasiFill{T,1} ) where {T,V}
0 commit comments