1
votes

I am trying to figure out if it is possible to access to multiple blocks of a diagonal block matrix, in MATLAB.

For example, let's say I have this (ideally sparse, but could be dense too) block matrix

    |A A 0 0|
    |A A 0 0|
M = |0 0 B B|
    |0 0 B B|

I know that, for example, one can access to the first sublock as M(1:2,1:2), but I cannot find a way to access to non sequencial cells.

Is there a way to access with a single command to the submatrices A and B. Ultimately I am interested in updating a really large sparse block matrix very quick.

To clarify, in my case the block diagonals are always the same size. I know I can update them in two commands doing M(1:2,1:2) = 1 and M(3:4,3:4) = 2, but can I do both in a single access? Also, I need to keep M as a 2D matrix since is used afterwards in matrix multiplication operations.

1
In order to properly answer this question you need to provide more details on what operations you want to perform on the block(s).excaza
Updating sparse matrices will never be quick, because of how they are stored in memoryAnder Biguri
@AnderBiguri Agreed, but is there any way to actually update all blocks in a single access? Even if the matrix is not sparseDan
M([1 3],[1 3]) ?Ander Biguri
Are the blocks always the same size?beaker

1 Answers

1
votes

Once you have your matrix M, with non-zero values in diagonal blocks and zeroes everywhere else (I assume), you can get an index of all the non-zero values (i.e. all the blocks) by using find:

index = find(M);

Using that index, you could access and update all of your blocks at once. For example, if you wanted to add 1 to all the blocks, you would do this:

M(index) = M(index)+1;

If you want to update each block to a different value, and given the size of each block, you can do this in one step using the index above and repelem. Here's an example:

M = [1 1 0 0; 1 1 0 0; 0 0 1 1; 0 0 1 1];  % Sample matrix
index = find(M);     % Get the linear indices
blockSizes = [2 2];  % Each block is a 2-by-2
newValues = [2 3];   % New values for each block
M(index) = repelem(newValues, blockSizes.^2)

M =

     2     2     0     0
     2     2     0     0
     0     0     3     3
     0     0     3     3