BlockArrays

BlockArrays

Creating uninitialized BlockArrays

A block array can be created with initialized blocks using the BlockArray{T}(block_sizes) function. The block_sizes are each an AbstractVector{Int} which determines the size of the blocks in that dimension. We here create a [1,2]×[3,2] block matrix of Float32s:

julia> BlockArray{Float32}(undef, [1,2], [3,2])
2×2-blocked 3×5 BlockArrays.BlockArray{Float32,2,Array{Float32,2}}:
 9.39116f-26  1.4013f-45   3.34245f-21  │  9.39064f-26  1.4013f-45
 ───────────────────────────────────────┼──────────────────────────
 3.28434f-21  9.37645f-26  3.28436f-21  │  8.05301f-24  9.39077f-26
 1.4013f-45   1.4013f-45   1.4013f-45   │  1.4013f-45   1.4013f-45

We can also any other user defined array type that supports similar.

Creating BlockArrays with uninitialized blocks.

A BlockArray can be created with the blocks left uninitialized using the BlockArray(undef, block_type, block_sizes...) function. The block_type should be an array type, it could for example be Matrix{Float64}. The block sizes are each an AbstractVector{Int} which determines the size of the blocks in that dimension. We here create a [1,2]×[3,2] block matrix of Float32s:

julia> BlockArray{Float32}(undef_blocks, [1,2], [3,2])
2×2-blocked 3×5 BlockArrays.BlockArray{Float32,2,Array{Float32,2}}:
 #undef  #undef  #undef  │  #undef  #undef
 ------------------------┼----------------
 #undef  #undef  #undef  │  #undef  #undef
 #undef  #undef  #undef  │  #undef  #undef

We can also use a SparseVector or any other user defined array type by specifying it as the second argument:

julia> BlockArray(undef_blocks, SparseVector{Float64, Int}, [1,2])
2-blocked 3-element BlockArrays.BlockArray{Float64,1,SparseVector{Float64,Int64}}:
 #undef
 ------
 #undef
 #undef

Note that accessing an undefined block will throw an "access to undefined reference"-error.

Setting and getting blocks and values

A block can be set by setblock!(block_array, v, i...) where v is the array to set and i is the block index. An alternative syntax for this is block_array[Block(i...)] = v or block_array[Block.(i)...].

julia> block_array = BlockArray{Float64}(unitialized_blocks, [1,2], [2,2])
2×2-blocked 3×4 BlockArrays.BlockArray{Float64,2,Array{Float64,2}}:
 #undef  #undef  │  #undef  #undef
 ----------------┼----------------
 #undef  #undef  │  #undef  #undef
 #undef  #undef  │  #undef  #undef

julia> setblock!(block_array, rand(2,2), 2, 1)
2×2-blocked 3×4 BlockArrays.BlockArray{Float64,2,Array{Float64,2}}:
 #undef      #undef      │  #undef  #undef
 ------------------------┼----------------
   0.590845    0.566237  │  #undef  #undef
   0.766797    0.460085  │  #undef  #undef

julia> block_array[Block(1, 1)] = [1 2];

julia> block_array
2×2-blocked 3×4 BlockArrays.BlockArray{Float64,2,Array{Float64,2}}:
 1.0       2.0       │  #undef  #undef
 --------------------┼----------------
 0.590845  0.566237  │  #undef  #undef
 0.766797  0.460085  │  #undef  #undef

Note that this will "take ownership" of the passed in array, that is, no copy is made.

A block can be retrieved with getblock(block_array, i...) or block_array[Block(i...)]:

julia> block_array[Block(1, 1)]
1×2 Array{Float64,2}:
 1.0  2.0

julia> block_array[Block(1), Block(1)]  # equivalent to above
 1×2 Array{Float64,2}:
  1.0  2.0

Similarly to setblock! this does not copy the returned array.

For setting and getting a single scalar element, the usual setindex! and getindex are available.

julia> block_array[1, 2]
2.0

Views of blocks

We can also view and modify views of blocks of BlockArray using the view syntax:

julia> A = BlockArray(ones(6), 1:3);

julia> view(A, Block(2))
2-element SubArray{Float64,1,BlockArrays.BlockArray{Float64,1,Array{Float64,1}},Tuple{BlockArrays.BlockSlice},false}:
 1.0
 1.0

julia> view(A, Block(2)) .= [3,4]; A[Block(2)]
2-element Array{Float64,1}:
 3.0
 4.0

Converting between BlockArray and normal arrays

An array can be repacked into a BlockArray with BlockArray(array, block_sizes...):

julia> block_array_sparse = BlockArray(sprand(4, 5, 0.7), [1,3], [2,3])
2×2-blocked 4×5 BlockArrays.BlockArray{Float64,2,SparseMatrixCSC{Float64,Int64}}:
 0.0341601  0.374187  │  0.0118196  0.299058  0.0     
 ---------------------┼-------------------------------
 0.0945445  0.931115  │  0.0460428  0.0       0.0     
 0.314926   0.438939  │  0.496169   0.0       0.0     
 0.12781    0.246862  │  0.732      0.449182  0.875096

To get back the underlying array use Array:

julia> Array(block_array_sparse))
4×5 SparseMatrixCSC{Float64,Int64} with 15 stored entries:
  [1, 1]  =  0.0341601
  [2, 1]  =  0.0945445
  [3, 1]  =  0.314926
  [4, 1]  =  0.12781
  ⋮
  [3, 3]  =  0.496169
  [4, 3]  =  0.732
  [1, 4]  =  0.299058
  [4, 4]  =  0.449182
  [4, 5]  =  0.875096