2

The matlab help page for matrix indexing says:

Logical Indexing with a Smaller Array

In most cases, the logical indexing array should have the same number of elements as the array being indexed into, but this is not a requirement. The indexing array may have smaller (but not larger) dimensions:

A = [1 2 3;4 5 6;7 8 9]
A =
     1     2     3
     4     5     6
     7     8     9

B = logical([0 1 0; 1 0 1])
B =
     0     1     0
     1     0     1

isequal(numel(A), numel(B))
ans =
     0

A(B)
ans =
     4
     7
     8

What kind of crazy rule is matlab using here?

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
Eric
  • 95,302
  • 53
  • 242
  • 374
  • 5
    Related: http://stackoverflow.com/questions/32379805/linear-indexing-logical-indexing-and-all-that – Adriaan Dec 02 '15 at 23:46
  • I don't understand what your actual question is? What code do you specifically not understand? – horchler Dec 02 '15 at 23:55
  • 2
    It's kind of explained right after the quote you provided: "MATLAB treats the missing elements of the indexing array as if they were present and set to zero". I say "kind of" because they omit the fact Matlab switches to linear indexing per the example after the sentence: `C = logical([B(:);0;0;0]);` and `isequal(A(C),A(B)) == true`. – TroyHaskin Dec 03 '15 at 00:04
  • You can view it as if Matlab is applying an __implicit `find`__: `A(find(B))`. (I'm not saying Matlab internally does that; but functionally it's equivalent). That implicit `find` takes care of the two possibly surprising issues: it linearizes the index array `B`, and it picks the integer indices of the `true` entries (making it unimportant that some `false` entries are missing) – Luis Mendo Dec 03 '15 at 00:39
  • Right, I hadn't realized it was linearizing the array. What sensible behaviour... – Eric Dec 03 '15 at 01:20

1 Answers1

0

To understand this behavior, it's necessary to understand how matrices are stored in memory. Matlab stores matrices using column major layout. This means the 2d matrix:

                       A =   1     2     3
                             4     5     6
                             7     8     9

is stored in memory as one dimensional array going down the columns of A:

A     = { array  = [1  4  7  2  5  8  3  6  9]  
          n_rows = 3
          n_cols = 3                            }

The matrix B:

                        B =  0     1     0
                             1     0     1

is stored in memory as:

B     = { array  = [0  1  1  0  0  1]  
          n_rows = 2
          n_cols = 3                            }

Let's put the underlying representations next to eachother:

A.array = [1  4  7  2  5  8  3  6  9] 
B.array = [0  1  1  0  0  1]  

Using logical indexing, A(B) gives you [4, 7, 8] If you think a bit deeper, what's causing the unintuitive result is the combination of: (1) Matlab uses column major layout and (2) the number of columns in A and B are different.

Note: I'm using pseudo code here. A.array isn't valid code etc...

Bonus: You can see what happens when the reshape command is called. The underlying data array doesn't change, just the n_rows and n_cols associated with the data array.

Matthew Gunn
  • 4,451
  • 1
  • 12
  • 30