def _learnStep(self):
        # Generate and evaluate lambda offspring
        arz = randn(self.numParameters, self.batchSize)
        arx = tile(self.center.reshape(self.numParameters, 1), (1, self.batchSize))\
                        + self.stepSize * dot(dot(self.B, self.D), arz)
        arfitness = zeros(self.batchSize)
        for k in range(self.batchSize):
            arfitness[k] = self._oneEvaluation(arx[:, k])

        # Sort by fitness and compute weighted mean into center
        arfitness, arindex = sorti(arfitness)  # minimization
        arz = arz[:, arindex]
        arx = arx[:, arindex]
        arzsel = arz[:, range(self.mu)]
        arxsel = arx[:, range(self.mu)]
        arxmut = arxsel - tile(self.center.reshape(self.numParameters, 1), (1, self.mu))

        zmean = dot(arzsel, self.weights)
        self.center = dot(arxsel, self.weights)

        if self.storeAllCenters:
            self._allCenters.append(self.center)

        # Cumulation: Update evolution paths
        self.stepPath = (1 - self.cumStep) * self.stepPath \
                + sqrt(self.cumStep * (2 - self.cumStep) * self.muEff) * dot(self.B, zmean)         # Eq. (4)
        hsig = norm(self.stepPath) / sqrt(1 - (1 - self.cumStep) ** (2 * self.numEvaluations / float(self.batchSize))) / self.chiN \
                    < 1.4 + 2. / (self.numParameters + 1)
        self.covPath = (1 - self.cumCov) * self.covPath + hsig * \
                sqrt(self.cumCov * (2 - self.cumCov) * self.muEff) * dot(dot(self.B, self.D), zmean) # Eq. (2)

        # Adapt covariance matrix C
        self.C = ((1 - self.covLearningRate) * self.C                    # regard old matrix   % Eq. (3)
             + self.covLearningRate * (1 / self.muCov) * (outer(self.covPath, self.covPath) # plus rank one update
                                   + (1 - hsig) * self.cumCov * (2 - self.cumCov) * self.C)
             + self.covLearningRate * (1 - 1 / self.muCov)                 # plus rank mu update
             * dot(dot(arxmut, diag(self.weights)), arxmut.T)
            )

        # Adapt step size self.stepSize
        self.stepSize *= exp((self.cumStep / self.dampings) * (norm(self.stepPath) / self.chiN - 1)) # Eq. (5)

        # Update B and D from C
        # This is O(n^3). When strategy internal CPU-time is critical, the
        # next three lines should be executed only every (alpha/covLearningRate/N)-th
        # iteration, where alpha is e.g. between 0.1 and 10
        self.C = (self.C + self.C.T) / 2 # enforce symmetry
        Ev, self.B = eig(self.C)          # eigen decomposition, B==normalized eigenvectors
        Ev = real(Ev)       # enforce real value
        self.D = diag(sqrt(Ev))      #diag(ravel(sqrt(Ev))) # D contains standard deviations now
        self.B = real(self.B)

        # convergence is reached
        if arfitness[0] == arfitness[-1] or (abs(arfitness[0] - arfitness[-1]) /
                                             (abs(arfitness[0]) + abs(arfitness[-1]))) <= self.stopPrecision:
            if self.verbose:
                print("Converged.")
            self.maxLearningSteps = self.numLearningSteps

        # or diverged, unfortunately
        if min(Ev) > 1e5:
            if self.verbose:
                print("Diverged.")
            self.maxLearningSteps = self.numLearningSteps
dataset/ETHPy150Open pybrain/pybrain/pybrain/optimization/distributionbased/cmaes.py/CMAES._learnStep/original