Vectorization fail with sub2ind?

4 次查看(过去 30 天)
I have the for loop code
for m=1:numel(N,1)
y = N(m,1); % y matrix index
x = N(m,2); % x matrix index
dy = N(m,4); % codfficient
dx = N(m,3); % coefficient
wts(y,x) = wts(y,x)+dx.*dy;
end
I attempted to vectorize this as follows
ind = sub2ind(size(wts),N(:,2),N(:,1));
wts(ind) = wts(ind)+N(:,3).*N(:,4);
Unfortunately, for some reason the result is totally wrong.
Someone later said that repeated values of "(x,y) / ind" will be erroneous. I don't know what that means, but there are many repeated values of the sub2ind index in my code (lots of addition).
How can this be fixed?
  4 个评论
per isakson
per isakson 2014-3-5
编辑:per isakson 2014-3-5
Why not show an executable example based on a for-loop?
Christopher
Christopher 2014-3-5
编辑:Christopher 2014-3-5
I have built the following script which I think is illustrative:
clear all
xygrd=10; % grid height, width
wts=zeros(xygrd,xygrd); % preallocate
wts2=zeros(xygrd,xygrd); % preallocate
% create points randomly allocated to the matrix xygrd*xygrd by randomly
% picking x,y indices
N1 = floor(rand(1000,2)*xygrd)+1; % x,y indices
N2 = rand(1000,2); % point values (dx,dy)
N=[N1 N2]; % x,y,dx,dy
for m=1:size(N,1)
y = N(m,1); % y matrix index
x = N(m,2); % x matrix index
dy = N(m,4); % dy
dx = N(m,3); % dx
wts(y,x) = wts(y,x)+dx.*dy;
end
% vectorization
ind = sub2ind(size(wts2),N(:,2),N(:,1));
wts2(ind) = wts2(ind)+N(:,3).*N(:,4);
pcolor(wts-wts2); % should all be zeros
matrix wts (from the for loop) is completely different from wts2. I need a vectorized code for the for loop.
Thanks for thinking about this with me.

请先登录,再进行评论。

采纳的回答

Roger Stafford
Roger Stafford 2014-3-5
编辑:Roger Stafford 2014-3-5
Here's a simple example to show you how repeated values of 'ind' will produce different results from your for-loop:
wts = zeros(3,1);
ind = [2;2;2];
wts(ind) = wts(ind) + [3;7;19];
wts
ans =
0
19
0
In your vectorization you would have been expecting [0;29;0] as in a for-loop, but instead only the last addition is performed, the other two results having been overwritten.
To do what you want, use matlab's 'accumarray' function:
wts = wts + accumarray([N(:,1),N(:,2)],N(:,3).*N(:,4),size(wts));
It will perform all the additions, even with repetitions.
(Note: You appear to have N(:,2) and N(:,1) in reversed order in your call to 'sub2ind' which would produce further errors.)
  1 个评论
Christopher
Christopher 2014-3-5
Thanks Roger, It appears you have found the correct method!
% diff vectorization
wts3 = wts3 + accumarray([N(:,1),N(:,2)],N(:,3).*N(:,4),size(wts));
is can be added to the script posted earlier, and it reproduces the for-loop.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Matrix Indexing 的更多信息

产品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by