How can I form a matrix of all possible values of three variables?

19 visualizzazioni (ultimi 30 giorni)
I have three variables (bgt, Trigger, alpha), and each one of it could take any value from the set of three values {0.1, 0.5, 0.9} . How can I form a matrix of size 27 by 3 that contains all the possible combinations? And then for the following Script, I want MATLAB to run each row of this newly formed matrix( 27 different runs in total) and save the results (Check % Save The Results Section ). Eventually, I want to pick any three rows easily and plot Mavg against its length (Three curves on the same plot. Nine plots in total)
Thanks!
Start_time = tic();
N = 5000;
p = 0.2;
% The three Variables
bgt = 0.9* N;
Trigger = 0.9 * N;
alpha = 0.9;
init_attack = 8; % no. of nodes attacked initially
mde = 0; %mode of attack
disturb = 350; % disturbance added to the loads
tol = 0.2; % tolerance parameter alpha C = L + a
iter = 1;
tmax = 120;
M_iter = zeros(iter, tmax);
for jj = 1:iter
N = numnodes(G);% number of nodes(components)
[G_dmg,attack,G_orig, needRemoveNode,LoadneedDist,M, tmax, lastIndex] = Load_initial(G,init_attack,mde,disturb,tol,Load, tmax); % initial attack (disruption)
alreadyCalled = false; % Say that decision and implement have not been called yet.
for tt = 3: tmax
if any(needRemoveNode)|| ~any(needRemoveNode)
[G_dmg,LoadneedDist,needRemoveNode,M, tmax, lastIndex] = Load_Stages(G_dmg,needRemoveNode,LoadneedDist,M, tmax, lastIndex); % a cascade of failure will be triggered
end
if (M(tt) >= (Trigger)) && ~alreadyCalled % triggering level
% Calling for the very first time if we get here.
[G_dmg, Nodes_p, tmax] = Loads_decision(G_dmg, tmax);
[G_dmg, M, tmax, lastIndex] = Loads_implement(G_dmg, Nodes_p, M, tmax, lastIndex, p, bgt, alpha);
alreadyCalled = true; % Set flag to indicate we've called it.
elseif alreadyCalled
% Once they've been called already, call them regardless of the "if" test.
[G_dmg, Nodes_p, tmax] = Loads_decision(G_dmg, tmax); %decide which nodes to recover first
[G_dmg, M, tmax, lastIndex] = Loads_implement(G_dmg, Nodes_p, M, tmax, lastIndex, p, bgt, alpha); % implement recovery
end
end
M_iter(jj,:)=M;
S = std(M_iter);
SE = S/sqrt(size(M_iter,1));
end
% Save The Results
% if Trigger == 0.1 * N
save('M_iter.mat','M_iter');
Mavg = mean(M_iter,1);
save('Mavg.mat','Mavg');
save('SE.mat','SE')
% elseif Trigger == 0.5 * N
% save('M_iter2.mat','M_iter');
% Mavg = mean(M_iter,1);
% save('Mavg2.mat','Mavg');
% save('SE2.mat','SE')
% elseif Trigger == 0.9 * N
% save('M_iter3.mat','M_iter');
% Mavg = mean(M_iter,1);
% save('Mavg3.mat','Mavg');
% save('SE3.mat','SE')
% end
% Plotting
figure(1)
% errorbar(1:length(Mavg),Mavg,SE);hold on
plot(1:length(Mavg),Mavg); hold on
legend({'Triggering Level = 10%', 'Triggering Level = 50%', 'Triggering Level = 90%'}, 'Location', 'NorthWest');
xlabel('Time')
ylabel('No. of Inactive Nodes')
toc(Start_time)

Risposta accettata

DGM
DGM il 7 Dic 2021
Modificato: DGM il 7 Dic 2021
This is what I did off the top of my head
v = [0.1 0.5 0.9];
k = 3;
combs = unique(nchoosek(repmat(v,[1 k]),k),'rows')
combs = 27×3
0.1000 0.1000 0.1000 0.1000 0.1000 0.5000 0.1000 0.1000 0.9000 0.1000 0.5000 0.1000 0.1000 0.5000 0.5000 0.1000 0.5000 0.9000 0.1000 0.9000 0.1000 0.1000 0.9000 0.5000 0.1000 0.9000 0.9000 0.5000 0.1000 0.1000
This can also be done using ndgrid and some reshaping. It's a bit faster, but the readability isn't remotely comparable. For the same reason, it's not something I find easy to remember either.
v = [0.1 0.5 0.9];
k = 3;
c = cell(1,k);
vc = repmat({v},[1 k]);
[c{:}] = ndgrid(vc{:});
n = length(c);
combs = reshape(cat(n+1,c{:}),[],n)
combs = 27×3
0.1000 0.1000 0.1000 0.5000 0.1000 0.1000 0.9000 0.1000 0.1000 0.1000 0.5000 0.1000 0.5000 0.5000 0.1000 0.9000 0.5000 0.1000 0.1000 0.9000 0.1000 0.5000 0.9000 0.1000 0.9000 0.9000 0.1000 0.1000 0.1000 0.5000
  3 Commenti
DGM
DGM il 8 Dic 2021
Modificato: DGM il 8 Dic 2021
Something like this might be a start
combs = % however you decide to generate the combination array
for k = 1:size(combs,1)
bgt = combs(k,1);
Trigger = combs(k,2);
alpha = combs(k,3);
% do the loop to calculate Miter
end
How you handle output collection is up to you. You could either collect the outputs in an N-D array or you can dump them to mat-files individually. Since I don't know what size they are intended to be, I'm going to leave that decision up to you.
Say you want Miter to be N-D. You might do the assignment like so:
M_iter(jj,:,k) = M;
or maybe you want to write each 2-D output to a unique file instead...
save(sprintf('M_iter%03d.mat',k),'M_iter');
If you want to plot the data for all 27 parameter combinations, you're probably going to be better off deciding on a way to collect the outputs into an ND array. Making a readable plot might be another challenge.
Waseem AL Aqqad
Waseem AL Aqqad il 8 Dic 2021
Modificato: Waseem AL Aqqad il 8 Dic 2021
Thank you so much. It's greatly appreciated.
To preallocate M_iter, I must do this (outside the two for loops) :
M_iter = zeros(iter, tmax, size(combs,1));
Instead of :
M_iter = zeros(iter, tmax);
Correct?

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Loops and Conditional Statements in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by