'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'

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))):
        return self
    N = es.N
    varis = ((es.sigma ** 2) * array(((N * [es.C]) if np.isscalar(es.C) else (es.C if np.isscalar(es.C[0]) else [es.C[i][i] for i in xrange(N)]))))
    dmean = ((es.mean - es.gp.geno(es.gp.into_bounds(es.gp.pheno(es.mean)))) / (varis ** 0.5))
    fvals = sorted(function_values)
    l = (1 + len(fvals))
    val = (fvals[((3 * l) // 4)] - fvals[(l // 4)])
    val = (val / np.mean(varis))
    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
    if (len(self.hist) > (20 + ((3 * N) / es.popsize))):
        self.hist.pop()
    dfit = np.median(self.hist)
    damp = min(1, ((es.sp.mueff / 10.0) / N))
    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).    '))
    if (dmean.any() and ((not self.weights_initialized) or (es.countiter == 2))):
        self.gamma = array((N * [(2 * dfit)]))
        self.weights_initialized = True
    if self.weights_initialized:
        edist = array((abs(dmean) - (3 * max(1, ((N ** 0.5) / es.sp.mueff)))))
        if (1 < 3):
            self.gamma *= (exp((((edist > 0) * np.tanh((edist / 3))) / 2.0)) ** damp)
            self.gamma[(self.gamma > (5 * dfit))] *= (exp(((-1.0) / 3)) ** damp)
        elif ((1 < 3) and (edist > 0).any()):
            self.gamma[(edist > 0)] *= (1.1 ** min(1, ((es.sp.mueff / 10.0) / N)))
        else:
            solutions = es.pop
            r = self.feasible_ratio(solutions)
            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 self
