Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More convenient syntax for merging blocks #359

Open
mtfishman opened this issue Mar 28, 2024 · 0 comments
Open

More convenient syntax for merging blocks #359

mtfishman opened this issue Mar 28, 2024 · 0 comments

Comments

@mtfishman
Copy link
Collaborator

mtfishman commented Mar 28, 2024

It would be nice to have a more convenient/compact syntax for merging adjacent blocks. Right now you can do that by indexing with new axes that have a new blocking structure (see the related discussion #347), but that requires a lot of work to be done "by hand" by the user to determine the new block sizes.

From what I can tell, the best way to do this right now is:

 julia> using BlockArrays

julia> a = BlockArray(randn(8, 8), [2, 2, 2, 2], [2, 2, 2, 2])
4×4-blocked 8×8 BlockMatrix{Float64}:
 -0.0707114  -1.679060.138973    0.544946-0.134462   0.6112722.18339    -0.883239
 -0.68735     0.857573-0.0080504   3.64798-0.471002   1.57178-0.0149043   0.903188
 ───────────────────────┼─────────────────────────┼──────────────────────────┼───────────────────────
 -0.0604537   0.2315461.18174     0.208313-1.72071    0.879961-0.366364   -0.73705 
  1.08236    -2.60451.76942     1.0568-1.85228    1.83546-1.06417     0.930053
 ───────────────────────┼─────────────────────────┼──────────────────────────┼───────────────────────
 -1.02677    -0.354130.671171    0.3176931.12187   -0.09320430.125758   -1.45183 
  0.328434   -1.46481-1.93467    -0.866749-0.923225  -1.20646-1.13039    -0.715379
 ───────────────────────┼─────────────────────────┼──────────────────────────┼───────────────────────
  1.34041    -0.5744960.273291    1.57875-0.635733  -0.00893333-0.554791   -0.625784
  0.396603   -0.569414-0.898214   -1.756611.02851   -0.392836-0.942213    0.627758

julia> a[blockedrange([4, 4]), blockedrange([4, 4])]
2×2-blocked 8×8 BlockMatrix{Float64}:
 -0.0707114  -1.67906    0.138973    0.544946-0.134462   0.611272     2.18339    -0.883239
 -0.68735     0.857573  -0.0080504   3.64798-0.471002   1.57178     -0.0149043   0.903188
 -0.0604537   0.231546   1.18174     0.208313-1.72071    0.879961    -0.366364   -0.73705 
  1.08236    -2.6045     1.76942     1.0568-1.85228    1.83546     -1.06417     0.930053
 ──────────────────────────────────────────────┼───────────────────────────────────────────────
 -1.02677    -0.35413    0.671171    0.3176931.12187   -0.0932043    0.125758   -1.45183 
  0.328434   -1.46481   -1.93467    -0.866749-0.923225  -1.20646     -1.13039    -0.715379
  1.34041    -0.574496   0.273291    1.57875-0.635733  -0.00893333  -0.554791   -0.625784
  0.396603   -0.569414  -0.898214   -1.756611.02851   -0.392836    -0.942213    0.627758

as discussed in #347. A proposal for a more convenient syntax would be:

julia> r = BlockVector(Block.(1:4), [2, 2])
2-blocked 4-element BlockVector{Block{1, Int64}, Vector{BlockRange{1, Tuple{UnitRange{Int64}}}}, Tuple{BlockedUnitRange{Vector{Int64}}}}:
 Block(1)
 Block(2)
 ────────
 Block(3)
 Block(4)

julia> a[r, r]
2×2-blocked 8×8 BlockMatrix{Float64}:
 -0.0707114  -1.67906    0.138973    0.544946-0.134462   0.611272     2.18339    -0.883239
 -0.68735     0.857573  -0.0080504   3.64798-0.471002   1.57178     -0.0149043   0.903188
 -0.0604537   0.231546   1.18174     0.208313-1.72071    0.879961    -0.366364   -0.73705 
  1.08236    -2.6045     1.76942     1.0568-1.85228    1.83546     -1.06417     0.930053
 ──────────────────────────────────────────────┼───────────────────────────────────────────────
 -1.02677    -0.35413    0.671171    0.3176931.12187   -0.0932043    0.125758   -1.45183 
  0.328434   -1.46481   -1.93467    -0.866749-0.923225  -1.20646     -1.13039    -0.715379
  1.34041    -0.574496   0.273291    1.57875-0.635733  -0.00893333  -0.554791   -0.625784
  0.396603   -0.569414  -0.898214   -1.756611.02851   -0.392836    -0.942213    0.627758

(which doesn't work right now). Writing out BlockVector(Block.(1:4), [2, 2]) is a bit annoying, but the idea is that it expresses the intent better: the user doesn't have to deal with any of the block lengths themselves, they just express which blocks should get merged together. This is analogous to the block version of indexing with blockedrange([2, 2]) in order to define a new blocking structure. Perhaps it even warrants a devoted syntax like blockedblockrange([2, 2]) for constructing BlockVector(Block.(1:4), [2, 2]) (or a devoted type BlockedBlockRange).

Related to #184, one could imagine generalizing this to something like BlockVector([Block(1), Block(3), Block(2), Block(4)], [2, 2]), which would be a fused operation for permuting blocks along an axis and then merging adjacent blocks. We would have many applications for that kind of operation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant