Forloop taking too long to execute in code
1 view (last 30 days)
Show older comments
My code is trying to take data that is saved in a 4D matrix 175 x 121 x 139 x 12 and another 4D matrix 175 x 121 x139 x 13 (these two 4D matrices represent differnet subject groups in an experiment) and compare same cell across the two groups in the 175 x 121 x 139 matrix. The forloop I am using is taking forever to run (30 minute, and not even half was run through). Is there any way to revise the code?
%% Grab Data
test = xff('rest-rainbow');
%The first 12 subjects are blind, the next 13 are sighted, therefore I am
%creating two separate groups for them here. Please enter the number of
%subjects you have in each condition here:
num_subj_bl = 12;
num_subj_si = 13;
blind = test.Map(1:12);
sighted = test.Map(13:25);
[Dim1, Dim2, Dim3] = size(blind(1).VMPData);
fmap = zeros(175, 121, 139);
for a= 1:Dim1
for b= 1:Dim2
for c= 1:Dim3
%These first 3 forloops loop through each unique voxel in the 175 x 121 X
%139 3D matrix that is generated for each subject
%These forloops loop through each individual subject in the blind and
%sighted conditions and put the corresponding voxels across all the
%subjects in a column vector. Therefore, voxel (1,1,1) across all 12 blind
%subjects will be put in the vector blind_vox and voxel (1,1,1) across all
%13 sighted subjects will be put in the vector sighted_vox.
blind_vox = [];
sighted_vox = [];
for x= 1:num_subj_bl
vox = blind(x).VMPData(a,b,c);
blind_vox = [blind_vox;vox];
end
for y= 1:num_subj_si
vox1= sighted(y).VMPData(a,b,c);
sighted_vox = [sighted_vox;vox];
end
%Padcat takes the uneven column vectors since they both have a
%different number of subjects and turns them into even column
%vectors by padding the smaller vector with NaN values
vect_for_BF = padcat(blind_vox, sighted_vox);
%This runs the BF test on the 2 column matrix
[p,stats] = vartestn(vect_for_BF,'TestType','BrownForsythe','Display','off');
%This will contain the f values for all the BF tests run
fmap(a,b,c) = stats.fstat;
end
end
end
0 Comments
Accepted Answer
Bob Thompson
on 9 Sep 2019
Some things that I have noticed.
[Dim1, Dim2, Dim3] = size(blind(1).VMPData);
fmap = zeros(175, 121, 139);
Might be smart to replace the specific sizes of the zeros array with your sizes, or the size command isn't really helping you at all.
for x= 1:num_subj_bl
vox = blind(x).VMPData(a,b,c);
blind_vox = [blind_vox;vox];
end
for y= 1:num_subj_si
vox1= sighted(y).VMPData(a,b,c);
sighted_vox = [sighted_vox;vox];
end
Both of these loops can be replaced with a reshape.
In looking things over a bit more closely, it seems like the bottle neck is vartestn. I am not familiar with the command, so I don't know if this will work, but what about reshaping all of the values into a single large n x 2 array and only running the command once? Maybe something like the following:
blind(x).VMPData(a,b,c) = nan(Dim1,Dim2,Dim3); % Pad array for same size, makes reshape easier
blind_vox = reshape([blind(:).VMPData],[],1);
sighted_vox = reshape([sighted(:).VMPData],[],1);
[p,stats] = vartestn([blind_vox,sighted_vox],'TestType','BrownForsythe','Display','off');
fmap = reshape([stats.fstat],Dim1,Dim2,Dim3);
This is a pretty rough first thought, so it likely won't work perfectly, but it should give you an idea of what I had in mind.
2 Comments
Bob Thompson
on 9 Sep 2019
If that is the case then I do not know any way of avoiding the triple for loops. You could look into parfor, but I do not have any experience utilizing the parallel computing box and wouldn't be able to help you.
For the record, it would be possible to clean up the appearance of your code a bit by using arrayfun, but arrayfun is ultimately still just a series of for loops, and isn't likely to speed up the process at all.
More Answers (0)
See Also
Categories
Find more on Loops and Conditional Statements 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!