Index Error in for loop, MATLAB - matlab

I am running this program below and I keep getting this error "Index exceeds matrix dimensions" for line "Tour1 = pop(kk(1:10),:);". I don't know what I have missed out. Can anyone help please.
Thanks
for i = 1:100 %Population Initialization
pop(i,1) = 50 - rand*(50-1);
pop(i,2) = 1 - rand*(1-0.1);
pop(i,3) = 0.2 - rand*(0.2-0.01);
Kc(i) = pop(i,1);
T1(i) = pop(i,2);
T2(i) = pop(i,3);
fitness(i) = obj(Kc(i), T1(i), T2(i));
%% TOURNAMENT SELECTION
for j = 1:10 %Select first parent
kk = randperm(100);
Tour1 = pop(kk(1:10),:);
temp1 = mat2cell(Tour1(j,:),1,ones(1,numel(Tour1(j,:))));
ZET1(j) = obj(temp1{:});
end
[Val1 Ind1] = max(ZET1);
parent1 = Tour1(Ind1,:);
end

Just place the final end before executing the j block
for i = 1:100 %Population Initialization
pop(i,1) = 50 - rand*(50-1);
pop(i,2) = 1 - rand*(1-0.1);
pop(i,3) = 0.2 - rand*(0.2-0.01);
Kc(i) = pop(i,1);
T1(i) = pop(i,2);
T2(i) = pop(i,3);
fitness(i) = obj(Kc(i), T1(i), T2(i));
end
for j = 1:10 %Select first parent
kk = randperm(100);
Tour1 = pop(kk(1:10),:);
temp1 = mat2cell(Tour1(j,:),1,ones(1,numel(Tour1(j,:))));
ZET1(j) = obj(temp1{:});
end
[Val1 Ind1] = max(ZET1);
parent1 = Tour1(Ind1,:);

Do you really want to have the second for inside the first one?
At the first execution of the outer loop, i is one. You populate pop (1, :), but no more.
At the inner loop, you then try to access pop (kk (1:10), :), with kk (1:10) being within [1..100]. But there is no pop (i, :) for i > 1.

Related

How to correct grid search?

Trying to find the optimal hyperparameters for my svm model using a grid search, but it simply returns 1 for the hyperparameters.
function evaluations = inner_kfold_trainer(C,q,k,features_xy,labels)
features_xy_flds = kdivide(features_xy, k);
labels_flds = kdivide(labels, k);
evaluations = zeros(k,3);
for i = 1:k
fprintf('Fold %i of %i\n',i,k);
train_data = cell2mat(features_xy_flds(1:end ~= i));
train_labels = cell2mat(labels_flds(1:end ~= i));
test_data = cell2mat(features_xy_flds(i));
test_labels = cell2mat(labels_flds(i));
%AU1
train_labels = train_labels(:,1);
test_labels = test_labels(:,1);
[k,~] = size(test_labels);
%train
sv = fitcsvm(train_data,train_labels, 'KernelFunction','polynomial', 'PolynomialOrder',q,'BoxConstraint',C);
sv.predict(test_data);
%Calculate evaluative measures
%svm_outputs = zeros(k,1);
sv_predictions = sv.predict(test_data);
[precision,recall,F1] = evaluation(sv_predictions,test_labels);
evaluations(i,1) = precision;
evaluations(i,2) = recall;
evaluations(i,3) = F1;
end
save('eval.mat', 'evaluations');
end
an inner-fold cross validation function
and below the grid function where something seems to be going wrong
function [q,C] = grid_search(features_xy,labels,k)
% n x n grid
n = 3;
q_grid = linspace(1,19,n);
C_grid = linspace(1,59,n);
tic
evals = zeros(n,n,3);
for i = 1:n
for j = 1:n
fprintf('## i=%i, j=%i ##\n', i, j);
svm_results = inner_kfold_trainer(C_grid(i), q_grid(j),k,features_xy,labels);
evals(i,j,:) = mean(svm_results(:,:));
% precision only
%evals(i,j,:) = max(svm_results(:,1));
toc
end
end
f = evals;
% retrieving the best value of the hyper parameters, to use in the outer
% fold
[M1,I1] = max(f);
[~,I2] = max(M1(1,1,:));
index = I1(:,:,I2);
C = C_grid(index(1))
q = q_grid(index(2))
end
When I run grid_search(features_xy,labels,8) for example, I get C=1 and q=1, for any k(the no. of folds) value. Also features_xy is a 500*98 matrix.

Calculating values in a for loop

I have a for loop that is storing values. For some reason, it is calculating values for all the number up to and including those in the for loop, instead of just the ones in the array.
t = 3600:50:172800;x = 0.1;y = 0; ro = 0.1;
T = zeros(1,length(t));
for Cm = 1E6:1E6:4E6
for i = 1:length(t)
T = T_ILS(x,y,ro,Cm,t);
Tall(Cm,:) = [T];
end
end
The error I get is "Requested 2000000x3385 array exceeds maximum array size preferences". I would like the for loop to calculate just the Cm values and not every number in between.
You are not computing every value in between, but your indices are messed up. Cm takes values in the millions, but you use it to index Tall(Cm,:). You probably want
t = 3600:50:172800;x = 0.1;y = 0; ro = 0.1;
T = zeros(1,length(t));
Cm = 1E6:1E6:4E6;
for j = 1:length(Cm)
for i = 1:length(t)
T(i) = T_ILS(x,y,ro,Cm(j),t(i));
end
Tall(j,:) = [T];
end
Notice that the main function call assigns to T(i) and uses t(i) in the function arguments to justify the existence of the for loop.
In the inner loop, T is the output of the function T_ILS, using the same arguments each time.
for i = 1:length(t)
T = T_ILS(x,y,ro,Cm,t);
Tall(Cm,:) = [T];
end
I don't know what this function computes, but you probably wanted to do this instead
for i = 1:length(t)
T = T_ILS(x,y,ro,Cm,t(i));
Tall(Cm,:) = [T];
end
to account for each value of the vector t, or even better:
for t = 3600:50:172800
T = T_ILS(x,y,ro,Cm,t);
Tall(Cm,:) = [T];
end
EDIT: Also, to make this answer complete, I'd like to merge #MadPhysicist's answer with mine. The result would be
Cm = 1E6:1E6:4E6; x = 0.1;y = 0; ro = 0.1;
T = zeros(1,length(t));
for i = 1:length(Cm)
for t = 3600:50:172800;
T = T_ILS(x,y,ro,Cm(i),t);
Tall(i,:) = [T];
end
end

Using xlswrite to save numerical data

Hi I would like to save numerical data from an operation inside a loop. Lets see my segmentation example:
clear all, clc;
a=1:35;
A = arrayfun( #(x) sprintf( '%04d', x ), a, 'UniformOutput', false );
I = cellfun( #(b) imread( ['C:Teste/' b '/c1/' b '.png'] ), A, 'UniformOutput', false );
for i = a
% Gaussian Filter
W = fspecial('gaussian',[10,10],2);
J = imfilter(I,W);
% Finding Circular objects -- Houng Transform
[centers, radii, metric] = imfindcircles(J,[5 10], 'Sensitivity',0.93,'Edge',0.27);
idx_mask = ones(size(radii));
min_dist = 2; % relative value.
for i = 2:length(radii)
cur_cent = centers(i, :);
for j = 1:i-1
other_cent = centers(j,:);
x_dist = other_cent(1) - cur_cent(1);
y_dist = other_cent(2) - cur_cent(2);
if sqrt(x_dist^2+y_dist^2) < min_dist*(radii(i) + radii(j)) && idx_mask(j) == 1
idx_mask(i) = 0;
break
end
end
end
idx_mask = logical(idx_mask);
centers_use = centers(idx_mask, :);
radii_use = radii(idx_mask, :);
metric_use = metric(idx_mask, :);
viscircles(centers_use, radii_use,'EdgeColor','b');
a=length(centers_use)
end
So the point is to save the 35 results in one column of an xls file.
I was trying to do this but only the last element of the loop is printed in the exel file...
filename = 'testdata.xlsx';
A = vertcat('Test', 'Results', num2cell(a'));
sheet = 1;
xlRange = 'F03';
xlswrite(filename,A,sheet,xlRange)
Can please anyone help me out? I know there many questions related to this one but none of them covers my issue...
I will leave here one image for testing:
Thanks a lot in advance.
John
As #excaza said, you need to expand b
a=1:35;
for i = a
b=10+a;
end
filename = 'testdata.xlsx';
A = vertcat('Example', 'Results', num2cell(b'));
sheet = 1;
xlRange = 'B1';
xlswrite(filename,A,sheet,xlRange)

Subscripted assignment dimension mismatch in matlab

I executed this code using Feature Matrix 517*11 and Label Matrix 517*1. But once the dimensions of matrices change the code cant be run. How can I fix this?
The error is:
Subscripted assignment dimension mismatch.
in this line :
edges(k,j) = quantlevels(a);
Here is my code:
function [features,weights] = MI(features,labels,Q)
if nargin <3
Q = 12;
end
edges = zeros(size(features,2),Q+1);
for k = 1:size(features,2)
minval = min(features(:,k));
maxval = max(features(:,k));
if minval==maxval
continue;
end
quantlevels = minval:(maxval-minval)/500:maxval;
N = histc(features(:,k),quantlevels);
totsamples = size(features,1);
N_cum = cumsum(N);
edges(k,1) = -Inf;
stepsize = totsamples/Q;
for j = 1:Q-1
a = find(N_cum > j.*stepsize,1);
edges(k,j) = quantlevels(a);
end
edges(k,j+2) = Inf;
end
S = zeros(size(features));
for k = 1:size(S,2)
S(:,k) = quantize(features(:,k),edges(k,:))+1;
end
I = zeros(size(features,2),1);
for k = 1:size(features,2)
I(k) = computeMI(S(:,k),labels,0);
end
[weights,features] = sort(I,'descend');
%% EOF
function [I,M,SP] = computeMI(seq1,seq2,lag)
if nargin <3
lag = 0;
end
if(length(seq1) ~= length(seq2))
error('Input sequences are of different length');
end
lambda1 = max(seq1);
symbol_count1 = zeros(lambda1,1);
for k = 1:lambda1
symbol_count1(k) = sum(seq1 == k);
end
symbol_prob1 = symbol_count1./sum(symbol_count1)+0.000001;
lambda2 = max(seq2);
symbol_count2 = zeros(lambda2,1);
for k = 1:lambda2
symbol_count2(k) = sum(seq2 == k);
end
symbol_prob2 = symbol_count2./sum(symbol_count2)+0.000001;
M = zeros(lambda1,lambda2);
if(lag > 0)
for k = 1:length(seq1)-lag
loc1 = seq1(k);
loc2 = seq2(k+lag);
M(loc1,loc2) = M(loc1,loc2)+1;
end
else
for k = abs(lag)+1:length(seq1)
loc1 = seq1(k);
loc2 = seq2(k+lag);
M(loc1,loc2) = M(loc1,loc2)+1;
end
end
SP = symbol_prob1*symbol_prob2';
M = M./sum(M(:))+0.000001;
I = sum(sum(M.*log2(M./SP)));
function y = quantize(x, q)
x = x(:);
nx = length(x);
nq = length(q);
y = sum(repmat(x,1,nq)>repmat(q,nx,1),2);
I've run the function several times without getting any error.
I've used as input for "seq1" and "seq2" arrays such as 1:10 and 11:20
Possible error might rise in the loops
for k = 1:lambda1
symbol_count1(k) = sum(seq1 == k);
end
if "seq1" and "seq2" are defined as matrices since sum will return an array while
symbol_count1(k)
is expected to be single value.
Another possible error might rise if seq1 and seq2 are not of type integer since they are used as indexes in
M(loc1,loc2) = M(loc1,loc2)+1;
Hope this helps.

How to skip an error inside a loop and let the loop continue

The following is my full code: (Most of it isn't useful for what I'm asking, but I just put in the entire code for context, the part of the code that is causing me trouble is towards the end)
clc
clear
P = xlsread('b3.xlsx', 'P');
d = xlsread('b3.xlsx', 'd');
CM = xlsread('b3.xlsx', 'Cov');
Original_PD = P; %Store original PD
LM_rows = size(P,1)+1; %Expected LM rows
LM_columns = size(P,2); %Expected LM columns
LM_FINAL = zeros(LM_rows,LM_columns); %Dimensions of LM_FINAL
% Start of the outside loop
for k = 1:size(P,2)
P = Original_PD(:,k);
interval = cell(size(P,1)+2,1);
for i = 1:size(P,1)
interval{i,1} = NaN(size(P,1),2);
interval{i,1}(:,1) = -Inf;
interval{i,1}(:,2) = d;
interval{i,1}(i,1) = d(i,1);
interval{i,1}(i,2) = Inf;
end
interval{i+1,1} = [-Inf*ones(size(P,1),1) d];
interval{i+2,1} = [d Inf*ones(size(P,1),1)];
c = NaN(size(interval,1),1);
for i = 1:size(c,1)
c(i,1) = mvncdf(interval{i,1}(:,1),interval{i,1}(:,2),0,CM);
end
c0 = c(size(P,1)+1,1);
f = c(size(P,1)+2,1);
c = c(1:size(P,1),:);
b0 = exp(1);
b = exp(1)*P;
syms x;
eqn = f*x;
for i = 1:size(P,1)
eqn = eqn*(c0/c(i,1)*x + (b(i,1)-b0)/c(i,1));
end
eqn = c0*x^(size(P,1)+1) + eqn - b0*x^size(P,1);
x0 = solve(eqn);
for i = 1:size(x0)
id(i,1) = isreal(x0(i,1));
end
x0 = x0(id,:);
x0 = x0(x0 > 0,:);
clear x;
for i = 1:size(P,1)
x(i,:) = (b(i,1) - b0)./(c(i,1)*x0) + c0/c(i,1);
end
x = [x0'; x];
x = double(x);
x = x(:,sum(x <= 0,1) == 0)
lamda = -log(x);
LM_FINAL(:,k) = lamda;
end
% end of the outside loop
The important part of the above loop is towards the end:
x = x(:,sum(x <= 0,1) == 0)
This condition is sometimes not satisfied and hence the variable x is empty, which means LM_FINAL(:,k) = lamda is also empty. When this happens, I get the error:
x =
Empty matrix: 43-by-0
Improper assignment with rectangular empty matrix.
Error in Solution (line 75)
LM_FINAL(:,k) = lamda;
How can I skip this error so that the column for LM_FINAL remains as empty, but the loop continues (so that the rest of LM_FINAL's columns are filled) rather than terminating?
You can use try and catch phrase to explicitly handle errors inside loop (or elsewhere in your code).