8

I'm looking for an elegant solution to this very simple problem in MATLAB. Suppose I have a matrix

>> M = magic(5)

M =

    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9 

and a logical variable of the form

I =

     0     0     0     0     0
     0     1     1     0     0
     0     1     1     0     0
     0     0     0     0     0
     0     0     0     0     0

If I try to retrieve the elements of M associated to 1 values in I, I get a column vector

>> M(I)

ans =

     5
     6
     7
    13

What would be the simplest way to obtain the matrix [5 7 ; 6 13] from this logical indexing?

If I know the shape of the non-zero elements of I, I can use a reshape after the indexing, but that's not a general case.

Also, I'm aware that the default behavior for this type of indexing in MATLAB enforces consistency with respect to the case in which non-zero values in I do not form a matrix, but I wonder if there is a simple solution for this particular case.

nrz
  • 10,435
  • 4
  • 39
  • 71
foglerit
  • 7,792
  • 8
  • 44
  • 64

3 Answers3

11

This is a one way to do this. It is assumed that all rows of I have same number of ones. It is also assumed that all columns of I have same number have ones, because Submatrix must be rectangular.

%# Define the example data.

M = magic(5);
I = zeros(5);
I(2:3, 2:3) = 1;

%# Create the Submatrix.

Submatrix = reshape(M(find(I)), max(sum(I)), max(sum(I')));
nrz
  • 10,435
  • 4
  • 39
  • 71
3

Here is a very simple solution:

T = I(any(I'),any(I));
T(:) = M(I);
Dennis Jaheruddin
  • 21,208
  • 8
  • 66
  • 122
  • Just what I was going to answer :-) – Luis Mendo Mar 17 '15 at 22:36
  • That does not work allways, e.g. when not symmetric. – rst Apr 05 '16 at 09:02
  • @RobertStettler If you mean the matrix `I` cannot be made randomly, that is true, but looking at the question I think that is a reasonable limitation. If you mean something else: I don't see how symetry is relevant here, could you perhaps present an example where the solution fails? (Input matrix, output, expected output). – Dennis Jaheruddin Apr 06 '16 at 12:34
  • OK, I was not precise enough in my comment: If the selection matrix `I` is not symmetric, you get some issues with the form of `T`. In fact, I believe you can correct the answer by simply changing the first line to: `T = I(any(I'), any(I));`. Try your solution by using this example input matrix: `I = zeros(5);I(1:4, 2:3) = 1;` – rst Apr 07 '16 at 06:32
  • @YonggooNoh It is nice to see the enthusiasm, but do note the general site policy: If you think a post is good, vote for it. Chatty comments make it harder for future readers to extract the relevant info from a thread. – Dennis Jaheruddin May 23 '17 at 11:01
2
M = magic(5);
I = [ ... ];

ind = find(I); %# find indices of ones in I
[y1, x1] = ind2sub(size(M), ind(1));   %# get top-left position
[y2, x2] = ind2sub(size(M), ind(end)); %# get bottom-right position
O = M(y1:y2, x1:x2); %# copy submatrix
Kijewski
  • 25,517
  • 12
  • 101
  • 143