예제 #1
0
        public void RectangularMatrixAccess()
        {
            // create a matrix via outer product
            ColumnVector      cv = new ColumnVector(new double[] { 1, 2 });
            RowVector         rv = new RowVector(new double[] { 3, 4, 5 });
            RectangularMatrix M  = cv * rv;

            // check dimensions
            Assert.IsTrue(M.RowCount == cv.Dimension);
            Assert.IsTrue(M.ColumnCount == rv.Dimension);

            // check values
            for (int r = 0; r < M.RowCount; r++)
            {
                for (int c = 0; c < M.ColumnCount; c++)
                {
                    Assert.IsTrue(M[r, c] == cv[r] * rv[c]);
                }
            }

            // extract a column
            ColumnVector mc = M.Column(1);

            Assert.IsTrue(mc.Dimension == M.RowCount);
            for (int i = 0; i < mc.Dimension; i++)
            {
                Assert.IsTrue(mc[i] == M[i, 1]);
            }

            // extract a row
            RowVector mr = M.Row(1);

            Assert.IsTrue(mr.Dimension == M.ColumnCount);
            for (int i = 0; i < mr.Dimension; i++)
            {
                Assert.IsTrue(mr[i] == M[1, i]);
            }

            // test clone
            RectangularMatrix MC = M.Copy();

            Assert.IsTrue(MC.RowCount == M.RowCount);
            Assert.IsTrue(MC.ColumnCount == M.ColumnCount);

            // test equality of clone
            Assert.IsTrue(MC == M);
            Assert.IsFalse(MC != M);

            // test independence of clone
            MC[0, 0] += 1.0;
            Assert.IsFalse(MC == M);
            Assert.IsTrue(MC != M);
        }
예제 #2
0
        /// <summary>
        /// Generates a resource consumption pattern matrix
        /// </summary>
        /// <param name="ip">The current InputParameters object</param>
        private RectangularMatrix GenResConsPat(InputParameters ip)
        {
            bool throwAway;
            int  numThrows = 0;

            RectangularMatrix outputMatrix;

            do
            {
                throwAway    = false;
                outputMatrix = new RectangularMatrix(ip.RCP, ip.CO);

                // Flowchart 5.1(a): Generate vector X
                RowVector X = GenRandNumbers.GenStdNormalVec(ip.CO);

                // The following code is used in both 5.1(b) and 5.1(c):
                RowVector[] Y = new RowVector[ip.RCP - 1];
                RowVector[] Z = new RowVector[Y.Length];

                for (int i = 0; i < Y.Length; ++i)
                {
                    Y[i] = GenRandNumbers.GenStdNormalVec(ip.CO);
                }

                // Flowchart 5.1(b): Generate (DISP1 - 1) vectors Y
                // Then create Z vectors based on X and Y
                double COR1 =
                    GenRandNumbers.GenUniformDbl(ip.COR1LB, ip.COR1UB);
                double sqrtConstant1 = Math.Sqrt(1 - COR1 * COR1);
                for (int i = 0; i < ip.DISP1 - 1; ++i)
                {
                    Z[i] = (COR1 * X) + (sqrtConstant1 * Y[i]);
                }

                // Flowchart 5.1(c): Generate (RCP - DISP1) vectors Y
                // Then create the remaining Z vectors based on X and Y
                double COR2 =
                    GenRandNumbers.GenUniformDbl(ip.COR2LB, ip.COR2UB);
                double sqrtConstant2 = Math.Sqrt(1 - COR2 * COR2);
                for (int i = ip.DISP1 - 1; i < Z.Length; ++i)
                {
                    Z[i] = (COR2 * X) + (sqrtConstant2 * Y[i]);
                }

                // Flowchart 5.1(d):
                // Take the absolute values of X and the Z's and
                // scale both by 10.0.
                X = X.Map(x => 10.0 * Math.Abs(x));
                for (int i = 0; i < Z.Length; ++i)
                {
                    Z[i] = Z[i].Map(z => 10.0 * Math.Abs(z));
                }

                // Round X and the Z's to integers
                X = X.Map(x => Math.Ceiling(x));
                for (int i = 0; i < Z.Length; ++i)
                {
                    Z[i] = Z[i].Map(z => Math.Ceiling(z));
                }

                // Flowchart 5.1(e):
                // Now punch out values in the Z's at random to make
                // the matrix sparse
                for (int i = 0; i < Z.Length; ++i)
                {
                    Z[i] = Z[i].Map(x => ((GenRandNumbers.GenUniformDbl() < D) ? x : 0.0));
                }

                // Flowchart 5.1(f):
                // Copy X into first row of outputMatrix.
                outputMatrix.CopyRowInto(X, 0);
                // Copy the Z's into the remaining rows of outputMatrix.
                for (int i = 0; i < Z.Length; ++i)
                {
                    outputMatrix.CopyRowInto(Z[i], i + 1);
                }

                // Ensure that the first row has no zeros
                // There is a very small probability of getting a zero with
                // the Ceiling function, but given that there are a finite
                // number of double-precision floating point numbers, it
                // is not impossible to get a 0.0.
                double[] firstRow = outputMatrix.Row(0).ToArray();

                if (Array.Exists(firstRow, x => x == 0.0))
                {
                    throwAway = true;
                    break;
                }

                // Ensure that each *row* has at least one non-zero entry
                for (int i = 0; i < outputMatrix.RowCount; ++i)
                {
                    double[] nextRow = outputMatrix.Row(i).ToArray();

                    if (Array.TrueForAll(nextRow, x => x == 0.0))
                    {
                        throwAway = true;
                        break;
                    }
                }

                // Ensure that each *column* has at least one non-zero entry
                // Technically, this check is redundant, as the first row, X,
                // is not supposed to have any zero entries. But just to be
                // on the safe side...
                for (int j = 0; j < outputMatrix.ColumnCount; ++j)
                {
                    double[] nextCol = outputMatrix.Column(j).ToArray();

                    if (Array.TrueForAll(nextCol, x => x == 0.0))
                    {
                        string s = "There is a column with all zeros. " +
                                   "That should not happen since the first row is " +
                                   "supposed to have no zeros.";
                        throw new ApplicationException(s);
                    }
                }

                if (throwAway)
                {
                    ++numThrows;
                }
            } while (throwAway);

            Console.WriteLine("RES_CONS_PAT: {0} Throw aways\n", numThrows);

            return(outputMatrix);
        }
예제 #3
0
        private void Solve(int iteration, ref CMAState cmaState, ref Solution solution, bool isOnce = false)
        {
            //ColumnVector xmean = new ColumnVector(parameters);

            double tolX = this.StandardDeviationToleranceMultiple * this.InitialVarianceEstimate;

            int stopeval = this.StopEvals;

            RectangularMatrix arx       = new RectangularMatrix(cmaState.p.N, cmaState.p.Lambda);
            ColumnVector      arfitness = new ColumnVector(cmaState.p.Lambda);

            bool isRestart    = false;
            bool isGoodEnough = false;
            int  counteval    = 0;

            while (counteval < stopeval)
            {
                // Generate and evaluate lambda offspring
                for (int k = 0; k < cmaState.p.Lambda; k++)
                {
                    double[] sample = cmaState.Sample(arx.Column(k));
                    for (int r = 0; r < cmaState.p.N; r++)
                    {
                        arx[r, k] = sample[r];
                    }

                    arfitness[k] = this.ObjectiveFunction(arx.Column(k).ToArray(), this.UserData);

                    counteval++;
                }

                // Sort by fitness and compute weighted mean into xmean
                // minimization
                int[] arindex;
                arfitness = Utilities.Sort(arfitness, out arindex);                 // one based index

                int mu = cmaState.p.Mu;
                cmaState.ReEstimate(
                    (RectangularMatrix)Utilities.GetColumns(arx, arindex.Take(cmaState.p.Mu)),
                    arfitness.First(),
                    arfitness.SkipWhile((f, i) => i < (mu - 1)).First());

                cmaState.UpdateEigenSystem(1, 0);


                if ((solution.StopReason == StopReason.NotSet) || (arfitness[0] < solution.MinimizedFitness))
                {
                    solution.StopReason       = StopReason.Incomplete;
                    solution.MinimizedFitness = arfitness[0];
                    solution.BestCMAState     = cmaState;
                    solution.BestNumEvals     = counteval;
                    solution.BestNumRestarts  = iteration;
                    solution.BestParameters   = cmaState.mean.ToArray();
                }

                if (arfitness[0] <= this.StopFitnessMinimization)
                {
                    isGoodEnough = true;
                    break;
                }

                if (IsRestart(ref solution, arfitness, tolX, cmaState))
                {
                    isRestart = true;
                    break;
                }

                if (isOnce)
                {
                    break;
                }
            }

            if ((isRestart) && (iteration > this.MaxRestarts))
            {
                solution.StopReason = StopReason.MaxRestarts;
            }
            else if ((isRestart) && ((cmaState.p.Lambda * this.RestartPopulationMultiple) > MAX_POPULATIONSIZE))
            {
                solution.StopReason = StopReason.MaxPopulation;
            }
            else if (isRestart)
            {
                solution.History    = new Queue <double>();
                solution.StopReason = StopReason.Restart;
                int previousLambda = cmaState.p.Lambda;
                cmaState = new CMAState(_initialCmaParams, new ColumnVector(this.InitialParameters), this.InitialVarianceEstimate);
                cmaState.p.UpdateLambda((int)(previousLambda * this.RestartPopulationMultiple));
            }
            else if (isGoodEnough)
            {
                solution.StopReason = StopReason.GoodEnough;
            }
            else
            {
                solution.StopReason = StopReason.MaxIterations;
            }

            solution.LatestCMAState    = cmaState;
            solution.LatestNumEvals    = counteval;
            solution.LatestNumRestarts = iteration;
            solution.LatestParameters  = cmaState.mean.ToArray();
        }
예제 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="pop"></param>
        /// <param name="muBest"></param>
        /// <param name="muWorst"></param>
        public void ReEstimate(RectangularMatrix pop, double muBest, double muWorst)
        {
            if (pop.ColumnCount != p.Mu)
            {
                throw new ApplicationException("");
            }

            int n = p.N;

            fitnessHistory[gen % fitnessHistory.Count()] = muBest;             // needed for divergence check

            ColumnVector oldmean = new ColumnVector(mean.Dimension);

            for (int i = 0; i < mean.Dimension; i++)
            {
                oldmean[i] = mean [i];
            }

            double[] BDz = new double[n];             // valarray<double>

            /* calculate xmean and rgBDz~N(0,C) */
            for (int i = 0; i < n; ++i)
            {
                mean[i] = 0.0;

                for (int j = 0; j < pop.ColumnCount; ++j)
                {
                    mean[i] += p.Weights[j] * (pop.Column(j))[i];
                }

                BDz[i] = Math.Sqrt(p.MuEff) * (mean[i] - oldmean[i]) / sigma;
            }

            ColumnVector tmp = new ColumnVector(n);             // [vector<double>]

            /* calculate z := D^(-1) * B^(-1) * rgBDz into rgdTmp */
            for (int i = 0; i < n; ++i)
            {
                double sum = 0.0;

                for (int j = 0; j < n; ++j)
                {
                    sum += B[j, i] * BDz[j];
                }

                tmp[i] = sum / d[i];
            }

            /* cumulation for sigma (ps) using B*z */
            for (int i = 0; i < n; ++i)
            {
                double sum = 0.0;

                for (int j = 0; j < n; ++j)
                {
                    sum += B[i, j] * tmp[j];
                }

                ps[i] = (1.0 - p.CCumSig) * ps[i] + Math.Sqrt(p.CCumSig * (2.0 - p.CCumSig)) * sum;
            }

            /* calculate norm(ps)^2 */
            double psxps = ps.Sum(x => x * x);

            double chiN = Math.Sqrt((double)p.N) * (1.0 - 1.0 / (4.0 * p.N) + 1.0 / (21.0 * p.N * p.N));

            /* cumulation for covariance matrix (pc) using B*D*z~N(0,C) */
            bool   isHsig = Math.Sqrt(psxps) / Math.Sqrt(1.0 - Math.Pow(1.0 - p.CCumSig, 2.0 * gen)) / chiN < 1.5 + 1.0 / (p.N - 0.5);
            double hsig   = (isHsig) ? 1.0 : 0.0;

            //pc = (1.0 - p.ccumcov) * pc + hsig * Math.Sqrt(p.ccumcov * (2.0 - p.ccumcov)) * BDz;
            pc = pc.Select(x => x * (1.0 - p.CCumCov)).Zip(BDz.Select(x => x * Math.Sqrt(p.CCumCov * (2.0 - p.CCumCov)) * hsig), (lhs, rhs) => lhs + rhs).ToArray();

            /* stop initial phase (MK, this was not reachable in the org code, deleted) */
            /* remove momentum in ps, if ps is large and fitness is getting worse */

            if (gen >= fitnessHistory.Count())
            {
                // find direction from muBest and muWorst (muBest == muWorst handled seperately
                double direction = (muBest < muWorst) ? -1.0 : 1.0;

                int now      = gen % fitnessHistory.Count();
                int prev     = (gen - 1) % fitnessHistory.Count();
                int prevprev = (gen - 2) % fitnessHistory.Count();

                bool fitnessWorsens = (muBest == muWorst) ||                 // <- increase norm also when population has converged (this deviates from Hansen's scheme)
                                      ((direction * fitnessHistory[now] < direction * fitnessHistory[prev])
                                       &&
                                       (direction * fitnessHistory[now] < direction * fitnessHistory[prevprev]));

                if (psxps / p.N > 1.5 + 10.0 * Math.Sqrt(2.0 / p.N) && fitnessWorsens)
                {
                    double tfac = Math.Sqrt((1 + Math.Max(0.0, Math.Log(psxps / p.N))) * p.N / psxps);
                    ps     = ps.Select(x => x * tfac).ToArray();
                    psxps *= tfac * tfac;
                }
            }

            /* update of C  */
            /* Adapt_C(t); not used anymore */
            if (p.CCov != 0.0)
            {
                //flgEigensysIsUptodate = 0;

                /* update covariance matrix */
                for (int i = 0; i < n; ++i)
                {
                    for (int j = 0; j <= i; ++j)
                    {
                        C[i, j] =
                            (1 - p.CCov) * C[i, j]
                            +
                            p.CCov * (1.0 / p.MuCov) * pc[i] * pc[j]
                            +
                            (1 - hsig) * p.CCumCov * (2.0 - p.CCumCov) * C[i, j];

                        /*C[i][j] = (1 - p.ccov) * C[i][j]
                         + sp.ccov * (1./sp.mucov)
                         * (rgpc[i] * rgpc[j]
                         + (1-hsig)*sp.ccumcov*(2.-sp.ccumcov) * C[i][j]); */
                        for (int k = 0; k < p.Mu; ++k)
                        {
                            /* additional rank mu update */
                            C[i, j] += p.CCov * (1 - 1.0 / p.MuCov) * p.Weights[k]
                                       * ((pop.Column(k))[i] - oldmean[i])
                                       * ((pop.Column(k))[j] - oldmean[j])
                                       / sigma / sigma;

                            // * (rgrgx[index[k]][i] - rgxold[i])
                            // * (rgrgx[index[k]][j] - rgxold[j])
                            // / sigma / sigma;
                        }
                    }
                }
            }

            /* update of sigma */
            sigma *= Math.Exp(((Math.Sqrt(psxps) / chiN) - 1.0) / p.Damp);
            /* calculate eigensystem, must be done by caller  */
            //cmaes_UpdateEigensystem(0);


            /* treat minimal standard deviations and numeric problems
             * Note that in contrast with the original code, some numerical issues are treated *before* we
             * go into the eigenvalue calculation */

            treatNumericalIssues(muBest, muWorst);

            gen++;             // increase generation
        }