Skip to content

Commit 0c93075

Browse files
committed
Initial version of ContinuumArrays, with own implementation of AbstractAxisArray
1 parent 2857eca commit 0c93075

File tree

8 files changed

+1541
-5
lines changed

8 files changed

+1541
-5
lines changed

REQUIRE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
julia 0.7
2+
IntervalSets

examples/BSplines.jl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using ContinuumArrays, LazyArrays, IntervalSets
2+
import ContinuumArrays: AbstractAxisMatrix, ℵ₀
3+
import Base: axes, getindex, convert
4+
5+
struct Spline{order,T} <: AbstractAxisMatrix{T}
6+
points::Vector{T}
7+
end
8+
9+
const LinearSpline{T} = Spline{1,T}
10+
const HeavisideSpline{T} = Spline{0,T}
11+
12+
Spline{o}(pts::AbstractVector{T}) where {o,T} = Spline{o,float(T)}(pts)
13+
14+
axes(B::Spline{o}) where o = (first(B.points)..last(B.points), Base.OneTo(length(B.points)-o-1))
15+
16+
function getindex(B::LinearSpline{T}, x::Real, k::Int) where T
17+
x axes(B,1) && 1 k  size(B,2)|| throw(BoundsError())
18+
19+
p = B.points
20+
n = length(p)
21+
22+
k > 1 && x p[k-1] && return zero(T)
23+
k < n && x p[k+1] && return zero(T)
24+
x == p[k] && return one(T)
25+
x < p[k] && return (x-p[k-1])/(p[k]-p[k-1])
26+
return (x-p[k+1])/(p[k]-p[k+1]) # x ≥ p[k]
27+
end
28+
29+
function getindex(B::HeavisideSpline{T}, x::Real, k::Int) where T
30+
x axes(B,1) && 1 k  size(B,2)|| throw(BoundsError())
31+
32+
p = B.points
33+
n = length(p)
34+
35+
x < p[k] && return zero(T)
36+
k < n && x > p[k+1] && return zero(T)
37+
return one(T)
38+
end
39+
40+
# getindex(B::LinearSpline, ::Colon, k::Int) = Mul(B, [Zeros{Int}(k-1); 1; Zeros{Int}(size(B,2)-k)])
41+
42+
# function convert(::Type{SymTridiagonal}, AB::Mul{<:Any,<:Any,<:Any,<:ContinuumArrays.Adjoint{<:Any,<:LinearSpline},<:LinearSpline})
43+
# Ac,B = AB.A, AB.B
44+
# A = parent(Ac)
45+
# @assert A.points == B.points
46+
# x = A.points
47+
# SymTridiagonal(x, x/2) # TODO fix
48+
# end
49+
#
50+
# materialize(M::Mul{<:Any,<:Any,<:Any,<:ContinuumArrays.Adjoint{<:Any,<:LinearSpline},<:LinearSpline}) =
51+
# convert(SymTridiagonal, M)
52+
53+
## tests
54+
55+
B = HeavisideSpline([1,2,3])
56+
@test size(B) == (ℵ₀, 2)
57+
58+
@test_throws BoundsError B[0.1, 1]
59+
@test B[1.1,1] === 1.0
60+
@test B[2.1,1] === 0.0
61+
@test B[1.1,2] === 0.0
62+
@test B[2.1,2] === 1.0
63+
@test_throws BoundsError B[2.1,3]
64+
@test_throws BoundsError B[3.1,2]
65+
66+
@test all(B[[1.1,2.1], 1] .=== [1.0,0.0])
67+
@test all(B[1.1,1:2] .=== [1.0,0.0])
68+
@test all(B[[1.1,2.1], 1:2] .=== [1.0 0.0; 0.0 1.0])
69+
70+
@test_throws BoundsError B[[0.1,2.1], 1]

examples/BSplinesSphericalHarmonics.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
SH = SphericalHarmonics()
2-
Spl = BSplines(0.0:0.01:1)
3-
S = SH Spl
2+
CS = CubicSplines(0.0:0.01:1)
3+
QS = QuadraticSplines(0.0:0.01:1)
4+
LS = LinearSplines(0.0:0.01:1)
5+
S = SH CS
46

57
λ = @. -(1:∞)*((1:∞) +1)
68
L = BlockDiagonal(Diagonal.(Fill.(λ,1:2:∞))) # create a Block matrix with growing block sizes
79
Δ_s = Mul(SH, L, inv(SH)) # the Laplace–Boltrami operator
8-
D_r = Mul(Spl, SymTridiagonal(...), inv(Spl))
9-
R = Mul(Spl, Diagonal(Spl.points), inv(Spl))
10+
D_r = Mul(QS, SymTridiagonal(...), inv(CS))
11+
R = Mul(QS, Banded(...), inv(QS)) # Diagonal(Spl.points)
12+
D̃_r = Mul(LS, SymTridiagonal(...), inv(QS))
1013

11-
Δ = I (D_r*R^2*D_r) + Δ_s I # creates Laplacian as a Mul(S, ..., inv(S)) operator
14+
Δ = I (D̃_r*R^2*D_r) + Δ_s I # creates Laplacian as a Mul(S, ..., inv(S)) operator
1215

1316
# finite_dimensional case
1417
N = 100
@@ -31,4 +34,8 @@ MPI_f = Mul(S_N, BlockVector{Float64,MPIVector{Float64}}(undef, blocklengths(bac
3134
MPI_f .= f # automatically generates data remotely, via MPI version of FastTransforms
3235

3336
MPI_v = similar(MPI_f)
37+
38+
C = Mul(SH QS, I (QS' * LS), inv(SH LS))
39+
MPI_C = ...
40+
3441
MPI_v .= Mul(MPI_Δ_N, MPI_f) # applies the Laplacian and fills in missing information.

src/ContinuumArrays.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module ContinuumArrays
2+
using Base, LinearAlgebra, IntervalSets
3+
import Base: getindex, size, axes, length, ==, isequal, iterate, CartesianIndices, LinearIndices,
4+
Indices, IndexStyle, getindex, setindex!, parent, vec, convert, similar, zero,
5+
map, eachindex
6+
import Base: @_inline_meta, DimOrInd, OneTo, @_propagate_inbounds_meta, @_noinline_meta,
7+
DimsInteger, error_if_canonical_getindex, @propagate_inbounds, _return_type, _default_type,
8+
_maybetail, tail, _getindex, _maybe_reshape, index_ndims, _unsafe_getindex,
9+
index_shape, to_shape, unsafe_length, @nloops, @ncall
10+
11+
12+
import LinearAlgebra: transpose, adjoint
13+
14+
abstract type AbstractAxisArray{T,N} end
15+
AbstractAxisVector{T} = AbstractAxisArray{T,1}
16+
AbstractAxisMatrix{T} = AbstractAxisArray{T,2}
17+
AbstractAxisVecOrMat{T} = Union{AbstractAxisVector{T}, AbstractAxisMatrix{T}}
18+
19+
struct ℵ₀ <: Number end
20+
_length(::AbstractInterval) = ℵ₀
21+
_length(d) = length(d)
22+
23+
size(A::AbstractAxisArray) = _length.(axes(A))
24+
axes(A::AbstractAxisArray) = error("Override axes for $(typeof(A))")
25+
26+
include("indices.jl")
27+
include("abstractaxisarray.jl")
28+
include("adjtrans.jl")
29+
include("multidimensional.jl")
30+
end

0 commit comments

Comments
 (0)