我在C中有以下代码:
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
a[b[i]][c[j]]+=1;
}
}
有没有办法在不使用for循环的情况下在Matlab中编写这个?我的意思是Matlab方式使用(:)更快。
像a(b(:),c(:))=a(b(:),c(:))+1
之类的东西让我出现内存错误。
答案 0 :(得分:3)
有趣。 虽然我(还)没有为您提供解决方案(底部的解决方案),但我有一些注意事项和指示:
1。内存不足错误是因为您在右侧创建了一个512 * 256 x 512 * 256元素的临时矩阵(a(b(:),c(:))+1
)。那是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)中存在的所有索引递增1。而且没有了。这需要一些创造性思维来实现这一目标。使用较小的数组来查看正在发生的事情:
>> 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;
答案 1 :(得分: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));
答案 2 :(得分:-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