private void eidgendecomposition(CMAEvolutionaryAlgorithm algorithm, int N, int flgforce) { if (countCUpdatesSinceEigenupdate == 0 && flgforce < 2) { return; } if (!algorithm.getFlgDiag() && flgforce <= 0 && countCUpdatesSinceEigenupdate < 1.0 / algorithm.getCcov() / N / 5.0) { return; } if (algorithm.getFlgDiag()) { for (int i = 0; i < N; i++) { algorithm.getDiag()[i] = Math.sqrt(algorithm.getC()[i][i]); } algorithm.setCountCupdatesSinceEigenupdate(0); } else { // set B <- C for (int i = 0; i < N; i++) { for (int j = 0; j <= i; j++) { algorithm.getB()[i][j] = algorithm.getB()[j][i] = algorithm.getC()[i][j]; } } // eigendecomposition: double[] offdiag = new double[N]; tred2(N, algorithm.getB(), algorithm.getDiag(), offdiag); tql2(N, algorithm.getDiag(), offdiag, algorithm.getB()); checkEigenSystem(N, algorithm.getC(), algorithm.getDiag(), algorithm.getB()); for (int i = 0; i < N; i++) { if (algorithm.getDiag()[i] < 0.0) { if (algorithm.isDebug()) { System.err.println("ERROR - An eigenvalue has become negative."); } } algorithm.getDiag()[i] = Math.sqrt(algorithm.getDiag()[i]); } algorithm.setCountCupdatesSinceEigenupdate(0); } /* * TODO: Check if necessary */ if (StatUtils.min(algorithm.getDiag()) == 0.0) { algorithm.setAxisRatio(Double.POSITIVE_INFINITY); } else { algorithm.setAxisRatio( StatUtils.max(algorithm.getDiag()) / StatUtils.min(algorithm.getDiag())); } } // eigendecomposition
private void testAndCorrectNumerics( CMAEvolutionaryAlgorithm algorithm, int N, List<Individual> individuals) { /* * Flat fitness, Test if funtion values are identical */ /* * we should sort the individuals by fitness value */ Collections.sort(individuals, algorithm.getComparator()); if (algorithm.getGenerations() > 0) { if (individuals.get(0).getFitness() == individuals .get((int) Math.min(algorithm.getLambda() - 1, algorithm.getLambda() / 2.0 + 1) - 1) .getFitness()) { if (debug) { System.err.println( "WARNING - Flat fitness landscape, consider reformulation of fitness," + "step-size increased"); } algorithm.setSigma( algorithm.getSigma() * Math.exp((0.2 + algorithm.getCs() / algorithm.getDamps()))); } } /* * Align (renormalize) scale C and (consequently sigma) */ /* * e.g. for infinite stationary state simulations (noise handling needs to be introduces for * that) */ /* * handling needs to be introduced for that) */ double fac = 1; if (StatUtils.max(algorithm.getDiag()) < 1.0e-6) { fac = 1.0 / StatUtils.max(algorithm.getDiag()); } else if (StatUtils.min(algorithm.getDiag()) > 1.0e+4) { fac = 1.0 / StatUtils.min(algorithm.getDiag()); } if (fac != 1.0) { algorithm.setSigma(algorithm.getSigma() / fac); for (int i = 0; i < N; i++) { algorithm.getPc()[i] *= fac; algorithm.getDiag()[i] *= fac; for (int j = 0; j <= i; j++) { algorithm.getC()[i][j] *= fac * fac; } } } }
@Override public List<Individual> operate(EvolutionaryAlgorithm algorithm, List<Individual> individuals) throws OperatorException { List<Individual> new_population = new ArrayList<Individual>(individuals.size()); CMAEvolutionaryAlgorithm alg = (CMAEvolutionaryAlgorithm) algorithm; debug = algorithm.isDebug(); double[] chromosome; int N = individuals.get(0).getDimension(); countCUpdatesSinceEigenupdate = alg.getCountCupdatesSinceEigenupdate(); // latest possibility to generate B and diagD: eidgendecomposition(alg, N, 0); // ensure minimal and maximal standard deviation: double minsqrtdiagC = Math.sqrt(StatUtils.min(alg.diag(alg.getC()))); double maxsqrtdiagC = Math.sqrt(StatUtils.max(alg.diag(alg.getC()))); /* * TODO: test if it is necessary * */ for (int i = 0; i < individuals.size(); i++) { new_population.add((Individual) individuals.get(i).clone()); } if (lowerStandardDeviation != null && lowerStandardDeviation.length > 0) { for (int i = 0; i < N; i++) { double d = lowerStandardDeviation[Math.min(i, lowerStandardDeviation.length - 1)]; if (d > alg.getSigma() * minsqrtdiagC) { alg.setSigma(d / minsqrtdiagC); } } } if (upperStandardDeviation != null && upperStandardDeviation.length > 0) { for (int i = 0; i < N; i++) { double d = upperStandardDeviation[Math.min(i, upperStandardDeviation.length - 1)]; if (d < alg.getSigma() * maxsqrtdiagC) { alg.setSigma(d / maxsqrtdiagC); } } } testAndCorrectNumerics(alg, N, new_population); double[] artmp = new double[N]; /* * Sample the distribution */ for (int iNk = 0; iNk < alg.getLambda(); iNk++) { chromosome = new_population.get(iNk).getChromosomeAt(0); if (alg.getFlgDiag()) { for (int i = 0; i < N; i++) { chromosome[i] = this.checkBounds( alg, alg.getxMean()[i] + alg.getSigma() * alg.getDiag()[i] * EAFRandom.nextGaussian()); } } else { for (int i = 0; i < N; i++) { artmp[i] = alg.getDiag()[i] * EAFRandom.nextGaussian(); } /* * add mutation (sigma * B * (D*z)) */ for (int i = 0; i < N; i++) { double sum = 0.0; for (int j = 0; j < N; j++) { sum += alg.getB()[i][j] * artmp[j]; } chromosome[i] = this.checkBounds(alg, alg.getxMean()[i] + alg.getSigma() * sum); } } new_population.get(iNk).setChromosomeAt(0, chromosome); } return new_population; }