arraysmatlabindexing

# Why is indexing via sub2ind not the same as indexing via A(i, j) in Matlab?

Assume that you have this matrix

``````>> P = zeros(8, 12)
P =

0   0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
``````

And you want to add `1` on each coordinate. If it's the same coordinate, it will be `+1`.

``````>> angles = [1 2 1 3 3 2 5 6 2 1 3 8]
angles =

1   2   1   3   3   2   5   6   2   1   3   8

>> r = [1 2 4 2 5 6 1 4 6 6 3 6]
r =

1   2   4   2   5   6   1   4   6   6   3   6
``````

If I use `sub2ind`

``````>> indices = sub2ind(size(P), angles, r);
>> P(indices) = P(indices) + 1;
>> P
P =

1   0   0   1   0   1   0   0   0   0   0   0
0   1   0   0   0   1   0   0   0   0   0   0
0   1   1   0   1   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
1   0   0   0   0   0   0   0   0   0   0   0
0   0   0   1   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   1   0   0   0   0   0   0
``````

But if I using normal indexing

``````>> for k = 1:length(r)
P(angles(k), r(k)) = P(angles(k), r(k)) + 1;
end
>> P
P =

1   0   0   1   0   1   0   0   0   0   0   0
0   1   0   0   0   2   0   0   0   0   0   0
0   1   1   0   1   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
1   0   0   0   0   0   0   0   0   0   0   0
0   0   0   1   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   1   0   0   0   0   0   0
``````

If you look closely, there is a `2` inside the matrix `P`, but not inside the matrix `P` above.

Question:

Why does `sub2ind` indexing differ from regular `P(i, j)` indexing?

Solution

• The difference arises because there is a pair of coordinates repeated (marked in boldface here):

``````angles = [1 2 1 3 3 𝟐 5 6 𝟐 1 3 8]
r =      [1 2 4 2 5 𝟔 1 4 𝟔 6 3 6]
``````

In the `sub2ind` version, the repeated pair of coordinates causes `indices` to have a repeated value. The line `P(indices) = P(indices)+1;` only adds `1` once to that entry of `P`. This is not related to `ind2sub`, it's just the way indexed assignment works: the changes are not "accumulated", so a repeated entry acts on the original value, without regard of previous occurrences of the same entry. For example:

``````>> x = [10 20 30];
ind = [2 3 3];
x(ind) = x(ind)+1
x =
10    21    31
``````

Or, perhaps more clearly, note how the value `50` is useless here:

``````>> x = [10 20 30];
>> x([2 3 3]) = [40 50 60]
x =
10    40    60
``````

On the other hand, in the `for` version you explicitly accumulate the changes, so if an entry appears twice you add `1` twice to that entry.