Hi everyone, I need to create a counter inside a parfor loop. This counter is necessary in order to save the workspace of each iteration and to give at each workspace an increasing name like: workspace1, workspace2 and so on. However Matlab give me an error due to the fact that in parfor loop each loop is solved independtly from the others. Below I report a matlab script example. Anyone can help me??
parentdir = 'C:\Users\Stefanoo Menicanti\Dropbox\Stefano Menicanti\Matlab\File Script\NEW\Configuratore\Math_Script'; %parent directory
j=1;
parfor r= 1:3
for i = [100 200 300]
for frontal_section = 36
for layer = 2
for turn_per_layer = 5:10
for x = 0.22
for a = 0.66
for d_s_1 = 0.05
for d_s_2 = 0.05
[diso_min,dins_int1,dins_1,dt_1,Irms1,Irms1_1,nsh_1,nsv_1,Ns1,hb_1,wb_1,hw,W1,dt_2,dins_int2,Irms2,Irms2_1,nsh_2,nsv_2,Ns2,Nl_2,m2,hb_2,wb_2,dins_2,W2,dc_1,dc_2,MLT1,diso,MLT2,MLTiso,Ac,B,H,G,Vc,V_cl,V_sl_y,Lbox,Wbox,Hbox,Vbox,power_density,Pc_s,Pc,P_cl,P_sl_y,Rth_cl,Rth_LV_cl,Rth_iso,Rth_pol_LV,Rth_pol_HVr,Rth_pol_HVz,Rth_hs_LV,Rth_hs_HV,Rth_hs_sl_y,Rth_hs_amb,Aconv_HV,Arad_HV,Aconv_sl,Arad_sl,Lconv_HV,Lconv_sl,Pw1_r,Pw2_r,Pwt_r,Ploss,T_sl_r,T_HV_r,T_LV_r,T_cl_r,T_sl_y_r,T_B_HS_r,efficiency] = Procedure_with_litz_wire_strand_imposed_by_user_prova_parfor(Pout,Vdc_1,Vdc_2,n_cells,s_c,Vdc_1_cell,Vdc_2_cell,n,Viso,fsw,T,Ta,Tmax,d,phi,Lk,core_material,Bsat,kc,alpha,beta,Kc,rho_core,kcore,Ec,Tmax_core,Eins,Eins_b,Tconductivity_b,Epol,r,i,s,frontal_section,layer,turn_per_layer,x,a,d_s_1,d_s_2);
if (T_HV_r <= Tmax)&&(T_LV_r <= Tmax)&&(T_sl_r <= Tmax_core)&&(diso>= (diso_min))
Iteration = j;
parsave(fullfile(parentdir,['work_space',num2str(Iteration),'.mat']),diso_min,dins_int1,dins_1,dt_1,Irms1,Irms1_1,nsh_1,nsv_1,Ns1,hb_1,wb_1,hw,W1,dt_2,dins_int2,Irms2,Irms2_1,nsh_2,nsv_2,Ns2,Nl_2,m2,hb_2,wb_2,dins_2,W2,dc_1,dc_2,MLT1,diso,MLT2,MLTiso,Ac,B,H,G,Vc,V_cl,V_sl_y,Lbox,Wbox,Hbox,Vbox,power_density,Pc_s,Pc,P_cl,P_sl_y,Rth_cl,Rth_LV_cl,Rth_iso,Rth_pol_LV,Rth_pol_HVr,Rth_pol_HVz,Rth_hs_LV,Rth_hs_HV,Rth_hs_sl_y,Rth_hs_amb,Aconv_HV,Arad_HV,Aconv_sl,Arad_sl,Lconv_HV,Lconv_sl,Pw1_r,Pw2_r,Pwt_r,Ploss,T_sl_r,T_HV_r,T_LV_r,T_cl_r,T_sl_y_r,T_B_HS_r,efficiency);
j = j+1;
end
end
end
end
end
end
end
end
end
end

 Réponse acceptée

Matt J
Matt J le 11 Jan 2022
Modifié(e) : Matt J le 11 Jan 2022

0 votes

You need to learn to use struct arrays. If you have your fixed input parameters and outputs be the fields of structs, you can avoid passing such an unwieldy number of input and output arguments. Notice also how I am able to eliminate 9 of your loops using ind2sub().
Loopvars={1:3, [100 200 300], 36,2,5:10, 0.22, 0.66, 0.05, 0.05};
siz=cellfun('length',Loopvars);
J=prod(siz);
keep=false(J,1);
parfor j=1:J
subs=cell(1,9);
[subs{1:9}]=ind2sub(siz,j);
varsj=cellfun(@(x,k) x(k), LoopVars,subs,'uni',0);
[r,i,frontal_section,layer,turn_per_layer,x,a,ds_1,ds_2] =deal(varsj{:});
outputs(j)= Procedure_with_litz_wire_strand_imposed_by_user_prova_parfor(inputs,...
r,i,s,frontal_section,...
layer,turn_per_layer,x,a,d_s_1,d_s_2);
if (outputs(j).T_HV_r <= inputs.Tmax)&&(outputs(j).T_LV_r <= inputs.Tmax)&&...
(outputs(j).T_sl_r <= inputs.Tmax_core)&&(outputs(j).diso>= inputs.diso_min);
keep(j)=1;
end
end
outputs=outputs(keep);
for i=1:numel(outputs)
S=ouput(i);
save(fullfile(parentdir,"work_space" + i), '-struct','S')
end

15 commentaires

Matt J
Matt J le 11 Jan 2022
Modifié(e) : Matt J le 11 Jan 2022
Somewhat simpler:
parfor j=1:J
[subs{1:9}]=ind2sub(siz,j);
varsj=cellfun(@(x,k) x(k), LoopVars,subs,'uni',0);
outputs(j)= ...
Procedure_with_litz_wire_strand_imposed_by_user_prova_parfor(inputs, varsj{:});
keep(j)=(outputs(j).T_HV_r <= inputs.Tmax)&&(outputs(j).T_LV_r <= inputs.Tmax)&&...
(outputs(j).T_sl_r <= inputs.Tmax_core)&&(outputs(j).diso>= inputs.diso_min);
end
Stefano Menicanti
Stefano Menicanti le 11 Jan 2022
Thanks for your supporting. I'm trying to use your Matlab code, however matlab says that parfor loop can't run due to subs.... How can i solve the problem? Thanks
Matt J
Matt J le 11 Jan 2022
Modifié(e) : Matt J le 11 Jan 2022
See the revised code. In particular, I have added this line
subs=cell(1,9);
Stefano Menicanti
Stefano Menicanti le 11 Jan 2022
thanks. I think that outputs(j) ,that you have defined, is an array which is composed by all the variables that I have to determine by means of my function. Can you confirm please? and if, do i need to create an array structure with all the outputs? Thank you so much.
Matt J
Matt J le 11 Jan 2022
Modifié(e) : Matt J le 11 Jan 2022
No, I am suggesting that you rewrite the function Procedure_with_litz_wire_strand_imposed_by_user_prova_parfor() so that instead of outputting a long list of variables,
[diso_min,dins_int1,dins_1,...]=Procedure_with_litz_wire(____)
you instead return a single struct variable called "output",
output=Procedure_with_litz_wire(____)
whose fields are,
output.diso_min=...
output.dins_int1=...
output.dins_1=...
...
I am also suggesting you reduce the number of input arguments to 10 in a similar manner.
thank you very for your supporting. I have done all the corrections you said abd the code is very fast. About 22000 iteration in only 3 minutes. Hovewever I need to create a scatter plot which shws efficiency vs power density releated to each iteration. To achieve this goal I implemented the code reported below, I saw that the computational effort is high and the time need to create the plot is very high. Are there any way to have a faster code?
for i=1:numel(outputs)
c = outputs(i).T_LV_r - Ta;
po = scatter(outputs(i).power_density,outputs(i).efficiency,[],c, 'filled'); % xlabel('Efficiency %'), ylabel('Power density [kW\l]')
row = dataTipTextRow('Iteration',i);
po.DataTipTemplate.DataTipRows(end+1) = row;
colorbar
hold on
end
Matt J
Matt J le 12 Jan 2022
Keep the plot invisible until the loop is done:
for i=1:numel(outputs)
c = outputs(i).T_LV_r - Ta;
po = scatter(outputs(i).power_density,outputs(i).efficiency,[],c, 'filled',...
'Visible','off'); % xlabel('Efficiency %'), ylabel('Power density [kW\l]')
row = dataTipTextRow('Iteration',i);
po.DataTipTemplate.DataTipRows(end+1) = row;
colorbar
hold on
end
po.Visible='on';
Stefano Menicanti
Stefano Menicanti le 13 Jan 2022
I tried you solution but after 14 minutes scatter plot does not appear and code is still running..... I don't know why
Stefano Menicanti
Stefano Menicanti le 13 Jan 2022
I tried with less iteration, about 50, and at the end the plot is composed by only one point.
Matt J
Matt J le 13 Jan 2022
Modifié(e) : Matt J le 13 Jan 2022
As far as I know, your data may indeed contain only 1 point.
But you could also remove some of the other stuff from the loop to see if it goes faster:
for i=1:numel(outputs)
c = outputs(i).T_LV_r - Ta;
po = scatter(outputs(i).power_density,outputs(i).efficiency,[],c, 'filled',...
'Visible','off'); % xlabel('Efficiency %'), ylabel('Power density [kW\l]')
% row = dataTipTextRow('Iteration',i);
% po.DataTipTemplate.DataTipRows(end+1) = row;
% colorbar
hold on
end
po.Visible='on';
Stefano Menicanti
Stefano Menicanti le 13 Jan 2022
if I remove 'visible', the scatter plot shows all the 50 points.
Matt J
Matt J le 13 Jan 2022
Ah, I see.Try this:
for i=numel(outputs):-1:1
c = outputs(i).T_LV_r - Ta;
po(i) = scatter(outputs(i).power_density,outputs(i).efficiency,[],c, 'filled',...
'Visible','off'); % xlabel('Efficiency %'), ylabel('Power density [kW\l]')
hold on
end
set(po,'Visible','on');
colorbar
Stefano Menicanti
Stefano Menicanti le 13 Jan 2022
thanks, it works. which is the advantage of going from the last element of outputs to the first one?
Matt J
Matt J le 13 Jan 2022
It avoids the need to pre-allocate po. I don't know how to pre-allocate a scatter plot handle vector.
Stefano Menicanti
Stefano Menicanti le 13 Jan 2022
ok thanks, your supporting has been very important.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Loops and Conditional Statements dans Centre d'aide et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by