Skip to content

Commit 3673dfe

Browse files
committed
ContinuumArrays proposal
1 parent 9839a27 commit 3673dfe

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

src/QuasiMatrices.jl

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,107 @@ typeof(B)
148148

149149

150150
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

Comments
 (0)