I’m defining a multi-dimensional Hankel array, as follows:
struct Hankel{T,N,V<:AbstractArray{T},D<:Tuple{Vararg{Int}}} <: AbstractArray{T,N}
v::V
d::D
function Hankel(v::AbstractArray, d::Tuple{Vararg{Int}})
Δ = length(d)
@assert Δ ≤ ndims(v)
@assert all(0 .≤ d .≤ size(v)[1:Δ])
return new{eltype(v), Δ + ndims(v), typeof(v), typeof(d)}(v, d)
end
end
Hankel(v::AbstractArray, d::Int...) = Hankel(v, d)
Base.IndexStyle(::Type{<:Hankel}) = IndexCartesian()
function Base.size(A::Hankel)
Δ = length(A.d)
return (A.d..., (size(A.v)[1:Δ] .- A.d .+ 1)..., size(A.v)[(Δ + 1):end]...)
end
@inline function Base.getindex(A::Hankel{T,N}, I::Vararg{Int,N}) where {T,N}
@boundscheck checkbounds(A, I...)
Δ = length(A.d)
j, k, b = I[1:Δ], I[(Δ + 1):(2Δ)], I[(2Δ + 1):end]
return A.v[(j .+ k .- 1)..., b...]
end
This seems to work fine. However I’m having a weird type-instability issue when I try to index this with CartesianIndex
.
using Tests
N = (5,8,4); d = (3,4,2); B = (7,9)
v = randn(N..., B...);
A = @inferred Hankel(v, d) # this is fine
j = rand(CartesianIndices(d));
k = rand(CartesianIndices(N .- d .+ 1));
b = rand(CartesianIndices(B));
@inferred A[j,k,b] # fails
Can someone help diagnosing this?