JuliaArrays / JuliaArrays/BlockArrays.jl

There and back again: a block indexing tale

Open
#346 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Julia
Stars
254
Forks
39
PR merge metrics
No merged PRs in 30d

Description

I think a helpful abstraction could be a BlockIndices type, analogous to the CartesianIndices type in Base Julia, to aid with converting back and forth between cartesian indices and block indices. I would find that very helpful for advanced slicing operations, for example when performing slicing operations across block arrays with mismatched blocking structures.

As a minimal demonstration:

using BlockArrays

struct BlockIndices{N,R<:NTuple{N,OrdinalRange{Int,Int}}} <: AbstractArray{BlockIndex{N},N}
  indices::R
end

BlockIndices(a::AbstractArray) = BlockIndices(axes(a))

function Base.getindex(a::BlockIndices{N}, index::Vararg{Integer,N}) where {N}
  return BlockIndex(findblockindex.(a.indices, index))
end

which would allow for this syntax for converting back and forth between cartesian indices and block indices:

julia> a = BlockArray(randn(4, 4), [2, 2], [2, 2])
2×2-blocked 4×4 BlockMatrix{Float64}:
  1.05776   -0.19332   │   0.804285  -0.0377738
 -1.00564    0.368672  │   1.26819    1.02757  
 ──────────────────────┼───────────────────────
  0.37596   -1.43335   │   0.280084  -1.06666  
  0.996146  -1.04132   │  -1.21102    0.661257 

julia> CartesianIndices(a)[Block(1, 2)[2, 1]]
CartesianIndex(2, 3)

julia> BlockIndices(a)[2, 3]
Block(1, 2)[2, 1]

I found it interesting that indexing into CartesianIndices with a BlockIndex already works, I assume it is because the CartesianIndices object gets the same blocked axes as the BlockArray.

Something that doesn't work right now is indexing into CartesianIndices with a Block and getting back out a CartesianIndices, for example:

julia> CartesianIndices(a)[Block(1, 2)]
2×2 Matrix{CartesianIndex{2}}:
 CartesianIndex(1, 3)  CartesianIndex(1, 4)
 CartesianIndex(2, 3)  CartesianIndex(2, 4)

but that should be simple to fix.

We may be able to make BlockIndices a subtype of AbstractBlockArray and automatically inherit a lot of AbstractBlockArray behavior, since it will have blocked axes.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the existing CartesianIndices and BlockIndex behavior described in the issue, along with the proposed BlockIndices and AbstractBlockArray relationship. Use the provided conversion and CartesianIndices[Block(...)] examples as the acceptance cases; done means both directions work and block selection returns the expected Cartesian indices.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
data
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.