Code covered by the BSD License  

Highlights from
OpenOpt

image thumbnail

OpenOpt

by

 

25 Nov 2006 (Updated )

nonSmoothSolve (similar to fsolve), non-smooth & noisy local + some global solvers; works in Octave

ooIter(prob, r)
function r = ooIter(prob, r)
% disp(r.x.')
global globstat
if ~isfield(r, 'istop'); r.istop = 0; end
if ismember(r.istop, prob.advanced.ignoreIStop)
    r.istop = 0;
end
istop = 0;% continue calculations

% if isfield(r,'x'); x = r.x; else x = r.xf; end
% if isfield(r,'f'); f = r.f; else f = r.ff; end
% isNonSmoothSolve = isfield(prob, 'TolFunSolve') || isequal(lower(prob.solverName), 'nonsmoothsolve');
x = globstat.xPrevF;
if isfield(prob, 'TolFunSolve');
    x = r.x;
end
if any(size(x)~=[prob.n 1])
    if size(x,1)~= prob.n && size(x,2) == prob.n
        x=x.';
        if ~globstat.nIter; prob.warn(('you must pass n x 1 vector x to the iterfcn, not 1 x n')); end
    elseif size(x,1) == prob.n && size(x,2) > 1
        x = x(:,1);
%         prob.err('you must pass (size prob.n x 1) vector x to the iterfcn')
    end
end
f = globstat.fPrevF;
if isfield(prob, 'TolFunSolve')
    f = r.f;
end
if numel(f)>1
    if size(f,2)>1; f=f(1); end
    f = sum(f);%by columns
end

violations = prob.advanced.getViolations(x, prob);
MaxV = max(abs(violations));
if isempty(MaxV)
    if isfield(prob, 'TolFunSolve') || isequal(lower(prob.solverName), 'nonsmoothsolve') && globstat.isFinished
        % called from ooRunProbSolver, solver already finished
        MaxV = norm(prob.f(r.xf, inf));
    else
        if ~prob.primal.isUC; prob.warn('something wrong was occured'); end
        MaxV = 0; 
    end
end
% if ~globstat.nIter; globstat.tmp.min_violations = violations; end
% if norm(globstat.tmp.min_violations, 1)<= norm(violations, 1)
%     violationsAreDecreased = 1;
% else
%     violationsAreDecreased = 0;
% end
% if r.f< globstat.ff && (~any(violations>prob.TolCon) || norm(violations,1) <= norm(globstat.tmp.prev_violations, 1)) ||...
%         (globstat.ff-norm(violations,1)>=r.f-norm(globstat.tmp.prev_violations, 1) && ~any(violations>prob.TolCon))


% WARN! don't replace ~any() by all() - it doesn't work for empty matricies 
if f < globstat.ff %&& (~any(violations>prob.TolCon) || violationsAreDecreased)
     %&& ~(any(violations>prob.TolCon) && norm(violations,1) > norm(globstat.tmp.prev_violations, 1))
    globstat.ff = f;
    globstat.xf = x;
end%todo: handle fiter - xiter mismatch case 



% if violationsAreDecreased
%     globstat.tmp.min_violations = violations;
% end


if ~isfield(globstat, 'fPrev'); globstat.fPrev=inf; end

if ~isempty(prob.user.outputfcn)
    r = feval(prob.user.outputfcn, prob, r);
end
if prob.iterPrint>0 && (~mod(globstat.nIter, prob.iterPrint) || globstat.isFinished)
    f1='            '; 
    f2='';
    if isfield(globstat, 'lastX')
        val = prob.normx(x-globstat.lastX);
        if isfinite(val); f1 = sprintf('   %0.2e', val); end
        
    end
    
    if isfield(r, 'df'); f2 = sprintf('      %0.2e', norm(r.df)); end


    
    if ~globstat.nIter
        if globstat.tmp.dispBestVal
            secondColumn = 'Best ObjFuncVal ';
        else
            secondColumn = 'max(abs(constr))';
        end
        s = sprintf('  Iter   Current ObjFunVal   %s  norm(deltaX)', secondColumn);
        if isfield(r, 'df'); s = [s  '  norm(gradient)']; end
        disp(s)
    end
    
    if globstat.tmp.dispBestVal
        secondColumn = globstat.ff;
    else secondColumn = MaxV;
    end
    iterspaces = char(' ' * ones(1, 7-ceil(log10(globstat.nIter+0.1+~globstat.nIter))));
    outMsg = sprintf('   %d%s%+0.8e   %+0.8e', globstat.nIter, iterspaces, f, secondColumn);
    s = [outMsg f1 f2];
    if ~ispc
        s = strrep(s, 'e+', 'e+0');
        s = strrep(s, 'e-', 'e-0');
    end
    disp(s)
end
NOW = now;
TimeFromStart = 24*60*60*(NOW - prob.advanced.timeStart);
if ~globstat.isFinished && (~isfield(r, istop) || ~r.istop)%may be 1st cond is enough?//Dmitrey.
    [mf indOpt]= min(f);

    if globstat.nIter%so fields lastX & fPrev already exist
        EpsFun = norm(globstat.fPrev - mf);
        EpsX = norm(globstat.lastX - x(:,indOpt));
        if EpsFun<prob.TolFun && EpsFun && ~ismember(4, prob.advanced.ignoreIStop); istop = 4; end
        globstat.fPrev = mf;
        if EpsX<prob.TolX && EpsX && ~ismember(3, prob.advanced.ignoreIStop); istop = 3; end
        globstat.lastX = x(:,indOpt);
    else
        globstat.fPrev = mf;
        globstat.lastX = x(:,indOpt); %#ok<FNDSB>
        globstat.tmp.lastDrawTime = NOW;
    end
    globstat.nIter = globstat.nIter + 1;
    globstat.iterCPUTime(globstat.nIter) = cputime - prob.advanced.cputimeStart - globstat.advanced.drawCPUTime;
    
    globstat.iterTime(globstat.nIter) = TimeFromStart - globstat.advanced.drawTime;

    globstat.iterFvals(globstat.nIter) = mf;
    
    if f<prob.fEnough && ~ismember(10, prob.advanced.ignoreIStop); istop = 10; end
    
    %is actual, for example, for hPSO
%     if globstat.nIter>prob.MaxNonEnhance && norm(diff(globstat.iterFvals(globstat.nIter-prob.MaxNonEnhance:globstat.nIter)))<min(prob.TolFun, prob.TolCon) && ~ismember(5, prob.advanced.ignoreIStop)
%         istop = 5;
%     end
        
    if any(isnan(x)) && ~ismember(-4, prob.advanced.ignoreIStop)
        istop = -4; 
    end

    if prob.advanced.traceIterX
        globstat.iterFvals(:, globstat.nIter) = x(:,indOpt);
    end

    if globstat.nIter >= prob.MaxIter && ~ismember(-7, prob.advanced.ignoreIStop)
        istop = -7; 
    end

    if cputime-prob.advanced.cputimeStart > prob.MaxCPUTime && ~ismember(-8, prob.advanced.ignoreIStop)
        istop = -8;
    end

    if TimeFromStart > prob.MaxTime && ~ismember(-9, prob.advanced.ignoreIStop)
        istop = -9;
    end

    if istop && ~ismember(istop, prob.advanced.ignoreIStop)
        r.istop = istop; 
        r.xf = globstat.xf;
        r.ff = globstat.ff;
    end
    
    if ~prob.doPlot || ...
            (globstat.nIter~=1 && 24*60*60*(NOW-globstat.tmp.lastDrawTime)<prob.graphics.timePlotInterval) ||...
            (mod(globstat.nIter, prob.graphics.minNPoints2draw) && ~(globstat.nIter==1))
        return
    end
else
    if isempty(globstat.iterFvals)...%for example, solver failed before 1st iter end, then iterfcn was called from ooRun to update figure
            || ~prob.doPlot;return; end
end
cpu_time = cputime;
now_time = NOW;% to economy now() calls, which are rather expensive
globstat.tmp.lastDrawTime = now_time;
prob.draw(prob, r);% prob.draw can point to other func then oodraw
% so I decided to place time handling here, not in oodraw, 
% it's more general case (however, user can use another func then ooIter)
cpu_time = cputime - cpu_time;%elapsed for drawing
now_time = (now-now_time)*24*60*60;%elapsed for drawing
globstat.advanced.drawCPUTime = globstat.advanced.drawCPUTime + cpu_time;
globstat.advanced.drawTime = globstat.advanced.drawTime + now_time;

Contact us