Best way to flatten 2D matrix to 1D when slicing from 3D matrix variable

I have a 3D matrix in Matlab to store a sequence of 2D arrays. I need to find the maximum value and its row and column indices, which is pretty simple for a single variable that contains a 2D array, as in

A = rand(10,10);
[m,i] = max(A(:));
[I,J] = ind2sub( size(A) , i )

      

The problem is that I cannot use this syntax for 3D matrix

A = rand(10,10,3);
[m,i] = max( A(:,:,1)(:) );
[I,J] = ind2sub(size( A(:,:,1) ), i )

Error: ()-indexing must appear last in an index expression.

      

I can create a temporary variable to hold the 2D slice, but I thought I'd see if there is a better means of doing this, perhaps making a call to change? Is there a way to use a simple linearization / smoothing operator (:)

in this context?

+3


source to share


3 answers


Here's what I would do:

[B i]=max(reshape(A,[],size(A,3)));
[II,JJ]=ind2sub(size(A),i );

      



The only limitation is that it won't handle random cases where there is more than one max per 2D slice.

+4


source


You can convert it to a cell array and use cellfun

B=mat2cell(reshape(A,[1, size(A,2).^2, size(A,3)]),[1],[size(A,2).^2], [ones(size(A,3),1)]);
[M,I]= cellfun(@max,B)
[R,C] = ind2sub(size(A),I);

      

M

contains the maximum value and the I

corresponding index.


Assuming it A

is an array 3x3x2

.



A =[

    0.7952    0.4456    0.7547
    0.1869    0.6463    0.2760
    0.4898    0.7094    0.6797];

A(:,:,2) =[

    0.6551    0.4984    0.5853
    0.1626    0.9597    0.2238
    0.1190    0.3404    0.7513];

      

Convert each slice to a cell array 1x9x2

B=mat2cell(reshape(A,[1, size(A,2).^2, size(A,3)]),[1],[size(A,2).^2], [ones(size(A,3),1)]);

B(:,:,1) = 

    [1x9 double]


B(:,:,2) = 

    [1x9 double]

      

Take the maximum of each piece. R

is the row and C

is the column for the corresponding maximum value in M

.

[M,I]= cellfun(@max,B)
[R,C] = ind2sub(size(A),I)

R(:,:,1) =

     1

R(:,:,2) =

     2

C(:,:,1) =

     1

C(:,:,2) =

     2

      

+1


source


After execution, max automatically pulls the indices in the (reverse) order:

A = rand(10,10,3);
[m,J] = max(max(A(:,:,1)));
[m,I] = max(A(:,J,1));

      

% Check: A (I, J, 1) == m

0


source







All Articles