@@ -148,3 +148,107 @@ typeof(B)
148
148
149
149
150
150
factorize (B)
151
+
152
+
153
+ # # Option 3 ContinuumArrays.jl
154
+
155
+ using LinearAlgebra, IntervalSets, FillArrays, LazyArrays
156
+ import Base: size, getindex, show, + , * , - , convert, copyto!, length, axes, parent, eltype
157
+ import LinearAlgebra: adjoint, SymTridiagonal
158
+ import InfiniteArrays: Infinity
159
+ import LazyArrays: MemoryLayout
160
+
161
+ abstract type ContinuumArray{T, N} end
162
+ const ContinuumVector{T} = ContinuumArray{T, 1 }
163
+ const ContinuumMatrix{T} = ContinuumArray{T, 2 }
164
+
165
+ eltype (:: Type{<:ContinuumArray{T}} ) where T = T
166
+ eltype (:: ContinuumArray{T} ) where T = T
167
+
168
+ struct ℵ₀ <: Number end
169
+ _length (:: AbstractInterval ) = ℵ₀
170
+ _length (d) = length (d)
171
+
172
+ size (A:: ContinuumArray ) = _length .(axes (A))
173
+ axes (A:: ContinuumArray , j:: Int ) = axes (A)[j]
174
+ size (A:: ContinuumArray , j:: Int ) = size (A)[j]
175
+
176
+ struct ContinuumLayout <: MemoryLayout end
177
+ MemoryLayout (:: ContinuumArray ) = ContinuumLayout ()
178
+
179
+ getindex (B:: ContinuumMatrix , K:: AbstractVector , j:: Real ) =
180
+ [B[k, j] for k in K]
181
+
182
+ getindex (B:: ContinuumMatrix , k:: Real , J:: AbstractVector ) =
183
+ [B[k, j] for j in J]
184
+
185
+ getindex (B:: ContinuumMatrix , K:: AbstractVector , J:: AbstractVector ) =
186
+ [B[k, j] for k in K, j in J]
187
+
188
+ getindex (B:: ContinuumMatrix , :: Colon , :: Colon ) = copy (B)
189
+ getindex (B:: ContinuumMatrix , :: Colon , J) = B[:, J]
190
+ getindex (B:: ContinuumMatrix , K, :: Colon ) = B[K, axes (B,2 )]
191
+
192
+
193
+ # use lazy multiplication
194
+ materialize (M:: Mul ) = M
195
+ * (A:: ContinuumArray , B:: ContinuumArray ) = materialize (Mul (A,B))
196
+
197
+ struct CAdjoint{T,PAR} <: ContinuumMatrix{T}
198
+ parent:: PAR
199
+ end
200
+
201
+ CAdjoint (A:: ContinuumArray{T} ) where T = CAdjoint {T, typeof(A)} (A)
202
+
203
+ parent (A:: CAdjoint ) = A. parent
204
+
205
+ axes (A:: CAdjoint ) = reverse (axes (parent (A)))
206
+ adjoint (A:: ContinuumArray ) = CAdjoint (A)
207
+ getindex (A:: CAdjoint , k:: Real , j:: Real ) = adjoint (parent (A)[j,k])
208
+
209
+
210
+
211
+ struct LinearSpline{T} <: ContinuumMatrix{T}
212
+ points:: Vector{T}
213
+ end
214
+
215
+ LinearSpline (p:: Vector{T} ) where T = LinearSpline {float(T)} (p)
216
+
217
+ axes (B:: LinearSpline ) = (first (B. points).. last (B. points), Base. OneTo (length (B. points)))
218
+
219
+ function getindex (B:: LinearSpline{T} , x:: Real , k:: Int ) where T
220
+ x ∈ axes (B,1 ) && 1 ≤ k ≤ size (B,2 )|| throw (BoundsError ())
221
+
222
+ p = B. points
223
+ n = length (p)
224
+
225
+ k > 1 && x ≤ p[k- 1 ] && return zero (T)
226
+ k < n && x ≥ p[k+ 1 ] && return zero (T)
227
+ x == p[k] && return one (T)
228
+ x < p[k] && return (x- p[k- 1 ])/ (p[k]- p[k- 1 ])
229
+ return (x- p[k+ 1 ])/ (p[k]- p[k+ 1 ]) # x ≥ p[k]
230
+ end
231
+
232
+ getindex (B:: LinearSpline , :: Colon , k:: Int ) = Mul (B, [Zeros {Int} (k- 1 ); 1 ; Zeros {Int} (size (B,2 )- k)])
233
+
234
+ function convert (:: Type{SymTridiagonal} , AB:: Mul{<:Any,<:Any,<:Any,<:CAdjoint{<:Any,<:LinearSpline},<:LinearSpline} )
235
+ Ac,B = AB. A, AB. B
236
+ A = parent (Ac)
237
+ @assert A. points == B. points
238
+ x = A. points
239
+ SymTridiagonal (x, x/ 2 ) # TODO fix
240
+ end
241
+
242
+ materialize (M:: Mul{<:Any,<:Any,<:Any,<:CAdjoint{<:Any,<:LinearSpline},<:LinearSpline} ) =
243
+ convert (SymTridiagonal, M)
244
+
245
+ # # tests
246
+
247
+ B = LinearSpline ([1 ,2 ,3 ])
248
+
249
+ using Plots
250
+ x = range (1 , stop= 3 , length= 1000 )
251
+ plot (B[x,:])
252
+
253
+
254
+ @test B' B isa SymTridiagonal
0 commit comments