问题
I want to simplify this code to working without for loop.
for i=1:N
for j=1:N
if ismember(j,A)
PID(i,i)=TFP(i,j)+ PID(i,i);
end
end
end
in which A
is a matrix that contains some labels. I previously stored TFP
in the form of N*N sparse double. So, I came up with the following solution but I couldn't find a way to implement membership condition (Specified by ?) in that.
PID = sum(TFP).*(?);
Can it be implemented without a loop?
回答1:
Your ismember(j,A)
is equivalent of just using the values of A
to index. So you can use that and completely avoid the ismember
function (which is by far the slowest part of the code).
So a first step for optimization is
A2=unique(A); % just in case you do not do this already
for i=1:N
for j=A2
PID(i,i)=TFP(i,j)+ PID(i,i);
end
end
This should be already very fast. Loops are not bad in MATLAB and get heavily optimized by the JIT compiler.
The next step to optimization is to get all the indices together and remove the secondary loop. You can do this with linear indexing, so
A2=unique(A); % just in case you do not do this already
for i=1:N
PID(i,i)=sum(TFP(i,A2));
end
And finally, you can get rid of this by diagonalizing the sum of the desired columns:
A2=unique(A); % just in case you do not do this already
PID=diag(sum(TFP(:,A2),2));
回答2:
Instead of summing the result of element-wise multiplication you can use matrix multiplication. It computes the sum of products without creating a temporary array:
J = ismember(1:N, A).';
PID = diag(TFP * J);
回答3:
I am not sure i completely uderstand your problem Have you tried this?
j=1:N;
PID = sum(TFP).*ismember(j,A);
ismember would work as a matrix that when is true is equal to'1' so it would allow to multiply.
来源:https://stackoverflow.com/questions/60302296/checking-membership-in-an-array-without-for-loop-in-matlab