# How to parallelise sections of my for loop

2 views (last 30 days)
KieranSQ on 8 Oct 2020
Commented: KieranSQ on 23 Oct 2020
Hello,
I am trying to think of a way to make my for loop quicker. It has occurred to me that I could parallelise the commands in the loops and then bring them back together at the end. Is there such a thing in matlab or am I overcomplicating everything?
My MWE is:
for kx = 1:length(w)
for ky = 1:length(w) %These could be linearised
for kkx = 1:length(w)
for kky = 1:length(w)
for freq_sign_ansatz = 1:2
for freq_sign_test = 1:2
[pqf, v1qf, v2qf, pw1f, pw2f, v1w1f, v1w2f, v2w1f, v2w2f] = Convection_basis(kx,ky,kkx,kky,w, freq_ansatz, freq_test);
pq_freq(freq_sign_ansatz, freq_sign_test) = pqf(kx,ky,kkx,kky,freq_ansatz, freq_test);
v1w1_freq(freq_sign_ansatz, freq_sign_test) = v1w1f(kx,ky,kkx,kky,freq_ansatz, freq_test);
v1w2_freq(freq_sign_ansatz, freq_sign_test) = v1w2f(kx,ky,kkx,kky,freq_ansatz, freq_test);
v2w1_freq(freq_sign_ansatz, freq_sign_test) = v2w1f(kx,ky,kkx,kky,freq_ansatz, freq_test);
v2w2_freq(freq_sign_ansatz, freq_sign_test) = v2w2f(kx,ky,kkx,kky,freq_ansatz, freq_test);
pw1_freq(freq_sign_ansatz, freq_sign_test) = pw1f(kx,ky,kkx,kky,freq_ansatz, freq_test);
pw2_freq(freq_sign_ansatz, freq_sign_test) = pw2f(kx,ky,kkx,kky,freq_ansatz, freq_test);
v1q_freq(freq_sign_ansatz, freq_sign_test) = v1qf(kx,ky,kkx,kky,freq_ansatz, freq_test);
v2q_freq(freq_sign_ansatz, freq_sign_test) = v2qf(kx,ky,kkx,kky,freq_ansatz, freq_test);
end
end
index = [(kx - 1) * Length_Wavenumbers + ky, (kkx - 1) * Length_Wavenumbers + kky];
if w(kkx) == w(kx) && w(kx) == 0 && (w(kky) == w(ky) && w(kky) == 0) && zero_counter == 0
zero_counter = 1;
zero_entries(zero_counter) = {index};
end
pq{index(1), index(2)} = pq_freq; %pd_dxw
v1w1{index(1), index(2)} = v1w1_freq; %pd_dxw
v1w2{index(1), index(2)} = v1w2_freq; %pd_dxw
v2w1{index(1), index(2)} = v2w1_freq; %pd_dxw
v2w2{index(1), index(2)} = v2w2_freq; %pd_dxw
pw1{index(1), index(2)} = pw1_freq; %pd_dxw
pw2{index(1), index(2)} = pw2_freq; %pd_dxw
v1q{index(1), index(2)} = v1q_freq; %vd_dxq
v2q{index(1), index(2)} = v2q_freq; %vd_dxq
end
end
end
end
Clearly here I could linearise some of the for loops through combinations of kx,ky,kkx,kky but I was interested whether there is a way of parallelising it as each pw1 etc are square matrices which are independent of each other before I combine them into a cell.
I am new to the way of parallelising things.

Gaurav Garg on 12 Oct 2020
Hi,
Rather than using 4-6 for loops, you can try making a single for loop traversing through all the elements.
For example -
for i = 1:2
for j = 1:2
%do anything
end
end
can be rewritten as (using parfor loop)
parfor i=1:4
[r,c] = ind2sub([2 2],i)
disp(r);
disp(c);
end
Here, ind2sub function has been used to convert the single iterator into r and c which are the iterators i and j in the first case.
Similarly you can rewrite your loops as (not tested)-
parfor x = 1:length(w)*length(w)*length(w)*length(w)
[kx, ky, kkx, kky] = ind2sub([length(w) length(w) length(w) length(w)],x);
end
KieranSQ on 23 Oct 2020
Thank you! I will give this a go :)