2

我在 C 中有以下代码:

for(i=0;i<m;i++)
{
    for(j=0;j<n;j++)
    {
        a[b[i]][c[j]]+=1;
    }
}

有没有办法在 Matlab 中编写而不使用 for 循环?我的意思是使用 (:) 更快的 Matlab 方式。

类似的东西a(b(:),c(:))=a(b(:),c(:))+1给了我内存不足的错误。

4

3 回答 3

3

有趣的。 虽然我(还)没有为您提供解决方案(底部的解决方案),但我有一些注释和指示:

1. 内存不足错误是因为您在右侧 ( a(b(:),c(:))+1) 创建了一个 512*256 x 512*256 元素的临时矩阵。那是 2^34 字节——17GB!所以这就是为什么你得到一个内存不足的错误。还要注意,这个数组甚至不是你想要的!看这个例子:

>> a = magic(5);
>> b = [1 5 4]; % The rows that contain the numbers 1,2,3 respectively
>> c = [3 4 5]; % The columns that contain ^ ...

现在,a(1,3) == 1, a(5,4) == 2 等等。但是当您说 时a(b,c),您选择的是行 (1,5,4) 和列 (3,4,5)对于每一行!

>> a(b,c)
ans =

     1     8    15
    25     2     9
    19    21     3

你只关心对角线。解决方案是使用sub2ind将您的下标对转换为线性索引。

>> a(sub2ind(size(a),b,c))
ans =

     1     2     3

2. 你提出的解决方案也没有达到你想要的效果。由于 Matlab 缺少增量运算符,因此您只需将 (b,c) 中存在的所有索引加一。没有更多了。将其矢量化需要一些创造性思维。使用较小的数组来查看发生了什么:

>> a = zeros(4,4);
>> b = ones(8,4);
>> c = ones(8,4);
>> a(b,c) = a(b,c) + 1;
>> a
a =

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

编辑我们走吧!矢量化增量:

>> idxs = sub2ind(size(a),b(:),c(:)); % convert subscripts to linear indices
>> [unique_idxs,~,ic] = unique(idxs); % Get the unique indices and their locations
>> increment_counts = histc(ic,1:max(ic)); % Get the number of occurrences of each idx
>> a(unique_idxs) = a(unique_idxs) + increment_counts;
于 2013-08-13T17:50:26.623 回答
1

假设您有以下矩阵:

a = zeros(256);  % or initialized with other values
b = randi(256, [512 256]);
c = randi(256, [512 256]);

这是一个更快的矢量化解决方案:

a = a + sparse(b,c,1,size(a,1),size(a,2));

这是另一个:

a = a + accumarray([b(:) c(:)], 1, size(a));
于 2013-08-13T21:06:22.967 回答
-1

回答:是的。

a(b, c) = a(b, c) + 1;

例子:

>> a = zeros(5);
>> b = [1,3];
>> c = [2,4,5];
>> a(b,c) = a(b,c) + 1;
>> a

a =

     0     1     0     1     1
     0     0     0     0     0
     0     1     0     1     1
     0     0     0     0     0
     0     0     0     0     0
于 2013-08-13T18:00:35.673 回答