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

 採用された回答

Matt J
Matt J 2022 年 1 月 11 日
編集済み: Matt J 2022 年 1 月 11 日

0 投票

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 件のコメント

Matt J
Matt J 2022 年 1 月 11 日
編集済み: Matt J 2022 年 1 月 11 日
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 2022 年 1 月 11 日
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 2022 年 1 月 11 日
編集済み: Matt J 2022 年 1 月 11 日
See the revised code. In particular, I have added this line
subs=cell(1,9);
Stefano Menicanti
Stefano Menicanti 2022 年 1 月 11 日
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 2022 年 1 月 11 日
編集済み: Matt J 2022 年 1 月 11 日
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.
Stefano Menicanti
Stefano Menicanti 2022 年 1 月 12 日
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 2022 年 1 月 12 日
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 2022 年 1 月 13 日
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 2022 年 1 月 13 日
I tried with less iteration, about 50, and at the end the plot is composed by only one point.
Matt J
Matt J 2022 年 1 月 13 日
編集済み: Matt J 2022 年 1 月 13 日
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 2022 年 1 月 13 日
if I remove 'visible', the scatter plot shows all the 50 points.
Matt J
Matt J 2022 年 1 月 13 日
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 2022 年 1 月 13 日
thanks, it works. which is the advantage of going from the last element of outputs to the first one?
Matt J
Matt J 2022 年 1 月 13 日
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 2022 年 1 月 13 日
ok thanks, your supporting has been very important.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by