How can I change for-loop into matrix way?

I'd like to vectorize the for-loop below, but cannot come up with any idea. Could you help me?
for i=1:100
for j=1:1000
A(i+1,j)= B(find(C(B==A(i,j),:,D==E(i))>F(i,j),1));
end
end

9 Comments

Are you sure, that your 2nd loop is "for j=1000"?
Yes. The second loop needs much more iterations than the first one.
@icdi Jan means, shouldn't you have this instead:
for j=1:1000
With " for j=1000" the inner loop is only doing 1 iteration for every i.
icdi
icdi on 7 Jun 2021
Edited: icdi on 7 Jun 2021
Oh it was my mistake. you are right. It's for j=1:1000.
I edited it. Thanks for letting me know that.
We also need to know the sizes of all the variables.
icdi
icdi on 7 Jun 2021
Edited: icdi on 7 Jun 2021
A is 101 X 1000, and A(1,:) is given.
B is 15 X 1.
C is 15 X 15 X 3.
E is 101 X 1.
F is 100 X 1000.
Thanks!
And D is 3x1?
Also, is the loop working in its current form? As far as I can see, there is no reason why
find(C(B==A(i,j),:,D==E(i))>F(i,j),1)
should be gauranteed to give a number between 1 and 15, as the code assumes it will. This will only be true if there is a unique m with B(m)=A(i,j) and a unique n with D(n)=E(i).
icdi
icdi on 8 Jun 2021
Edited: icdi on 8 Jun 2021
Yes all of your points are right.
D is 3x1. For all i and j, A(i,j) is supposed to have one of elements of B, and E(i) also has one of elements of D. So this code can give the series of numbers between 1 and 15.
So the elements of B and D are all unique? Also, what is supposed to happen if find() returns empty [], i.e., if
C(B==A(i,j),k,D==E(i)) < F(i,j)
for all k=1...15?

Sign in to comment.

 Accepted Answer

This gives some speed-up.
%Fake Data
m=100;n=1000;
B=rand(15,1);
D=rand(3,1);
A=B(randi(15,m+1,n));
E=D(randi(3,m+1,1));
C=rand(15,15,3);
F=0.3*ones(size(A));
%Original version
tic;
for i=1:m
for j=1:n
A(i+1,j)= B(find(C(B==A(i,j),:,D==E(i))>F(i,j),1));
end
end
toc
Elapsed time is 0.372233 seconds.
A1=A;
%Proposed version
tic;
locD=(1:3)*(D==E.');
for i=1:m
Ai=A(i,:);
Ei=E(i);
Fi=F(i,:);
[~,locB]=ismember(Ai,B);
[~,idx]=max( C(locB,:,locD(i))>Fi(:) ,[],2);
A(i+1,:)= B(idx);
end
toc
Elapsed time is 0.050406 seconds.
A2=A;
isequal(A1,A2)
ans = logical
1

1 Comment

Thanks! Your code works very well and saves me time. Thanks again.

Sign in to comment.

More Answers (0)

Asked:

on 7 Jun 2021

Commented:

on 8 Jun 2021

Community Treasure Hunt

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

Start Hunting!