Skip to content

Parallel evaluation inefficiency #1

@zymbuzz

Description

@zymbuzz

% non-parallel evaluation and remaining NaN-values

Hi, thanks for this great procedure. I would like to note that the parallel evaluation slows down considerably if the function is evaluated as Nan. I would like to suggest a work-around that could be improved on.

        if flgEvalParallel
            qqqqq=find(isnan(fitness.raw));
            tries100=1;
            % fitness.raw(k) = NaN;
            tries = flgEvalParallel;  % in parallel case this is the first re-trial
            % Resample, until fitness is not NaN
            while ~isempty(qqqqq)
                Nnanssss=length(qqqqq);
                Nminattemps=36;
                Nnanreplics=floor(Nminattemps/Nnanssss);
                if Nnanreplics>1
                    qqqqqrepelem=repelem(qqqqq,1,Nnanreplics);
                else
                    qqqqqrepelem=qqqqq;
                end
                NnanTRIES=length(qqqqqrepelem);

                arzTRIES=nan(N,NnanTRIES);
                arxTRIES=arzTRIES;
                arxvalidTRIES=arzTRIES;

                eeeee=0;
                for k=qqqqqrepelem
                    eeeee=eeeee+1;
                    if k <= lambda  % regular samples (not the re-evaluation-samples)
                        arzTRIES(:,eeeee) = randn(N,1); % (re)sample

                        if flgDiagonalOnly
                            arxTRIES(:,eeeee) = xmean + sigma * diagD .* arzTRIES(:,eeeee);              % Eq. (1)
                        else
                            arxTRIES(:,eeeee) = xmean + sigma * (BD * arzTRIES(:,eeeee));                % Eq. (1)
                        end
                    else % re-evaluation solution with index > lambda
                        if flgDiagonalOnly
                            arxTRIES(:,eeeee) = arx(:,k-lambda) + (noiseEpsilon * sigma) * diagD .* randn(N,1);
                        else
                            arxTRIES(:,eeeee) = arx(:,k-lambda) + (noiseEpsilon * sigma) * (BD * randn(N,1));
                        end
                    end

                    % You may handle constraints here. You may either resample
                    % arz(:,k) and/or multiply it with a factor between -1 and 1
                    % (the latter will decrease the overall step size) and
                    % recalculate arx accordingly. Do not change arx or arz in any
                    % other way.

                    if ~bnd.isactive
                        arxvalidTRIES(:,eeeee) = arxTRIES(:,eeeee);
                    else
                        arxvalidTRIES(:,eeeee) = xintobounds(arxTRIES(:,eeeee), lbounds, ubounds);
                    end
                end
                fitnessrawTRIES = feval(fitfun, arxvalidTRIES, varargin{:});
                tries = tries + length(qqqqqrepelem);

                idTRIES=~isnan(fitnessrawTRIES);
                fitnessrawTRIES=fitnessrawTRIES(idTRIES);
                qqqqqrepelem=qqqqqrepelem(idTRIES);
                arzTRIES=arzTRIES(:,idTRIES);
                arxTRIES=arxTRIES(:,idTRIES);
                arxvalidTRIES=arxvalidTRIES(:,idTRIES);

                for k=qqqqq
                    idlalala= find(qqqqqrepelem==k,1,'first');
                    if ~isempty(idlalala)
                        arz(:,k)=arzTRIES(:,idlalala);
                        arx(:,k)=arxTRIES(:,idlalala);
                        arxvalid(:,k)=arxvalidTRIES(:,idlalala);
                        fitness.raw(k)=fitnessrawTRIES(idlalala);
                    end
                end

                qqqqq2=find(isnan(fitness.raw));
                if ~isempty(qqqqq2)
                    countevalNaN = countevalNaN + length(qqqqq2);
                    counteval = counteval + length(qqqqq) - length(qqqqq2); % retries due to NaN are not counted
                end
                if floor(tries/100) == tries100
                    warning([num2str(tries) ...
                        ' NaN objective function values at evaluation ' ...
                        num2str(counteval)]);
                end
                tries100=ceil(tries/100);
                qqqqq=qqqqq2;
            end
        else
            for k=find(isnan(fitness.raw)),
                % fitness.raw(k) = NaN;
                tries = flgEvalParallel;  % in parallel case this is the first re-trial
                % Resample, until fitness is not NaN
                while isnan(fitness.raw(k))
                    if k <= lambda  % regular samples (not the re-evaluation-samples)
                        arz(:,k) = randn(N,1); % (re)sample

                        if flgDiagonalOnly
                            arx(:,k) = xmean + sigma * diagD .* arz(:,k);              % Eq. (1)
                        else
                            arx(:,k) = xmean + sigma * (BD * arz(:,k));                % Eq. (1)
                        end
                    else % re-evaluation solution with index > lambda
                        if flgDiagonalOnly
                            arx(:,k) = arx(:,k-lambda) + (noiseEpsilon * sigma) * diagD .* randn(N,1);
                        else
                            arx(:,k) = arx(:,k-lambda) + (noiseEpsilon * sigma) * (BD * randn(N,1));
                        end
                    end

                    % You may handle constraints here. You may either resample
                    % arz(:,k) and/or multiply it with a factor between -1 and 1
                    % (the latter will decrease the overall step size) and
                    % recalculate arx accordingly. Do not change arx or arz in any
                    % other way.

                    if ~bnd.isactive
                        arxvalid(:,k) = arx(:,k);
                    else
                        arxvalid(:,k) = xintobounds(arx(:,k), lbounds, ubounds);
                    end
                    % You may handle constraints here.  You may copy and alter
                    % (columns of) arxvalid(:,k) only for the evaluation of the
                    % fitness function. arx should not be changed.
                    fitness.raw(k) = feval(fitfun, arxvalid(:,k), varargin{:});
                    tries = tries + 1;
                    if isnan(fitness.raw(k))
                        countevalNaN = countevalNaN + 1;
                    end
                    if mod(tries, 100) == 0
                        warning([num2str(tries) ...
                            ' NaN objective function values at evaluation ' ...
                            num2str(counteval)]);
                    end
                end
                counteval = counteval + 1; % retries due to NaN are not counted
            end
        end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions