public static double getBICValue(Array2DRowRealMatrix mat) { double num = (double)0f; EigenDecomposition eigenDecomposition = new EigenDecomposition(new Covariance(mat).getCovarianceMatrix()); double[] realEigenvalues = eigenDecomposition.getRealEigenvalues(); for (int i = 0; i < realEigenvalues.Length; i++) { num += java.lang.Math.log(realEigenvalues[i]); } return(num * (double)(mat.getRowDimension() / 2)); }
/** * @param mat * A matrix with feature vectors as rows. * @return Returns the BICValue of the Gaussian model that approximates the * the feature vectors data samples */ public static double GetBICValue(Array2DRowRealMatrix mat) { double ret = 0; EigenDecomposition ed = new EigenDecomposition(new Covariance(mat).getCovarianceMatrix()); double[] re = ed.getRealEigenvalues(); for (int i = 0; i < re.Length; i++) { ret += Math.Log(re[i]); } return(ret * (mat.getRowDimension() / 2)); }
public SimpleEVD(T mat) { this.mat = mat; this.is64 = mat is DMatrixRMaj; if (is64) { eig = (EigenDecomposition <T>)DecompositionFactory_DDRM.eig(mat.getNumCols(), true); } else { eig = (EigenDecomposition <T>)DecompositionFactory_FDRM.eig(mat.getNumCols(), true); } if (!eig.decompose((T)mat)) { throw new InvalidOperationException("Eigenvalue Decomposition failed"); } }
public void ProcessData() { int N = dataSet.GetLength(0); int[,] indices = new int[N, numberOfKNN]; double[,] sortedDistances = new double[N, numberOfKNN]; for (var i = 0; i < N; i++) { double[] dataPoint = Enumerable.Range(0, dataSet.GetLength(1)).Select(x => dataSet[i, x]).ToArray(); int[] ind = NearestNeighborSearch.KnnSearch(dataSet, dataPoint, numberOfKNN).Item1; double[] sortedDist = NearestNeighborSearch.KnnSearch(dataSet, dataPoint, numberOfKNN).Item2; for (var j = 0; j < numberOfKNN; j++) { indices[i, j] = ind[j]; sortedDistances[i, j] = sortedDist[j]; } } // build ad hoc bandwidth function by autotuning epsilon for each point double[] epss = new double[401]; for (var i = 0; i < 401; i++) { epss[i] = Math.Pow(2, -30 + i * 0.1); // Will store both distance and index in here } double[] rho0 = evaluateRho0(sortedDistances, NNofKDE); // pre-kernel used with ad hoc bandwidth only for estimating dimension and sampling density double[,] dt = evaluateDt(sortedDistances, rho0, indices, numberOfKNN); // tune epsilon on the pre-kernel double[] dpreGlobal = evaluateDpreGlobal(epss, dt, numberOfKNN, N); (double maxval, int maxind) = findMaxvalMaxind(dpreGlobal, epss); double dim = 2 * maxval; // use ad hoc bandwidth function, rho0, to estimate the density for (var i = 0; i < dt.GetLength(0); i++) { for (var j = 0; j < dt.GetLength(1); j++) { dt[i, j] = Math.Exp(-dt[i, j] / (2 * epss[maxind])) / Math.Pow(2 * Math.PI * epss[maxind], (dim / 2)); } } // the matrix created here might be large, must change it to sparse format double[,] reshapedDt = reshapeDt(dt, indices, N, numberOfKNN); double[,] symmetricDt = new double[reshapedDt.GetLength(0), reshapedDt.GetLength(1)]; for (var i = 0; i < reshapedDt.GetLength(0); i++) { for (var j = 0; j < reshapedDt.GetLength(1); j++) { symmetricDt[i, j] = (reshapedDt[i, j] + reshapedDt[j, i]) / 2; } } // sampling density estimate for bandwidth function double[] qest = new double[symmetricDt.GetLength(0)]; for (var i = 0; i < symmetricDt.GetLength(0); i++) { double sum = 0; for (var j = 0; j < symmetricDt.GetLength(1); j++) { sum += reshapedDt[i, j]; } qest[i] = sum / (N * Math.Pow(rho0[i], dim)); } if (differentialOperator == 1) { beta = -0.5; alpha = -dim / 4 + 0.5; } else if (differentialOperator == 2) { beta = -0.5; alpha = -dim / 4; } double c1 = 2 - (2 * alpha) + (dim * beta) + (2 * beta); double c2 = 0.5 - (2 * alpha) + (2 * dim * alpha) + (dim * beta / 2) + beta; for (var i = 0; i < sortedDistances.GetLength(0); i++) { for (int j = 0; j < sortedDistances.GetLength(1); j++) { sortedDistances[i, j] = Math.Pow(sortedDistances[i, j], 2); } } // construct bandwidth function rho(x) from the sampling density estimate double[] rho = new double[qest.Length]; double sumRho = 0; for (var i = 0; i < qest.Length; i++) { rho[i] = Math.Pow(qest[i], beta); sumRho += rho[i]; } for (var i = 1; i < qest.Length; i++) { rho[i] = rho[i] / sumRho * rho.Length; } // construct the exponent of K^S_epsilon for (var i = 0; i < sortedDistances.GetLength(0); i++) { for (var j = 0; j < sortedDistances.GetLength(1); j++) { sortedDistances[i, j] = sortedDistances[i, j] / rho[i]; } } for (var i = 0; i < sortedDistances.GetLength(0); i++) { for (var j = 0; j < sortedDistances.GetLength(1); j++) { sortedDistances[i, j] = sortedDistances[i, j] / rho[indices[i, j]]; } } // tune epsilon for the final kernel double epsilon = evaluateFinalEpsilon(epss, sortedDistances, N, numberOfKNN); // K^S_epsilon with final choice of epsilon for (var i = 0; i < sortedDistances.GetLength(0); i++) { for (var j = 0; j < sortedDistances.GetLength(1); j++) { sortedDistances[i, j] = Math.Exp(-sortedDistances[i, j] / (4 * epsilon)); } } // the matrix created here might be large, must change it to sparse format double[,] reshapedSortedDistances = reshapeDt(sortedDistances, indices, N, numberOfKNN); double[,] symmetricSortedDistances = new double[reshapedSortedDistances.GetLength(0), reshapedSortedDistances.GetLength(1)]; for (var i = 0; i < reshapedSortedDistances.GetLength(0); i++) { for (var j = 0; j < reshapedSortedDistances.GetLength(1); j++) { symmetricSortedDistances[i, j] = (reshapedSortedDistances[i, j] + reshapedSortedDistances[j, i]) / 2; } } double temp; // q^S_epsilon (this is the sampling density estimate q(x) obtained from the VB kernel) for (var i = 0; i < symmetricSortedDistances.GetLength(0); i++) { temp = 0; for (var j = 0; j < symmetricSortedDistances.GetLength(1); j++) { temp += symmetricSortedDistances[i, j]; } qest[i] = temp / Math.Pow(rho[i], dim); } double[,] Dinv1 = new double[N, N]; for (var i = 0; i < N; i++) { Dinv1[i, i] = Math.Pow(qest[i], -alpha); } double[,] DtimesDinv = new double[N, N]; DtimesDinv = Accord.Math.Matrix.Dot(symmetricSortedDistances, Dinv1); double[,] newD = new double[N, N]; newD = Accord.Math.Matrix.Dot(Dinv1, DtimesDinv); double[,] Sinv = new double[N, N]; double temp2; for (var i = 0; i < N; i++) { temp2 = 0; for (var j = 0; j < N; j++) { temp2 += newD[i, j]; } Sinv[i, i] = Math.Pow(Math.Pow(rho[i], 2) * temp2, -0.5); } double[,] newDtimesSinv = new double[N, N]; newDtimesSinv = Accord.Math.Matrix.Dot(newD, Sinv); double[,] finalD = new double[N, N]; finalD = Accord.Math.Matrix.Dot(Sinv, newDtimesSinv); for (var i = 0; i < N; i++) { finalD[i, i] = finalD[i, i] - Math.Pow(rho[i], -2) + 1; } double[] DMAPEigVals; double[,] DMAPEigVecs; bool sort = true; bool inPlace = false; bool scaled = true; (DMAPEigVals, DMAPEigVecs) = EigenDecomposition.FindEigenValuesAndEigenvectorsSymmetricOnly(finalD, numberOfEigenvectors, inPlace, sort, scaled); for (var i = 0; i < numberOfEigenvectors; i++) { DMAPEigVals[i] = Math.Log(DMAPEigVals[i]) / epsilon; } DMAPEigVecs = Accord.Math.Matrix.Dot(Sinv, DMAPEigVecs); // normalize qest into a density for (var i = 0; i < N; i++) { qest[i] = qest[i] / (N * Math.Pow(4 * Math.PI * epsilon, dim / 2)); } // constuct the invariant measure of the system double[] peq = new double[N]; for (var i = 0; i < N; i++) { peq[i] = qest[i] * Math.Pow(Sinv[i, i], -2); } double normalizationFactor = 0; for (var i = 0; i < N; i++) { normalizationFactor += peq[i] / qest[i] / N; } // normalize the invariant measure for (var i = 0; i < N; i++) { peq[i] = peq[i] / normalizationFactor; } //normalize eigenfunctions such that: \sum_i psi(x_i)^2 p(x_i)/q(x_i) = 1 double[] EigVec_i = new double[N]; double[] tempVector = new double[N]; double meanTempVector = 0; for (var i = 0; i < numberOfEigenvectors; i++) { EigVec_i = Enumerable.Range(0, DMAPEigVecs.GetLength(0)).Select(x => DMAPEigVecs[x, i]).ToArray(); for (var j = 0; j < N; j++) { tempVector[j] = Math.Pow(EigVec_i[j], 2) * (peq[j] / qest[j]); } meanTempVector = FindMeanOfVector(tempVector); for (var j = 0; j < N; j++) { DMAPEigVecs[j, i] = DMAPEigVecs[j, i] / Math.Sqrt(meanTempVector); } } DMAPeigenvalues = DMAPEigVals; DMAPeigenvectors = DMAPEigVecs; }
/** Revises the CMA-ES distribution to reflect the current fitness results in the provided subpopulation. */ public void UpdateDistribution(IEvolutionState state, Subpopulation subpop) { // % Sort by fitness and compute weighted mean into xmean // [arfitness, arindex] = sort(arfitness); % minimization // xmean = arx(:,arindex(1:mu))*weights; % recombination % Eq.39 // counteval += lambda; // only need partial sort? ((List <Individual>)subpop.Individuals).Sort(); SimpleMatrixD artmp = new SimpleMatrixD(GenomeSize, mu); SimpleMatrixD xold = xmean; xmean = new SimpleMatrixD(GenomeSize, 1); for (int i = 0; i < mu; i++) { DoubleVectorIndividual dvind = (DoubleVectorIndividual)subpop.Individuals[i]; // won't modify the genome SimpleMatrixD arz = new SimpleMatrixD(GenomeSize, 1, true, dvind.genome); arz = (arz.minus(xold).divide(sigma)); for (int j = 0; j < GenomeSize; j++) { xmean.set(j, 0, xmean.get(j, 0) + weights[i] * dvind.genome[j]); artmp.set(j, i, arz.get(j, 0)); } } // % Cumulation: Update evolution paths SimpleMatrixD y = xmean.minus(xold).divide(sigma); SimpleMatrixD bz = invsqrtC.mult(y); SimpleMatrixD bz_scaled = bz.scale(Math.Sqrt(cs * (2.0 - cs) * mueff)); ps = ps.scale(1.0 - cs).plus(bz_scaled); double h_sigma_value = ((ps.dot(ps) / (1.0 - Math.Pow(1.0 - cs, 2.0 * (state.Generation + 1)))) / GenomeSize); int hsig = (h_sigma_value < (2.0 + (4.0 / (GenomeSize + 1)))) ? 1 : 0; SimpleMatrixD y_scaled = y.scale(hsig * Math.Sqrt(cc * (2.0 - cc) * mueff)); pc = pc.scale(1.0 - cc).plus(y_scaled); // % Adapt covariance matrix C c = c.scale(1.0 - c1 - cmu); c = c.plus(pc.mult(pc.transpose()).plus(c.scale((1.0 - hsig) * cc * (2.0 - cc))).scale(c1)); c = c.plus((artmp.mult(SimpleMatrixD.diag(weights).mult(artmp.transpose()))).scale(cmu)); // % Adapt step-size sigma sigma = sigma * Math.Exp((cs / damps) * (ps.normF() / chiN - 1.0)); // % Update B and D from C if ((state.Generation - lastEigenDecompositionGeneration) > 1.0 / ((c1 + cmu) * GenomeSize * 10.0)) { lastEigenDecompositionGeneration = state.Generation; // make sure the matrix is symmetric (it should be already) // not sure if this is necessary for (int i = 0; i < GenomeSize; i++) { for (int j = 0; j < i; j++) { c.set(j, i, c.get(i, j)); } } // this copy gets modified by the decomposition DMatrixRMaj copy = c.copy().getMatrix(); EigenDecomposition <DMatrixRMaj> eig = DecompositionFactory_DDRM.eig(GenomeSize, true, true); if (eig.decompose(copy)) { SimpleMatrixD dinv = new SimpleMatrixD(GenomeSize, GenomeSize); for (int i = 0; i < GenomeSize; i++) { double eigrt = Math.Sqrt(eig.getEigenValue(i).real); d.set(i, i, eigrt); dinv.set(i, i, 1 / eigrt); CommonOps_DDRM.insert(eig.getEigenVector(i), b.getMatrix(), 0, i); } invsqrtC = b.mult(dinv.mult(b.transpose())); CommonOps_DDRM.mult(b.getMatrix(), d.getMatrix(), bd); } else { state.Output.Fatal("CMA-ES eigendecomposition failed. "); } } CommonOps_DDRM.scale(sigma, bd, sbd); // % Break, if fitness is good enough or condition exceeds 1e14, better termination methods are advisable // if arfitness(1) <= stopfitness || max(D) > 1e7 * min(D) // break; // end if (useAltTermination && CommonOps_DDRM.elementMax(d.diag().getMatrix()) > 1e7 * CommonOps_DDRM.elementMin(d.diag().getMatrix())) { state.Evaluator.SetRunCompleted("CMAESSpecies: Stopped because matrix condition exceeded limit."); } }
public override void Setup(IEvolutionState state, IParameter paramBase) { base.Setup(state, paramBase); IMersenneTwister random = state.Random[0]; IParameter def = DefaultBase; IParameter subpopBase = paramBase.Pop(); IParameter subpopDefaultBase = ECDefaults.ParamBase.Push(Subpopulation.P_SUBPOPULATION); if (!state.Parameters.ParameterExists(paramBase.Push(P_SIGMA), def.Push(P_SIGMA))) { state.Output.Message("CMA-ES sigma was not provided, defaulting to 1.0"); sigma = 1.0; } else { sigma = state.Parameters.GetDouble(paramBase.Push(P_SIGMA), def.Push(P_SIGMA), 0.0); if (sigma <= 0) { state.Output.Fatal("If CMA-ES sigma is provided, it must be > 0.0", paramBase.Push(P_SIGMA), def.Push(P_SIGMA)); } } double[] cvals = new double[GenomeSize]; string covarianceInitialization = state.Parameters.GetStringWithDefault(paramBase.Push(P_COVARIANCE), def.Push(P_COVARIANCE), V_IDENTITY); string covs = "Initial Covariance: <"; for (int i = 0; i < GenomeSize; i++) { if (i > 0) { covs += ", "; } if (covarianceInitialization.Equals(V_SCALED)) { cvals[i] = (MaxGenes[i] - MinGenes[i]); } else if (covarianceInitialization.Equals(V_IDENTITY)) { cvals[i] = 1.0; } else { state.Output.Fatal("Invalid covariance initialization type " + covarianceInitialization, paramBase.Push(P_COVARIANCE), def.Push(P_COVARIANCE)); } // cvals is standard deviations, so we change them to variances now cvals[i] *= cvals[i]; covs += cvals[i]; } state.Output.Message(covs + ">"); // set myself up and define my initial distribution here int n = GenomeSize; b = SimpleMatrixD.identity(n); c = new SimpleMatrixD(CommonOps_DDRM.diag(cvals)); d = SimpleMatrixD.identity(n); bd = CommonOps_DDRM.identity(n, n); sbd = CommonOps_DDRM.identity(n, n); invsqrtC = SimpleMatrixD.identity(n); // Here we do one FIRST round of eigendecomposition, because newIndividual needs // a valid version of sbd. If c is initially the identity matrix (and sigma = 1), // then sbd is too, and we're done. But if c is scaled in any way, we need to compute // the proper value of sbd. Along the way we'll wind up computing b, d, bd, and invsqrtC EigenDecomposition <DMatrixRMaj> eig = DecompositionFactory_DDRM.eig(GenomeSize, true, true); if (eig.decompose(c.copy().getMatrix())) { SimpleMatrixD dinv = new SimpleMatrixD(GenomeSize, GenomeSize); for (int i = 0; i < GenomeSize; i++) { double eigrt = Math.Sqrt(eig.getEigenValue(i).real); d.set(i, i, eigrt); dinv.set(i, i, 1 / eigrt); CommonOps_DDRM.insert(eig.getEigenVector(i), b.getMatrix(), 0, i); } invsqrtC = b.mult(dinv.mult(b.transpose())); CommonOps_DDRM.mult(b.getMatrix(), d.getMatrix(), bd); } else { state.Output.Fatal("CMA-ES eigendecomposition failed. "); } CommonOps_DDRM.scale(sigma, bd, sbd); // End FIRST round of eigendecomposition // Initialize dynamic (internal) strategy parameters and constants pc = new SimpleMatrixD(n, 1); ps = new SimpleMatrixD(n, 1); // evolution paths for C and sigma chiN = Math.Sqrt(n) * (1.0 - 1.0 / (4.0 * n) + 1.0 / (21.0 * n * n)); // expectation of ||N(0,I)|| == norm(randn(N,1)) xmean = new SimpleMatrixD(GenomeSize, 1); bool meanSpecified = false; string val = state.Parameters.GetString(paramBase.Push(P_MEAN), def.Push(P_MEAN)); if (val != null) { meanSpecified = true; if (val.Equals(V_CENTER)) { for (int i = 0; i < GenomeSize; i++) { xmean.set(i, 0, (MaxGenes[i] + MinGenes[i]) / 2.0); } } else if (val.Equals(V_ZERO)) { for (int i = 0; i < GenomeSize; i++) { xmean.set(i, 0, 0); // it is this anyway } } else if (val.Equals(V_RANDOM)) { for (int i = 0; i < GenomeSize; i++) { xmean.set(i, 0, state.Random[0].NextDouble(true, true) * (MaxGenes[i] - MinGenes[i]) + MinGenes[i]); } } else { state.Output.Fatal("Unknown mean value specified: " + val, paramBase.Push(P_MEAN), def.Push(P_MEAN)); } } else { state.Output.Fatal("No default mean value specified. Loading full mean from parameters.", paramBase.Push(P_MEAN), def.Push(P_MEAN)); } bool nonDefaultMeanSpecified = false; for (int i = 0; i < GenomeSize; i++) { double m_i = 0; try { m_i = state.Parameters.GetDouble(paramBase.Push(P_MEAN).Push("" + i), def.Push(P_MEAN).Push("" + i)); xmean.set(i, 0, m_i); nonDefaultMeanSpecified = true; } catch (FormatException e) { if (!meanSpecified) { state.Output.Error( "No default mean value was specified, but CMA-ES mean index " + i + " is missing or not a number.", paramBase.Push(P_MEAN).Push("" + i), def.Push(P_MEAN).Push("" + i)); } } } state.Output.ExitIfErrors(); if (nonDefaultMeanSpecified && meanSpecified) { state.Output.Warning("A default mean value was specified, but certain mean values were overridden."); } string mes = "Initial Mean: <"; for (int i = 0; i < GenomeSize - 1; i++) { mes = mes + xmean.get(i, 0) + ", "; } mes = mes + xmean.get(GenomeSize - 1, 0) + ">"; state.Output.Message(mes); if (!state.Parameters.ParameterExists(paramBase.Push(P_LAMBDA), def.Push(P_LAMBDA))) { lambda = 4 + (int)Math.Floor(3 * Math.Log(n)); } else { lambda = state.Parameters.GetInt(paramBase.Push(P_LAMBDA), def.Push(P_LAMBDA), 1); if (lambda <= 0) { state.Output.Fatal("If the CMA-ES lambda parameter is provided, it must be a valid integer > 0", paramBase.Push(P_LAMBDA), def.Push(P_LAMBDA)); } } if (!state.Parameters.ParameterExists(paramBase.Push(P_MU), def.Push(P_MU))) { mu = (int)(Math.Floor(lambda / 2.0)); } else { mu = state.Parameters.GetInt(paramBase.Push(P_MU), def.Push(P_MU), 1); if (mu <= 0) { state.Output.Fatal("If the CMA-ES mu parameter is provided, it must be a valid integer > 0", paramBase.Push(P_MU), def.Push(P_MU)); } } if (mu > lambda) // uh oh { state.Output.Fatal("CMA-ES mu must be <= lambda. Presently mu=" + mu + " and lambda=" + lambda); } weights = new double[mu]; bool weightsSpecified = false; for (int i = 0; i < mu; i++) { if (state.Parameters.ParameterExists(paramBase.Push(P_WEIGHTS).Push("" + i), def.Push(P_WEIGHTS).Push("" + i))) { state.Output.Message("CMA-ES weight index " + i + " specified. Loading all weights from parameters."); weightsSpecified = true; break; } } if (weightsSpecified) { for (int i = 0; i < mu; i++) { double m_i = 0; try { weights[i] = state.Parameters.GetDouble(paramBase.Push(P_WEIGHTS).Push("" + i), def.Push(P_WEIGHTS).Push("" + i)); } catch (FormatException e) { state.Output.Error("CMA-ES weight index " + i + " missing or not a number.", paramBase.Push(P_WEIGHTS).Push("" + i), def.Push(P_WEIGHTS).Push("" + i)); } } state.Output.ExitIfErrors(); } else { for (int i = 0; i < mu; i++) { weights[i] = Math.Log((lambda + 1.0) / (2.0 * (i + 1))); } } // normalize double sum = 0.0; for (int i = 0; i < mu; i++) { sum += weights[i]; } for (int i = 0; i < mu; i++) { weights[i] /= sum; } // compute mueff double sumSqr = 0.0; for (int i = 0; i < mu; i++) { sumSqr += weights[i] * weights[i]; } mueff = 1.0 / sumSqr; mes = "Weights: <"; for (int i = 0; i < weights.Length - 1; i++) { mes = mes + weights[i] + ", "; } mes = mes + (weights.Length - 1) + ">"; state.Output.Message(mes); useAltTermination = state.Parameters.GetBoolean(paramBase.Push(P_ALTERNATIVE_TERMINATION), def.Push(P_ALTERNATIVE_TERMINATION), false); useAltGenerator = state.Parameters.GetBoolean(paramBase.Push(P_ALTERNATIVE_GENERATOR), def.Push(P_ALTERNATIVE_GENERATOR), false); altGeneratorTries = state.Parameters.GetIntWithDefault(paramBase.Push(P_ALTERNATIVE_GENERATOR_TRIES), def.Push(P_ALTERNATIVE_GENERATOR_TRIES), DEFAULT_ALT_GENERATOR_TRIES); if (altGeneratorTries < 1) { state.Output.Fatal( "If specified (the default is " + DEFAULT_ALT_GENERATOR_TRIES + "), alt-generation-tries must be >= 1", paramBase.Push(P_ALTERNATIVE_GENERATOR_TRIES), def.Push(P_ALTERNATIVE_GENERATOR_TRIES)); } if (!state.Parameters.ParameterExists(paramBase.Push(P_CC), def.Push(P_CC))) { cc = (4.0 + mueff / n) / (n + 4.0 + 2.0 * mueff / n); // time constant for cumulation for C } else { cc = state.Parameters.GetDoubleWithMax(paramBase.Push(P_CC), def.Push(P_CC), 0.0, 1.0); if (cc < 0.0) { state.Output.Fatal( "If the CMA-ES cc parameter is provided, it must be a valid number in the range [0,1]", paramBase.Push(P_CC), def.Push(P_CC)); } } if (!state.Parameters.ParameterExists(paramBase.Push(P_CS), def.Push(P_CS))) { cs = (mueff + 2.0) / (n + mueff + 5.0); // t-const for cumulation for sigma control } else { cs = state.Parameters.GetDoubleWithMax(paramBase.Push(P_CS), def.Push(P_CS), 0.0, 1.0); if (cs < 0.0) { state.Output.Fatal( "If the CMA-ES cs parameter is provided, it must be a valid number in the range [0,1]", paramBase.Push(P_CS), def.Push(P_CS)); } } if (!state.Parameters.ParameterExists(paramBase.Push(P_C1), def.Push(P_C1))) { c1 = 2.0 / ((n + 1.3) * (n + 1.3) + mueff); // learning rate for rank-one update of C } else { c1 = state.Parameters.GetDouble(paramBase.Push(P_C1), def.Push(P_C1), 0.0); if (c1 < 0) { state.Output.Fatal("If the CMA-ES c1 parameter is provided, it must be a valid number >= 0.0", paramBase.Push(P_C1), def.Push(P_C1)); } } if (!state.Parameters.ParameterExists(paramBase.Push(P_CMU), def.Push(P_CMU))) { cmu = Math.Min(1.0 - c1, 2.0 * (mueff - 2.0 + 1.0 / mueff) / ((n + 2.0) * (n + 2.0) + mueff)); } else { cmu = state.Parameters.GetDouble(paramBase.Push(P_CMU), def.Push(P_CMU), 0.0); if (cmu < 0) { state.Output.Fatal("If the CMA-ES cmu parameter is provided, it must be a valid number >= 0.0", paramBase.Push(P_CMU), def.Push(P_CMU)); } } if (c1 > (1 - cmu)) // uh oh { state.Output.Fatal("CMA-ES c1 must be <= 1 - cmu. You are using c1=" + c1 + " and cmu=" + cmu); } if (cmu > (1 - c1)) // uh oh { state.Output.Fatal("CMA-ES cmu must be <= 1 - c1. You are using cmu=" + cmu + " and c1=" + c1); } if (!state.Parameters.ParameterExists(paramBase.Push(P_DAMPS), def.Push(P_DAMPS))) { damps = 1.0 + 2.0 * Math.Max(0.0, Math.Sqrt((mueff - 1.0) / (n + 1.0)) - 1.0) + cs; // damping for sigma } else { damps = state.Parameters.GetDouble(paramBase.Push(P_DAMPS), def.Push(P_DAMPS), 0.0); if (damps <= 0) { state.Output.Fatal("If the CMA-ES damps parameter is provided, it must be a valid number > 0.0", paramBase.Push(P_DAMPS), def.Push(P_DAMPS)); } } double damps_min = 0.5; double damps_max = 2.0; if (damps > damps_max || damps < damps_min) { state.Output.Warning("CMA-ES damps ought to be close to 1. You are using damps = " + damps); } state.Output.Message("lambda: " + lambda); state.Output.Message("mu: " + mu); state.Output.Message("mueff: " + mueff); state.Output.Message("cmu: " + cmu); state.Output.Message("c1: " + c1); state.Output.Message("cc: " + cc); state.Output.Message("cs: " + cs); state.Output.Message("damps: " + damps); }