/** * <p> * Creates a matrix where all but the diagonal elements are zero. The values * of the diagonal elements are specified by the parameter 'vals'. * </p> * * <p> * To extract the diagonal elements from a matrix see {@link #diag()}. * </p> * * @see CommonOps_DDRM#diag(double...) * * @param vals The values of the diagonal elements. * @return A diagonal matrix. */ public static SimpleMatrixD diag(double[] vals) { DMatrixRMaj m = CommonOps_DDRM.diag(vals); SimpleMatrixD ret = wrap(m); return(ret); }
/** * Creates a newJava.Util.Random symmetric matrix that will have the specified real eigenvalues. * * @param num Dimension of the resulting matrix. * @param randJava.Util.Random number generator. * @param eigenvalues Set of real eigenvalues that the matrix will have. * @return AJava.Util.Random matrix with the specified eigenvalues. */ public static DMatrixRMaj symmetricWithEigenvalues(int num, Java.Util.Random rand, double[] eigenvalues) { DMatrixRMaj V = RandomMatrices_DDRM.orthogonal(num, num, rand); DMatrixRMaj D = CommonOps_DDRM.diag(eigenvalues); DMatrixRMaj temp = new DMatrixRMaj(num, num); CommonOps_DDRM.mult(V, D, temp); CommonOps_DDRM.multTransB(temp, V, D); return(D); }
/** * <p> * If a vector then a square matrix is returned if a matrix then a vector of diagonal ements is returned * </p> * * @see CommonOps_DDRM#extractDiag(DMatrixRMaj, DMatrixRMaj) * @return Diagonal elements inside a vector or a square matrix with the same diagonal elements. */ public T diag <T>() where T : SimpleMatrix <W> { T diag; if (bits() == 64) { if (MatrixFeatures_DDRM.isVector(mat)) { int N = Math.Max(mat.NumCols, mat.NumRows); diag = (T)createMatrix(N, N, mat.Type); CommonOps_DDRM.diag((DMatrixRMaj)diag.mat, N, ((DMatrixRMaj)mat).data); } else { int N = Math.Min(mat.NumCols, mat.NumRows); diag = (T)createMatrix(N, 1, mat.Type); CommonOps_DDRM.extractDiag((DMatrixRMaj)mat, (DMatrixRMaj)diag.mat); } } else { if (MatrixFeatures_DDRM.isVector(mat)) { int N = Math.Max(mat.NumCols, mat.NumRows); diag = (T)createMatrix(N, N, mat.Type); CommonOps_DDRM.diag((DMatrixRMaj)diag.mat, N, ((DMatrixRMaj)mat).data); } else { int N = Math.Min(mat.NumCols, mat.NumRows); diag = (T)createMatrix(N, 1, mat.Type); CommonOps_DDRM.extractDiag((DMatrixRMaj)mat, (DMatrixRMaj)diag.mat); } //if (MatrixFeatures_FDRM.isVector(mat)) //{ // int N = Math.Max(mat.NumCols, mat.NumRows); // diag = createMatrix(N, N, mat.Type); // CommonOps_FDRM.diag((FMatrixRMaj)diag.mat, N, ((FMatrixRMaj)mat).data); //} //else //{ // int N = Math.min(mat.NumCols, mat.NumRows); // diag = createMatrix(N, 1, mat.Type); // CommonOps_FDRM.extractDiag((FMatrixRMaj)mat, (FMatrixRMaj)diag.mat); //} } return(diag); }
/// <summary> /// If a vector then a square matrix is returned if a matrix then a vector of diagonal ements is returned. /// </summary> /// <returns>Diagonal elements inside a vector or a square matrix with the same diagonal elements.</returns> /// <see cref="CommonOps_DDRM.extractDiag(DMatrixRMaj, DMatrixRMaj)"/> public SimpleMatrixD diag() { SimpleMatrixD diag; if (MatrixFeatures_DDRM.isVector(mat)) { int N = Math.Max(mat.getNumCols(), mat.getNumRows()); diag = createMatrix(N, N); var dm = diag.getMatrix(); CommonOps_DDRM.diag(dm, N, mat.data); } else { int N = Math.Min(mat.getNumCols(), mat.getNumRows()); diag = createMatrix(N, 1); var dm = diag.getMatrix(); CommonOps_DDRM.extractDiag(mat, dm); } return(diag); }
public static SimpleMatrix <T> diag(Type type, double[] vals) { T m; if (type == typeof(DMatrixRMaj)) { m = CommonOps_DDRM.diag(vals) as T; } else { float[] f = new float[vals.Length]; for (int i = 0; i < f.Length; i++) { f[i] = (float)vals[i]; } m = CommonOps_FDRM.diag(f) as T; } SimpleMatrix <T> ret = wrap(m); return(ret); }
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); }
public virtual DMatrixRMaj getD(DMatrixRMaj D) { return(CommonOps_DDRM.diag(D, L.numCols, d)); }