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
@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; }