Forloop taking too long to execute in code
조회 수: 1 (최근 30일)
이전 댓글 표시
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
채택된 답변
Bob Thompson
2019년 9월 9일
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
Bob Thompson
2019년 9월 9일
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.
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 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!