Clear Filters
Clear Filters

Is there a way to execute two for-loops at once?

2 views (last 30 days)
For instance, in the loops below, I want the equations to be executed for the first column of both the SetNo and PhaseNo arrays. In other words when SetNo=1 and PhaseNo=1, then I need the counters to move to the 2nd column of each array when SetNo=3 and PhaseNo=1. The next few iterations would be as follows:
3rd iteration: SetNo=9 and PhaseNo=1
4th iteration: SetNo=9 and PhaseNo=2
5th iteration: SetNo=9 and PhaseNo=3, and so on.
I'm reusing the LC1max, LC2max, etc. variables so at the end of each iteration, I'd like to save based on the set and phase number. For instance, when SetNo=9 and PhaseNo=2, the variables would look like: LC1max_9_2, LC2max_9_2 , etc.
load SampleData2
SetNo=[1 3 9 9 9 10 10 10 45 46 49 49 49 50 50 50 51 51 51 52 52 52 53 54 57 58 59 60];
PhaseNo=[1 1 1 2 3 1 2 3 1 1 1 2 3 1 2 3 1 2 3 1 2 3 1 1 1 1 1 1];
for ii=1:length(SetNo);;
for jj=1:length(PhaseNo);
chosenSetNo = SetNo(ii);
chosenPhaseNo = PhaseNo(jj);
idx = data.('Set No.') == chosenSetNo & data.('Phase No.') == chosenPhaseNo;
data_1 = data(idx,:);
LC1 = data_1([],:);
LC2 = data_1([],:);
LC3 = data_1([],:);
LC4 = data_1([],:);
LC5 = data_1([],:);
LC6 = data_1([],:);
LC7 = data_1([],:);
%METHOD 1: LOGICAL INDEXING METHOD | This method helps save memory and
%possible errors.
LC1 = data_1(contains(data_1{:,4},"NESC 250B"|"NESC Insul"),:);
LC2 = data_1(contains(data_1{:,4},"Hurr"|"RULE 250C Insul"),:);
LC3 = data_1(contains(data_1{:,4},"Rule 250D"|"RULE 250D Insul NA+"|"RULE 250D Insul NA-"),:);
LC4 = data_1(contains(data_1{:,4},"Normal"),:);
LC5 = data_1(contains(data_1{:,4},"2%"),:);
LC6 = data_1(contains(data_1{:,4},"NESC 250B NL-, DE"|"NESC 250B NR-,DE"|"NESC 250B BI-, DE"),:);
LC7 = data_1(contains(data_1{:,4},"Rule 250D BI-, DE"|"Rule 250D NL-, DE"|"Rule 250D NR-, DE"),:);
%Delete the extra rows in LC1 & LC3 that apply to the full break cases for NESC 250B & Rule 250D
LC1([9,10,11],:) = [];
LC3([7,8,9],:) = [];
%Extract the rows that correspond with the maximum resultant in each load
%case.
[~,LC1MaxRes] = max(LC1.resultant);
LC1max = LC1(LC1MaxRes,:);
[~,LC2MaxRes] = max(LC2.resultant);
LC2max = LC2(LC2MaxRes,:);
[~,LC3MaxRes] = max(LC3.resultant);
LC3max = LC3(LC3MaxRes,:);
[~,LC4MaxRes] = max(LC4.resultant);
LC4max = LC4(LC4MaxRes,:);
[~,LC5MaxRes] = max(LC5.resultant);
LC5max = LC4(LC5MaxRes,:);
[~,LC6MaxRes] = max(LC6.resultant);
LC6max = LC6(LC6MaxRes,:);
[~,LC7MaxRes] = max(LC7.resultant);
LC7max = LC7(LC7MaxRes,:);
LC1max_ii_jj = LC1max;
LC2max_ii_jj = LC2max;
LC3max_ii_jj = LC3max;
LC4max_ii_jj = LC4max;
LC5max_ii_jj = LC5max;
LC6max_ii_jj = LC6max;
LC7max_ii_jj = LC7max;
end
end
  2 Comments
David Hill
David Hill on 17 Feb 2022
Do yu have the Parallel Computing Toolbox? Look at parfor()
James Lindsey
James Lindsey on 17 Feb 2022
Unfortunately I do not have the Parallel Computing Toolbox

Sign in to comment.

Accepted Answer

Voss
Voss on 17 Feb 2022
You can use a single for-loop:
SetNo=[1 3 9 9 9 10 10 10 45 46 49 49 49 50 50 50 51 51 51 52 52 52 53 54 57 58 59 60];
PhaseNo=[1 1 1 2 3 1 2 3 1 1 1 2 3 1 2 3 1 2 3 1 2 3 1 1 1 1 1 1];
for ii = 1:numel(SetNo)
% do something with SetNo(ii) and PhaseNo(ii)
end
And use the same index ii for indexing the result variables rather than using variables with different names.
  4 Comments
Voss
Voss on 18 Feb 2022
Maybe better for your purposes is to use an array of structs, which can store the SetNo and PhaseNo values associated with each result:
SetNo=[1 3 9 9 9 10 10 10 45 46 49 49 49 50 50 50 51 51 51 52 52 52 53 54 57 58 59 60];
PhaseNo=[1 1 1 2 3 1 2 3 1 1 1 2 3 1 2 3 1 2 3 1 2 3 1 1 1 1 1 1];
LCmax = cell(1,7);
results = repmat( ...
struct('SetNo',[],'PhaseNo',[],'LCmax',[]), ...
1,numel(SetNo));
for ii = 1:numel(SetNo)
results(ii).SetNo = SetNo(ii);
results(ii).PhaseNo = PhaseNo(ii);
% do something with SetNo(ii) and PhaseNo(ii)
% combine LC1-LC7 into a cell array so that they can be processed in a
% loop below:
LC_all = {LC1 LC2 LC3 LC4 LC5 LC6 LC7};
for jj = 1:numel(LC_all)
%Extract the rows that correspond with the maximum resultant in each load
%case.
[~,MaxResIdx] = max(LC_all{jj}.resultant);
LCmax{jj} = LC_all{jj}(MaxResIdx,:);
end
results(ii).LCmax = LCmax;
end
Then you can access specific results like this:
wanted_SetNo = 10;
wanted_PhaseNo = 1;
my_result = results([results.SetNo] == wanted_SetNo & [results.PhaseNo] == wanted_PhaseNo).LCmax;
% Again assuming wanted_SetNo and wanted_PhaseNo are valid
That way you don't have to keep the SetNo and PhaseNo arrays around since everything is in the struct array 'results'.
James Lindsey
James Lindsey on 21 Feb 2022
Thank you. This has been very helpful. One reason I was thinking about keeping them separate and naming them "LC1_1_1" is because I'll need to sum the elements. For instance, Set 1, Phase 1's values need to be summed with Set 3, Phase 1's values (columns titled Structure Loads Vert., Structure Loads Trans. and Structure Loads Long.) for each load case. How can I call or access the cells/values I need from the array titled "results" ?

Sign in to comment.

More Answers (0)

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!