Nested For Loop 3D Graph

1 view (last 30 days)
Elizabeth Cardona on 23 Aug 2020
Answered: Prasanth on 26 Aug 2020
I have two populations of cells (main and sub). This model goes through a set of predefined mu values, finds the minmum AIC (least error) and spits out the number of Components. Ideally, we want to have two components, given there is two populations. It worked fine when I only iterated through mu of the main values. Now, I am tryig to also iterate through mu of the sub values. Instead of a 2D plot (mu_main vs numComponents), I want a 3D plot (mu_main, mu_sub, numComponents). However, it does not run. Takes too long, goes into an infinite loop maybe? Am I doing the nested for loop incorrectly?
This is the old code that workds perfectly:
%% mu main
%% define known constants
% rng(0,'twister')
n_main = 100000;
n_sub = 5000;
sigma_main = 0.1;
sigma_sub = 0.1;
mu_main = 1;
mu_sub = 1;
%% change sigma_main values and run model
mumain_val = 1:0.02:3;
outputData = zeros(length(mumain_val), 2); % create an output array for (length sigma_sub),numComponents (19x2 double)
BestModel = cell(numel(mu_main),1); % pre-allocate array to hold fitgmdist outputs (1x19 cell)
allMus = cell(numel(mu_main),1); %pre-allocate array to hold mu outputs (1x19 cell)
for i = 1:length(mumain_val)
mumain_pos = i; %iteration
mu_main = mumain_val(mumain_pos); % sigma main from every iteration
y = sigma_main.*randn(n_main,1) + mu_main; %100000 main cells
y2 = sigma_sub.*randn(n_sub,1) + mu_sub; %10000 sub MB 231
C = cat(1, y, y2);
AIC = zeros(1,4); % create an ouput array for AIC
GMModels = cell(1,4); %pre allocate GMModels (1x4 cell)
options = statset('MaxIter',00); % add optitons here to better/refine the model
mutemp = cell(4,1); %mus from the last run
for k = 1:4
GMModels{k} = fitgmdist(C,k);
AIC(k)= GMModels{k}.AIC;
mutemp{k} = GMModels{k}.mu; %get the mus
end
[minAIC,numComponents] = min(AIC);
outputData(i,1) = mu_main;
outputData(i,2) = numComponents;
allMus{i} = mutemp; % 1 x 19 cell with mus
%BestModel = GMModels{numComponents} %gives only one sigma main
BestModel{i} = GMModels{outputData(i,2)}; %1x19 cell with gm distributions
end
%% plot sigma main vs numComponents
figure(2)
scatter(outputData(:,1),outputData(:,2))
xlabel('mu main')
ylabel('numComponents')
This is the new code with the extra variable, nested for loop that is not running:
%% mu main
%% define known constants
% rng(0,'twister')
n_main = 100000;
n_sub = 5000;
sigma_main = 0.1;
sigma_sub = 0.1;
mu_main = 0.1;
mu_sub = 0.1;
%% change sigma_main values and run model
mumain_val = 0.1:0.02:3;
musub_val = 0.1:0.02:3;
outputData = zeros(length(mumain_val), 3);% create an output array for (length sigma_sub),numComponents (19x2 double)
BestModel = cell(numel(mu_main),1); % pre-allocate array to hold fitgmdist outputs (1x19 cell)
allMus = cell(numel(mu_main),1); %pre-allocate array to hold mu outputs (1x19 cell)
for i = 1:length(mumain_val)
for j = 1:length(musub_val)
mumain_pos = i; %iteration
mu_main = mumain_val(mumain_pos); % sigma main from every iteration
musub_pos = i; %iteration
mu_sub = mumain_val(musub_pos); % sigma main from every iteration
y = sigma_main.*randn(n_main,1) + mu_main; %100000 main cells
y2 = sigma_sub.*randn(n_sub,1) + mu_sub; %10000 sub MB 231
C = cat(1, y, y2);
AIC = zeros(1,4); % create an ouput array for AIC
GMModels = cell(1,4); %pre allocate GMModels (1x4 cell)
options = statset('MaxIter',00); % add optitons here to better/refine the model
mutemp = cell(4,1); %mus from the last run
for k = 1:4
GMModels{k} = fitgmdist(C,k);
AIC(k)= GMModels{k}.AIC;
mutemp{k} = GMModels{k}.mu; %get the mus
end
[minAIC,numComponents] = min(AIC);
outputData(i,1) = n_main;
outputData(i,2) = n_sub;
outputData(i,3) = numComponents;
BestModel{i} = GMModels{outputData(i,3)}; %1x19 cell with gm distributions
allMus{i} = BestModel{i}.mu; % 1 x 19 cell with mus
end
end
%% plot sigma main vs numComponents
figure(2)
scatter3(outputData(:,1),outputData(:,2),outputData(:,3))
xlabel('mu main')
ylabel('mu sub')
zlabel('numComponents')

Prasanth on 26 Aug 2020
I am assuming that you are using MATLAB R2020a and you are trying to generate a 3D scatter plot using 'scatter3' function. You would like to know if the nested for loop implementation is correct.
Regarding your code, I am giving few pointers which might be helpful.
1. Your code is not in infinite loop. It is consuming more time to execute your code. You can use MATLAB Debugger to exactly know what is happening.
2. I see that you have created a nested for loop with 'j' as the iterator, but 'j' is not being used anywhere inside the loop. Since this loop is related to 'musub_val', you should consider changing the index of 'mu_sub' variables from 'i' to 'j'.
3. There is a scope to optimize your code. You can identify the statements that are relying only on 'i' and place them in the appropriate positon in the outermost for loop. This avoids the same statement running multiple times.