A block diagonal matrix is most often given as a square matrix
where each block, given as
In addition, the structure also result in easy computation of traces and determinants as
Furthermore factorizations, such as the eigenvalue decomposition, can be computed separated as
First we define a block diagonal matrix with
n = 100 # Number fo blocks
B = BlockDiagonal([rand(3,3) for i = 1:n])
x = randn(3n)
y = B*x
norm(x - B\y)
The block diagonal matrices can be converted to sparse of dense arrays as follows
S = sparse(B)
M = Matrix(B)
Traces, determinants and log-determinant can be computed efficiently as
tr(B)
det(B)
logdet(B)
The blocks can also be non-square. However, in this case fast traces, determinants, etc. are not available and the code will throw an error.
# Number of blocks
n = 100
# Creating n
B = BlockDiagonal([rand(rand(1:3),rand(1:3)) for i = 1:n])
BlockDiagonals.jl: A pretty general package with some overall nice features (including what looks like auto-diff related stuff). The flaw in the design of the package is, however, that it only stores the blocks and no global indices. As such the computations are all serial by nature. Furthermore, things like getindex
runs in linearly as it always need to start the first block and the looping forward.