private double[] mutate(CMAParamSet params, double[] x, double[][] range, int count) { int dim = range.length; if (!Mathematics.isInRange(params.meanX, range)) { // TODO Im not sure why this can happen... System.err.println("Error in MutateESRankMuCMA.mutate !"); Mathematics.projectToRange(params.meanX, range); } // System.out.println("--- In mutate!"); if (params != null && (params.firstAdaptionDone)) { double[] sampl = new double[dim]; // generate scaled random vector (D * z) for (int i = 0; i < dim; ++i) { sampl[i] = Math.sqrt(params.eigenvalues[i]) * RNG.gaussianDouble(1.); if (Double.isNaN(sampl[i])) sampl[i] = 0; } // System.out.println("Sampling around " + BeanInspector.toString(meanX)); /* add mutation (sigma * B * (D*z)) */ addMutationStep(params, x, sampl); int cnt = 0; while (!Mathematics.isInRange(x, range)) { // % You may handle constraints here. You may either resample // % arz(:,k) and/or multiply it with a factor between -1 and 1 // % (the latter will decrease the overall step size) and // % recalculate arx accordingly. Do not change arx or arz in any // % other way. // multiply sampl by a no in [-1,1] and try again double r; // actually we use [-1,-0.5] or [0.5, 1] cnt++; if (cnt > 10 * x.length) { // well... lets give it up. Probably the meanX is close to the bounds in several // dimensions // which is unlikely to be solved by random sampling. // if (!Mathematics.isInRange(params.meanX, range)) { // System.err.println("Error in MutateESRankMuCMA.mutate !"); break; // } r = 0; } else { r = RNG.randomDouble(-0.5, 0.5); if (Math.abs(r) < 0.5) r += Math.signum(r) * 0.5; // r is in [-1,-0.5] or [0.5,1] } // System.out.println("Reducing step by " + r + " for " + // BeanInspector.toString(params.meanX)); Mathematics.svMult(r, sampl, sampl); addMutationStep(params, x, sampl); } } else { if (params == null) { System.err.println( "Error in MutateESRankMuCMA: parameter set was null! Skipping mutation..."); } // no valid meanX yet, so just do a gaussian jump with sigma for (int i = 0; i < dim; ++i) { x[i] += RNG.gaussianDouble(getSigma(params, i)); checkValidDouble(x[i]); } } if (!Mathematics.isInRange(params.meanX, range)) { System.err.println("Error B in MutateESRankMuCMA.mutate !"); } if (TRACE_1) System.out.println("mutated indy: " + BeanInspector.toString(x)); return x; }
/** * To be called from Matlab giving the result of the question. * * @param y */ public void setAnswer(double[] y) { // logMPAndSysOut("Synch requesting B setAnswer " + getState()); synchronized (requesting) { // logMPAndSysOut("In Synch requesting B setAnswer " + getState()); if (!requesting) { String msg = "Error: not in requesting state when answer arrived!!"; System.err.println(msg); logMP(msg); } // System.err.println("answer is " + BeanInspector.toString(y)); if (y == null) { System.err.println("Error: Matlab function returned null array - this is bad."); System.err.println("X-value was " + BeanInspector.toString(getQuestion())); } answer = y; requesting = false; // answer is finished, break request loop logMP("-- setAnswer: " + BeanInspector.toString(y) + ", req state is " + requesting + "\n"); } // logMPAndSysOut("Synch requesting B done " + getState()); }
public String getState() { return "ID: " + runID + ", qu: " + BeanInspector.toString(question) + " quit,fin,req " + quit + "," + fin + "," + requesting; }
/** * Perform the main adaption of sigma and C using evolution paths. The evolution path is deduced * from the center of the selected population compared to the old mean value. See Hansen&Kern 04 * for further information. * * @param oldGen * @param selectedP */ public void adaptAfterSelection(Population oldGen, Population selectedP) { Population selectedSorted = selectedP.getSortedBestFirst(new AbstractEAIndividualComparator(-1)); int mu, lambda; mu = selectedP.size(); lambda = oldGen.size(); int generation = oldGen.getGeneration(); if (mu >= lambda) { // try to override by oldGen additional data: if (oldGen.hasData(EvolutionStrategies.esMuParam)) mu = (Integer) oldGen.getData(EvolutionStrategies.esMuParam); if (oldGen.hasData(EvolutionStrategies.esLambdaParam)) lambda = (Integer) oldGen.getData(EvolutionStrategies.esLambdaParam); } if (mu >= lambda) { mu = Math.max(1, lambda / 2); EVAERROR.errorMsgOnce( "Warning: invalid mu/lambda ratio! Setting mu to lambda/2 = " + mu + ", lambda = " + lambda); } CMAParamSet params; if (oldGen.getGeneration() <= 1) { // init new param set. At gen < 1 we shouldnt be called, but better do it once too // often if (oldGen.hasData(cmaParamsKey)) params = CMAParamSet.initCMAParams( (CMAParamSet) oldGen.getData(cmaParamsKey), mu, lambda, oldGen, getInitSigma(oldGen)); else params = CMAParamSet.initCMAParams(mu, lambda, oldGen, getInitSigma(oldGen)); } else { if (!oldGen.hasData(cmaParamsKey)) { if (oldGen.getGeneration() > 1) EVAERROR.errorMsgOnce("Error: population lost cma parameters. Incompatible optimizer?"); params = CMAParamSet.initCMAParams(mu, lambda, oldGen, getInitSigma(oldGen)); } else params = (CMAParamSet) oldGen.getData(cmaParamsKey); } if (lambda == 1 && (oldGen.size() == 1) && (selectedP.size() == 1) && (oldGen.getEAIndividual(0).equals(selectedP.getEAIndividual(0)))) { // nothing really happened, so do not adapt and just store default params lastParams = (CMAParamSet) params.clone(); oldGen.putData(cmaParamsKey, params); selectedP.putData(cmaParamsKey, params); return; } if (TRACE_1) { System.out.println("WCMA adaptGenerational **********"); // System.out.println("newPop measures: " + // BeanInspector.toString(newPop.getPopulationMeasures())); System.out.println("mu_eff: " + CMAParamSet.getMuEff(params.weights, mu)); System.out.println(params.toString()); System.out.println("*********************************"); } double[] newMeanX = calcMeanX(params.weights, selectedSorted); if (TRACE_1) System.out.println("newMeanX: " + BeanInspector.toString(newMeanX)); int dim = params.meanX.length; double[] BDz = new double[dim]; for (int i = 0; i < dim; i++) { /* calculate xmean and BDz~N(0,C) */ // Eq. 4 from HK04, most right term BDz[i] = Math.sqrt(CMAParamSet.getMuEff(params.weights, mu)) * (newMeanX[i] - params.meanX[i]) / getSigma(params, i); } // if (TRACE_2) System.out.println("BDz is " + BeanInspector.toString(BDz)); double[] newPathS = params.pathS.clone(); double[] newPathC = params.pathC.clone(); double[] zVect = new double[dim]; /* calculate z := D^(-1) * B^(-1) * BDz into artmp, we could have stored z instead */ for (int i = 0; i < dim; ++i) { double sum = 0.; for (int j = 0; j < dim; ++j) { sum += params.mB.get(j, i) * BDz[j]; // times B transposed, (Eq 4) in HK04 } if (params.eigenvalues[i] < 0) { EVAERROR.errorMsgOnce( "Warning: negative eigenvalue in MutateESRankMuCMA! (possibly multiple cases)"); zVect[i] = 0; } else { zVect[i] = sum / Math.sqrt(params.eigenvalues[i]); if (!checkValidDouble(zVect[i])) { System.err.println("Error, infinite zVect entry!"); zVect[i] = 0; // TODO MK } } } /* cumulation for sigma (ps) using B*z */ for (int i = 0; i < dim; ++i) { double sum = 0.; for (int j = 0; j < dim; ++j) sum += params.mB.get(i, j) * zVect[j]; newPathS[i] = (1. - params.c_sig) * params.pathS[i] + Math.sqrt(params.c_sig * (2. - params.c_sig)) * sum; if (!checkValidDouble(newPathS[i])) { System.err.println("Error, infinite pathS!"); } } // System.out.println("pathS diff: " + BeanInspector.toString(Mathematics.vvSub(newPathS, // pathS))); // System.out.println("newPathS is " + BeanInspector.toString(newPathS)); double psNorm = Mathematics.norm(newPathS); double hsig = 0; if (psNorm / Math.sqrt(1. - Math.pow(1. - params.c_sig, 2. * generation)) / expRandStepLen < 1.4 + 2. / (dim + 1.)) { hsig = 1; } for (int i = 0; i < dim; ++i) { newPathC[i] = (1. - getCc()) * params.pathC[i] + hsig * Math.sqrt(getCc() * (2. - getCc())) * BDz[i]; checkValidDouble(newPathC[i]); } // TODO missing: "remove momentum in ps" if (TRACE_1) { System.out.println("newPathC: " + BeanInspector.toString(newPathC)); System.out.println("newPathS: " + BeanInspector.toString(newPathS)); } if (TRACE_1) System.out.println("Bef: C is \n" + params.mC.toString()); if (params.meanX == null) params.meanX = newMeanX; updateCov(params, newPathC, newMeanX, hsig, mu, selectedSorted); updateBD(params); if (TRACE_2) System.out.println("Aft: C is " + params.mC.toString()); /* update of sigma */ double sigFact = Math.exp(((psNorm / expRandStepLen) - 1) * params.c_sig / params.d_sig); if (Double.isInfinite(sigFact)) params.sigma *= 10.; // in larger search spaces sigma tends to explode after init. else params.sigma *= sigFact; if (!testAndCorrectNumerics(params, generation, selectedSorted)) { // parameter seemingly exploded... params = CMAParamSet.initCMAParams( params, mu, lambda, params.meanX, ((InterfaceDataTypeDouble) oldGen.getEAIndividual(0)).getDoubleRange(), params.firstSigma); } if (TRACE_1) { System.out.println("sigma=" + params.sigma); System.out.print("psLen=" + (psNorm) + " "); outputParams(params, mu); } // take over data params.meanX = newMeanX; params.pathC = newPathC; params.pathS = newPathS; params.firstAdaptionDone = true; lastParams = (CMAParamSet) params.clone(); oldGen.putData(cmaParamsKey, params); selectedP.putData(cmaParamsKey, params); // if (TRACE_2) System.out.println("sampling around " + BeanInspector.toString(meanX)); }
double[] getAnswer() { logMP("-- mediator delivering " + BeanInspector.toString(answer) + "\n"); return answer; }
/** * To be called from Matlab. * * @return */ public Object getQuestion() { logMP("-- Question: " + BeanInspector.toString(question) + "\n"); return question; }