Example #1
0
        public void OptimizersTest()
        {
            //("Testing optimizers...");

            setup();

            // Loop over problems (currently there is only 1 problem)
            for (int i=0; i<costFunctions_.Count; ++i) {
                Problem problem = new Problem(costFunctions_[i], constraints_[i], initialValues_[i]);
                Vector initialValues = problem.currentValue();
                // Loop over optimizers
                for (int j = 0; j < (optimizationMethods_[i]).Count; ++j) {
                    double rootEpsilon = endCriterias_[i].rootEpsilon();
                    int endCriteriaTests = 1;
                   // Loop over rootEpsilon
                    for(int k=0; k<endCriteriaTests; ++k) {
                        problem.setCurrentValue(initialValues);
                        EndCriteria endCriteria = new EndCriteria(endCriterias_[i].maxIterations(),
                                                                  endCriterias_[i].maxStationaryStateIterations(),
                                                                  rootEpsilon,
                                                                  endCriterias_[i].functionEpsilon(),
                                                                  endCriterias_[i].gradientNormEpsilon());
                        rootEpsilon *= .1;
                        EndCriteria.Type endCriteriaResult =
                            optimizationMethods_[i][j].optimizationMethod.minimize(problem, endCriteria);
                        Vector xMinCalculated = problem.currentValue();
                        Vector yMinCalculated = problem.values(xMinCalculated);
                        // Check optimization results vs known solution
                        if (endCriteriaResult==EndCriteria.Type.None ||
                            endCriteriaResult==EndCriteria.Type.MaxIterations ||
                            endCriteriaResult==EndCriteria.Type.Unknown)
                            Assert.Fail("function evaluations: " + problem.functionEvaluation()  +
                                      " gradient evaluations: " + problem.gradientEvaluation() +
                                      " x expected:           " + xMinExpected_[i] +
                                      " x calculated:         " + xMinCalculated +
                                      " x difference:         " + (xMinExpected_[i]- xMinCalculated) +
                                      " rootEpsilon:          " + endCriteria.rootEpsilon() +
                                      " y expected:           " + yMinExpected_[i] +
                                      " y calculated:         " + yMinCalculated +
                                      " y difference:         " + (yMinExpected_[i]- yMinCalculated) +
                                      " functionEpsilon:      " + endCriteria.functionEpsilon() +
                                      " endCriteriaResult:    " + endCriteriaResult);
                    }
                }
            }
        }
Example #2
0
        public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria)
        {
            // set up of the problem
            //double ftol = endCriteria.functionEpsilon();    // end criteria on f(x) (see Numerical Recipes in C++, p.410)
            double xtol = endCriteria.rootEpsilon(); // end criteria on x (see GSL v. 1.9, http://www.gnu.org/software/gsl/)
            int    maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations();

            EndCriteria.Type ecType = EndCriteria.Type.None;
            P.reset();
            Vector x_ = P.currentValue();
            int    iterationNumber_ = 0;

            // Initialize vertices of the simplex
            bool end = false;
            int  n   = x_.Count;

            vertices_ = new InitializedList <Vector>(n + 1, x_);
            for (int i = 0; i < n; i++)
            {
                Vector direction = new Vector(n, 0.0);
                Vector vertice   = vertices_[i + 1];
                direction[i] = 1.0;
                P.constraint().update(ref vertice, direction, lambda_);
                vertices_[i + 1] = vertice;
            }
            // Initialize function values at the vertices of the simplex
            values_ = new Vector(n + 1, 0.0);
            for (int i = 0; i <= n; i++)
            {
                values_[i] = P.value(vertices_[i]);
            }
            // Loop looking for minimum
            do
            {
                sum_ = new Vector(n, 0.0);
                for (int i = 0; i <= n; i++)
                {
                    sum_ += vertices_[i];
                }
                // Determine the best (iLowest), worst (iHighest)
                // and 2nd worst (iNextHighest) vertices
                int iLowest = 0;
                int iHighest;
                int iNextHighest;
                if (values_[0] < values_[1])
                {
                    iHighest     = 1;
                    iNextHighest = 0;
                }
                else
                {
                    iHighest     = 0;
                    iNextHighest = 1;
                }
                for (int i = 1; i <= n; i++)
                {
                    if (values_[i] > values_[iHighest])
                    {
                        iNextHighest = iHighest;
                        iHighest     = i;
                    }
                    else
                    {
                        if ((values_[i] > values_[iNextHighest]) && i != iHighest)
                        {
                            iNextHighest = i;
                        }
                    }
                    if (values_[i] < values_[iLowest])
                    {
                        iLowest = i;
                    }
                }
                // Now compute accuracy, update iteration number and check end criteria
                //// Numerical Recipes exit strategy on fx (see NR in C++, p.410)
                //double low = values_[iLowest];
                //double high = values_[iHighest];
                //double rtol = 2.0*std::fabs(high - low)/
                //    (std::fabs(high) + std::fabs(low) + QL_EPSILON);
                //++iterationNumber_;
                //if (rtol < ftol ||
                //    endCriteria.checkMaxIterations(iterationNumber_, ecType)) {
                // GSL exit strategy on x (see GSL v. 1.9, http://www.gnu.org/software/gsl
                double simplexSize = Utils.computeSimplexSize(vertices_);
                ++iterationNumber_;
                if (simplexSize < xtol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType))
                {
                    endCriteria.checkStationaryPoint(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType);
                    endCriteria.checkMaxIterations(iterationNumber_, ref ecType);
                    x_ = vertices_[iLowest];
                    double low = values_[iLowest];
                    P.setFunctionValue(low);
                    P.setCurrentValue(x_);
                    return(ecType);
                }
                // If end criteria is not met, continue
                double factor = -1.0;
                double vTry   = extrapolate(ref P, iHighest, ref factor);
                if ((vTry <= values_[iLowest]) && (factor == -1.0))
                {
                    factor = 2.0;
                    extrapolate(ref P, iHighest, ref factor);
                }
                else if (Math.Abs(factor) > Const.QL_EPSILON)
                {
                    if (vTry >= values_[iNextHighest])
                    {
                        double vSave = values_[iHighest];
                        factor = 0.5;
                        vTry   = extrapolate(ref P, iHighest, ref factor);
                        if (vTry >= vSave && Math.Abs(factor) > Const.QL_EPSILON)
                        {
                            for (int i = 0; i <= n; i++)
                            {
                                if (i != iLowest)
                                {
#if QL_ARRAY_EXPRESSIONS
                                    vertices_[i] = 0.5 * (vertices_[i] + vertices_[iLowest]);
#else
                                    vertices_[i] += vertices_[iLowest];
                                    vertices_[i] *= 0.5;
#endif
                                    values_[i] = P.value(vertices_[i]);
                                }
                            }
                        }
                    }
                }
                // If can't extrapolate given the constraints, exit
                if (Math.Abs(factor) <= Const.QL_EPSILON)
                {
                    x_ = vertices_[iLowest];
                    double low = values_[iLowest];
                    P.setFunctionValue(low);
                    P.setCurrentValue(x_);
                    return(EndCriteria.Type.StationaryFunctionValue);
                }
            } while (end == false);
            throw new Exception("optimization failed: unexpected behaviour");
        }
Example #3
0
File: Simplex.cs Project: vdt/QLNet
        public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria)
        {
            // set up of the problem
            //double ftol = endCriteria.functionEpsilon();    // end criteria on f(x) (see Numerical Recipes in C++, p.410)
            double xtol = endCriteria.rootEpsilon(); // end criteria on x (see GSL v. 1.9, http://www.gnu.org/software/gsl/)
            int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations();
            EndCriteria.Type ecType = EndCriteria.Type.None;
            P.reset();
            Vector x_ = P.currentValue();
            int iterationNumber_ = 0;

            // Initialize vertices of the simplex
            bool end = false;
            int n = x_.Count;
            vertices_ = new InitializedList<Vector>(n + 1, x_);
            for (int i = 0; i < n; i++)
            {
                Vector direction = new Vector(n, 0.0);
                direction[i] = 1.0;
                P.constraint().update(vertices_[i + 1], direction, lambda_);
            }
            // Initialize function values at the vertices of the simplex
            values_ = new Vector(n + 1, 0.0);
            for (int i = 0; i <= n; i++)
                values_[i] = P.value(vertices_[i]);
            // Loop looking for minimum
            do
            {
                sum_ = new Vector(n, 0.0);
                for (int i = 0; i <= n; i++)
                    sum_ += vertices_[i];
                // Determine the best (iLowest), worst (iHighest)
                // and 2nd worst (iNextHighest) vertices
                int iLowest = 0;
                int iHighest;
                int iNextHighest;
                if (values_[0] < values_[1])
                {
                    iHighest = 1;
                    iNextHighest = 0;
                }
                else
                {
                    iHighest = 0;
                    iNextHighest = 1;
                }
                for (int i = 1; i <= n; i++)
                {
                    if (values_[i] > values_[iHighest])
                    {
                        iNextHighest = iHighest;
                        iHighest = i;
                    }
                    else
                    {
                        if ((values_[i] > values_[iNextHighest]) && i != iHighest)
                            iNextHighest = i;
                    }
                    if (values_[i] < values_[iLowest])
                        iLowest = i;
                }
                // Now compute accuracy, update iteration number and check end criteria
                //// Numerical Recipes exit strategy on fx (see NR in C++, p.410)
                //double low = values_[iLowest];
                //double high = values_[iHighest];
                //double rtol = 2.0*std::fabs(high - low)/
                //    (std::fabs(high) + std::fabs(low) + QL_EPSILON);
                //++iterationNumber_;
                //if (rtol < ftol ||
                //    endCriteria.checkMaxIterations(iterationNumber_, ecType)) {
                // GSL exit strategy on x (see GSL v. 1.9, http://www.gnu.org/software/gsl
                double simplexSize = Utils.computeSimplexSize(vertices_);
                ++iterationNumber_;
                if (simplexSize < xtol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType))
                {
                    endCriteria.checkStationaryPoint(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType);
                    endCriteria.checkMaxIterations(iterationNumber_, ref ecType);
                    x_ = vertices_[iLowest];
                    double low = values_[iLowest];
                    P.setFunctionValue(low);
                    P.setCurrentValue(x_);
                    return ecType;
                }
                // If end criteria is not met, continue
                double factor = -1.0;
                double vTry = extrapolate(ref P, iHighest, ref factor);
                if ((vTry <= values_[iLowest]) && (factor == -1.0))
                {
                    factor = 2.0;
                    extrapolate(ref P, iHighest, ref factor);
                }
                else if (Math.Abs(factor) > Const.QL_Epsilon)
                {
                    if (vTry >= values_[iNextHighest])
                    {
                        double vSave = values_[iHighest];
                        factor = 0.5;
                        vTry = extrapolate(ref P, iHighest, ref factor);
                        if (vTry >= vSave && Math.Abs(factor) > Const.QL_Epsilon)
                        {
                            for (int i = 0; i <= n; i++)
                            {
                                if (i != iLowest)
                                {
            #if QL_ARRAY_EXPRESSIONS
                                    vertices_[i] = 0.5 * (vertices_[i] + vertices_[iLowest]);
            #else
                                    vertices_[i] += vertices_[iLowest];
                                    vertices_[i] *= 0.5;
            #endif
                                    values_[i] = P.value(vertices_[i]);
                                }
                            }
                        }
                    }
                }
                // If can't extrapolate given the constraints, exit
                if (Math.Abs(factor) <= Const.QL_Epsilon)
                {
                    x_ = vertices_[iLowest];
                    double low = values_[iLowest];
                    P.setFunctionValue(low);
                    P.setCurrentValue(x_);
                    return EndCriteria.Type.StationaryFunctionValue;
                }
            } while (end == false);
            throw new ApplicationException("optimization failed: unexpected behaviour");
        }