为什么在Matlab中通过sub2ind索引与通过A(i,j)索引不一样?

ipakzgxi  于 7个月前  发布在  Matlab
关注(0)|答案(2)|浏览(81)

假设你有这个矩阵

>> 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

在每个坐标上加上1。如果是相同的坐标,则为+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

如果我使用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

但如果我用普通索引

>> 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

如果你仔细观察,在矩阵P中有一个2,但在上面的矩阵P中没有。

问题:

为什么sub2ind索引与常规P(i, j)索引不同?

xggvc2p6

xggvc2p61#

差异的产生是因为有一对坐标重复(在此以黑体标记):

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

sub2ind版本中,重复的坐标对导致indices具有重复的值。行P(indices) = P(indices)+1;只将1一次添加到P的条目。这与ind2sub无关,这只是索引赋值的工作方式:这些变化不是“累积的”,因此重复的条目作用于原始值,而不考虑相同条目的先前出现。举例来说:

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

或者,也许更清楚地,注意值50在这里是无用的:

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

另一方面,在for版本中,您显式累积更改,因此如果条目出现两次,则将1两次添加到该条目。

7xllpg7q

7xllpg7q2#

如果您想要一个更简单的实现,这就是accumarray设计的目的。

>> accumarray([angles', r'], 1, size(P))

ans =

     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

相关问题