How can I vectorize this function with nested FOR loop?

4 次查看(过去 30 天)
I have two for loops.L is one matrix of random numbers between 0,1 with dimension 24*100000.I want to vectorize it but i can't. because current code is very slow and take a long time.please help me.
K=zeros(100000,1);
T=zeros(100000,1);
for i=1:100000
for j=1:100000
K(j,1)=exp(-4*norm(L(:,i)-L(:,j))^2/norm(L(:,i))^2);
end
T(i,:)=sum(K)-1;
end
  2 个评论
Bob Thompson
Bob Thompson 2019-7-2
(L(:,i)-L(:,j))
This is what is going to make it difficult to vectorize. I believe there is a command to calculate this for you, but I'm not sure what exactly it is. It might be easier to do some research for this specifically, rather than the vectorization.
Jan
Jan 2019-7-2
编辑:Jan 2019-7-2
Why do you want to vectorize the code? There is no general benefit in doing this. Does the current code run too slow? Then an acceleration is the way to go. Vectorizing can improve the speed, but this is not in general.
To optimize the code, we need the chance to run it. Without meaningful input arguments, this is hard. So please provide L.
norm(x)^2 calculates an expensive square root only to square the result afterwards.
Do oyu have the parallel processing toolbox? A parfor might be very useful.

请先登录,再进行评论。

采纳的回答

Matt J
Matt J 2019-7-2
编辑:Matt J 2019-7-2
Using mat2tiles
chunksize=10000;
Lc=mat2tiles(L.',[chunksize,24]);
normL=mat2tiles(vecnorm(L,2,1), [1, chunksize]);
N=numel(Lc);
Tc=cell(N);
for i=1:N
for j=1:N
E=pdist2(Lc{i},Lc{j})./normL{j};
Tc{i,j}=sum( exp(-4*E.^2) ,1);
end
end
T=sum( cell2mat(Tc) ,1).'-1;
  18 个评论
abtin irani
abtin irani 2019-7-4
so,what can i do if i don't use pdist2.is there any other solution instead of pdist2 that doesn't give this error? i want one solution for chunksize=1000000. thank you for your answers.
Matt J
Matt J 2019-7-4
编辑:Matt J 2019-7-5
Well, maybe the question to ask is, why are you making the chunksize larger, when you toldu us that the code already worked when the chunksize was just 10,000? Why change/fix something that is not broken?

请先登录,再进行评论。

更多回答(1 个)

Jan
Jan 2019-7-4
n = 1000;
L = rand(24, n);
T = zeros(n, 1);
for i=1:n
K = exp(-4*sum((L(:,i) - L) .^ 2, 1) ./ sum(L(:,i).^2, 1));
T2(i) = sum(K, 2) - 1;
end
This is 100 times faster than the original version for n=1000.
With parfor instead of for a further acceleration is possible.
To my surprise the above code is faster than this, which omits the repeated squaring:
T = zeros(n,1);
L2 = L .^ 2;
for i=1:n
K = exp(-4*sum((L2(:,i) - 2*L(:,i).*L + L2), 1) ./ sum(L2(:,i), 1));
T(i) = sum(K, 2)-1;
end
  2 个评论
abtin irani
abtin irani 2019-7-4
excuse me i got this error. Error using .*
Matrix dimensions must agree.
Error in Untitled8 (line 33)
K=exp(-4*sum((L2(:,i) - 2*L(:,i).*L + L2), 1) ./ sum(L2(:,i), 1));
Jan
Jan 2019-7-4
You use Matlab < R2016b. Then:
K = exp(-4*sum((L2(:,i) - bsxfun(@times, 2*L(:,i), L) + L2), 1) ...
./ sum(L2(:,i), 1));
But the first version seems to be faster.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Parallel Computing 的更多信息

产品


版本

R2015a

Community Treasure Hunt

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

Start Hunting!

Translated by