function [curCompl,acceptedChild] = sodaEvolveComplex(sodaPar,curCompl,curSeq,propChild)
%
% <a href="matlab:web(fullfile(scemroot,'html','evolvecomplex.html'),'-helpbrowser')">View HTML documentation for this function in the help browser</a>    
%

% global DEBUG_VAR_Ratio 
% global DEBUG_REPLACE_BEST
% global DEBUG_REPLACE_WORST

iterCol = sodaPar.iterCol;
paretoCol = sodaPar.paretoCol;

% determine the last iteration in the current sequence:
maxIter = max(curSeq(:,iterCol));
lastEvalFromSeq = curSeq(:,iterCol)==maxIter;

if rand(1,1)<sodaPar.forceRecalcFraction
    curSeqRecalc = curSeq(lastEvalFromSeq,1:end);
    curSeqRecalc(1,sodaPar.evalCol) = false;
    [curSeqRecalc,TMP1,TMP2] = sodaCalcObjScore(sodaPar,curSeqRecalc,[],[],0);
    curSeq(lastEvalFromSeq,1:end)=curSeqRecalc;
end

% determine the density of the last iteration in the current sequence:
lastDensFromSeq = curSeq(lastEvalFromSeq,paretoCol);

% determine the best density in the current complex:
bestEvalRowNumber = randchoose(curCompl(:,sodaPar.paretoCol)==max(curCompl(:,paretoCol)));
bestDensFromCompl = curCompl(bestEvalRowNumber,paretoCol);


% determine the worst density in the current complex:
worstEvalRowNumber = randchoose(curCompl(:,sodaPar.paretoCol)==min(curCompl(:,paretoCol)));
worstDensFromCompl = curCompl(worstEvalRowNumber,paretoCol);

randUniDraw = rand;

% metropolis annealing:
switch sodaPar.optMethod
    case 'direct probability'

        densRatio = propChild(1,paretoCol)/lastDensFromSeq;        
        
        % determine the ratio between the best and worst evaluations 
        % in the current complex (\Gamma^{\itk}):
        bestWorstRatio = bestDensFromCompl/worstDensFromCompl;

        if densRatio > randUniDraw

            % replace the best member of the complex with the proposed offspring
            curCompl(bestEvalRowNumber,:) = propChild;
            acceptedChild = propChild;

        elseif ((bestWorstRatio > sodaPar.thresholdL) & (lastDensFromSeq > worstDensFromCompl))

            prevChild = [propChild(1,iterCol),curSeq(lastEvalFromSeq,2:end)];
            acceptedChild = prevChild;
            curCompl(worstEvalRowNumber,:) = prevChild;

        else

            prevChild = [propChild(1,iterCol),curSeq(lastEvalFromSeq,2:end)];
            acceptedChild = prevChild;

        end
        
    case 'likelihood'
        
        densDiff = propChild(1,paretoCol) - lastDensFromSeq;
        
        % determine the ratio between the best and worst evaluations 
        % in the current complex (\Gamma^{\itk}):
        bestWorstDiff = bestDensFromCompl-worstDensFromCompl;
        
        
        if densDiff>=log(randUniDraw)
            
            % replace the best member of the complex with the proposed offspring
            curCompl(bestEvalRowNumber,:) = propChild;
            acceptedChild = propChild;
           
        elseif ((bestWorstDiff > log(sodaPar.thresholdL)) & (lastDensFromSeq > worstDensFromCompl))
            
            prevChild = [propChild(1,iterCol),curSeq(lastEvalFromSeq,2:end)];
            acceptedChild = prevChild;
            curCompl(worstEvalRowNumber,:) = prevChild;
            
        else

            prevChild = [propChild(1,iterCol),curSeq(lastEvalFromSeq,2:end)];
            acceptedChild = prevChild;
           
        end
        
        
        
    case 'error minimization'

        nMeasurements = sodaPar.nMeasurements;
        
        densRatio = (propChild(1,paretoCol)/lastDensFromSeq)^(-nMeasurements.*(1+sodaPar.kurt)./2);
        
        % determine the ratio between the best and worst evaluations 
        % in the current complex (\Gamma^{\itk}):
        bestWorstRatio = (bestDensFromCompl/worstDensFromCompl)^(-nMeasurements*(1+sodaPar.kurt)/2);

        if densRatio > randUniDraw

            % replace the best member of the complex with the proposed offspring
            curCompl(bestEvalRowNumber,:) = propChild;
            acceptedChild = propChild;

        elseif ((bestWorstRatio > sodaPar.thresholdL) & (lastDensFromSeq > worstDensFromCompl))

            prevChild = [propChild(1,iterCol),curSeq(lastEvalFromSeq,2:end)];
            acceptedChild = prevChild;
            curCompl(worstEvalRowNumber,:) = prevChild;

        else
            
            prevChild = [propChild(1,iterCol),curSeq(lastEvalFromSeq,2:end)];
            acceptedChild = prevChild;

        end
end



% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % % % % % % % %        LOCAL FUNCTION     % % % % % % % % % % % % % % % %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %



function rowNumber = randchoose(logiVec)

TMP = randperm(sum(logiVec));
randChoice = TMP(1);
clear TMP
for n=1:numel(logiVec)
    if logiVec(n)
        randChoice=randChoice-1;
    end
    if randChoice==0
        rowNumber = n;
        break
    end
end


