(self, function_values, es, bounds=None)
return self
updates the weights for computing a boundary penalty.

        Arguments
        ---------
        `function_values`
            all function values of recent population of solutions
        `es`
            `CMAEvolutionStrategy` object instance, in particular the
            method `into_bounds` of the attribute `gp` of type `GenoPheno`
            is used.
        `bounds`
            not (yet) in use other than for ``bounds == [None, None]`` nothing
            is updated.

        Reference: Hansen et al 2009, A Method for Handling Uncertainty...
        IEEE TEC, with addendum at http://www.lri.fr/~hansen/TEC2009online.pdf
updates the weights for computing a boundary penalty.
updates the weights for computing a boundary penalty .
def update(self, function_values, es, bounds=None):
        """updates the weights for computing a boundary penalty.

        Arguments
        ---------
        `function_values`
            all function values of recent population of solutions
        `es`
            `CMAEvolutionStrategy` object instance, in particular the
            method `into_bounds` of the attribute `gp` of type `GenoPheno`
            is used.
        `bounds`
            not (yet) in use other than for ``bounds == [None, None]`` nothing
            is updated.

        Reference: Hansen et al 2009, A Method for Handling Uncertainty...
        IEEE TEC, with addendum at http://www.lri.fr/~hansen/TEC2009online.pdf

        """
        if bounds is None:
            bounds = self.bounds
        if bounds is None or (bounds[0] is None and bounds[1] is None):  # no bounds ==> no penalty
            return self  # len(function_values) * [0.0]  # case without voilations

        N = es.N
        ### prepare
        # compute varis = sigma**2 * C_ii
        varis = es.sigma**2 * array(N * [es.C] if np.isscalar(es.C) else (  # scalar case
                                es.C if np.isscalar(es.C[0]) else  # diagonal matrix case
                                [es.C[i][i] for i in xrange(N)]))  # full matrix case

        # dmean = (es.mean - es.gp.into_bounds(es.mean)) / varis**0.5
        dmean = (es.mean - es.gp.geno(es.gp.into_bounds(es.gp.pheno(es.mean)))) / varis**0.5

        ### Store/update a history of delta fitness value
        fvals = sorted(function_values)
        l = 1 + len(fvals)
        val = fvals[3*l // 4] - fvals[l // 4] # exact interquartile range apart interpolation
        val = val / np.mean(varis)  # new: val is normalized with sigma of the same iteration
        # insert val in history
        if np.isfinite(val) and val > 0:
            self.hist.insert(0, val)
        elif val == inf and len(self.hist) > 1:
            self.hist.insert(0, max(self.hist))
        else:
            pass  # ignore 0 or nan values
        if len(self.hist) > 20 + (3*N) / es.popsize:
            self.hist.pop()

        ### prepare
        dfit = np.median(self.hist)  # median interquartile range
        damp = min(1, es.sp.mueff/10./N)

        ### set/update weights
        # Throw initialization error
        if len(self.hist) == 0:
            raise _Error('wrongful initialization, no feasible solution sampled. ' +
                'Reasons can be mistakenly set bounds (lower bound not smaller than upper bound) or a too large initial sigma0 or... ' +
                'See description of argument func in help(cma.fmin) or an example handling infeasible solutions in help(cma.CMAEvolutionStrategy). ')
        # initialize weights
        if (dmean.any() and (not self.weights_initialized or es.countiter == 2)):  # TODO
            self.gamma = array(N * [2*dfit])
            self.weights_initialized = True
        # update weights gamma
        if self.weights_initialized:
            edist = array(abs(dmean) - 3 * max(1, N**0.5/es.sp.mueff))
            if 1 < 3:  # this is better, around a factor of two
                # increase single weights possibly with a faster rate than they can decrease
                #     value unit of edst is std dev, 3==random walk of 9 steps
                self.gamma *= exp((edist>0) * np.tanh(edist/3) / 2.)**damp
                # decrease all weights up to the same level to avoid single extremely small weights
                #    use a constant factor for pseudo-keeping invariance
                self.gamma[self.gamma > 5 * dfit] *= exp(-1./3)**damp
                #     self.gamma[idx] *= exp(5*dfit/self.gamma[idx] - 1)**(damp/3)
            elif 1 < 3 and (edist>0).any():  # previous method
                # CAVE: min was max in TEC 2009
                self.gamma[edist>0] *= 1.1**min(1, es.sp.mueff/10./N)
                # max fails on cigtab(N=12,bounds=[0.1,None]):
                # self.gamma[edist>0] *= 1.1**max(1, es.sp.mueff/10./N) # this was a bug!?
                # self.gamma *= exp((edist>0) * np.tanh(edist))**min(1, es.sp.mueff/10./N)
            else:  # alternative version, but not better
                solutions = es.pop  # this has not been checked
                r = self.feasible_ratio(solutions)  # has to be the averaged over N iterations
                self.gamma *= exp(np.max([N*[0], 0.3 - r], axis=0))**min(1, es.sp.mueff/10/N)
        es.more_to_write += list(self.gamma) if self.weights_initialized else N * [1.0]
        ### return penalty
        # es.more_to_write = self.gamma if not np.isscalar(self.gamma) else N*[1]
        return self
def update ( self , function_values , es , bounds = None ) : if bounds is None : bounds = self . bounds if bounds is None or ( bounds [ 0 ] is None and bounds [ 1 ] is None ) : # no bounds ==> no penalty return self # len(function_values) * [0.0]  # case without voilations N = es . N ### prepare # compute varis = sigma**2 * C_ii varis = es . sigma ** 2 * array ( N * [ es . C ] if np . isscalar ( es . C ) else ( # scalar case es . C if np . isscalar ( es . C [ 0 ] ) else # diagonal matrix case [ es . C [ i ] [ i ] for i in xrange ( N ) ] ) ) # full matrix case # dmean = (es.mean - es.gp.into_bounds(es.mean)) / varis**0.5 dmean = ( es . mean - es . gp . geno ( es . gp . into_bounds ( es . gp . pheno ( es . mean ) ) ) ) / varis ** 0.5 ### Store/update a history of delta fitness value fvals = sorted ( function_values ) l = 1 + len ( fvals ) val = fvals [ 3 * l // 4 ] - fvals [ l // 4 ] # exact interquartile range apart interpolation val = val / np . mean ( varis ) # new: val is normalized with sigma of the same iteration # insert val in history if np . isfinite ( val ) and val > 0 : self . hist . insert ( 0 , val ) elif val == inf and len ( self . hist ) > 1 : self . hist . insert ( 0 , max ( self . hist ) ) else : pass # ignore 0 or nan values if len ( self . hist ) > 20 + ( 3 * N ) / es . popsize : self . hist . pop ( ) ### prepare dfit = np . median ( self . hist ) # median interquartile range damp = min ( 1 , es . sp . mueff / 10. / N ) ### set/update weights # Throw initialization error if len ( self . hist ) == 0 : raise _Error ( 'wrongful initialization, no feasible solution sampled. ' + 'Reasons can be mistakenly set bounds (lower bound not smaller than upper bound) or a too large initial sigma0 or... ' + 'See description of argument func in help(cma.fmin) or an example handling infeasible solutions in help(cma.CMAEvolutionStrategy). ' ) # initialize weights if ( dmean . any ( ) and ( not self . weights_initialized or es . countiter == 2 ) ) : # TODO self . gamma = array ( N * [ 2 * dfit ] ) self . weights_initialized = True # update weights gamma if self . weights_initialized : edist = array ( abs ( dmean ) - 3 * max ( 1 , N ** 0.5 / es . sp . mueff ) ) if 1 < 3 : # this is better, around a factor of two # increase single weights possibly with a faster rate than they can decrease #     value unit of edst is std dev, 3==random walk of 9 steps self . gamma *= exp ( ( edist > 0 ) * np . tanh ( edist / 3 ) / 2. ) ** damp # decrease all weights up to the same level to avoid single extremely small weights #    use a constant factor for pseudo-keeping invariance self . gamma [ self . gamma > 5 * dfit ] *= exp ( - 1. / 3 ) ** damp #     self.gamma[idx] *= exp(5*dfit/self.gamma[idx] - 1)**(damp/3) elif 1 < 3 and ( edist > 0 ) . any ( ) : # previous method # CAVE: min was max in TEC 2009 self . gamma [ edist > 0 ] *= 1.1 ** min ( 1 , es . sp . mueff / 10. / N ) # max fails on cigtab(N=12,bounds=[0.1,None]): # self.gamma[edist>0] *= 1.1**max(1, es.sp.mueff/10./N) # this was a bug!? # self.gamma *= exp((edist>0) * np.tanh(edist))**min(1, es.sp.mueff/10./N) else : # alternative version, but not better solutions = es . pop # this has not been checked r = self . feasible_ratio ( solutions ) # has to be the averaged over N iterations self . gamma *= exp ( np . max ( [ N * [ 0 ] , 0.3 - r ] , axis = 0 ) ) ** min ( 1 , es . sp . mueff / 10 / N ) es . more_to_write += list ( self . gamma ) if self . weights_initialized else N * [ 1.0 ] ### return penalty # es.more_to_write = self.gamma if not np.isscalar(self.gamma) else N*[1] return self