/** * <p> * Performs a matrix inversion operation that does not modify the original * and stores the results in another matrix. The two matrices must have the * same dimension.<br> * <br> * B = A<sup>-1</sup> * </p> * * <p> * If the algorithm could not invert the matrix then false is returned. If it returns true * that just means the algorithm finished. The results could still be bad * because the matrix is singular or nearly singular. * </p> * * <p> * For medium to large matrices there might be a slight performance boost to using * {@link LinearSolverFactory_DSCC} instead. * </p> * * @param A (Input) The matrix that is to be inverted. Not modified. * @param inverse (Output) Where the inverse matrix is stored. Modified. * @return true if it could invert the matrix false if it could not. */ public static bool invert(DMatrixSparseCSC A, DMatrixRMaj inverse) { if (A.numRows != A.numCols) { throw new ArgumentException("A must be a square matrix"); } if (A.numRows != inverse.numRows || A.numCols != inverse.numCols) { throw new ArgumentException("A and inverse must have the same shape."); } LinearSolverSparse <DMatrixSparseCSC, DMatrixRMaj> solver; solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE); // Ensure that the input isn't modified if (solver.modifiesA()) { A = (DMatrixSparseCSC)A.copy(); } DMatrixRMaj I = CommonOps_DDRM.identity(A.numRows); // decompose then solve the matrix if (!solver.setA(A)) { return(false); } solver.solve(I, inverse); return(true); }
public void run() { DMatrixRMaj priorX = new DMatrixRMaj(9, 1, true, 0.5, -0.2, 0, 0, 0.2, -0.9, 0, 0.2, -0.5); DMatrixRMaj priorP = CommonOps_DDRM.identity(9); DMatrixRMaj trueX = new DMatrixRMaj(9, 1, true, 0, 0, 0, 0.2, 0.2, 0.2, 0.5, 0.1, 0.6); List <DMatrixRMaj> meas = createSimulatedMeas(trueX); DMatrixRMaj F = createF(T); DMatrixRMaj Q = createQ(T, 0.1); DMatrixRMaj H = createH(); foreach (KalmanFilter f in filters) { long timeBefore = DateTimeHelper.CurrentTimeMilliseconds; f.configure(F, Q, H); for (int trial = 0; trial < NUM_TRIALS; trial++) { f.setState(priorX, priorP); processMeas(f, meas); } long timeAfter = DateTimeHelper.CurrentTimeMilliseconds; Console.WriteLine("Filter = " + f.GetType().Name); Console.WriteLine("Elapsed time: " + (timeAfter - timeBefore)); //System.gc(); GC.Collect(); GC.WaitForPendingFinalizers(); } }
/** * Returns the Q matrix. */ public DMatrixRMaj getQ() { DMatrixRMaj Q = CommonOps_DDRM.identity(QR.numRows); DMatrixRMaj Q_k = new DMatrixRMaj(QR.numRows, QR.numRows); DMatrixRMaj u = new DMatrixRMaj(QR.numRows, 1); DMatrixRMaj temp = new DMatrixRMaj(QR.numRows, QR.numRows); int N = Math.Min(QR.numCols, QR.numRows); // compute Q by first extracting the householder vectors from the columns of QR and then applying it to Q for (int j = N - 1; j >= 0; j--) { CommonOps_DDRM.extract(QR, j, QR.numRows, j, j + 1, u, j, 0); u.set(j, 1.0); // A = (I - γ*u*u<sup>T</sup>)*A<br> CommonOps_DDRM.setIdentity(Q_k); CommonOps_DDRM.multAddTransB(-gammas[j], u, u, Q_k); CommonOps_DDRM.mult(Q_k, Q, temp); Q.set(temp); } return(Q); }
public static DMatrixRMaj ensureIdentity(DMatrixRMaj A, int numRows, int numCols) { if (A == null) { return(CommonOps_DDRM.identity(numRows, numCols)); } A.reshape(numRows, numCols); CommonOps_DDRM.setIdentity(A); return(A); }
private void processMeas(KalmanFilter f, List <DMatrixRMaj> meas) { DMatrixRMaj R = CommonOps_DDRM.identity(measDOF); foreach (DMatrixRMaj z in meas) { f.predict(); f.update(z, R); } }
/** * Computes the Q matrix from the information stored in the QR matrix. This * operation requires about 4(m<sup>2</sup>n-mn<sup>2</sup>+n<sup>3</sup>/3) flops. * * @param Q The orthogonal Q matrix. */ //@Override public DMatrixRMaj getQ(DMatrixRMaj Q, bool compact) { if (compact) { if (Q == null) { Q = CommonOps_DDRM.identity(numRows, minLength); } else { if (Q.numRows != numRows || Q.numCols != minLength) { throw new ArgumentException("Unexpected matrix dimension."); } else { CommonOps_DDRM.setIdentity(Q); } } } else { if (Q == null) { Q = CommonOps_DDRM.identity(numRows); } else { if (Q.numRows != numRows || Q.numCols != numRows) { throw new ArgumentException("Unexpected matrix dimension."); } else { CommonOps_DDRM.setIdentity(Q); } } } // Unlike applyQ() this takes advantage of zeros in the identity matrix // by not multiplying across all rows. for (int j = minLength - 1; j >= 0; j--) { int diagIndex = j * numRows + j; double before = QR.data[diagIndex]; QR.data[diagIndex] = 1; QrHelperFunctions_DDRM.rank1UpdateMultR(Q, QR.data, j * numRows, gammas[j], j, j, numRows, v); QR.data[diagIndex] = before; } return(Q); }
/** * <p> * Creates a reflector from the provided vector and gamma.<br> * <br> * Q = I - γ u u<sup>T</sup><br> * </p> * * <p> * In practice {@link VectorVectorMult_DDRM#householder(double, DMatrixD1, DMatrixD1, DMatrixD1)} multHouseholder} * should be used for performance reasons since there is no need to calculate Q explicitly. * </p> * * @param u A vector. Not modified. * @param gamma To produce a reflector gamma needs to be equal to 2/||u||. * @return An orthogonal reflector. */ public static DMatrixRMaj createReflector(DMatrixRMaj u, double gamma) { if (!MatrixFeatures_DDRM.isVector(u)) { throw new ArgumentException("u must be a vector"); } DMatrixRMaj Q = CommonOps_DDRM.identity(u.getNumElements()); CommonOps_DDRM.multAddTransB(-gamma, u, u, Q); return(Q); }
/** * Computes the Q matrix from the information stored in the QR matrix. This * operation requires about 4(m<sup>2</sup>n-mn<sup>2</sup>+n<sup>3</sup>/3) flops. * * @param Q The orthogonal Q matrix. */ public override DMatrixRMaj getQ(DMatrixRMaj Q, bool compact) { if (compact) { if (Q == null) { Q = CommonOps_DDRM.identity(numRows, minLength); } else { if (Q.numRows != numRows || Q.numCols != minLength) { throw new ArgumentException("Unexpected matrix dimension."); } else { CommonOps_DDRM.setIdentity(Q); } } } else { if (Q == null) { Q = CommonOps_DDRM.identity(numRows); } else { if (Q.numRows != numRows || Q.numCols != numRows) { throw new ArgumentException("Unexpected matrix dimension."); } else { CommonOps_DDRM.setIdentity(Q); } } } for (int j = rank - 1; j >= 0; j--) { double[] u = dataQR[j]; double vv = u[j]; u[j] = 1; QrHelperFunctions_DDRM.rank1UpdateMultR(Q, u, gammas[j], j, j, numRows, v); u[j] = vv; } return(Q); }
/** * Computes the Q matrix from the imformation stored in the QR matrix. This * operation requires about 4(m<sup>2</sup>n-mn<sup>2</sup>+n<sup>3</sup>/3) flops. * * @param Q The orthogonal Q matrix. */ public virtual DMatrixRMaj getQ(DMatrixRMaj Q, bool compact) { if (compact) { if (Q == null) { Q = CommonOps_DDRM.identity(numRows, minLength); } else { if (Q.numRows != numRows || Q.numCols != minLength) { throw new ArgumentException("Unexpected matrix dimension."); } else { CommonOps_DDRM.setIdentity(Q); } } } else { if (Q == null) { Q = CommonOps_DDRM.identity(numRows); } else { if (Q.numRows != numRows || Q.numCols != numRows) { throw new ArgumentException("Unexpected matrix dimension."); } else { CommonOps_DDRM.setIdentity(Q); } } } for (int j = minLength - 1; j >= 0; j--) { u[j] = 1; for (int i = j + 1; i < numRows; i++) { u[i] = QR.get(i, j); } QrHelperFunctions_DDRM.rank1UpdateMultR(Q, u, gammas[j], j, j, numRows, v); } return(Q); }
/** * <p> * Creates a reflector from the provided vector.<br> * <br> * Q = I - γ u u<sup>T</sup><br> * γ = 2/||u||<sup>2</sup> * </p> * * <p> * In practice {@link VectorVectorMult_DDRM#householder(double, DMatrixD1, DMatrixD1, DMatrixD1)} multHouseholder} * should be used for performance reasons since there is no need to calculate Q explicitly. * </p> * * @param u A vector. Not modified. * @return An orthogonal reflector. */ public static DMatrixRMaj createReflector(DMatrix1Row u) { if (!MatrixFeatures_DDRM.isVector(u)) { throw new ArgumentException("u must be a vector"); } double norm = NormOps_DDRM.fastNormF(u); double gamma = -2.0 / (norm * norm); DMatrixRMaj Q = CommonOps_DDRM.identity(u.getNumElements()); CommonOps_DDRM.multAddTransB(gamma, u, u, Q); return(Q); }
public static DMatrixRMaj checkIdentity(DMatrixRMaj A, int numRows, int numCols) { if (A == null) { return(CommonOps_DDRM.identity(numRows, numCols)); } else if (numRows != A.numRows || numCols != A.numCols) { throw new ArgumentException("Input is not " + numRows + " x " + numCols + " matrix"); } else { CommonOps_DDRM.setIdentity(A); } return(A); }
public void checkIdentical() { KalmanFilterSimple simple = new KalmanFilterSimple(); List <KalmanFilter> all = new List <KalmanFilter>(); all.Add(new KalmanFilterOperations()); all.Add(new KalmanFilterEquation()); all.Add(simple); DMatrixRMaj priorX = new DMatrixRMaj(9, 1, true, 0.5, -0.2, 0, 0, 0.2, -0.9, 0, 0.2, -0.5); DMatrixRMaj priorP = CommonOps_DDRM.identity(9); DMatrixRMaj F = BenchmarkKalmanPerformance.createF(T); DMatrixRMaj Q = BenchmarkKalmanPerformance.createQ(T, 0.1); DMatrixRMaj H = BenchmarkKalmanPerformance.createH(); foreach (KalmanFilter f in all) { f.configure(F, Q, H); f.setState(priorX, priorP); f.predict(); } foreach (KalmanFilter f in all) { compareFilters(simple, f); } DMatrixRMaj z = new DMatrixRMaj(H.numRows, 1); DMatrixRMaj R = CommonOps_DDRM.identity(H.numRows); foreach (KalmanFilter f in all) { f.update(z, R); } foreach (KalmanFilter f in all) { compareFilters(simple, f); } }
/** * Computes the eigenvalue of the provided tridiagonal matrix. Note that only the upper portion * needs to be tridiagonal. The bottom diagonal is assumed to be the same as the top. * * @param sideLength Number of rows and columns in the input matrix. * @param diag Diagonal elements from tridiagonal matrix. Modified. * @param off Off diagonal elements from tridiagonal matrix. Modified. * @return true if it succeeds and false if it fails. */ public bool process(int sideLength, double[] diag, double[] off, double[] eigenvalues) { if (diag != null) { helper.init(diag, off, sideLength); } if (Q == null) { Q = CommonOps_DDRM.identity(helper.N); } helper.setQ(Q); this.followingScript = true; this.eigenvalues = eigenvalues; this.fastEigenvalues = false; return(_process()); }
/** * Returns the Q matrix. */ public DMatrixRMaj getQ() { Equation.Equation eq = new Equation.Equation(); DMatrixRMaj Q = CommonOps_DDRM.identity(QR.numRows); DMatrixRMaj u = new DMatrixRMaj(QR.numRows, 1); int N = Math.Min(QR.numCols, QR.numRows); eq.alias(u, "u", Q, "Q", QR, "QR", QR.numRows, "r"); // compute Q by first extracting the householder vectors from the columns of QR and then applying it to Q for (int j = N - 1; j >= 0; j--) { eq.alias(j, "j", gammas[j], "gamma"); eq.process("u(j:,0) = [1 ; QR((j+1):,j)]"); eq.process("Q=(eye(r)-gamma*u*u')*Q"); } return(Q); }
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); }