Script optimization: for loop, if statement, large dataset.

2 views (last 30 days)
Hello, below is the part of my script that I would like to be optimized. I am using large data sets, so as of right now it can take a while to run. Any tips would be greatly appreciated, especially regarding the for loop! alpha, beta, and gammas are all the same length (7000000x1).
alpha = alpha(:);
beta = beta(:);
gammas = gammas(:);
red = zeros(size(alpha));
green = zeros(size(beta));
blue = zeros(size(gammas));
for i=1:length(alpha)
if alpha(i)~=0 && beta(i)~=0 && gammas(i)~=0
red(i) = alpha(i);
green(i) = beta(i);
blue(i) = gammas(i);
elseif alpha(i)==0 && beta(i)==0 && gammas(i)==0
red(i) = [];
green(i) = [];
blue(i) = [];
end
end
attempt2(:,1,1) = red;
attempt2(:,1,2) = green;
attempt2(:,1,3) = blue;
toc
end

Answers (2)

Mukul Rao
Mukul Rao on 23 Jun 2015
Edited: Mukul Rao on 23 Jun 2015
Hi Shayne, you seem to dynamically changing the size of the red, blue and green arrays in your loop which could cause errors due to invalid indexing and also affect performance. The use of for loop also greatly slows down performance, a vectorized approach would be more useful here using the & operator. Here is a suggestion for an alternate workflow to achieve the same goal:
%Set alpha, beta and gammas to some random array of length 7000000
alpha = randi([0,4],7000000,1);
beta = randi([0,4],7000000,1);
gammas = randi([0,4],7000000,1);
%Initialize red, green and blue
red = alpha;
green = beta;
blue = gammas;
%Check computational speed
tic
%Determine logical indices where alpha, beta and gamma are zero
ind1 = (alpha == 0);
ind2 = (beta == 0);
ind3 = (gammas == 0);
%Find logical indices where all three are zero
ind = ind1 & ind2 & ind3;
%Set those values of the colors to []
red(ind) = [];
blue(ind) = [];
green(ind) = [];
toc
Please note that here I am assuming it was your intention to have nonzero values for red,blue and green when alpha, beta and gamma were not all zero. To implement the exact logic as in your original code snippet, you need to make minor modifications. However, the essence is still the same - use a vectorized approach with logical indexing!

Guillaume
Guillaume on 23 Jun 2015
Edited: Guillaume on 24 Jun 2015
What is the ultimate purpose of the code? It just appear to copy the original arrays into a new one discarding some elements under a given condition. If that's the purpose:
attempt2 = [alpha(:); beta(:); gammas(:)]; %concatenate arrays
%Possibly, you are attempting to remove all rows that where all 3 channels are 0:
attempt2(:, all(attempt2 == 0, 2)) = [];
%Possibly, you are attempting to set all rows where at least one channel is 0 to 0:
attempt2(:, any(attempt2 == 0, 2)) = 0;
%move channels in the 3rd dimension, with second dimension being scalar. (But why?)
attempt2 = permute(attempt2, [1 3 2])
Note that in your original code, the part in the elseif will delete elements of the output arrays. Afterward, as soon as the if condition becomes true, the elements will be recreated again equal to 0. So in effect, unless the if condition never become true afterward, the elseif doesn't do anything.

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!