Skip to content

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

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions