Skip to content

blockedrange([Base.OneTo(2), Base.OneTo(3)]) as a generalization of blockedrange([2, 3]) #446

@mtfishman

Description

@mtfishman

The proposal is to define a more general version of blockedrange that supports passing a list of axes of the blocks, rather than just the lengths of the blocks, i.e. support blockisequal(blockedrange([Base.OneTo(2), Base.OneTo(3)]), blockedrange([2, 3])).

The reasoning is that blocks themselves may have more structure than what is just captured by their length, for example in GradedUnitRanges.jl we define a generalization of blocked unit ranges that also have symmetry sectors associated with the blocks (i.e. it is a graded vector space). Another example might be blocked ranges where the blocks themselves have a block structure. A more general blockedrange constructor would make it easier to write generic code for blocked ranges which preserves that kind of information, for example a more generic function for slicing a blocked unit range with a BlockRange could be written as:

function Base.getindex(b::AbstractBlockedUnitRange, I::BlockRange{1})
  blockaxeses = only.(axes.(blocks(b)))
  blockaxeses_new = blockaxes[Int.(I)]
  start = first(b[first(I)]) - 1
  return blockedrange(start, blockaxeses_new)
end

blockedrange is a great constructor because the way I see it, it is the "inverse" of blocklengths, i.e. for a one-based blocked range like r = blockedrange([2, 2]), blockisequal(r, blockedrange(blocklengths(r))). Another way to see it is that it allows the concatenation or direct sum of axes in such a way that you get out a blocked unit range/axis.

Note that this is also related to the proposal here: #369 (comment) for defining a function blockaxeses(a::AbstractArray) == axes.(blocks(a)) as a generalization of blocksizes(a) == size.(blocks(a)) introduced in #399, in which case a way to recreate a one-based blocked unit range r would be blockedrange(blockaxeses(r)).

I'm also open to suggestions on other names besides blockedrange for this, this might be overloading that syntax too much, but I think it is a good interface and I can't think of a better name. Another way I have been thinking about this is in terms of a more general concept of direct summing or concatenating axes, i.e. axis_cat([Base.OneTo(2), Base.OneTo(3)]) == Base.OneTo(5) (say to get the axes resulting from cat), but I'm not sure I like that name and anyway this would be a blocked version of that function.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions