stop fmincon if encounter warning about rank

Hi,
I'm running fmincon using the sqp algorithm to run a montecarlo.
Sometimes (a couple out of a hundred) it encounters a matrix close to singluar and gets caught.
Is there a way to stop the optimizer and move on to the next with an exitflag that will let me know it did so?
I tried interior point, but after 10000 maxiter it didn't get close to the minimum that sqp was finding, so seems like sqp is better for this problem if I can find a way to cancel the optimization and move on if it encounters the warning.
Thanks for any tips.

Answers (1)

Matt J
Matt J on 6 Feb 2014
Edited: Matt J on 6 Feb 2014
You can define your own stopping conditions using the OutputFcn option, see here
I don't think it offers a way to control the native exitflag output argument, but you can send the flag to a global variable, or use nested functions that share variables.

9 Comments

I've used the OutputFcn option to look at params at each iteration, but could you offer a bit more advice on what I should look for to check the RCOND->0 that is causing the matrix singularity problem in my application.
Are you suggesting to use iteration or funcCount or something else?
Will this slow down the process much?
Very much appreciate the tip.
Matt J
Matt J on 7 Feb 2014
Edited: Matt J on 7 Feb 2014
Use the 'state' input. When state='iter', start a timer. When state='interrupt', measure the elapsed time. When the elapsed time exceeds a threshold you think unreasonable, abort.
You can also use LASTWARN to get info about whether an RCOND-->0 condition has occurred.
Do you know what would be the msgid for this warning?
Thank you.
I assume the warning you're getting is the following?
>> A=[1e28 0; 0 1]; b=[2;2]; A\b;
Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 1.000000e-28.
If so, you can use laswarn to obtain it. I'm not sure the MSGIDs are independent of MATLAB version, however. In my version, it is
>> [~,msgid]=lastwarn
msgid =
MATLAB:nearlySingularMatrix
I'm having difficulty implementing your suggestion. I would like to check both methods, one based on time and the other based on RANK, but I can't get the time one to work, and the RANK one is coded in a strange way.
Any chance you can comment on my code?
I very much appreciate your advice.
function stop=outfun(x,optimValues,state);
stop=false;
telapsed=0;
[msgstr, msgid] = lastwarn;
msgchk='xxxxxxxxxxxxxxxxxxxxxxxxxxx';
if size(msgid,1)>0
msgchk=msgid(1:27);
end;
if msgchk == 'MATLAB:nearlySingularMatrix'
stop = true;
end
%state
chkstate=state(1:4);
if chkstate=='iter'
tstart = tic;
end
if chkstate=='inte'
telapsed = toc(tstart);
telapsed
end
if telapsed>240
stop = true;
end
As far as I can tell tstart is not a persistent variable, so its value will be forgotten on subsequent calls to the OutputFcn.
As for msgchk, I don't understand why you wouldn't just do
if strcmp(msgid,'MATLAB:nearlySingularMatrix')
stop = true;
end
Finally, you should issue your own warning when stopping prematurely, so that lastwarn will be reset.
Thank you, I did not know the strcmp command, so came with with some ad hoc way to do this. This is helpful.
Do you have a suggestion for how to check elapsed time in the OutputFcn?
Thanks again.
Like I said, the way you are doing it now seems fine, except that tstart would have to be made persistent, and reset to 0 at an appropriate point.

Sign in to comment.

Asked:

JD
on 6 Feb 2014

Commented:

on 8 Feb 2014

Community Treasure Hunt

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

Start Hunting!