function stop = outputfcnsanitycheck(params,optimValues,state,tol,numsteps) <params> is the current optimization parameter <optimValues>,<state> are optimization state stuff <tol> (optional) is a positive number. default: 1e-6. <numsteps> (optional) is the positive number of iterations in the past to compare to. default: 10. we look back <numsteps> iterations and check whether the resnorm field of <optimValues> has changed by less than <tol>. if so, we stop the optimization. the only reason for this is to patch up some weird cases where the regular optimizer doesn't stop when it should (in these cases, the optimizer goes on forever without anything actually changing). example: x = -1:.1:20; y = evaldoublegamma([1 1 1 1 2 .2 0 0],x); yn = y + 0.1*randn(size(y)); [params,d,d,exitflag,output] = lsqcurvefit(@(a,b) evaldoublegamma([a 0 0],b),ones(1,6),x,yn,[],[],defaultoptimset({'OutputFcn' @outputfcnplot}));
0001 function stop = outputfcnsanitycheck(params,optimValues,state,tol,numsteps) 0002 0003 % function stop = outputfcnsanitycheck(params,optimValues,state,tol,numsteps) 0004 % 0005 % <params> is the current optimization parameter 0006 % <optimValues>,<state> are optimization state stuff 0007 % <tol> (optional) is a positive number. default: 1e-6. 0008 % <numsteps> (optional) is the positive number of iterations in the 0009 % past to compare to. default: 10. 0010 % 0011 % we look back <numsteps> iterations and check whether the resnorm field 0012 % of <optimValues> has changed by less than <tol>. if so, we stop the 0013 % optimization. the only reason for this is to patch up some weird cases 0014 % where the regular optimizer doesn't stop when it should (in these cases, 0015 % the optimizer goes on forever without anything actually changing). 0016 % 0017 % example: 0018 % x = -1:.1:20; 0019 % y = evaldoublegamma([1 1 1 1 2 .2 0 0],x); 0020 % yn = y + 0.1*randn(size(y)); 0021 % [params,d,d,exitflag,output] = lsqcurvefit(@(a,b) evaldoublegamma([a 0 0],b),ones(1,6),x,yn,[],[],defaultoptimset({'OutputFcn' @outputfcnplot})); 0022 0023 % input 0024 if ~exist('tol','var') || isempty(tol) 0025 tol = 1e-6; 0026 end 0027 if ~exist('numsteps','var') || isempty(numsteps) 0028 numsteps = 10; 0029 end 0030 0031 % global stuff 0032 global OFSC_RES; 0033 0034 % do it 0035 switch state 0036 case 'init' 0037 OFSC_RES = []; 0038 case {'iter' 'done'} 0039 OFSC_RES = [OFSC_RES optimValues.resnorm]; 0040 if length(OFSC_RES) >= numsteps+1 0041 if abs(OFSC_RES(end)-OFSC_RES(end-numsteps)) < tol 0042 stop = 1; 0043 return; 0044 end 0045 end 0046 end 0047 0048 % return 0049 stop = 0; 0050 0051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0052 0053 % % for sanity checking, we also check whether optimValues.ratio 0054 % % is NaN; if it is, we stop the optimization. 0055 % % 0056 % % if isfield(optimValues,'ratio') && isnan(optimValues.ratio) && optimValues.iteration > 5 0057 % % stop = 1; 0058 % % return; 0059 % % end