Help vectorize for loop please
7 次查看(过去 30 天)
显示 更早的评论
I want to get rid of that for loop and just use/vectors/matrices, so i can optimize my code. if any one can help thanks.
%help compute the average
d = max(size(x));
c = 1/(d-1);
function y1 = f1(r)
y1 = tanh((1-r)*7) +.7;
end
%y2 will be returned
y2 = zeros(d,1);
z1 = x(1:2:2*N - 1);
z2 = x(2:2:2*N );
for j=1:(d/2)
Z1 = z1(j) - z1; %x - xj
Z2 = z2(j) - z2; %y - yj
Z3 = (Z2.*Z2) + (Z1.*Z1); %(x-xj)^2 + (y - yj)^2
Z3 = sqrt(Z3);%|X- Xj|
Z3(j) = 1;
Z1 = Z3.\Z1;% (x - xj)/|X - Xj|
Z2 = Z3.\Z2;% (y - yj)/|X - Xj|
Z4 = f1(Z3); % F( |X - Xj|)
Z1 = Z1.*Z4;%F( |X - Xj|)*(x - xj)/|X - Xj|
Z2 = Z2.*Z4;%F( |X - Xj|)*(y - yj)/|X - Xj|
y2(2*j - 1) = c*sum(Z1);
y2(2*j) = c*sum(Z2);
end
0 个评论
采纳的回答
Matt Tearle
2011-3-12
As far as I can tell, this seems to replace your code and is a tiny bit faster. (I tested only on small arrays, so maybe the savings will be significant on an actual problem). I assume that N = d/2? I'm also assuming that x is a column vector. I was using x = randi(10,20,1) to test, and I got the same answers as your code.
d = length(x);
c = 1/(d-1);
f1 = @(r) tanh((1-r)*7) +.7;
z1 = x(1:2:2*N - 1);
z2 = x(2:2:2*N );
y2 = zeros(d,1);
Z1 = bsxfun(@minus,z1',repmat(z1,1,d/2));
Z2 = bsxfun(@minus,z2',repmat(z2,1,d/2));
Z3 = sqrt((Z2.*Z2) + (Z1.*Z1));
Z3(1:((d/2)+1):end)=1;
Z1 = Z1./Z3;
Z2 = Z2./Z3;
Z4 = f1(Z3);
Z1 = Z1.*Z4;
Z2 = Z2.*Z4;
y2(1:2:2*N - 1) = sum(Z1)*c;
y2(2:2:2*N) = sum(Z2)*c;
4 个评论
Matt Tearle
2011-3-13
But, like everything in MATLAB, it's being continually improved, so, generally, the later the version, the better the JIT benefits.
更多回答(1 个)
Matt Tearle
2011-3-11
You don't need a loop at all -- all your statements inside the loop will work as vectorized statements with virtually no modification.
Just get rid of the subscripts on the first two lines.
Delete the line Z3(j) = 1; I don't know what you were hoping this did, but I doubt it was what it actually does. Before that line, Z3 is a scalar. Then if j is 1, it just overwrites Z3. For any other j, it will make Z3 a vector of j elements. The first will be whatever Z3 was from the previous line, the last will be 1, and everything in the middle will be 0. Is that what you intended? Maybe it is, given the use of sum(Z1) later, but it's a very strange algorithm.
Finally, use indexing like you did to extract z1 and z2 from x to get the results into y2.
3 个评论
Matt Tearle
2011-3-12
Oops, my bad. I misread your code (all those z1s and Z2s and y2s...!) OK. Ignore everything I said. New answer coming right now.
Matt Tearle
2011-3-12
BTW "I know matlab works much better with vectors then loops" is not necessarily true any more (depends on which version). Thanks to the JIT optimization, loops are now pretty quick. There are cases where you can tie yourself in knots trying to vectorize only to *lose* performance. In this case, I think you can get a bit of speed-up (see my new answer) by using matrices.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!