How to skip an error inside a loop so the loop continues?

The following is my full code: (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?

 Accepted Answer

You could wrap the code inside the line
if not(isempty(x))
...
end

2 Comments

Thanks, so just to confirm, this leaves the column of LM_FINAL as a column of 0's (i.e., unchanged) if the error happens and then proceeds to fill in the next column (assuming the error doesn't occur)?
Yes, that is what should happen. You have initialized the entire array to be zeros, which of course means that each column starts off as zero. If you do
if not(isempty(x))
lamda = -log(x);
LM_FINAL(:,k) = lamda;
end
then it is only going to run that code if x is not empty. If x is empty, then it is going to do nothing with LM_FINAL, which means that that column will continue to be all zeros.

Sign in to comment.

More Answers (1)

You could wrap the known troublesome code in try catch:
try
% code that generates an error
catch
% Error goes here but don't do anything, just ignore it.
end

6 Comments

I have a similar problem. I am given csv data files with N matrices (a different N each file) but N is unknown before reading the file. I created a loop to read the matrices one at a time and do some processing on them. After the N-th matrix is read and processed, the script tries to read the next [non-existent] matrix and generates an error. If I process a file at a time, this doesn't matter. the program (script) would have terminated anyway, if I had known a priori what N was. However, I want to add an outer loop to process all data files at a time. When I tried the try/catch solution, it didn't work: the error killed the script file operation. Is there maybe a variation on the If(not()) approach I could try or, is this error maybe considered too severe to be ignored? (I seem to remember MATLAB has various error severity levels ...) If you need me to provide code, I'd be happy to do so.
In the loop, skip the file if it doesn't exist:
if ~exist(fullFileName, 'file')
continue; % Skip to bottom of loop
end
Or you can use dir() to make sure you only have existing files in your filename list. See the FAQ for code samples:
Thanks for responding. (I have been "out of action" for a couple of weeks.) I have a set of M files. A file has Ni>0 matrices (0<i<M+1) and, generally, Ni does not equal Nj, for i not equal to j. I use the dir() function to get the complete list of non-empty .csv files. There is no way to know Ni when I begin to read file i. If I process a file at a time, there's no problem: once all the matrices have been read & processed, an error occurs when csvread tries to read the next matrix in the file (Ni+1), which doesn't exist, and the script terminates. (I have done my processing and saved the results so I don't lose anything.) The problem is, I want to process a whole batch of M files at once, in a loop. Because I don't know how to find the end of a csv file without crashing the script, I can never complete more than one loop iteration. My fundamental question then is really: how do I detect the end of a csv file without crashing the script. (I am able to read the last matrix; I just can't tell it's the last matrix in the file until I try to read another one.)
csvread() reads in the whole file. I don't know how you figure out how many matrices are bundled into that single file but somehow you have to figure it out. Then you can just index. Like say matrix #5 starts at row 130 and ends at row 190, then you can do
allMatrices = csvread(filename);
matrix5 = allMatrices(130:190, :); % Extract matrix #5
I have to aplogize and this is a perfect example of why it's necessary to include the actual code you're using when asking a question. I cannot do as you suggest because the software that creates these csv files includes a header line before each array (matrix) which is in hex format. csvread expects only integer or floating point numbers so, if I read these lines - including the case where I try to read the entire file, execution is terminated. I cannot directly control the format in which these files are created but, I will try to persuade the provider to alter them. Thanks and I'm sorry I wasted your time; your solution would obviously work, otherwise.
You could use importdata() which allows you to specify the number of headerlines. Alternatively you could preprocess the file to extract out each chunk and write each chunk to a separate file. Of course it's easier if you can get them to just supply you with individual files in the first place.

Sign in to comment.

Categories

Asked:

on 23 Feb 2014

Commented:

on 25 Oct 2016

Community Treasure Hunt

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

Start Hunting!