예제 #1
0
        public double GetStepLength(
            Func <double[], double> f,
            Func <double[], double>[] df,
            OptVector d,
            OptVector x0,
            double alpham)
        {
            int    maxIter = 15;
            double alphap  = 0;

            double c1 = 1E-4;
            double c2 = 0.5;

            Random rnd = new Random();

            double alphax = 1;

            double fx0 = f(x0.MinArray);
            double gx0 = OptimizationHelper.Derivative(df, x0) * d;

            double fxp = fx0;
            double gxp = gx0;

            for (int i = 1; i < maxIter; i++)
            {
                OptVector xx  = x0 + alphax * d;
                double    fxx = f(xx.MinArray);
                double    gxx = OptimizationHelper.Derivative(df, xx) * d;

                if (fxx > fx0 + c1 * alphax * gx0 ||
                    (i > 1 && fxx >= fxp))
                {
                    return(Zoom(f, df, x0, d, alphap, alphax));
                }

                if (Math.Abs(gxx) <= -c2 * gx0)
                {
                    return(alphax);
                }

                if (gxx >= 0)
                {
                    return(Zoom(f, df, x0, d, alphax, alphap));
                }

                alphap = alphax;
                fxp    = fxx;
                gxp    = gxx;

                alphax = alphax + (alpham - alphax) * 0.3;
            }

            return(alphax);
        }
예제 #2
0
        public double GetStepLength(
            Func <double[], double> f,
            OptVector d,
            OptVector x0,
            double alpham,
            int maxIter)
        {
            double alphap = 0;

            double c1 = 1E-7;
            double c2 = 0.5;

            double alphax = alpham;//rnd.NextDouble();

            double fx0 = f(x0.MinArray);
            double gx0 = new OptVector(numericalDerivative.EvaluatePartialDerivative(f, x0.MinArray, 1)) * d;

            double fxp = fx0;
            double gxp = gx0;

            for (int i = 1; i < maxIter; i++)
            {
                OptVector xx  = x0 + alphax * d;
                double    fxx = f(xx.MinArray);
                double    gxx = new OptVector(numericalDerivative.EvaluatePartialDerivative(f, xx.MinArray, 1)) * d;

                if (fxx > fx0 + c1 * alphax * gx0 ||
                    (i > 1 && fxx >= fxp))
                {
                    return(Zoom(f, x0, d, alphap, alphax, maxIter));
                }

                if (Math.Abs(gxx) <= -c2 * gx0)
                {
                    return(alphax);
                }

                if (gxx >= 0)
                {
                    return(Zoom(f, x0, d, alphax, alphap, maxIter));
                }

                alphap = alphax;
                fxp    = fxx;
                gxp    = gxx;

                double r = rnd.NextDouble();

                alphax = alphax + (alpham - alphax) * r;
            }

            return(alphax);
        }
예제 #3
0
        public double PolakRibiere(
            OptVector derivativeNew,
            OptVector derivativeOld)
        {
            double num = derivativeNew * (derivativeNew - derivativeOld);
            double den = derivativeOld * derivativeOld;

            if (den == 0.0)
            {
                return(1.0);
            }

            return(Math.Max(0, num / den));
        }
예제 #4
0
        public double GetAlpha(
            OptVector[] A,
            OptVector p,
            double num)
        {
            var denom = p * OptVector.Mult(A, p);

            if (denom == 0.0)
            {
                return(1.0);
            }

            return(num / denom);
        }
예제 #5
0
        private OptVector[] BuildMatrixA(
            List <Func <double[], double> > equalityConstraints,
            List <InequalityConstraintProperties> inequalityConstraints,
            OptVector[] lagrangianHessian,
            OptVector x)
        {
            List <OptVector> constraintDerivative = new List <OptVector>();

            for (int i = 0; i < equalityConstraints.Count; i++)
            {
                constraintDerivative.Add(new OptVector(numericalDerivative.EvaluatePartialDerivative(equalityConstraints[i], x.MinArray, 1)));
            }

            for (int i = 0; i < inequalityConstraints.Count; i++)
            {
                if (inequalityConstraints[i].IsActive)
                {
                    constraintDerivative.Add(new OptVector(numericalDerivative.EvaluatePartialDerivative(inequalityConstraints[i].Function, x.MinArray, 1)));
                }
            }

            OptVector[] bufHessian = new OptVector[lagrangianHessian.Length];

            OptVector[] modifiedLagrangian = OptVector.Sum(lagrangianHessian, epsilonNw);

            Array.Copy(modifiedLagrangian, bufHessian, lagrangianHessian.Length);

            for (int i = 0; i < bufHessian.Length; i++)
            {
                OptVector buf = new OptVector(constraintDerivative.Count);

                for (int j = 0; j < constraintDerivative.Count; j++)
                {
                    buf[j] = constraintDerivative[j][i];
                }

                bufHessian[i].Add(buf);
            }

            var lagrangianList = bufHessian.ToList();

            foreach (var item in constraintDerivative)
            {
                var res = OptVector.Add(item, new OptVector(constraintDerivative.Count, -epsilonSe));
                lagrangianList.Add(res);
            }

            return(lagrangianList.ToArray());
        }
예제 #6
0
        private bool CheckEarlyExit(
            OptVector xNew,
            OptVector xOld)
        {
            OptVector diff = xNew - xOld;

            double result = 0.0;

            foreach (var value in diff.MinArray)
            {
                result += value * value;
            }

            return(result < Precision);
        }
예제 #7
0
        public OptVector Solve(
            OptVector[] A,
            OptVector b,
            OptVector startX,
            int nIter)
        {
            OptVector[] normA = A;
            OptVector   normb = b;

            if (!OptVector.Equals(A, OptVector.Transpose(A)))
            {
                OptVector[] At = OptVector.Transpose(A);
                normA = OptVector.Mult(At, A);
                normb = OptVector.Mult(At, b);
            }

            OptVector rNew  = normb - OptVector.Mult(normA, startX);
            OptVector p     = rNew;
            OptVector x     = new OptVector(startX);
            double    r2Old = rNew * rNew;

            double alpha = 1.0;
            double beta  = 1.0;

            for (int i = 0; i < nIter; i++)
            {
                alpha = GetAlpha(normA, p, r2Old);

                x = x + alpha * p;

                rNew = rNew - alpha * OptVector.Mult(normA, p);

                double r2New = rNew * rNew;

                if (r2New < Precision)
                {
                    return(x);
                }

                beta = GetBeta(r2New, r2Old);

                p = rNew + beta * p;

                r2Old = r2New;
            }

            return(x);
        }
예제 #8
0
        private double Zoom(
            Func <double[], double> f,
            OptVector x0,
            OptVector d,
            double alphal,
            double alphah,
            int maxIter)
        {
            double c1 = 1E-7;
            double c2 = 0.5;

            double fx0 = f(x0.MinArray);
            double gx0 = new OptVector(numericalDerivative.EvaluatePartialDerivative(f, x0.MinArray, 1)) * d;

            double alphax = 0.0;

            for (int i = 0; i < maxIter; i++)
            {
                alphax = 0.5 * (alphal + alphah);
                OptVector xx  = x0 + alphax * d;
                double    fxx = f(xx.MinArray);

                OptVector xl  = x0 + alphal * d;
                double    fxl = f(xl.MinArray);

                if (fxx > fx0 + c1 * alphax * gx0 ||
                    fxx >= fxl)
                {
                    alphah = alphax;
                }
                else
                {
                    double gxx = new OptVector(numericalDerivative.EvaluatePartialDerivative(f, xx.MinArray, 1)) * d;
                    if (Math.Abs(gxx) <= -c2 * gx0)
                    {
                        return(alphax);
                    }

                    if (gxx * (alphah - alphal) >= 0.0)
                    {
                        alphah = alphal;
                    }

                    alphal = alphax;
                }
            }
            return(alphax);
        }
예제 #9
0
        private static double Zoom(
            Func <double[], double> f,
            Func <double[], double>[] df,
            OptVector x0,
            OptVector d,
            double alphal,
            double alphah)
        {
            int    maxIter = 10;
            double c1      = 1E-4;
            double c2      = 0.5;

            double fx0 = f(x0.MinArray);
            double gx0 = OptimizationHelper.Derivative(df, x0) * d;

            double alphax = 0.0;

            for (int i = 0; i < maxIter; i++)
            {
                alphax = 0.5 * (alphal + alphah);
                OptVector xx  = x0 + alphax * d;
                double    fxx = f(xx.MinArray);
                double    gxx = OptimizationHelper.Derivative(df, xx) * d;
                OptVector xl  = x0 + alphal * d;
                double    fxl = f(xl.MinArray);

                if (fxx > fx0 + c1 * alphax * gx0 ||
                    fxx >= fxl)
                {
                    alphah = alphax;
                }
                else
                {
                    if (Math.Abs(gxx) <= -c2 * gx0)
                    {
                        return(alphax);
                    }
                    if (gxx * (alphah - alphal) >= 0.0)
                    {
                        alphah = alphal;
                    }
                    alphal = alphax;
                }
            }
            return(alphax);
        }
예제 #10
0
        private List <InequalityConstraintProperties> SetInequalityLambda(
            List <InequalityConstraintProperties> inqManager,
            OptVector inqLambda)
        {
            int lambdaIndex = 0;

            for (int i = 0; i < inqManager.Count; i++)
            {
                if (inqManager[i].IsActive)
                {
                    inqManager[i].Lambda = inqLambda[lambdaIndex];
                    lambdaIndex++;
                }
            }

            return(inqManager);
        }
예제 #11
0
        private OptVector ApplyBound(
            OptVector x,
            double[] lowerBound,
            double[] upperBound)
        {
            OptVector boundx = new OptVector(x);

            if (lowerBound != null &&
                upperBound != null)
            {
                for (int i = 0; i < x.Count; i++)
                {
                    if (x[i] < lowerBound[i])
                    {
                        boundx[i] = lowerBound[i];
                    }
                    else if (x[i] > upperBound[i])
                    {
                        boundx[i] = upperBound[i];
                    }
                }
            }
            else if (lowerBound != null)
            {
                for (int i = 0; i < x.Count; i++)
                {
                    if (x[i] < lowerBound[i])
                    {
                        boundx[i] = lowerBound[i];
                    }
                }
            }
            else if (upperBound != null)
            {
                for (int i = 0; i < x.Count; i++)
                {
                    if (x[i] > upperBound[i])
                    {
                        boundx[i] = upperBound[i];
                    }
                }
            }

            return(boundx);
        }
예제 #12
0
        private OptVector CalculateDirection(
            OptVector[] A,
            OptVector b,
            OptVector x,
            OptVector lambdaEq,
            OptVector lambdaIq)
        {
            OptVector leq        = new OptVector(lambdaEq);
            OptVector liq        = new OptVector(lambdaIq);
            OptVector startValue = OptVector.Add(x, leq);

            startValue = OptVector.Add(startValue, liq);

            //startValue = new MinVector(startValue.Count);
            OptVector result = linearSolver.Solve(A, b, startValue, 1000);

            return(result);
        }
예제 #13
0
        private bool RemoveNegativeLambda(
            ref List <InequalityConstraintProperties> inequalityConstraintsProp,
            OptVector lambda)
        {
            bool removed = false;

            inequalityConstraintsProp = SetInequalityLambda(inequalityConstraintsProp, lambda);

            foreach (var item in inequalityConstraintsProp)
            {
                if (item.Lambda < 0.0 &&
                    item.IsActive)
                {
                    item.IsActive = false;
                    removed       = true;
                    break;
                }
            }
            return(removed);
        }
예제 #14
0
        static void TestFunc()
        {
            OptVector a = new OptVector(new double[] { 1, 2 });
            OptVector b = new OptVector(new double[] { 3, 4 });

            OptVector c = new OptVector(new double[] { 1, 3 });
            OptVector d = new OptVector(new double[] { 4, 7 });

            var res = OptVector.Mult(a, b);

            var res1 = OptVector.SubtractFromIdentity(res);

            var res2 = OptVector.Div(res, 2);

            OptVector[] aa = new OptVector[] { a, b };
            OptVector[] bb = new OptVector[] { c, d };

            var res3 = OptVector.Mult(res, bb);
            var res4 = OptVector.Sum(res, bb);

            var res5 = OptVector.Mult(res, c);
        }
예제 #15
0
        private double GetEqualityConstraintsViolation(
            List <Func <double[], double> > equalityConstraints,
            OptVector x)
        {
            if (equalityConstraints.Count == 0)
            {
                return(0.0);
            }

            double maxViolation = 0.0;

            foreach (var func in equalityConstraints)
            {
                double violation = Math.Abs(func(x.MinArray));
                if (violation > maxViolation)
                {
                    maxViolation = violation;
                }
            }

            return(maxViolation);
        }
예제 #16
0
        static void TestCGMethod()
        {
            MINRES   minres = new MINRES();
            CGMethod cg     = new CGMethod();

            OptVector[] A2 = new OptVector[3];
            A2[0] = new OptVector(new double[] { 2, 1, 3 });
            A2[1] = new OptVector(new double[] { 2, 6, 8 });
            A2[2] = new OptVector(new double[] { 6, 8, 18 });

            OptVector b2 = new OptVector(new double[] { 1, 3, 5 });

            var minresSol = minres.Solve(A2, b2, new OptVector(new double[3]), 50);
            var sol2      = cg.Solve(A2, b2, new OptVector(new double[3]), 50);

            OptVector[] A = new OptVector[3];
            A[0] = new OptVector(new double[] { 2, 0, 1 });
            A[1] = new OptVector(new double[] { 1, 6, 0 });
            A[2] = new OptVector(new double[] { 3, 2, 3 });

            OptVector x = new OptVector(new double[] { 2, 5, 7 });

            var sol  = cg.Solve(A, x, new OptVector(new double[3]), 50);
            var solm = minres.Solve(A, x, new OptVector(new double[3]), 50);

            OptVector[] A1 = new OptVector[3];
            A1[0] = new OptVector(new double[] { 3, 1, -6 });
            A1[1] = new OptVector(new double[] { 2, 1, -5 });
            A1[2] = new OptVector(new double[] { 6, -3, 3 });

            OptVector b1 = new OptVector(new double[] { -10, -8, 0 });

            var sol1  = cg.Solve(A1, b1, new OptVector(new double[3]), 200);
            var solm1 = minres.Solve(A1, b1, new OptVector(new double[3]), 200);

            OptVector diff  = b1 - OptVector.Mult(A1, solm1);
            OptVector diff1 = b1 - OptVector.Mult(A1, sol1);
        }
예제 #17
0
        private double[] Execute(
            Func <double[], double> f,
            List <Func <double[], double> > equalityConstraints,
            List <Func <double[], double> > inequalityConstraints,
            double[] lowerBound,
            double[] upperBound,
            double[] startValues,
            int nIter)
        {
            OptVector xOld = new OptVector(startValues);
            OptVector xNew = new OptVector(xOld);
            OptVector lastFeasibleSolution = new OptVector(xOld);

            List <Func <double[], double> > eqConstraints = new List <Func <double[], double> >();

            if (equalityConstraints != null)
            {
                eqConstraints = new List <Func <double[], double> >(equalityConstraints);
            }

            List <Func <double[], double> > inqConstraints = new List <Func <double[], double> >();

            if (inequalityConstraints != null)
            {
                inqConstraints = new List <Func <double[], double> >(inequalityConstraints);
            }

            var boundsConstraints = CreateBoundsConstraints(lowerBound, upperBound);

            OptVector lambdaEq = new OptVector(eqConstraints.Count);

            List <InequalityConstraintProperties> inequalityConstraintsProp = new List <InequalityConstraintProperties>();

            foreach (var item in inqConstraints)
            {
                inequalityConstraintsProp.Add(new InequalityConstraintProperties(false, 0.0, item, false, 0.0, false, -1));
            }

            foreach (var item in boundsConstraints)
            {
                inequalityConstraintsProp.Add(new InequalityConstraintProperties(false, 0.0, item.Function, false, 0.0, true, item.Index));
            }

            OptVector[] hessian = OptVector.GetIdentity(startValues.Length);

            int iqIndexStart = -1;

            SetInequalityActiveConstraint(xNew, ref inequalityConstraintsProp, ref iqIndexStart);

            Func <double[], double> lagrangian = BuildLagrangian(f, eqConstraints, inequalityConstraintsProp, lambdaEq.MinArray);

            double directionValue = 0.0;
            double lastMinValue   = double.MaxValue;

            double[] eqPenaltyParams = GetAndSetPenaltyParam(
                f,
                eqConstraints,
                ref inequalityConstraintsProp,
                xOld);

            for (int i = 0; i < nIter; i++)
            {
                OptVector lambdaIq = new OptVector(inequalityConstraintsProp.Where(x => x.IsActive).Select(x => x.Lambda).ToArray());

                OptVector direction = GetGradientDirection(
                    xNew,
                    eqConstraints,
                    lambdaEq,
                    inequalityConstraintsProp,
                    hessian,
                    lagrangian,
                    lambdaIq);

                OptVector directionX = ExtractX(direction, xOld);

                lambdaIq = lambdaIq + ExtractInequalityLambda(direction, xOld, lambdaEq, lambdaIq);

                if (RemoveNegativeLambda(ref inequalityConstraintsProp, lambdaIq))
                {
                    lagrangian = BuildLagrangian(f, eqConstraints, inequalityConstraintsProp, lambdaEq.MinArray);
                    continue;
                }

                directionValue = directionX * directionX;

                if (directionValue < Precision)
                {
                    inequalityConstraintsProp = SetInequalityLambda(inequalityConstraintsProp, lambdaIq);

                    SetInequalityActiveConstraint(xNew, ref inequalityConstraintsProp, ref iqIndexStart);

                    if (EarlyExit &&
                        !inequalityConstraintsProp.Any(x => !x.IsValid))
                    {
                        lastFeasibleSolution = xNew;
                        break;
                    }

                    lagrangian = BuildLagrangian(f, eqConstraints, inequalityConstraintsProp, lambdaEq.MinArray);
                }
                else
                {
                    double step = ComputeStepLength(
                        f,
                        equalityConstraints,
                        inequalityConstraintsProp,
                        directionX,
                        xOld,
                        1.0,
                        eqPenaltyParams);

                    OptVector stepValue = step * directionX;

                    xNew = xOld + stepValue;

                    OptVector gradient = xNew - xOld;

                    if (gradient.Length() == 0.0 ||
                        stepValue.Length() < 1E-10)
                    {
                        OptVector nDirection = directionX.Normalize();

                        step = ComputeStepLength(
                            f,
                            equalityConstraints,
                            inequalityConstraintsProp,
                            nDirection,
                            xOld,
                            1.0,
                            eqPenaltyParams);

                        OptVector stVal = step * nDirection;

                        if (stVal.Length() < localMinCheck)
                        {
                            stepValue = nDirection;
                            hessian   = OptVector.GetIdentity(xNew.Count);
                        }
                        else
                        {
                            stepValue = stVal;
                        }


                        xNew = xOld + stepValue;
                    }

                    if (xNew.MinArray.Contains(double.NaN))
                    {
                        xNew    = lastFeasibleSolution;
                        xOld    = xNew;
                        hessian = OptVector.GetIdentity(xNew.Count);

                        foreach (var item in inequalityConstraintsProp)
                        {
                            item.Lambda = 0.0;
                        }

                        lambdaEq = new OptVector(eqConstraints.Count);

                        eqPenaltyParams = GetAndSetPenaltyParam(
                            f,
                            eqConstraints,
                            ref inequalityConstraintsProp,
                            xNew);

                        lagrangian = BuildLagrangian(f, eqConstraints, inequalityConstraintsProp, lambdaEq.MinArray);

                        continue;
                    }

                    lambdaEq = lambdaEq + ExtractEqualityLambda(direction, xOld, lambdaEq);

                    inequalityConstraintsProp = SetInequalityLambda(inequalityConstraintsProp, lambdaIq);

                    SetInequalityActiveConstraint(xNew, ref inequalityConstraintsProp, ref iqIndexStart);

                    hessian = CalculateLagrangianHessian(lagrangian, hessian, xNew, xOld, stepValue);

                    lagrangian = BuildLagrangian(f, eqConstraints, inequalityConstraintsProp, lambdaEq.MinArray);

                    //Set penalty params
                    eqPenaltyParams = SetPenaltyEqParam(eqPenaltyParams, lambdaEq);

                    SetPenaltyIqParam(ref inequalityConstraintsProp);

                    //Penalty Parameters

                    double newEqConstraintsViolation = GetEqualityConstraintsViolation(eqConstraints, xNew);

                    double minValue = f(xNew.MinArray);

                    if (minValue < lastMinValue &&
                        !inequalityConstraintsProp.Any(x => !x.IsValid) &&
                        newEqConstraintsViolation < equalityConstraintTol)
                    {
                        lastFeasibleSolution = xNew;
                        lastMinValue         = minValue;
                    }

                    xOld = xNew;
                }
            }

            return(lastFeasibleSolution.MinArray);
        }
예제 #18
0
        private void SetInequalityActiveConstraint(
            OptVector x,
            ref List <InequalityConstraintProperties> inequalityConstraints,
            ref int iqIndexStart)
        {
            int    zeroIndex    = -1;
            int    maxIndex     = -1;
            double maxViolation = double.MinValue;

            for (int i = 0; i < inequalityConstraints.Count; i++)
            {
                double fValue = inequalityConstraints[i].Function(x.MinArray);

                inequalityConstraints[i].IsValid = (fValue > inequalityConstraintTol) ?
                                                   false :
                                                   true;
            }

            bool checkValidity = inequalityConstraints.Any(k => !k.IsValid);

            for (int i = 0; i < inequalityConstraints.Count; i++)
            {
                double fValue = inequalityConstraints[i].Function(x.MinArray);
                //Check negative lambda
                if (inequalityConstraints[i].Lambda < 0.0)
                {
                    continue;
                }
                //Check zero
                else if (Math.Abs(fValue) < 1E-15 &&
                         !checkValidity &&
                         !inequalityConstraints[i].IsActive)
                {
                    zeroIndex = i;
                }
                else if (fValue > inequalityConstraintTol &&
                         zeroIndex < 0 &&
                         fValue > maxViolation &&
                         !inequalityConstraints[i].IsActive)
                {
                    maxIndex     = i;
                    maxViolation = fValue;
                }
            }

            //Add constraint
            if (zeroIndex >= 0)
            {
                inequalityConstraints[zeroIndex].IsActive = true;
            }
            else if (maxIndex >= 0)
            {
                inequalityConstraints[maxIndex].IsActive = true;
            }
            else
            //Add constraint if all active have lambda > 0 (not feasible case)
            if (inequalityConstraints.Count(k => k.IsActive) != 0 &&
                inequalityConstraints.Count(k => k.IsActive) ==
                inequalityConstraints.Count(k => k.IsActive && k.Lambda > 0.0))
            {
                //maxIndex = GetIqNotValidIndex(inequalityConstraints);
                ActivateInqConstraint(ref inequalityConstraints, ref iqIndexStart);
            }
            else if (!inequalityConstraints.Any(k => k.IsActive) &&
                     inequalityConstraints.Any(k => !k.IsValid))
            {
                ActivateInqConstraint(ref inequalityConstraints, ref iqIndexStart);
            }
        }
예제 #19
0
        private double ComputeStepLength(
            Func <double[], double> f,
            List <Func <double[], double> > equalityConstraints,
            List <InequalityConstraintProperties> inequalityConstraints,
            OptVector direction,
            OptVector x,
            double maxStep,
            double[] eqPenaltyParams)
        {
            double stepLength = 1.0;

            double meritFunction(double[] k)
            {
                double normEq = 0.0;

                if (equalityConstraints != null)
                {
                    for (int i = 0; i < equalityConstraints.Count; i++)
                    {
                        normEq += eqPenaltyParams[i] * equalityConstraints[i](k);
                    }
                }
                double normIq = 0.0;

                if (inequalityConstraints != null)
                {
                    for (int i = 0; i < inequalityConstraints.Count; i++)
                    {
                        normIq += inequalityConstraints[i].PenaltyParam * Math.Max(0.0, inequalityConstraints[i].Function(k));
                    }
                }

                return(f(k) + normEq + normIq);
            }

            stepLength = strongWolfeLineSearch.GetStepLength(meritFunction, direction, x, maxStep, 350);


            foreach (var item in inequalityConstraints.Where(k => !k.IsActive))
            {
                double fvalue = item.Function((x + direction).MinArray);
                if (fvalue < inequalityConstraintTol)
                {
                    continue;
                }

                double step = 1.0;

                if (item.Linear)
                {
                    step = 1.0 - Math.Abs(fvalue / direction[item.BoundIndex]);
                }
                else
                {
                    OptVector derivative = new OptVector(numericalDerivative.EvaluatePartialDerivative(item.Function, x.MinArray, 1));
                    double    fVal       = item.Function(x.MinArray);

                    Func <double[], double> fBase = (k) =>
                    {
                        OptVector diff = new OptVector(k) - x;
                        double    mult = derivative * diff;
                        return(Math.Abs(fVal + mult));
                    };
                    step = strongWolfeLineSearch.GetStepLength(fBase, direction, x, 1.0, 120);
                }

                if (step < stepLength &&
                    step > 0)
                {
                    stepLength = step;
                }
            }


            return(stepLength);
        }
예제 #20
0
        private OptVector[] CalculateLagrangianHessian(
            Func <double[], double> lagrangian,
            OptVector[] lagrangianHessian,
            OptVector xNew,
            OptVector xOld,
            OptVector step)
        {
            OptVector s = step;
            OptVector y = new OptVector(numericalDerivative.EvaluatePartialDerivative(lagrangian, xNew.MinArray, 1)) -
                          new OptVector(numericalDerivative.EvaluatePartialDerivative(lagrangian, xOld.MinArray, 1));

            OptVector[] yy = OptVector.Mult(y, y);
            double      ys = y * s;

            OptVector partialDenom = OptVector.Mult(lagrangianHessian, s);

            OptVector[] num   = OptVector.Mult(partialDenom, OptVector.Mult(s, lagrangianHessian));
            double      denom = -1.0 * s * partialDenom;

            #region Positive definiteness

            if (ys < 1E-15)
            {
                double theta = 0.999999;

                OptVector yNew  = new OptVector(y);
                double    ysNew = ys;

                while (ysNew < lambda * s * partialDenom &&
                       theta >= 0.0)
                {
                    yNew = y * theta + (1.0 - theta) * partialDenom;

                    ysNew = yNew * s;

                    theta = theta - 1E-5;
                }

                y  = yNew;
                ys = ysNew;

                yy = OptVector.Mult(y, y);
            }

            #endregion

            if (ys == 0.0)
            {
                if (step.Length() > 0)
                {
                    return(OptVector.GetIdentity(xNew.Count, step));
                }

                return(OptVector.GetIdentity(xNew.Count));
            }

            OptVector[] addParam1 = OptVector.Div(yy, ys);
            OptVector[] addParam2 = OptVector.Div(num, denom);

            return(OptVector.Sum(OptVector.Sum(lagrangianHessian, addParam1), addParam2));
        }
예제 #21
0
        public OptVector Solve(
            OptVector[] A,

            OptVector b,
            OptVector startX,
            int nIter)
        {
            OptVector[] symmA = A;
            OptVector   normb = b;

            //Symmetrize matrix
            if (CheckSymmetry)
            {
                OptVector[] At = OptVector.Transpose(A);

                if (!OptVector.Equals(A, At))
                {
                    symmA = OptVector.Mult(At, A);
                    normb = OptVector.Mult(At, b);
                }
            }



            OptVector v0 = new OptVector(b.Count);
            OptVector v1 = normb - OptVector.Mult(symmA, startX);

            double    beta1 = v1.Length();
            double    betaN = 0.0;
            double    n     = beta1;
            double    c0    = 1.0;
            double    c1    = 1.0;
            double    s0    = 0.0;
            double    s1    = 0.0;
            OptVector w0    = new OptVector(v1.Count);
            OptVector w_1   = new OptVector(v1.Count);
            OptVector x     = new OptVector(startX);

            for (int i = 0; i < nIter; i++)
            {
                //Calculate Lanczos Vectors
                OptVector v     = (1.0 / beta1) * v1;
                OptVector Av    = OptVector.Mult(symmA, v);
                double    alpha = v * Av;
                v1    = Av - alpha * v - beta1 * v0;
                betaN = v1.Length();

                //Calculate QR factors
                double lambda = c1 * alpha - c0 * s1 * beta1;
                double p1     = Math.Sqrt(lambda * lambda + betaN * betaN);
                double p2     = s1 * alpha + c0 * c1 * beta1;
                double p3     = s0 * beta1;

                //Calculate New Givens Rotations
                c0 = c1;
                c1 = lambda / p1;

                s0 = s1;
                s1 = betaN / p1;

                //Update Solution
                OptVector w = (1.0 / p1) * (v - p3 * w_1 - p2 * w0);

                x = x + c1 * n * w;
                n = -s1 * n;

                residual = Math.Abs(n);

                if (residual < precisionConst)
                {
                    break;
                }

                beta1 = betaN;
                v0    = v;
                w_1   = w0;
                w0    = w;
            }

            return(x);
        }
예제 #22
0
 private OptVector ExtractX(
     OptVector direction,
     OptVector x)
 {
     return(new OptVector(SubArray(direction.MinArray, 0, x.Count)));
 }
예제 #23
0
        static void Main(string[] args)
        {
            double oneOver2Pi = 1.0 / (1.0 * Math.Sqrt(2 * Math.PI));

            Console.WriteLine(NormalCDFInverse(0.99));
            Console.WriteLine(inv_cdf(0.99));
            Console.WriteLine(InverseCDF.QNorm(0.99, 0, 1, true, false));
            Console.WriteLine(NormalCDFInverse(0.5));
            Console.WriteLine(inv_cdf(0.5));
            Console.WriteLine(InverseCDF.QNorm(0.5, 0, 1, true, false));
            Console.WriteLine(NormalCDFInverse(0.31));
            Console.WriteLine(inv_cdf(0.31));
            Console.WriteLine(InverseCDF.QNorm(0.31, 0, 1, true, false));

            //x4−8x2 + 5
            Func <double[], double> testFunc1 = (x) =>
            {
                return(Math.Pow(x[0], 4) - 8 * Math.Pow(x[0], 2) + 5);
            };

            Func <double[], double>[] dtestFunc1 = new Func <double[], double> [1];

            dtestFunc1[0] = (x) =>
            {
                return(4 * Math.Pow(x[0], 3) - 16 * x[0]);
            };

            Func <double[], double> testConstr = (x) =>
            {
                return(5 - Math.Exp(x[0]) + 2.0 * Math.Pow(x[0] - 1, 2));
            };

            Func <double[], double> testv = (x) =>
            {
                double a = x[0];
                return(0.0);
            };

            //Func<Variables, double> testFunc = (x) => {
            //    return Math.Pow(x.Vars[0], 4) - 3 * Math.Pow(x.Vars[0], 3) + 2;
            //};

            //Func<Variables, double> dTestfunc = (x) =>
            //{
            //    return 4 * Math.Pow(x.Vars[0], 3) - 9 * Math.Pow(x.Vars[0], 2);
            //};

            //x4−3x3 + 2

            //TestFunc();

            Func <double[], double> bananaFunc = (x) =>
            {
                return(Math.Pow(1 - x[0], 2) + 100 * Math.Pow(x[1] - x[0] * x[0], 2));
            };

            Func <double[], double> powell = (x) =>
            {
                return(Math.Pow(x[0] + 10 * x[1], 2) +
                       5 * Math.Pow(x[2] - x[3], 2) +
                       Math.Pow(x[1] + 2 * x[2], 4) +
                       10 * Math.Pow(x[0] - x[3], 4));
            };

            OptVector[] ttt = new OptVector[3];
            ttt[0] = new OptVector(new double[3] {
                1, 2, 3
            });
            ttt[1] = new OptVector(new double[3] {
                4, 5, 6
            });
            ttt[2] = new OptVector(new double[3] {
                7, 8, 9
            });

            var tr = OptVector.Transpose(ttt);

            //TestsSQP.Test0();
            TestsSQP.Test1();
            TestsSQP.Test2();
            TestsSQP.Test3();
            ////TestsSQP.Test4();
            ////TestsSQP.Test5();
            TestsSQP.Test6();
            TestsSQP.Test7();
            TestsSQP.Test8();
            TestsSQP.Test9();
            TestsSQP.Test10();
            TestsSQP.Test11();
            TestsSQP.Test12();
            TestsSQP.Test13();
            TestsSQP.Test14();
            TestsSQP.Test15();
            TestsSQP.Test16();
            TestsSQP.Test17();
            TestsSQP.Test18();
            TestsSQP.Test19();
            TestsSQP.Test20();
            TestsSQP.Test21();
            TestsSQP.Test22();
            TestsSQP.Test23();
            TestsSQP.Test24();
            TestsSQP.Test25();
            TestsSQP.Test26();
            TestsSQP.Test27();
            TestsSQP.Test28();
            //TestCGMethod();

            BFGS bfsg = new BFGS();

            var result0 = bfsg.Solve(powell, new double[] { 3.0, -1.0, 0.0, 1.0 }, 10000);

            Console.WriteLine("Min " + powell(result0));

            NLCG gradient = new NLCG();

            var result = gradient.Solve(powell, new double[] { 3.0, -1.0, 0.0, 1.0 }, 4000);

            Console.WriteLine("Min " + powell(result));

            SteepestDescent gradientSteep = new SteepestDescent();

            var result1 = gradientSteep.Solve(powell, new double[] { 3.0, -1.0, 0.0, 1.0 }, 10000);

            Console.WriteLine("Min " + powell(result1));

            //Variables result = SteepestDescent(testFunc, dTestFunc, 2, 20);

            for (int i = 0; i < result.Length; i++)
            {
                Console.WriteLine("result " + result[i]);
            }

            //Console.WriteLine("ver " + testFunc(result));

            Console.ReadLine();
        }
예제 #24
0
        private OptVector GetGradientDirection(OptVector xNew, List <Func <double[], double> > eqConstraints, OptVector lambdaEq, List <InequalityConstraintProperties> inequalityConstraintsProp, OptVector[] hessian, Func <double[], double> lagrangian, OptVector lambdaIq)
        {
            OptVector b = BuildVectorB(eqConstraints, inequalityConstraintsProp, lagrangian, xNew);

            OptVector[] A = BuildMatrixA(eqConstraints, inequalityConstraintsProp, hessian, xNew);

            OptVector direction = CalculateDirection(A, b, xNew, lambdaEq, lambdaIq);

            return(direction);
        }