Search code examples
matlabmatrixconcatenationdiagonal

How can I get counterdiagonals of a matrix and concatenate them?


Short Version

How can I do concatMap in MATLAB? I'm trying to build a single vector from a series of smaller, differently sized vectors. I know I can do:

result = [];
for i=1:N
    result = [result nextPart(i)];
end

but that has a serious speed impact and there must be a smarter way to do concatMap.


Long Version

I'm trying to write a MATLAB function that returns the counterdiagonals of a block. For example, if you have the block:

1 2 4
3 5 7
6 8 9

then counterDiagonals(block) should return [1 2 3 4 5 6 7 8 9].

I have a function that will find a single counter diagonal of a block. i.e. counterDiagonal(x, 3) will return [4 5 6].

Therefore, counterDiagonals should be as simple as concatMap counterDiagonal(x, i) (1:N) where N is (2*length(block)-1). How can I do this in MATLAB in an efficient way?


Solution

  • I believe what you want to do can be accomplished using the functions ROT90 and SPDIAGS:

    A = [1 2 4; 3 5 7; 6 8 9];  %# Sample matrix
    result = rot90(A);          %# Rotate the matrix counter-clockwise
    result = spdiags(result);   %# Find all the diagonals
    result = result(result ~= 0).';  %'# Remove zero padding and format the results
                                      %#   into a row vector
    

    And you should end up with result = [1 2 3 4 5 6 7 8 9].

    EDIT: As Amro mentions in a comment, the above code assumes that there are no zeroes in the original matrix A. If there are zeroes in the original matrix, one solution is to replace them with a non-zero flag value that you know doesn't appear in the original matrix (like, for example, NaN), run the above code, then replace the flag values in the result:

    A = [0 2 4; 3 0 7; 6 8 0];  %# Sample matrix
    result = rot90(A);          %# Rotate the matrix counter-clockwise
    result(result == 0) = nan;  %# Replace zeroes with NaN
    result = spdiags(result);   %# Find all the diagonals
    result = result(result ~= 0).';  %'# Remove zero padding and format the results
                                      %#   into a row vector
    result(isnan(result)) = 0;  %# Put the original zeroes back