How to replace all for-loops ?
이전 댓글 표시
I had posted a function here for vectorization. Now this is the same function and even I tried myself to replace all for-loops like previous but I didn't succeed because in this the outer loop has enclosed all the for-loops and instead of pop being a vector, now it is a matrix due to which I failed to do so. The code is:
clear all; clc
u=[1 2 10 20];
dim=length(u);
pop=rand(10,dim);
C = size(pop,2);
P=C/2;
M=2*C;
e = zeros(size(pop,1),1);
for ii = 1:size(pop,1)
% calculate xo
b = pop(ii,:);
xo=zeros(1,M);
for k=1:M
for i=1:P
xo(1,k)=xo(1,k)+u(i)*exp(-1i*(k-1)*pi*cos(u(P+i)));
end
end
% calculate xe
xe=zeros(1,M);
for k=1:M
for i=1:P
xe(1,k)=xe(1,k)+b(i)*exp(-1i*(k-1)*pi*cos(b(P+i)));
end
end
abc=0.0;
for m1=1:M
abc=abc+(abs(xo(1,m1)-xe(1,m1))).^2;
end
abc=abc/M;
e(ii)=abc
end
댓글 수: 18
Walter Roberson
2023년 1월 10일
Do the computations involve complex values? I am wondering why you square the absolute value of the difference, instead of squaring the difference? The result would be the same unless there are imaginary parts.
Sadiq Akbar
2023년 1월 10일
I don't know if it's possible to remove all loops, but you can easyly remove three of your loops.
u = [1 2 10 20];
pop = rand(10, numel(u));
P = width(pop)/2;
M = width(pop)*2;
H = height(pop);
e = zeros(H,1);
for ii = 1:H
b = pop(ii,:);
xo=zeros(1,M);
xe=zeros(1,M);
abc = 0;
for jj=1:M
for kk=1:P
xo(1,jj) = xo(1,jj) + u(kk) * exp(-1i*(jj-1) * pi * cos(u(P+kk)));
xe(1,jj) = xe(1,jj) + b(kk) * exp(-1i*(jj-1) * pi * cos(b(P+kk)));
end
abc = abc+(abs(xo(1,jj)-xe(1,jj))).^2;
end
e(ii) = abc/M;
end
e
Sadiq Akbar
2023년 1월 10일
Rik
2023년 1월 10일
Why exactly do you want to replace all for loops?
Sadiq Akbar
2023년 1월 10일
Rik
2023년 1월 10일
For loops in Matlab are actually quite fast, as long as you properly pre-allocate any large array. The main exception is if there is a direct function to do something. Note that arrayfun and cellfun will just hide the loop and will therefore be even slower than a normal loop (since hiding the loop creates additional overhead).
You should note that there is an interdependence between iterations, so the chances of finding a direct function are not looking good.
To add on @Rik's comment, I vectorised a part of the code, and here is the comparison.
You can see that double for loop is faster than the vectorized code.
u = [1 2 10 20];
pop = rand(10, numel(u));
P = width(pop)/2;
M = width(pop)*2;
H = height(pop);
e1=vector(P,M,H,pop,u);
e2=twofor(P,M,H,pop,u);
%comparing results from both methods
result_comparison=isequal(e1,e2)
tic
for i=1:1e3
y=vector(P,M,H,pop,u);
end
t1=toc;
fprintf('time taken by vector method = %0.4f seconds', t1)
tic
for i=1:1e3
z=twofor(P,M,H,pop,u);
end
t2=toc;
fprintf('time taken by double for loop method = %0.4f seconds', t2)
function e = vector(P,M,H,pop,u)
e=zeros(H,1);
xo=zeros(1,M);
xe=zeros(1,M);
for ii = 1:H
b=pop(ii,:);
xo=(exp(-1i*(0:M-1)'*pi*cos(u(P+1:2*P)))*u(1:P)')';
xe=(exp(-1i*(0:M-1)'*pi*cos(b(P+1:2*P)))*b(1:P)')';
e(ii)=sum(abs(xo-xe).^2)/M;
end
end
function e = twofor(P,M,H,pop,u)
e = zeros(H,1);
for ii = 1:H
b = pop(ii,:);
xo = zeros(1,M);
xe = zeros(1,M);
abc = 0;
for jj=1:M
for kk=1:P
xo(1,jj) = xo(1,jj) + u(kk) * exp(-1i*(jj-1) * pi * cos(u(P+kk)));
xe(1,jj) = xe(1,jj) + b(kk) * exp(-1i*(jj-1) * pi * cos(b(P+kk)));
end
abc = abc+(abs(xo(1,jj)-xe(1,jj))).^2;
end
e(ii) = abc/M;
end
end
Sadiq Akbar
2023년 1월 11일
Rik
2023년 1월 11일
Using tic toc will only give a general idea of execution times. The inherent variation in execution times may be large enough in this case that the order may affect which version wins if you only call them once.
What you should actually use is the timeit function.
Sadiq Akbar
2023년 1월 11일
As @Rik mentioned, tic toc will only give an approximate idea of execution time. Results from running tic-toc a single time will always vary. That is why I ran in individual for loops to get a better idea of their execution time.
If you want to see the stark difference between run times, increase the number of iterations. I have increased the count to 1e5. You can see the (obvious) difference in execution times now.
u = [1 2 10 20];
pop = rand(10, numel(u));
P = width(pop)/2;
M = width(pop)*2;
H = height(pop);
e1=vector(P,M,H,pop,u);
e2=twofor(P,M,H,pop,u);
%comparing results from both methods
result_comparison=isequal(e1,e2)
tic
for i=1:1e5
y=vector(P,M,H,pop,u);
end
t1=toc;
fprintf('time taken by vector method = %0.4f seconds', t1)
tic
for i=1:1e5
z=twofor(P,M,H,pop,u);
end
t2=toc;
fprintf('time taken by double for loop method = %0.4f seconds', t2)
function e = vector(P,M,H,pop,u)
e=zeros(H,1);
xo=zeros(1,M);
xe=zeros(1,M);
for ii = 1:H
b=pop(ii,:);
xo=(exp(-1i*(0:M-1)'*pi*cos(u(P+1:2*P)))*u(1:P)')';
xe=(exp(-1i*(0:M-1)'*pi*cos(b(P+1:2*P)))*b(1:P)')';
e(ii)=sum(abs(xo-xe).^2)/M;
end
end
function e = twofor(P,M,H,pop,u)
e = zeros(H,1);
for ii = 1:H
b = pop(ii,:);
xo = zeros(1,M);
xe = zeros(1,M);
abc = 0;
for jj=1:M
for kk=1:P
xo(1,jj) = xo(1,jj) + u(kk) * exp(-1i*(jj-1) * pi * cos(u(P+kk)));
xe(1,jj) = xe(1,jj) + b(kk) * exp(-1i*(jj-1) * pi * cos(b(P+kk)));
end
abc = abc+(abs(xo(1,jj)-xe(1,jj))).^2;
end
e(ii) = abc/M;
end
end
Sadiq Akbar
2023년 1월 11일
Sadiq Akbar
2023년 1월 11일
Sadiq Akbar
2023년 1월 11일
Dyuman Joshi
2023년 1월 11일
Because there is no answer, only comments.
Do you want to accept my comment as answer?
Sadiq Akbar
2023년 1월 11일
Jan
2023년 1월 11일
I've moved Dyuman Joshi's comment to the answers section, such that it can be accepted now.
채택된 답변
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!